Skip to content

Commit

Permalink
Load external dataset
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienmaillard committed Sep 18, 2023
1 parent 8ff37f3 commit 14f1c8d
Show file tree
Hide file tree
Showing 20 changed files with 426 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static void main(final String[] args) {
final var schedulerService = new CachedSchedulerService(stores.results());
final var scheduleAction = new ScheduleAction(specificationService, schedulerService);

final var generateSchedulingLibAction = new GenerateSchedulingLibAction(merlinService);
final var generateSchedulingLibAction = new GenerateSchedulingLibAction(merlinService, merlinService);

//establish bindings to the service layers
final var bindings = new SchedulerBindings(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import gov.nasa.jpl.aerie.json.JsonParseResult;
import gov.nasa.jpl.aerie.json.JsonParser;
import gov.nasa.jpl.aerie.json.SchemaCache;
import gov.nasa.jpl.aerie.scheduler.server.models.ActivityType;
import gov.nasa.jpl.aerie.scheduler.server.models.SchedulingDSL;
import gov.nasa.jpl.aerie.scheduler.server.services.MissionModelService;

Expand All @@ -17,7 +18,7 @@

public class ActivityTemplateJsonParser implements JsonParser<SchedulingDSL.ActivityTemplate> {

private final Map<String, MissionModelService.ActivityType> activityTypesByName = new HashMap<>();
private final Map<String, ActivityType> activityTypesByName = new HashMap<>();

public ActivityTemplateJsonParser(MissionModelService.MissionModelTypes activityTypes){
activityTypes.activityTypes().forEach((actType)-> activityTypesByName.put(actType.name(), actType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ private void getSchedulingDslTypescript(final Context ctx) {
try {
final var body = parseJson(ctx.body(), hasuraMissionModelIdActionP);
final var missionModelId = body.input().missionModelId();

final var response = this.generateSchedulingLibAction.run(missionModelId);
final var planId = body.input().planId();
final var response = this.generateSchedulingLibAction.run(missionModelId, planId);
final String resultString;
if (response instanceof GenerateSchedulingLibAction.Response.Success r) {
var files = Json.createArrayBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
import gov.nasa.jpl.aerie.json.JsonParser;
import gov.nasa.jpl.aerie.scheduler.server.models.HasuraAction;
import gov.nasa.jpl.aerie.scheduler.server.models.MissionModelId;
import gov.nasa.jpl.aerie.scheduler.server.models.PlanId;
import gov.nasa.jpl.aerie.scheduler.server.models.SpecificationId;
import gov.nasa.jpl.aerie.scheduler.server.models.Timestamp;
import gov.nasa.jpl.aerie.scheduler.server.services.ScheduleFailure;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Optional;

import static gov.nasa.jpl.aerie.json.BasicParsers.*;
import static gov.nasa.jpl.aerie.json.BasicParsers.anyP;
import static gov.nasa.jpl.aerie.json.BasicParsers.longP;
import static gov.nasa.jpl.aerie.json.BasicParsers.productP;
import static gov.nasa.jpl.aerie.json.BasicParsers.stringP;
import static gov.nasa.jpl.aerie.json.Uncurry.tuple;
import static gov.nasa.jpl.aerie.json.Uncurry.untuple;
import static gov.nasa.jpl.aerie.scheduler.server.remotes.postgres.PostgresParsers.pgTimestampP;
Expand All @@ -34,6 +37,11 @@ private SchedulerParsers() {}
. map(
MissionModelId::new,
MissionModelId::id);
public static final JsonParser<PlanId> planIdP
= longP
. map(
PlanId::new,
PlanId::id);

public static final JsonParser<ScheduleFailure> scheduleFailureP = productP
.field("type", stringP)
Expand Down Expand Up @@ -67,29 +75,34 @@ private SchedulerParsers() {}
* @return a parser that accepts hasura action / session details along with specified input type into a tuple
* of the form (name,input,session) ready for application of a mapping
*/
private static <I> JsonParser<Pair<Pair<Pair<String, I>, HasuraAction.Session>, String>> hasuraActionP(final JsonParser<I> inputP) {
private static <I extends HasuraAction.Input> JsonParser<HasuraAction<I>> hasuraActionF(final JsonParser<I> inputP) {
return productP
.field("action", productP.field("name", stringP))
.field("input", inputP)
.field("session_variables", hasuraActionSessionP)
.field("request_query", stringP);
.field("request_query", stringP)
.map(
untuple((name, input, session, requestQuery) -> new HasuraAction<>(name, input, session)),
$ -> tuple($.name(), $.input(), $.session(), ""));
}

/**
* parser for a hasura action that accepts a plan id as its sole input, along with normal hasura session details
*/
public static final JsonParser<HasuraAction<HasuraAction.SpecificationInput>> hasuraSpecificationActionP
= hasuraActionP(productP.field("specificationId", specificationIdP))
= hasuraActionF(productP.field("specificationId", specificationIdP)
.map(
untuple((name, specificationId, session, requestQuery) -> new HasuraAction<>(name, new HasuraAction.SpecificationInput(specificationId), session)),
action -> tuple(action.name(), action.input().specificationId(), action.session(), ""));
untuple(HasuraAction.SpecificationInput::new),
HasuraAction.SpecificationInput::specificationId));

/**
* parser for a hasura action that accepts a mission model id as its sole input, along with normal hasura session details
*/
public static final JsonParser<HasuraAction<HasuraAction.MissionModelIdInput>> hasuraMissionModelIdActionP
= hasuraActionP(productP.field("missionModelId", missionModelIdP))
= hasuraActionF(productP
.field("missionModelId", missionModelIdP)
.optionalField("planId", planIdP)
.map(
untuple((name, missionModelId, session, requestQuery) -> new HasuraAction<>(name, new HasuraAction.MissionModelIdInput(missionModelId), session)),
action -> tuple(action.name(), action.input().missionModelId(), action.session(), ""));
untuple(HasuraAction.MissionModelIdInput::new),
input -> tuple(input.missionModelId(), input.planId())));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package gov.nasa.jpl.aerie.scheduler.server.models;

import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
import gov.nasa.jpl.aerie.merlin.protocol.types.ValueSchema;

import java.util.Map;

public record ActivityType(String name, Map<String, ValueSchema> parameters, Map<String, Map<String, SerializedValue>> presets) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gov.nasa.jpl.aerie.scheduler.server.models;

import gov.nasa.jpl.aerie.constraints.model.DiscreteProfile;
import gov.nasa.jpl.aerie.constraints.model.LinearProfile;

import java.util.Collection;
import java.util.Map;

public record ExternalProfiles(
Map<String, LinearProfile> realProfiles,
Map<String, DiscreteProfile> discreteProfiles,
Collection<ResourceType> resourceTypes) {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package gov.nasa.jpl.aerie.scheduler.server.models;

import java.util.Optional;

public record HasuraAction<I extends HasuraAction.Input>(String name, I input, Session session)
{
public record Session(String hasuraRole, String hasuraUserId) { }

public sealed interface Input permits SpecificationInput, MissionModelIdInput { }

public record SpecificationInput(SpecificationId specificationId) implements Input { }
public record MissionModelIdInput(MissionModelId missionModelId) implements Input { }
public record MissionModelIdInput(MissionModelId missionModelId, Optional<PlanId> planId) implements Input { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package gov.nasa.jpl.aerie.scheduler.server.models;

import gov.nasa.jpl.aerie.merlin.protocol.types.ValueSchema;

public record ResourceType(String name, ValueSchema schema) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package gov.nasa.jpl.aerie.scheduler.server.models;

import gov.nasa.jpl.aerie.merlin.driver.engine.ProfileSegment;
import gov.nasa.jpl.aerie.merlin.protocol.types.RealDynamics;
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
import gov.nasa.jpl.aerie.merlin.protocol.types.ValueSchema;
import org.apache.commons.lang3.tuple.Pair;

import java.util.List;
import java.util.Map;

public record UnwrappedProfileSet(
Map<String, Pair<ValueSchema, List<ProfileSegment<RealDynamics>>>> realProfiles,
Map<String, Pair<ValueSchema, List<ProfileSegment<SerializedValue>>>> discreteProfiles
){}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import gov.nasa.jpl.aerie.scheduler.server.exceptions.NoSuchMissionModelException;
import gov.nasa.jpl.aerie.scheduler.server.exceptions.NoSuchPlanException;
import gov.nasa.jpl.aerie.scheduler.server.models.MissionModelId;
import gov.nasa.jpl.aerie.scheduler.server.models.PlanId;

public record GenerateSchedulingLibAction(
MissionModelService missionModelService
MissionModelService missionModelService,
PlanService.ReaderRole planService
) {
public GenerateSchedulingLibAction {
Objects.requireNonNull(missionModelService);
Objects.requireNonNull(planService);
}

/**
Expand All @@ -25,20 +30,27 @@ record Success(Map<String, String> files) implements Response {}
}

/**
* execute the scheduling operation on the target plan (or retrieve existing scheduling results)
* generates the scheduling typescript files
*
* @param missionModelId the id of the mission model for which to generate a scheduling library
* @param planId the optional id of the plan concerned by this code generation, if plan id is provided, code will be generated for external resources
* associated with the plan
* @return a response object wrapping the results of generating the code (either successful or not)
*/
public Response run(final MissionModelId missionModelId) {
public Response run(final MissionModelId missionModelId, final Optional<PlanId> planId) {
try {
final var schedulingDsl = getTypescriptResource("scheduler-edsl-fluent-api.ts");
final var schedulerAst = getTypescriptResource("scheduler-ast.ts");
final var windowsDsl = getTypescriptResource("constraints/constraints-edsl-fluent-api.ts");
final var windowsAst = getTypescriptResource("constraints/constraints-ast.ts");
final var temporalPolyfillTypes = getTypescriptResource("constraints/TemporalPolyfillTypes.ts");

final var missionModelTypes = missionModelService.getMissionModelTypes(missionModelId);

var missionModelTypes = missionModelService.getMissionModelTypes(missionModelId);
if(planId.isPresent()) {
final var allResourceTypes = planService.getResourceTypes(planId.get());
missionModelTypes = new MissionModelService.MissionModelTypes(missionModelTypes.activityTypes(), allResourceTypes);
}

final var generatedSchedulerCode = TypescriptCodeGenerationService.generateTypescriptTypesFromMissionModel(missionModelTypes);
final var generatedConstraintsCode = gov.nasa.jpl.aerie.constraints.TypescriptCodeGenerationService
Expand All @@ -54,7 +66,8 @@ public Response run(final MissionModelId missionModelId) {
"file:///mission-model-generated-code.ts", generatedConstraintsCode,
"file:///%s".formatted(temporalPolyfillTypes.basename), temporalPolyfillTypes.source
));
} catch (final NoSuchMissionModelException | IOException | MissionModelService.MissionModelServiceException e) {
} catch (final IOException | MissionModelService.MissionModelServiceException | PlanServiceException |
NoSuchPlanException | NoSuchMissionModelException e) {
return new Response.Failure(e.getMessage());
}
}
Expand Down
Loading

0 comments on commit 14f1c8d

Please sign in to comment.