-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User metadata annotations #1183
Conversation
706142f
to
416b628
Compare
Fixed a broken test - aerie/constraints/src/main/java/gov/nasa/jpl/aerie/constraints/TypescriptCodeGenerationService.java Lines 392 to 397 in 416b628
|
416b628
to
41fa6ad
Compare
41fa6ad
to
7167780
Compare
7167780
to
1aa1832
Compare
1aa1832
to
1c8f031
Compare
New e2e tests should be passing now. Updates since the walkthrough:
|
1c8f031
to
2d79c22
Compare
2d79c22
to
a697d44
Compare
...-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/AutoValueMappers.java
Outdated
Show resolved
Hide resolved
merlin-driver/src/main/java/gov/nasa/jpl/aerie/merlin/driver/json/ValueSchemaJsonParser.java
Outdated
Show resolved
Hide resolved
merlin-driver/src/main/java/gov/nasa/jpl/aerie/merlin/driver/json/ValueSchemaJsonParser.java
Outdated
Show resolved
Hide resolved
examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/Mission.java
Outdated
Show resolved
Hide resolved
...les/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/Banannotation.java
Outdated
Show resolved
Hide resolved
merlin-sdk/src/main/java/gov/nasa/jpl/aerie/merlin/protocol/types/ValueSchema.java
Outdated
Show resolved
Hide resolved
merlin-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/TypePattern.java
Show resolved
Hide resolved
merlin-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/TypePattern.java
Show resolved
Hide resolved
...-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/AutoValueMappers.java
Outdated
Show resolved
Hide resolved
...-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/AutoValueMappers.java
Outdated
Show resolved
Hide resolved
For ease of review, I've pushed all changes as I looked into whether |
d1ff473
to
387f492
Compare
e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/types/ActivityType.java
Outdated
Show resolved
Hide resolved
...-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/AutoValueMappers.java
Outdated
Show resolved
Hide resolved
...-framework-processor/src/main/java/gov/nasa/jpl/aerie/merlin/processor/AutoValueMappers.java
Show resolved
Hide resolved
b087461
to
e3368f2
Compare
…ncies This fixes a bug with de-duplication of annotated types
e3368f2
to
62b7566
Compare
Description
This is our second attempt. Our first attempt was #1055.
Short term goal: Allow users to provide unit information for parameters, computed attributes, and resources in their mission model, such that this information can be displayed in the UI and extracted via the API.
Broader goal: Set up a pattern that missions, and Aerie developers, can use to add more kinds of metadata in the future, e.g. Range.
There are two (mostly) independent problems to solve here:
The following sections delve into these problems:
How to define custom metadata
We knew from the outset that we would eventually want to be able to annotate deeply nested aspects of a value schema with metadata. E.g. a rover's pose could be characterized by a compound piece of data:
We had originally descoped this capability, but then pivoted (i.e. we increased scope) when the path to implementing it became clear.
The two options to select between were Javadoc tags, and annotations. I will describe both approaches, and explain why we have settled on annotations.
Surface Syntax
This Javadoc tags approach amounted to parsing javadoc comments as strings, and extracting portions of them based on a set of tags, such as @aerie.unit.
It lended itself quite well to class style parameters, since it could be part of the javadoc comment attached to the parameter itself:
Javadoc tags approach
Example of using javadoc to add unit information to a parameter:
Example of using javadoc to add unit information to a computed attributes record:
Example of using
@aerie.resourceName
to assign a unit to all resources that match a regular expression:A limitation that we discovered of parsing the javadocs is that our implementation would only parse javadocs in a known set of locations. This works fine for parameters and computed attributes, but it breaks down for resources, which in practice are defined in submodels.
The second approach we pursued was to introduce a
@Unit
annotation, which could be attached to the type of a parameter or computed attribute:Annotation approach
Example of using an annotation to add unit information to a parameter:
Example of using an annotation to add unit information to a computed attributes record:
What about resources? Those are defined through a different process from parameters and computed attributes. Resources get registered at runtime, in the mission model constructor, rather than at compile time like the other entities. The approach with javadocs would record a regular expression and do name matching at runtime. The current approach instead expects a mission model to provide the units to the registrar as runtime values. Two convenience methods have been defined:
This approach allows us to avoid any custom handling of units in the annotation processor, which means that it will generalize to any future metadata we would like to include. If it turns out that the regular expressions would be a significant quality of life improvement, we can consider that a separate feature.
How is custom metadata serialized
In Java, there is now a new kind of ValueSchema: a
MetaSchema
, which carries aMap<String, SerializedValue>
, as well as a nestedValueSchema
. The interpretation is that all of the metadata in theMetaSchema
applies to the nestedValueSchema
.The
withMeta
method, used to construct aMetaSchema
, checks to see if the inner value is itself aMetaSchema
, and if so merges the two, overlaying the outer one on top of the inner one.When serializing to json, this
Map<String, SerializedValue>
is attached to the nested object, like so:MetaSchema(Map.of("unit", "m"), IntSchema())
becomesFuture-proofing
One of the goals of this PR is to lay the groundwork for adding additional metadata to value schemas.
Part of this PR brings annotations into the
Resolver
andTypePattern
machinery. This allows us to generate value mappers for annotated types.This PR allows users to define their own annotations, and as long as a value mapper is provided for that annotation, Aerie will be able to serialize it and include it in the value schema.
One generalization that this PR leaves undone is to allow for using value mapper methods to define value mappers for annotated types. The nuance here is that, in this PR, we have users use the
@WithMetadata(Unit.class)
annotation to declare an annotation of interest, and we use that to generate a type rule, rather than the users writing the type rule as the return type from a static method, the way that other value mappers are defined. This is due to a limitation of type use annotations that we may be able to work around in the future.Verification
The Banananation example model was updated to include some unit information for parameters, computed attributes, and resources.
Things to test manually:
The second bullet may be handled by e2e tests
Documentation
Future work
@AutoValueMapper.Annotation
to make adding your own metadata annotations less verbose