Attributes for External Sources & Events #1591
Replies: 4 comments 1 reply
-
I am strongly in favor of Option 2: enforcing arguments to have a well defined schema.
|
Beta Was this translation helpful? Give feedback.
-
We met today as a group to discuss options for this and make some decisions to allow GSFC to continue prototyping. Decisions made
Important remaining questions:
While there are still some big unknowns, some of the important questions have been settled, & GSFC team will prototype and meet again with Aerie devs in ~1 week |
Beta Was this translation helpful? Give feedback.
-
Architecture Discussion 2 Notes (11/12)
Conclusions
|
Beta Was this translation helpful? Give feedback.
-
Some Implementation NotesIn implementing this feature, we have encountered 3 different options. They are each enumerated here, with links to their implementing branch(es) where applicable. These all utilize JSON Schema. Implementation 1: Separate SchemasOne way that this implementation can be done is by the use of entirely separated attribute/type schemas. This means that each external source type and each event type has its own attribute/type schema, each of which need to be created and uploaded to AERIE separately. The format of these attribute schemas, regardless of if they are source or event type attribute schemas, would be fundamentally similar, and would look as follows:
They would be uploaded fro a modal like the following: In terms of the backend, the process for validating a source would be as such:
In this process, we make several queries (this can be narrowed down to just 2) against the database, fetching from 2 tables. This is the implementation that can be found here. Implementation 2: Unified Type SchemasThe second option (and the third option) do away with separation of type schemas to a degree. This simplification/option relies on the assumption that event types aren't really reused across source types. This, while a restriction, we believe is a very valid assumption as we have yet to encounter any overlap between event types and source types. When there is overlap, which should be rare, redefining a type across two different source type schemas and renaming them slightly could be done to prevent collisions, though that is far from an ideal solution to this potentially rare case. It is here that we make a fundamental distinction between the second and third options. We mentioned earlier having an internal schema for the external source's formatting. One possible option here is to write the JSON Schema in a vague enough way that references some We will elaborate on the
Here, we have a schema for name-like properties and address-like properties, each of which are reused in the main schema. Instead of expanding those subschemas repeatedly, they are sectioned off so that they can be used repeatedly. An additional feature of
A simple step can combine the two, and allow the first schema to reference the Using this and some conditional logic, we have a way to define a separate
This option requires only 1 call to the database, though it does incur some transformation work on the part of the gateway. The UI would be the same as the first option, just that the creation modal should only have the option to create external source types instead of also having the option to create an external event type. This implementation can be found here. Implementation 3: Per-source-type MegaschemaThis final option combines the
which combines with a user provided
to produce the following megaschema:
this option proposes skipping the computation and just uploading the final object to the database. This would require more work on the user's part, though it is a lot less opaque about what is going on. That being said, validating that this schema above is correct requires a metaschema, which proved to be quite difficult to write correctly. It was in doing so that it became abundantly clear that this option, while more transparent, requires excessive repetition on the user part, and will likely require a user to copy and paste a template when creating new source types, as opposed to just defining a simple Owing to the above difficulties, there is no implementation available for this as it was sort of ruled out as unnecessarily complicated for users and developers. However, should this be the chosen option, we can flesh out the mega-metaschema. |
Beta Was this translation helpful? Give feedback.
-
What
As an extension of external events & sources, we would like to implement something referred to as
arguments
that will allow for expanded capabilities for incorporating events & sources with procedural scheduling (and eventually, constraints).The main goal is to allow procedural scheduling & constraints access to more data about specific external sources & events, which in turn allows mission planners access to more complex planning involving external sources & events.
One important note (discussed later in 'Why' and 'Terminology'): although the
arguments
term is meant to share similarity with an activity directive'sarguments
the arguments introduced here refer to existing data from the external source/event (that is currently not captured), and are immutable. They are not input directly by the user or editable after creation by the user (unless they alter the actual event/source definition). The reference to activity directive'sarguments
is to represent that thesearguments
are specific to a source/event the same way a set ofarguments
is specific to an activity directive.Why
With the initial introduction of external events & sources, we are able to 'categorize' our events & sources during procedural scheduling by the following:
Derivation Group
,External Source Type
, andExternal Event Type
. That is to say: if we are looking for specific events and/or sources we can 'filter' down our potentials based on those 3 fields.For example: if we are looking for all events that pertain to contact periods with the DSN, we will probably have a
DSN Contact
external event type that contains them. We may also have aDSN Contact File
external source type and evenDSN Contact Baseline
orDSN Contact Backup
derivation groups. This is helpful for very basic filtering and classification of our events & sources, however mission planning may require more detailed information about the specific sources and/or events in order to fulfil planning conditions (see the example below).Adding
arguments
to our external events & sources allows mission planners a powerful interface for filtering and classifying events & sources that can directly query events or sources within a shared type that may have unique data/values. Thesearguments
represent data that already exists in the original event definition, and creates an immutable interface to access it from within the event/source itself.These
arguments
were not needed for a baseline implementation of external events/source and procedural scheduling, but are needed for a powerful, complex implementation that can cover what mission planners need access to in order to properly generate activities from external events.arguments
are also especially helpful when you have sources or events used for something generic (ex: aWeather Report
source, as seen in the example below, that may refer to the weather report from a number of different locations). To avoid creating a dozen redundant source or event types to categorize a single piece of data about the source or event,arguments
let us keep the generic source or event type and attach as much additional, classifying data to the source or event as we need.Refer to the example below for more information.
Example/Use Case
Using the 'Weather' example used for external sources & events, the following will depict the use-case of arguments within sources and events.
Arguments in an External Source
Say we have an external source,
WEATHER_REPORT_2024_012_019.json
of typeWeather Report
. This weather report happens to contain the forecasts for the week of January 12th => 19th of 2024. Below is the file's content:Along with our usual information of
key
,valid_at
, and theperiod
, we can see this source has a field ofarguments
that contain additional data about our external source. In this example, we can see the source tells us where the report came from (readingFrom
,lastUpdate
), where the reading is for (location
,locationElevation
,locationLatitude
,locationLongitude
), and some information about the content (avgHumidity
,hasPrecipitation
).This additional information from the external source can help us filter potential sources within the features of procedural scheduling & constraints. Say we want to gather the events from all sources for
Greenbelt, MD
, we can now use thelocation
argument on the source to then get all the contained events, and use them in a goal or constraint.What if we not only want all the events pertaining to
Greenbelt, MD
weather reports, but all the events forGreenbelt, MD
that have alow
of<= 32
, and a chance ofprecipitation
? Our source's events may look like the following:Again, we get information relevant to the event type:
chanceOfPrecipitation
,low
, andhigh
- and values that are specific to that event instance:85
,28
,52
.With
arguments
fully configured on our external source & it's encapsulated events, we can describe a complex scheduling goal that can...Greenbelt, MD
hasPrecipitation: true
low <= 32
andchanceOfPrecipitation >= 80
How
Approach 1: No Schema
Explanation
The first approach is to not use schemas and keep the
arguments
being implemented to a basickey: value
mapping on the external source & event. This is presented as the first approach as it is the simplest, lowest overhead, lowest friction, and 'loosest' implementation.This approach is not ideal as it lacks safety for the user and potentially makes interacting with external events/sources more difficult than if the user had submitted a well-defined schema for their
arguments
, however provides the 'quickest' and easiest process for the user to get started with external source/eventarguments
.Example: External Source
Below is an example of what the
arguments
field of an external source would look like with this approach. Note that there is no change on an external event/source-type level to accommodate for this change.Approach 2: Strict Implementation
Explanation
The second approach is referred to as the strict approach. This implementation implements
arguments
as a schema-like object on the external source/event type level, as well as then implementingarguments
at the external source/event level as akey: object
mapping. Our approach to implementation would utilize JSON Schema in order to allow the user to define their schemas through the JSON Schema language, and then upload or otherwise ingest them into Aerie for use. See below for examplesExample: External Event Type
Example: External Event
Problem 1: The user CAN'T make mistakes
One of the most impactful problems with this approach is that the user cannot make mistakes, and to a greater extent, the source cannot make mistakes. This means, if the user translates the original source incorrectly to the uploaded
JSON
format and includes a field that is not expected for a given source or event type, the source cannot be uploaded. Additionally, if the source itself includes an undefined argument, it cannot be uploaded.Problem 2: UX Friction
The other heavily impactful problem is that to actually implement this approach, the user will need to pre-define their external source and event types manually so that the
arguments
schema can be written and then used to validate the to-be-uploaded external source. This means that to upload an external source a user needs to:Approach 3: Optional Schemas
The third approach is a mixture of the previous two, where the user by default would not need to upload any schemas for their
arguments
, but could opt-in to utilizing schemas. This does essentially incur the complexity of implementing both approach 1 & 2, but would help solve some of the problems (namely UX) by allowing the simplest option by default. Implementing this approach also raises the question of how does a user 'switch' in/out of 'schema' mode and how is that applied (per-source, or per-user, or per-Aerie instance?).Questions/Discussion Points
Supporting complex arguments
Consider an
argument
that is a nested JSON structure:We currently believe these sorts of complex structures should be supported by this feature, as it is entirely possible that planners will have source files that make use of complex structures like above. This is also a major factor in why we believe we can implement the 'schemas' through JSON Schema, as it inherently supports the building and 'schema'-tizing of complex objects like this.
Do we need arguments for external sources?
The case of arguments for external events is more direct: we have an event that may be of a shared type, but have a completely unique piece of data about itself. This is also true for arguments on external sources, however when we filter down the results of a query based on an argument of external events, we get the specifically matching external event(s) to plan against. With external sources, we can filter down to specific sources, but those sources may have external events we don't care about inside. In this case, it would probably be a more efficient query to just query the external events out-right.
Updating Schemas
Should these schemas be updatable? One option is to instead of making the schema updatable, use a new source type/event type when the schema needs to be updated. Additionally, we can choose to avoid implementing any sense of updating in this first iteration, and leave that as a problem to solve later (and so schemas become immutable for now).
Terminology: Metadata vs. Arguments vs. Properties
Initially, we were referring to this feature as
metadata
(and even further back,properties
for external events specifically), however after a conversation we concluded thatarguments
may be a more sufficient name as this feature is closer to thearguments
an activity directive may have rather thanmetadata
. Another option is to useproperties
again - not sure if this term is used elsewhere in Aerie.An argument against
arguments
as the name is that due to the user's familiarity with activity directivearguments
, they may assume that the arguments on an external source or event are mutable and defined by the user - which is NOT the case.How do we define the schemas?
The following applies to approach 2 & 3 which make use of schemas for validating
arguments
. Additionally, we are assuming the schemas would be implemented with JSON Schema as mentioned above.In the UI
CreateGroupsOrTypesModal
already lets the user define external source & event types (though it currently isn't required, as the GraphQL mutation already does that). However because we do expect to support complex objects as 'types', this could become a nightmare to develop within the UI (as opposed to if the options were limited to a simple dropdown of, for example, 'boolean' or 'integer' or 'string'). Note there are tools (1, 2) that could be integrated with Aerie's UI to make this process easier, but may not be worth the trade off of implementing.File Input
File input can be implemented for schemas by having the user upload a JSON Schema that defines their new type's
arguments
. There is more work to be done to figure out exactly how this would work on the back-end, but by using JSON Schema this approach is heavily simplified (i.e., we don't have to do work of defining/re-defining a schema structure).Conclusion
External event and source
arguments
would allow for more complex procedural scheduling (and eventually, constraint writing) to be performed as Aerie could capture additional data on a source-specific or event-specific level.Beta Was this translation helpful? Give feedback.
All reactions