From 66a7b7eb9cc5009c321251acc43a9f72b795e5c4 Mon Sep 17 00:00:00 2001 From: Matt Dailis Date: Sun, 19 Dec 2021 16:58:25 -0800 Subject: [PATCH] Persist return value in postgres --- .../sql/merlin/tables/activity_type.sql | 5 ++++ .../server/http/ResponseSerializers.java | 1 + .../postgres/ActivityAttributesRecord.java | 13 +++++++++ .../postgres/CreateActivityTypeAction.java | 28 +++++++++++++++---- .../GetSimulatedActivitiesAction.java | 11 ++++---- .../PostSimulatedActivitiesAction.java | 6 ++-- .../PostgresMissionModelRepository.java | 7 ++++- .../remotes/postgres/PostgresParsers.java | 7 +++-- .../postgres/SimulatedActivityRecord.java | 3 +- 9 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/ActivityAttributesRecord.java diff --git a/deployment/postgres-init-db/sql/merlin/tables/activity_type.sql b/deployment/postgres-init-db/sql/merlin/tables/activity_type.sql index 611f30a840..e841638bd0 100644 --- a/deployment/postgres-init-db/sql/merlin/tables/activity_type.sql +++ b/deployment/postgres-init-db/sql/merlin/tables/activity_type.sql @@ -3,6 +3,7 @@ create table activity_type ( name text not null, parameters merlin_parameter_set not null, required_parameters merlin_required_parameter_set not null, + return_value_schema jsonb, constraint activity_type_natural_key primary key (model_id, name), @@ -21,3 +22,7 @@ comment on column activity_type.model_id is e'' 'The model defining this activity type.'; comment on column activity_type.parameters is e'' 'The set of parameters accepted by this activity type.'; +comment on column activity_type.required_parameters is e'' + 'A description of which parameters are required to be provided to instantiate this activity type'; +comment on column activity_type.return_value_schema is e'' + 'The type of value returned by the effect model of this activity type'; diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/http/ResponseSerializers.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/http/ResponseSerializers.java index 58476ef409..e08f4413ed 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/http/ResponseSerializers.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/http/ResponseSerializers.java @@ -157,6 +157,7 @@ public static JsonValue serializeSimulatedActivity(final SimulatedActivity simul .add("duration", serializeDuration(simulatedActivity.duration)) .add("parent", serializeNullable(id -> Json.createValue(id.id()), simulatedActivity.parentId)) .add("children", serializeIterable((id -> Json.createValue(id.id())), simulatedActivity.childIds)) + .add("returnValue", serializeArgument(simulatedActivity.returnValue)) .build(); } diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/ActivityAttributesRecord.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/ActivityAttributesRecord.java new file mode 100644 index 0000000000..20c5a71926 --- /dev/null +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/ActivityAttributesRecord.java @@ -0,0 +1,13 @@ +package gov.nasa.jpl.aerie.merlin.server.remotes.postgres; + +import gov.nasa.jpl.aerie.merlin.driver.ActivityInstanceId; +import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue; + +import java.util.Map; +import java.util.Optional; + +public record ActivityAttributesRecord( + Optional directiveId, + Map arguments, + SerializedValue returnValue +) {} diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/CreateActivityTypeAction.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/CreateActivityTypeAction.java index 8b4a150582..a8fd23234d 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/CreateActivityTypeAction.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/CreateActivityTypeAction.java @@ -1,18 +1,25 @@ package gov.nasa.jpl.aerie.merlin.server.remotes.postgres; import gov.nasa.jpl.aerie.merlin.protocol.types.Parameter; +import gov.nasa.jpl.aerie.merlin.protocol.types.ValueSchema; import org.intellij.lang.annotations.Language; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; +import java.util.Optional; + +import static gov.nasa.jpl.aerie.merlin.server.http.ValueSchemaJsonParser.valueSchemaP; /*package-local*/ final class CreateActivityTypeAction implements AutoCloseable { private static final @Language("SQL") String sql = """ - insert into activity_type (model_id, name, parameters, required_parameters) - values (?, ?, ?::json, ?::json) - on conflict (model_id, name) do update set parameters = ?::json, required_parameters = ?::json + insert into activity_type (model_id, name, parameters, required_parameters, return_value_schema) + values (?, ?, ?::json, ?::json, ?::json) + on conflict (model_id, name) do update + set parameters = ?::json, + required_parameters = ?::json, + return_value_schema = ?::json returning model_id """; @@ -22,15 +29,24 @@ public CreateActivityTypeAction(final Connection connection) throws SQLException this.statement = connection.prepareStatement(sql); } - public long apply(final long modelId, final String name, final List parameters, final List requiredParameters) + public long apply( + final long modelId, + final String name, + final List parameters, + final List requiredParameters, + final ValueSchema returnTypeValueSchema) throws SQLException, FailedInsertException { + final var valueSchemaString = valueSchemaP.unparse(returnTypeValueSchema).toString(); + this.statement.setLong(1, modelId); this.statement.setString(2, name); PreparedStatements.setParameters(this.statement, 3, parameters); PreparedStatements.setRequiredParameters(this.statement, 4, requiredParameters); - PreparedStatements.setParameters(this.statement, 5, parameters); - PreparedStatements.setRequiredParameters(this.statement, 6, requiredParameters); + this.statement.setString(5, valueSchemaString); + PreparedStatements.setParameters(this.statement, 6, parameters); + PreparedStatements.setRequiredParameters(this.statement, 7, requiredParameters); + this.statement.setString(8, valueSchemaString); try (final var results = statement.executeQuery()) { if (!results.next()) throw new FailedInsertException("activity_type"); diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/GetSimulatedActivitiesAction.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/GetSimulatedActivitiesAction.java index a547295214..363400f35d 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/GetSimulatedActivitiesAction.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/GetSimulatedActivitiesAction.java @@ -55,18 +55,19 @@ public Map get(final long datasetId, final Timest final var start = simulationStart.toInstant().plus(startOffset.in(MICROSECONDS), ChronoUnit.MICROS); final var duration = parseOffset(resultSet, 5, start); final var attributes = parseActivityAttributes(resultSet.getCharacterStream(6)); - final var directiveId = attributes.getLeft(); - final var arguments = attributes.getRight(); + final var initialChildIds = new ArrayList(); activities.put(id, new SimulatedActivityRecord( type, - arguments, + attributes.arguments(), start, duration, parentId, initialChildIds, - directiveId)); + attributes.directiveId(), + attributes.returnValue() + )); } // Since child IDs are not stored, we assign them by examining the parent ID of each activity @@ -84,7 +85,7 @@ private Optional readOptionalLong(final ResultSet resultSet, final int ind return Optional.of(value); } - private Pair, Map> parseActivityAttributes(final Reader jsonStream) { + private ActivityAttributesRecord parseActivityAttributes(final Reader jsonStream) { final var json = Json.createReader(jsonStream).readValue(); return activityAttributesP .parse(json) diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostSimulatedActivitiesAction.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostSimulatedActivitiesAction.java index becea7e63e..3da562adbc 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostSimulatedActivitiesAction.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostSimulatedActivitiesAction.java @@ -50,7 +50,7 @@ public Map apply( setTimestamp(statement, 4, endTimestamp); setTimestamp(statement, 5, startTimestamp); statement.setString(6, act.type); - statement.setString(7, buildAttributes(act.directiveId, act.arguments)); + statement.setString(7, buildAttributes(act.directiveId, act.arguments, act.returnValue)); statement.addBatch(); } @@ -67,8 +67,8 @@ public Map apply( return simIdToPostgresId; } - private String buildAttributes(final Optional directiveId, final Map arguments) { - return activityAttributesP.unparse(Pair.of(directiveId, arguments)).toString(); + private String buildAttributes(final Optional directiveId, final Map arguments, final SerializedValue returnValue) { + return activityAttributesP.unparse(new ActivityAttributesRecord(directiveId, arguments, returnValue)).toString(); } @Override diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostgresMissionModelRepository.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostgresMissionModelRepository.java index fcfeba2f77..daf6051be6 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostgresMissionModelRepository.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/PostgresMissionModelRepository.java @@ -135,7 +135,12 @@ public void updateActivityTypes( final String missionModelId, final Map> activityArgumentsP = mapP(serializedValueP); public static final JsonParser> simulationArgumentsP = mapP(serializedValueP); - public static final JsonParser, Map>> activityAttributesP = productP + public static final JsonParser activityAttributesP = productP .optionalField("directiveId", activityInstanceIdP) .field("arguments", activityArgumentsP) + .field("return_value", serializedValueP) .map(Iso.of( - untuple((directiveId, arguments) -> Pair.of(directiveId, arguments)), - $ -> tuple($.getLeft(), $.getRight()) + untuple(ActivityAttributesRecord::new), + $ -> tuple($.directiveId(), $.arguments(), $.returnValue()) )); } diff --git a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/SimulatedActivityRecord.java b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/SimulatedActivityRecord.java index 3e22653e64..9d8570022b 100644 --- a/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/SimulatedActivityRecord.java +++ b/merlin-server/src/main/java/gov/nasa/jpl/aerie/merlin/server/remotes/postgres/SimulatedActivityRecord.java @@ -16,5 +16,6 @@ Duration duration, Optional parentId, List childIds, - Optional directiveId + Optional directiveId, + SerializedValue returnValue ) {}