Skip to content

Commit

Permalink
Persist return value in postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
mattdailis committed Jan 18, 2022
1 parent e15884a commit 66a7b7e
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<ActivityInstanceId> directiveId,
Map<String, SerializedValue> arguments,
SerializedValue returnValue
) {}
Original file line number Diff line number Diff line change
@@ -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
""";

Expand All @@ -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<Parameter> parameters, final List<String> requiredParameters)
public long apply(
final long modelId,
final String name,
final List<Parameter> parameters,
final List<String> 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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,19 @@ public Map<Long, SimulatedActivityRecord> 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<Long>();

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
Expand All @@ -84,7 +85,7 @@ private Optional<Long> readOptionalLong(final ResultSet resultSet, final int ind
return Optional.of(value);
}

private Pair<Optional<ActivityInstanceId>, Map<String, SerializedValue>> parseActivityAttributes(final Reader jsonStream) {
private ActivityAttributesRecord parseActivityAttributes(final Reader jsonStream) {
final var json = Json.createReader(jsonStream).readValue();
return activityAttributesP
.parse(json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public Map<ActivityInstanceId, Long> 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();
}
Expand All @@ -67,8 +67,8 @@ public Map<ActivityInstanceId, Long> apply(
return simIdToPostgresId;
}

private String buildAttributes(final Optional<ActivityInstanceId> directiveId, final Map<String, SerializedValue> arguments) {
return activityAttributesP.unparse(Pair.of(directiveId, arguments)).toString();
private String buildAttributes(final Optional<ActivityInstanceId> directiveId, final Map<String, SerializedValue> arguments, final SerializedValue returnValue) {
return activityAttributesP.unparse(new ActivityAttributesRecord(directiveId, arguments, returnValue)).toString();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ public void updateActivityTypes( final String missionModelId, final Map<String,
try (final var createActivityTypeAction = new CreateActivityTypeAction(connection)) {
final var id = toMissionModelId(missionModelId);
for (final var activityType : activityTypes.values()) {
createActivityTypeAction.apply(id, activityType.name(), activityType.parameters(), activityType.requiredParameters());
createActivityTypeAction.apply(
id,
activityType.name(),
activityType.parameters(),
activityType.requiredParameters(),
activityType.returnTypeValueSchema());
}
}
} catch (final SQLException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ public static Duration parseOffset(final ResultSet resultSet, final int index, f
public static final JsonParser<Map<String, SerializedValue>> activityArgumentsP = mapP(serializedValueP);
public static final JsonParser<Map<String, SerializedValue>> simulationArgumentsP = mapP(serializedValueP);

public static final JsonParser<Pair<Optional<ActivityInstanceId>, Map<String, SerializedValue>>> activityAttributesP = productP
public static final JsonParser<ActivityAttributesRecord> 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())
));
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
Duration duration,
Optional<Long> parentId,
List<Long> childIds,
Optional<ActivityInstanceId> directiveId
Optional<ActivityInstanceId> directiveId,
SerializedValue returnValue
) {}

0 comments on commit 66a7b7e

Please sign in to comment.