From f13b669d57b0fa6990d436fe9ad3946ad22447e8 Mon Sep 17 00:00:00 2001 From: JoelCourtney Date: Thu, 30 Jan 2025 16:22:32 -0800 Subject: [PATCH] Move anchor update into general activity modify mutation --- .../GraphQLMerlinDatabaseService.java | 63 +++++++------------ .../services/MerlinDatabaseService.java | 9 --- .../services/SynchronousSchedulerAgent.java | 1 - .../services/MockMerlinDatabaseService.java | 4 -- 4 files changed, 24 insertions(+), 53 deletions(-) diff --git a/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/GraphQLMerlinDatabaseService.java b/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/GraphQLMerlinDatabaseService.java index 49716468f3..5cabdd407a 100644 --- a/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/GraphQLMerlinDatabaseService.java +++ b/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/GraphQLMerlinDatabaseService.java @@ -135,7 +135,7 @@ public record DatasetIds(DatasetId datasetId, SimulationDatasetId simulationData * @param gqlStr the graphQL query or mutation to send to aerie * @return the json response returned by aerie, or an empty optional in case of io errors */ - protected Optional postRequest(final String gqlStr) throws IOException, MerlinServiceException { + private Optional postRequest(final String gqlStr) throws IOException, MerlinServiceException { try { //TODO: (mem optimization) use streams here to avoid several copies of strings final var reqBody = Json.createObjectBuilder().add("query", gqlStr).build(); @@ -426,7 +426,7 @@ public Map updatePlanActivityDirective for (final var activity : plan.getActivities()) { if(activity.getParentActivity().isPresent()) continue; // Skip generated activities if (!activity.isNew()) { - final var actFromInitialPlan = initialPlan.getActivityById(activity.id()); + final var actFromInitialPlan = initialPlan.getActivityById(activity.id()).get(); //if act was present in initial plan final var activityDirectiveFromSchedulingDirective = new ActivityDirective( activity.startOffset(), @@ -435,9 +435,9 @@ public Map updatePlanActivityDirective activity.anchorId(), activity.anchoredToStart() ); - if (!activityDirectiveFromSchedulingDirective.equals(actFromInitialPlan.get())) { + if (!activityDirectiveFromSchedulingDirective.equals(actFromInitialPlan)) { final var newState = activityDirectiveFromSchedulingDirective.serializedActivity(); - final var oldState = actFromInitialPlan.get().serializedActivity(); + final var oldState = actFromInitialPlan.serializedActivity(); if (!Objects.equals(newState.getTypeName(), oldState.getTypeName())) { throw new IllegalStateException( "Modified activities cannot change type. Was " + oldState.getTypeName() @@ -472,32 +472,6 @@ public Map updatePlanActivityDirective return ids; } - @Override - public void updatePlanActivityDirectiveAnchors(final PlanId planId, final Plan plan, final Map uploadIdMap) - throws MerlinServiceException, IOException - { - final var request = new StringBuilder(); - final var acts = plan.getActivities(); - request.append("mutation {"); - var hasUpdate = false; - for (final SchedulingActivity act: acts) { - if (act.isNew() && act.anchorId() != null) { - hasUpdate = true; - final var id = uploadIdMap.get(act.id()).id(); - request.append(""" - update_%d: update_activity_directive_by_pk(pk_columns: {id: %d, plan_id: %d}, _set: {anchor_id: %d}) { - id - } - """.formatted(id, id, planId.id(), uploadIdMap.get(act.anchorId()).id()) - ); - } - } - if (hasUpdate) { - request.append("}"); - postRequest(request.toString()); - } - } - /** * {@inheritDoc} */ @@ -597,6 +571,10 @@ mutation createAllPlanActivityDirectives($activities: [activity_directive_insert .add("start_offset", act.startOffset().toString()) .add("anchored_to_start", act.anchoredToStart()); + if (act.anchorId() != null) { + insertionObject.add("anchor_id", act.anchorId().toString()); + } + if (act.name() != null) insertionObject = insertionObject.add("name", act.name()); //add duration to parameters if controllable @@ -676,6 +654,12 @@ private void modifyActivityDirectives( .add("anchored_to_start", act.anchoredToStart()) .add("name", act.name()); + if (act.anchorId() == null) { + activityObject.addNull("anchor_id"); + } else { + activityObject.add("anchor_id", act.anchorId().id()); + } + final var insertionObjectArguments = Json.createObjectBuilder(); for (final var arg : act.arguments().entrySet()) { insertionObjectArguments.add(arg.getKey(), serializedValueP.unparse(arg.getValue())); @@ -683,6 +667,7 @@ private void modifyActivityDirectives( activityObject.add("arguments", insertionObjectArguments.build()); arguments.add("activity_%d".formatted(id), activityObject); } + request.append("}"); postRequest(request.toString(), arguments.build()).orElseThrow(() -> new NoSuchPlanException(planId)); } @@ -694,15 +679,15 @@ private void deleteActivityDirectives( { if (ids.isEmpty()) return; ensurePlanExists(planId); - final var request = new StringBuilder(); - request.append("mutation deletePlanActivityDirectives {"); - for (final var id : ids) { - request.append(""" - delete_%d: delete_activity_directive_by_pk(id: %d, plan_id: %d) {affected_rows} - """.formatted(id.id(), id.id(), planId.id())); - } - request.append("}"); - postRequest(request.toString()).orElseThrow(() -> new NoSuchPlanException(planId)); + final var idString = ids.stream().map(String::valueOf).collect(Collectors.joining(",")); + final var request = """ + mutation deletePlanActivityDirectives($planId: Int! = %d, $directiveIds: [Int!]! = [%s]) { + delete_activity_directive(where: {_and: {plan_id: {_eq: $planId}, id: {_in: $directiveIds}}}) { + affected_rows + } + } + """.formatted(planId.id(), idString); + postRequest(request).orElseThrow(() -> new NoSuchPlanException(planId)); } diff --git a/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/MerlinDatabaseService.java b/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/MerlinDatabaseService.java index 18939f8d1f..dba36cd5d4 100644 --- a/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/MerlinDatabaseService.java +++ b/scheduler-server/src/main/java/gov/nasa/jpl/aerie/scheduler/server/services/MerlinDatabaseService.java @@ -169,15 +169,6 @@ Map updatePlanActivityDirectives( ) throws IOException, NoSuchPlanException, MerlinServiceException, NoSuchActivityInstanceException; - /** - * update the list of SchedulingActivityDirectives with anchors, replacing the anchorIds generated by the - * scheduler by the new ids generated by the database - * @throws MerlinServiceException - * @throws IOException - */ - void updatePlanActivityDirectiveAnchors(final PlanId planId, final Plan plan, final Map uploadIdMap) - throws MerlinServiceException, IOException; - /** * delete all the activity instances stored in the target plan container * diff --git a/scheduler-worker/src/main/java/gov/nasa/jpl/aerie/scheduler/worker/services/SynchronousSchedulerAgent.java b/scheduler-worker/src/main/java/gov/nasa/jpl/aerie/scheduler/worker/services/SynchronousSchedulerAgent.java index 1347e2afac..3cbfbc9571 100644 --- a/scheduler-worker/src/main/java/gov/nasa/jpl/aerie/scheduler/worker/services/SynchronousSchedulerAgent.java +++ b/scheduler-worker/src/main/java/gov/nasa/jpl/aerie/scheduler/worker/services/SynchronousSchedulerAgent.java @@ -279,7 +279,6 @@ public void schedule( ); } - merlinDatabaseService.updatePlanActivityDirectiveAnchors(specification.planId(), solutionPlan, uploadIdMap); //collect results and notify subscribers of success final var results = collectResults(solutionPlan, uploadIdMap, goals); diff --git a/scheduler-worker/src/test/java/gov/nasa/jpl/aerie/scheduler/worker/services/MockMerlinDatabaseService.java b/scheduler-worker/src/test/java/gov/nasa/jpl/aerie/scheduler/worker/services/MockMerlinDatabaseService.java index f79c1acf1d..c9ea480a5f 100644 --- a/scheduler-worker/src/test/java/gov/nasa/jpl/aerie/scheduler/worker/services/MockMerlinDatabaseService.java +++ b/scheduler-worker/src/test/java/gov/nasa/jpl/aerie/scheduler/worker/services/MockMerlinDatabaseService.java @@ -140,10 +140,6 @@ public Map updatePlanActivityDirective return res; } - @Override - public void updatePlanActivityDirectiveAnchors(final PlanId planId, final Plan plan, final Map uploadIdMap) - {} - @Override public void ensurePlanExists(final PlanId planId) {