Skip to content

Commit

Permalink
Merge pull request #1249 from NASA-AMMOS/include_constraint_id
Browse files Browse the repository at this point in the history
Include constraintID
  • Loading branch information
goetzrrGit authored Dec 5, 2023
2 parents 2b90a43 + b3c1940 commit 2dff316
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 64 deletions.
6 changes: 3 additions & 3 deletions deployment/hasura/metadata/actions.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -280,16 +280,16 @@ type ResourceSamplesResponse {

type ConstraintResponse {
success: String!
constraintId: Int!,
constraintName: String!,
type: String!,
errors: [UserCodeError!]!
results: [ConstraintResult!]!
}

type ConstraintResult {
violations: [ConstraintViolation!]!,
gaps: [Interval!]!
constraintId: Int!,
constraintName: String!,
type: String!,
resourceIds: [String!]!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ void constraintsSucceedOneViolation() throws IOException {
final var constraintsResponses = hasura.checkConstraints(planId);
assertEquals(1, constraintsResponses.size());

// Check the Result
// Check the Response
final var constraintResponse = constraintsResponses.get(0);
assertTrue(constraintResponse.success());
assertEquals(constraintId, constraintResponse.constraintId());
assertEquals(constraintName, constraintResponse.constraintName());
assertEquals("plan", constraintResponse.type());
// Check the Result
assertTrue(constraintResponse.result().isPresent());
final var constraintResult = constraintResponse.result().get();
assertEquals(constraintId, constraintResult.constraintId());
assertEquals(constraintName, constraintResult.constraintName());

// Resources
final var resources = constraintResult.resourceIds();
assertEquals(2, resources.size());
Expand Down Expand Up @@ -139,7 +140,10 @@ void constraintsSucceedNoViolations() throws IOException {
final var constraintResponses = hasura.checkConstraints(planId);

assertEquals(1, constraintResponses.size());
assertTrue( constraintResponses.get(0).success());
assertTrue(constraintResponses.get(0).success());
assertEquals(constraintId, constraintResponses.get(0).constraintId());
assertEquals(constraintName, constraintResponses.get(0).constraintName());
assertEquals("plan", constraintResponses.get(0).type());
assertTrue( constraintResponses.get(0).result().isPresent());
assertEquals(0, constraintResponses.get(0).result().get().violations().size());
}
Expand All @@ -153,6 +157,7 @@ void constraintCachedViolation() throws IOException {
// There's the correct number of results
assertEquals(1, cachedRuns.size());
assertEquals(1, constraintResponses.size());
assertEquals(cachedRuns.get(0).constraintId(),constraintId);

// Check properties
final var cachedRun = cachedRuns.get(0);
Expand Down Expand Up @@ -190,9 +195,6 @@ void constraintCachedNoViolations() throws IOException {
// Check results
assertTrue(cachedRun.results().isPresent());
final var results = cachedRun.results().get();
assertEquals(constraintId, results.constraintId());
assertEquals("fruit_equal_peel",results.constraintName());
assertEquals("plan",results.type());
assertEquals(2,results.resourceIds().size());
assertEquals("/peel",results.resourceIds().get(0));
assertEquals("/fruit",results.resourceIds().get(1));
Expand Down Expand Up @@ -240,13 +242,16 @@ void constraintsWorkMonthLongActivity() throws IOException {
final var constraintsResponses = hasura.checkConstraints(planId);
assertEquals(1, constraintsResponses.size());

// Check the Result
// Check the Response
final var constraintResponse = constraintsResponses.get(0);
assertTrue(constraintResponse.success());
assertEquals(constraintId,constraintResponse.constraintId());
assertEquals(constraintName, constraintResponse.constraintName());
assertEquals("plan", constraintResponse.type());

//Check Result
assertTrue(constraintResponse.result().isPresent());
final var constraintResult = constraintResponse.result().get();
assertEquals(constraintId, constraintResult.constraintId());
assertEquals(constraintName, constraintResult.constraintName());

// Resources
final var resources = constraintResult.resourceIds();
Expand Down Expand Up @@ -274,6 +279,9 @@ void runConstraintsOnOldSimulation() throws IOException {
// Expect no violations on the new simulation
final var newConstraintResponses = hasura.checkConstraints(planId, newSimDatasetId);
assertEquals(1, newConstraintResponses.size());
assertEquals(constraintId, newConstraintResponses.get(0).constraintId());
assertEquals(constraintName, newConstraintResponses.get(0).constraintName());
assertEquals("plan", newConstraintResponses.get(0).type());
assertTrue(newConstraintResponses.get(0).result().isPresent());
final var newConstraintResult = newConstraintResponses.get(0).result().get();
assertTrue(newConstraintResult.violations().isEmpty());
Expand All @@ -286,12 +294,12 @@ void runConstraintsOnOldSimulation() throws IOException {
// Check the Result
final var oldConstraintResponse = oldConstraintsResponses.get(0);
assertTrue(oldConstraintResponse.success());
assertEquals(constraintId, oldConstraintResponse.constraintId());
assertEquals(constraintName, oldConstraintResponse.constraintName());
assertEquals("plan", oldConstraintResponse.type());
assertTrue(oldConstraintResponse.result().isPresent());
final var constraintResult = oldConstraintResponse.result().get();

assertEquals(constraintId, constraintResult.constraintId());
assertEquals(constraintName, constraintResult.constraintName());

// Resources
final var resources = constraintResult.resourceIds();
assertEquals(2, resources.size());
Expand Down Expand Up @@ -372,22 +380,25 @@ void oneViolationCurrentSimulation() throws IOException {
final var noDatasetResponses = hasura.checkConstraints(planId);
assertEquals(1, noDatasetResponses.size());
assertTrue(noDatasetResponses.get(0).success());
assertEquals(constraintId, noDatasetResponses.get(0).constraintId());
assertEquals(constraintName, noDatasetResponses.get(0).constraintName());
assertEquals("plan", noDatasetResponses.get(0).type());
assertTrue(noDatasetResponses.get(0).result().isPresent());
final var nRecordResults = noDatasetResponses.get(0).result().get();

// Constraint Results w/ SimDatasetId
final var withDatasetResponses = hasura.checkConstraints(planId, simDatasetId);
assertEquals(1, withDatasetResponses.size());
assertTrue( withDatasetResponses.get(0).success());
assertTrue(withDatasetResponses.get(0).success());
assertEquals(constraintId, withDatasetResponses.get(0).constraintId());
assertEquals(constraintName, withDatasetResponses.get(0).constraintName());
assertEquals("plan", withDatasetResponses.get(0).type());
assertTrue(withDatasetResponses.get(0).result().isPresent());
final var wRecordResults = withDatasetResponses.get(0).result().get();

// The results should be the same
assertEquals(nRecordResults, wRecordResults);

// Check the Result
assertEquals(constraintName, nRecordResults.constraintName());
assertEquals(constraintId, nRecordResults.constraintId());

// Resources
assertEquals(1, nRecordResults.resourceIds().size());
Expand Down Expand Up @@ -432,13 +443,12 @@ void oneViolationOutdatedSimIdPassed() throws IOException {

final var constraintResponse = constraintResponses.get(0);
assertTrue(constraintResponse.success());
assertEquals(constraintId, constraintResponse.constraintId());
assertEquals(constraintName, constraintResponse.constraintName());
assertEquals("plan", constraintResponse.type());
assertTrue(constraintResponse.result().isPresent());
final var record = constraintResponse.result().get();

// Check the Result
assertEquals(constraintName, record.constraintName());
assertEquals(constraintId, record.constraintId());

// Resources
assertEquals(1, record.resourceIds().size());
assertTrue(record.resourceIds().contains("/my_boolean"));
Expand Down Expand Up @@ -481,6 +491,9 @@ void compilationFailsOutdatedSimulationSimDatasetId() throws IOException {
final var constraintResponses = hasura.checkConstraints(planId, newSimDatasetId);
assertEquals(1,constraintResponses.size());
final var constraintResponse = constraintResponses.get(0);
assertEquals(constraintId, constraintResponse.constraintId());
assertEquals(constraintName, constraintResponse.constraintName());
assertEquals("plan", constraintResponse.type());
assertFalse(constraintResponse.success());
assertTrue(constraintResponse.result().isEmpty());
assertEquals(1,constraintResponse.errors().size());
Expand All @@ -502,6 +515,9 @@ void compilationFailsOutdatedSimulationNoSimDataset() throws IOException {
assertEquals(1,constraintResponses.size());
final var constraintResponse = constraintResponses.get(0);
assertFalse(constraintResponse.success());
assertEquals(constraintId, constraintResponse.constraintId());
assertEquals(constraintName, constraintResponse.constraintName());
assertEquals("plan", constraintResponse.type());
assertTrue(constraintResponse.result().isEmpty());
assertEquals(1,constraintResponse.errors().size());
final ConstraintError error = constraintResponse.errors().get(0);
Expand All @@ -526,7 +542,9 @@ void constraintInvalidModification() throws IOException {
final var constraintsResponses = hasura.checkConstraints(planId);
assertEquals(1, constraintsResponses.size());
assertTrue(constraintsResponses.get(0).success());

assertEquals(constraintId, constraintsResponses.get(0).constraintId());
assertEquals(constraintName, constraintsResponses.get(0).constraintName());
assertEquals("plan", constraintsResponses.get(0).type());
// Attempt to update a constraint with an invalid syntax and capture the error response
hasura.updateConstraint(
constraintId,
Expand All @@ -536,6 +554,9 @@ void constraintInvalidModification() throws IOException {
final var constraintsErrorResponses = hasura.checkConstraints(planId);
assertEquals(1, constraintsErrorResponses.size());
assertFalse(constraintsErrorResponses.get(0).success());
assertEquals(constraintId, constraintsErrorResponses.get(0).constraintId());
assertEquals(constraintName, constraintsErrorResponses.get(0).constraintName());
assertEquals("plan", constraintsErrorResponses.get(0).type());
assertTrue(constraintsErrorResponses.get(0).result().isEmpty());
assertEquals(1, constraintsErrorResponses.get(0).errors().size());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@

public record ConstraintRecord(
boolean success,
int constraintId,
String constraintName,
String type,
Optional<ConstraintResult> result,
List<ConstraintError> errors

) {
public static ConstraintRecord fromJSON(JsonObject json){
return new ConstraintRecord(
json.getBoolean("success"),
json.getInt("constraintId"),
json.getString("constraintName"),
json.getString("type"),
json.getJsonObject("results").isEmpty() ? Optional.empty() : Optional.of(ConstraintResult.fromJSON(json.getJsonObject("results"))),
json.getJsonArray("errors").getValuesAs(ConstraintError::fromJSON));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import javax.json.JsonString;
import java.util.List;

public record ConstraintResult(int constraintId,
String constraintName,
String type,
List<String> resourceIds,
List<ConstraintResult.ConstraintViolation> violations,
List<ConstraintResult.Interval> gaps){
public record ConstraintResult(
List<String> resourceIds,
List<ConstraintResult.ConstraintViolation> violations,
List<ConstraintResult.Interval> gaps
) {
public record ConstraintViolation(List<Integer> activityInstanceIds, List<Interval> windows) {

public static ConstraintViolation fromJSON(JsonObject json) {
Expand All @@ -34,9 +33,6 @@ public static ConstraintResult fromJSON(JsonObject json) {
final var violations = json.getJsonArray("violations").getValuesAs(ConstraintViolation::fromJSON);

return new ConstraintResult(
json.getInt("constraintId"),
json.getString("constraintName"),
json.getString("type"),
resourceIds,
violations,
gaps
Expand Down
6 changes: 3 additions & 3 deletions e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/utils/GQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ mutation cancelSimulation($id: Int!) {
query checkConstraints($planId: Int!, $simulationDatasetId: Int) {
constraintViolations(planId: $planId, simulationDatasetId: $simulationDatasetId) {
success
constraintId
constraintName
type
results {
constraintId
constraintName
resourceIds
type
gaps {
end
start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import gov.nasa.jpl.aerie.merlin.server.exceptions.NoSuchPlanDatasetException;
import gov.nasa.jpl.aerie.merlin.server.exceptions.NoSuchPlanException;
import gov.nasa.jpl.aerie.merlin.server.exceptions.SimulationDatasetMismatchException;
import gov.nasa.jpl.aerie.merlin.server.models.Constraint;
import gov.nasa.jpl.aerie.merlin.server.remotes.MissionModelAccessException;
import gov.nasa.jpl.aerie.merlin.server.services.ConstraintsDSLCompilationService;
import gov.nasa.jpl.aerie.merlin.server.services.GetSimulationResultsAction;
Expand Down Expand Up @@ -216,11 +217,8 @@ public static JsonValue serializeConstraintViolation(final Violation violation)
public static JsonValue serializeConstraintResult(final ConstraintResult list) {
return Json
.createObjectBuilder()
.add("constraintId", list.constraintId)
.add("constraintName", list.constraintName)
.add("violations", serializeIterable(ResponseSerializers::serializeConstraintViolation, list.violations))
.add("gaps", serializeIterable(ResponseSerializers::serializeInterval, list.gaps))
.add("type", list.constraintType.name())
.add("resourceIds", serializeIterable(Json::createValue, list.resourceIds))
.build();
}
Expand Down Expand Up @@ -315,16 +313,20 @@ public static JsonValue serializeResourceSamples(final Map<String, List<Pair<Dur
.build();
}

public static JsonValue serializeConstraintResults(final List<Failable<?>> list) {
var results = list.stream().map(failable -> {
public static JsonValue serializeConstraintResults(final Map<Constraint, Failable<?>> resultMap) {
var results = resultMap.entrySet().stream().map(entry -> {

var failableObject = failable.getOptional();
final var constraint = entry.getKey();
final var failable = entry.getValue();

// There should always be a failable but this is here
// just in case
if (failableObject.isEmpty()) {
if (failable.getOptional().isEmpty()) {
return Json.createObjectBuilder()
.add("success", JsonValue.FALSE)
.add("constraintId", constraint.id())
.add("constraintName", constraint.name())
.add("type",constraint.type().name())
.add("errors", Json.createArrayBuilder().add(
Json.createObjectBuilder()
.add("message", "Internal error processing a constraint")
Expand All @@ -336,27 +338,33 @@ public static JsonValue serializeConstraintResults(final List<Failable<?>> list)

// failure was a compilation error
if (failable.isFailure()
&& failableObject.get() instanceof ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error) {
return serializeConstraintCompileErrors((Failable<ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error>) failable);
&& failable.getOptional().get() instanceof ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error) {
return serializeConstraintCompileErrors(constraint, (Failable<ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error>) failable);
}

// failure that are errors exceptions that were captured
if (failable.isFailure()) {
return Json.createObjectBuilder()
.add("success", JsonValue.FALSE)
.add("constraintId", constraint.id())
.add("constraintName", constraint.name())
.add("type",constraint.type().name())
.add("errors", Json.createArrayBuilder().add(
Json.createObjectBuilder()
.add("message", ((Error) failableObject.get()).getMessage())
.add("message", failable.getMessage())
.add("stack", "")
.add("location", JsonValue.EMPTY_JSON_OBJECT).build()).build())
.add("results", JsonValue.EMPTY_JSON_OBJECT)
.build();
}

// successful runs
var constraintResult = (ConstraintResult) failableObject.get();
var constraintResult = (ConstraintResult) failable.getOptional().get();
return Json.createObjectBuilder()
.add("success", JsonValue.TRUE)
.add("constraintId", constraint.id())
.add("constraintName", constraint.name())
.add("type",constraint.type().name())
.add("errors", JsonValue.EMPTY_JSON_ARRAY)
.add("results", serializeConstraintResult(constraintResult))
.build();
Expand Down Expand Up @@ -483,7 +491,7 @@ public static JsonValue serializeInvalidJsonException(final InvalidJsonException
.build();
}

public static JsonValue serializeConstraintCompileErrors(final Failable<ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error> ex) {
public static JsonValue serializeConstraintCompileErrors(final Constraint constraint, final Failable<ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult.Error> ex) {

final var userCodeError = ex
.getOptional()
Expand All @@ -504,6 +512,9 @@ public static JsonValue serializeConstraintCompileErrors(final Failable<Constrai

return Json.createObjectBuilder()
.add("success", JsonValue.FALSE)
.add("constraintId", constraint.id())
.add("constraintName", constraint.name())
.add("type",constraint.type().name())
.add("errors", userCodeErrorArrayBuilder.build())
.add("results", Json.createObjectBuilder().build())
.build();
Expand Down
Loading

0 comments on commit 2dff316

Please sign in to comment.