REST API for accessing adjuncts (including highlights)#821
REST API for accessing adjuncts (including highlights)#821asfgit merged 10 commits intoapache:masterfrom
Conversation
07247e8 to
45261c7
Compare
Big changes to config key construction, following on from previous deprecation
4a148f9 to
83c3d50
Compare
|
rebased to incorporate deprecation around the multiple config REST classes and add a tidy API for that |
|
@ahgittin The description says |
|
@tbouron It's up to date. Primarily it is still just the one commit adding the Adjunct API -- it does have a lot of lines but they are mostly boilerplate (like a couple hundred just to declare the API) ... REST cruft and annotations. However the merge of the |
|
Cool, thanks @ahgittin. I'm reviewing it right now. |
There was a problem hiding this comment.
Thanks @ahgittin for the PR. There are few minor comments but most importantly, I tested it and found 2 interesting things:
- If you run in karaf mode (which is the default now) the new endpoint is not available! It's not the case for classic though.
- on the swagger page, it is never mentioned that the entire
Entity PolicyandEntity Policy Configare deprecated.
| /** | ||
| * True if everything has been _started_ (or it is starting) but not stopped, | ||
| * even if it is suspended; see also {@link #isActive()} | ||
| * even if it is suspended; see also {@link #isRunning()} |
There was a problem hiding this comment.
Neither of isRunning or isActive methods are available in the class. Did you want to link to somewhere else?
There was a problem hiding this comment.
isRunning is inherited from EntityAdjunct, so I think this javadoc link is ok.
There was a problem hiding this comment.
isRunning() is avail, inherited from EntityAdjunct
| } | ||
|
|
||
| public interface FeedSupport { | ||
| public interface FeedSupport extends Iterable<Feed> { |
There was a problem hiding this comment.
Is it really necessary to extend from Iterable and have an iterator() method here where we can get it from the getFeed().iterator() method (which always returns a collection) ? I don't see the benefit of creating this small shortcut
There was a problem hiding this comment.
Adding this gives consistency with entity's enrichers() and policies() which both return something that implements Iterable<T>. I therefore think it's a good idea.
There was a problem hiding this comment.
this is to bring it in line with other AdjunctSupport classes. have made more steps in this direction in a new commit.
| return Lifecycle.CREATED; | ||
| } | ||
|
|
||
| return Lifecycle.STOPPED; |
There was a problem hiding this comment.
What other adjunct should it be to arrive here? Enrichers? In this case, is an enricher really STOPPED instead of CREATED?
There was a problem hiding this comment.
you are right, changed
| } | ||
|
|
||
| @Beta | ||
| public static Lifecycle inferAdjunctStatus(EntityAdjunct a) { |
There was a problem hiding this comment.
Sounds like this method is not in a right class. Would be more meaningful inside an Adjuncts class for example (an since it's static, it is not an issue to move it)
There was a problem hiding this comment.
I would also deprecate the entire Policies class as all methods are already deprecated
There was a problem hiding this comment.
good spot. moved to EntityAdjuncts and deprecated this class, removing previously deprecated methods
| @ApiParam(value = "Entity ID or name", required = true) | ||
| @PathParam("entity") final String entityToken, | ||
| @ApiParam(value = "Filter by adjunct type", required = false) | ||
| @QueryParam("adjunctType") final String adjunctType); |
There was a problem hiding this comment.
type would be better here as we already have the context, i.e. we are looking at a specific type for an adjunct. But no strong feelings. It will also be consistent with the POST operation below
There was a problem hiding this comment.
I wondered about type as well. Problem is we don't support filtering by the actual type (e.g. if someone is looking for AutoScalerPolicy only). It's a very similar discussion to the subtype/supertype/category discussion for PR https://github.com/apache/brooklyn-server/pull/810/files#diff-53a117c93b2d8af2b0b2198599c0c6d1. I think we should follow the same naming here as we do there - i.e. supertype.
There was a problem hiding this comment.
no, the POST takes a specific registered type, whereas this is essentially the adjunct kind; have improved comments to make clear. would adjunctKind be a better name? or supertype for consistency with /catalog/types ?
| EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctId); | ||
| if (adjunct instanceof Policy) ((Policy)adjunct).resume(); | ||
| else if (adjunct instanceof Feed) ((Feed)adjunct).resume(); | ||
| else throw WebResourceUtils.badRequest("%s does not support start/resume", adjunct); |
There was a problem hiding this comment.
Do you think enrichers should support suspend/resume? If so, worth adding a TODO here.
| EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctId); | ||
| if (adjunct instanceof Policy) ((Policy)adjunct).suspend(); | ||
| else if (adjunct instanceof Feed) ((Feed)adjunct).suspend(); | ||
| else throw WebResourceUtils.badRequest("%s does not support suspend", adjunct); |
| return Response.status(Response.Status.OK).build(); | ||
| } | ||
|
|
||
| public static String getStringValueForDisplay(BrooklynRestResourceUtils utils, EntityAdjunct policy, Object value) { |
There was a problem hiding this comment.
This method is unused, can be deleted
| import com.google.common.collect.ImmutableSet; | ||
| import com.google.common.collect.Sets; | ||
|
|
||
| /** @deprecated since 0.13.0 use RegisteredType methods */ |
There was a problem hiding this comment.
Missing Javadoc link for RegisteredType
| } | ||
| for (Feed p: ((EntityInternal)entity).feeds()) { | ||
| if (adjunct.equals(p.getDisplayName())) return p; | ||
| } |
There was a problem hiding this comment.
You can group the loops of the same type, that would reduce in half the processing time
There was a problem hiding this comment.
Depends whether we worry about a display name being the same as an id anywhere - and thus what guarantees we're trying to give.
I probably agree @tbouron. If we do want to keep them separate, we should iterate over all ids (policies, enrichers, feeds) before going on to display names.
There was a problem hiding this comment.
no - in perverse case where we have feed<ID=1 name=2> and feed<ID=2 name=foo> a call to get "2" should return the latter, whereas combining loops would return the former
we do need to compare all by ID's first however
agree it's an edge case and isn't significant but think the code should stay with separate loops.
PS processing time change would not be as large as you say as the string comparison dominates execution time and that is unchanged by combining loops.
|
BTW, I just realised that there is no tests coverage for the new endpoints |
aledsage
left a comment
There was a problem hiding this comment.
LGTM - only minor comments.
| AbstractBrooklynObjectSpec<?, ?> spec; | ||
| if (rt!=null) { | ||
| spec = brooklyn().getTypeRegistry().createSpec(rt, null, null); | ||
| } else { |
There was a problem hiding this comment.
(I see this code is taken from PolicyResource.addPolicy, and has been approved - therefore no strong feelings for this PR.)
Do we really need the fallback to java, or can we assume that it must be in the catalog? (we don't even support feeds, which aren't in the catalog yet).
Ideally I'd like us to not have to support this code path, or to have a deprecation warning logged in that else branch (telling people to add it to the catalog).
There was a problem hiding this comment.
i'd like to switch to yaml for this, have added comment
| @ApiResponse(code = 404, message = "Could not find application or entity"), | ||
| @ApiResponse(code = 400, message = "Type is not a suitable adjunct") | ||
| }) | ||
| public AdjunctSummary addAdjunct( |
There was a problem hiding this comment.
I compared the EntityApi.addChildren to this. It would be really nice if one could just pass in YAML for the adjunct being added (similar to addChildren).
How feasible would that be? I'm guessing our yaml parser just doesn't have the right entry points for that.
Perhaps we should mark this as @Beta (including in the swagger description text, and come back to it in a v2?
There was a problem hiding this comment.
have added comment about supporting yaml. this isn't an addition, it's just a migration, so i wouldn't deprecate until we have the yaml parser for it. (with yoml it should be easy to plug in to the right place. not too hard even so.)
| * | ||
| * @throws 404 or 412 (unless input is null in which case output is null) */ | ||
| public EntityAdjunct getAdjunct(Entity entity, String adjunct) { | ||
| if (adjunct==null) return null; |
There was a problem hiding this comment.
Feels wrong to return null if the adjunct param is null.
Looking at the uses of it, that results in a subsequent NPE (i.e. a 500 response code).
I'd change this method to return an appropriate 4xx response code (not sure which one - writing this offline!)
I know that in this PR you've just followed the same convention as for getPolicy(), getEntity(), etc. But I think they are wrong as well! Happy for us to do that in a different PR.
There was a problem hiding this comment.
let's make it separate just in case -- agree no use case for null input. i'd probably make it a fail-fast NPE (500 or 412 precondition failed) rather than a 404.
| EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctId); | ||
| if (adjunct instanceof Policy) ((Policy)adjunct).resume(); | ||
| else if (adjunct instanceof Feed) ((Feed)adjunct).resume(); | ||
| else throw WebResourceUtils.badRequest("%s does not support start/resume", adjunct); |
There was a problem hiding this comment.
Do you think enrichers should support suspend/resume? If so, worth adding a TODO here.
| return result; | ||
| } | ||
|
|
||
| // TODO support parameters ?show=value,summary&name=xxx &format={string,json,xml} |
There was a problem hiding this comment.
I'd move that comment to the AdjunctsApi interface, rather than in the impl (given it's about the api rather than the implementation).
| public String getConfig(String application, String entityToken, String adjunctToken, String configKeyName) { | ||
| EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctToken); | ||
| Set<ConfigKey<?>> cki = adjunct.config().findKeysDeclared(ConfigPredicates.nameSatisfies(Predicates.equalTo(configKeyName))); | ||
| if (cki.isEmpty()) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, adjunctToken, entityToken); |
There was a problem hiding this comment.
Should be "in adjunct ", rather than "in policy ".
|
|
||
| EntityAdjunct adjunct = brooklyn().getAdjunct(entity, adjunctToken); | ||
| Set<ConfigKey<?>> cki = adjunct.config().findKeysDeclared(ConfigPredicates.nameSatisfies(Predicates.equalTo(configKeyName))); | ||
| if (cki.isEmpty()) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, adjunctToken, entityToken); |
There was a problem hiding this comment.
Should be "in adjunct ", rather than "in policy ".
| public ConfigSummary transform() { | ||
| MutableMap.Builder<String, URI> lb = new MutableMap.Builder<String, URI>(); | ||
|
|
||
| if (ub!=null && entity!=null) { |
There was a problem hiding this comment.
Feels like a programming error if someone called includeLinks (to supply a UriBuilder), but the entity is null. Perhaps fail-fast rather than just missing out the links? Otherwise our unit tests may well all pass if such a programming error is introduced.
There was a problem hiding this comment.
there might be a context where someone wants to include whatever links are possible but an entity may or may not be present. i wouldn't say it's necessarily a programming error. if inclusion in links is wanted unit tests should check it explicitly rather than constrain this method to fail-fast.
i'll update javadoc on includeLinks methods
| @Api("Entity Policies") | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| /** @deprecated since 0.12.0 use AdjunctApi */ |
There was a problem hiding this comment.
Shouldn't this be "since 0.13.0"?
(Please search https://github.com/apache/brooklyn-server/pull/821/files for that text)
| } | ||
| for (Feed p: ((EntityInternal)entity).feeds()) { | ||
| if (adjunct.equals(p.getDisplayName())) return p; | ||
| } |
There was a problem hiding this comment.
Depends whether we worry about a display name being the same as an id anywhere - and thus what guarantees we're trying to give.
I probably agree @tbouron. If we do want to keep them separate, we should iterate over all ids (policies, enrichers, feeds) before going on to display names.
…lasses deprecating more methods which need to change or should go will need to add FeedSpec in future to bring it fully in line
…date other deprecated
e2c3f4c to
28dbb83
Compare
|
one question from above to call out special @tbouron (given how github hides things) regarding the you've suggested |
|
left it as tests added that's everything addresses i think |
|
@ahgittin Sorry, I did miss your comment. I was suggesting type to be consistent with the |


NB: builds on #810 and #818, review and merge those first
This is then just one commit (currently) which:
AdjunctApicombining all the functionality ofPolicyApiandPolicyConfigApigeneralized across adjunct typesAdjunctConfigSummaryCatalogApi/catalogendpoint (since we are deprecating; also there is some overlap atCatalogPolicyItemandPolicyConfigSummaryetc)This is mostly a drop-in replacement for the
/applications/XXX/entities/XXX/policies/*endpoints, now using/applications/XXX/entities/XXX/adjuncts/*and returning other items. Note also that:GET /v1/applications/XXX/entities/XXX/adjuncts?adjunctType=policyfilters by policy (same for other types)adjunctTypeis included in the returned objectGET /v1/applications/XXX/entities/XXX/adjuncts/XXXincludes more info (config keys aka parameters, and values)linkson the detail object include links tostartandstopif and only if the adjunct supports that; it is recommended that clients use this value or at least check its presence rather than assume the declared.../startand.../stopendpoints will always be supported, as some adjuncts don't support (such as enrichers ... though we could and might change that ... so doing this check will be future-proof)