use of org.kie.kogito.trusty.service.common.responses.ExecutionsResponse in project kogito-apps by kiegroup.
the class ExecutionsApiV1IT method givenARequestWhenExecutionEndpointIsCalledThenTheExecutionHeaderIsReturned.
@Test
void givenARequestWhenExecutionEndpointIsCalledThenTheExecutionHeaderIsReturned() throws ParseException {
Execution execution = new Decision("test1", "http://localhost:8081/model/service", "http://localhost:8081", OffsetDateTime.parse("2020-01-01T00:00:00Z", DateTimeFormatter.ISO_OFFSET_DATE_TIME).toInstant().toEpochMilli(), true, "name", "model", "namespace", Collections.emptyList(), Collections.emptyList());
Mockito.when(executionService.getExecutionHeaders(any(OffsetDateTime.class), any(OffsetDateTime.class), any(Integer.class), any(Integer.class), any(String.class))).thenReturn(new MatchedExecutionHeaders(List.of(execution), 1));
ExecutionsResponse response = given().contentType(ContentType.JSON).when().get("/executions?from=2000-01" + "-01T00:00:00Z&to=2021" + "-01-01T00:00:00Z").as(ExecutionsResponse.class);
Assertions.assertEquals(1, response.getHeaders().size());
}
use of org.kie.kogito.trusty.service.common.responses.ExecutionsResponse in project kogito-apps by kiegroup.
the class ExecutionsApiV1IT method givenMoreResultsThanQueryLimitThenPaginationIsCorrect.
@Test
void givenMoreResultsThanQueryLimitThenPaginationIsCorrect() throws ParseException {
List<Execution> executions = generateExecutions(15);
mockGetExecutionHeaders(executions, 0, 10);
mockGetExecutionHeaders(executions, 5, 10);
mockGetExecutionHeaders(executions, 10, 10);
ExecutionsResponse response = given().contentType(ContentType.JSON).when().get("/executions?from=2000-01-01T00:00:00Z&to=2021-01-01T00:00:00Z&limit=10").as(ExecutionsResponse.class);
Assertions.assertEquals(10, response.getHeaders().size());
Assertions.assertEquals(15, response.getTotal());
Assertions.assertEquals(0, response.getOffset());
Assertions.assertEquals(10, response.getLimit());
response = given().contentType(ContentType.JSON).when().get("/executions?from=2000-01-01T00:00:00Z&to=2021-01-01T00:00:00Z&limit=10&offset=5").as(ExecutionsResponse.class);
Assertions.assertEquals(10, response.getHeaders().size());
Assertions.assertEquals(15, response.getTotal());
Assertions.assertEquals(5, response.getOffset());
Assertions.assertEquals(10, response.getLimit());
response = given().contentType(ContentType.JSON).when().get("/executions?from=2000-01-01T00:00:00Z&to=2021-01-01T00:00:00Z&limit=10&offset=10").as(ExecutionsResponse.class);
Assertions.assertEquals(5, response.getHeaders().size());
Assertions.assertEquals(15, response.getTotal());
Assertions.assertEquals(10, response.getOffset());
Assertions.assertEquals(10, response.getLimit());
}
use of org.kie.kogito.trusty.service.common.responses.ExecutionsResponse in project kogito-apps by kiegroup.
the class AbstractTrustyExplainabilityEnd2EndIT method doTest.
@Test
public void doTest() {
try (final Network network = Network.newNetwork();
final KogitoInfinispanContainer infinispan = new KogitoInfinispanContainer().withNetwork(network).withNetworkAliases(INFINISPAN_ALIAS);
final KogitoKafkaContainer kafka = new KogitoKafkaContainer().withNetwork(network).withNetworkAliases(KAFKA_ALIAS);
final KogitoKeycloakContainer keycloak = new KogitoKeycloakContainer().withEnv(KEYCLOAK_DB_VENDOR_VARIABLE, KEYCLOAK_DB_VENDOR_VALUE).withNetwork(network).withNetworkAliases(KEYCLOAK_ALIAS);
final ExplainabilityServiceMessagingContainer explService = new ExplainabilityServiceMessagingContainer(KAFKA_BOOTSTRAP_SERVERS, EXPL_SERVICE_SAMPLES).withLogConsumer(new Slf4jLogConsumer(LOGGER)).withNetwork(network).withNetworkAliases(EXPL_SERVICE_ALIAS);
final InfinispanTrustyServiceContainer trustyService = new InfinispanTrustyServiceContainer(INFINISPAN_SERVER_LIST, KAFKA_BOOTSTRAP_SERVERS, true).withEnv(TRUSTY_SERVICE_OIDC_AUTH_SERVER_URL_VARIABLE, TRUSTY_SERVICE_OIDC_AUTH_SERVER_URL_VALUE).withEnv(TRUSTY_SERVICE_OIDC_CLIENT_ID_VARIABLE, TRUSTY_SERVICE_OIDC_CLIENT_ID_VALUE).withEnv("INFINISPAN_USE_AUTH", "FALSE").withLogConsumer(new Slf4jLogConsumer(LOGGER)).withNetwork(network).withNetworkAliases(TRUSTY_SERVICE_ALIAS);
final KogitoServiceContainer kogitoService = kogitoServiceContainerProducer.apply(KAFKA_BOOTSTRAP_SERVERS, KOGITO_SERVICE_URL).withLogConsumer(new Slf4jLogConsumer(LOGGER)).withNetwork(network).withNetworkAliases(KOGITO_SERVICE_ALIAS)) {
infinispan.start();
assertTrue(infinispan.isRunning());
kafka.start();
assertTrue(kafka.isRunning());
keycloak.start();
assertTrue(keycloak.isRunning());
explService.start();
assertTrue(explService.isRunning());
trustyService.start();
assertTrue(trustyService.isRunning());
kogitoService.start();
assertTrue(kogitoService.isRunning());
final String accessToken = given().port(keycloak.getFirstMappedPort()).param(KEYCLOAK_GRANT_TYPE_PARAM_NAME, KEYCLOAK_GRANT_TYPE_PARAM_VALUE).param(KEYCLOAK_USERNAME_PARAM_NAME, KEYCLOAK_USERNAME_PARAM_VALUE).param(KEYCLOAK_PASSWORD_PARAM_NAME, KEYCLOAK_PASSWORD_PARAM_VALUE).param(KEYCLOAK_CLIENT_ID_PARAM_NAME, KEYCLOAK_CLIENT_ID_PARAM_VALUE).param(KEYCLOAK_CLIENT_SECRET_PARAM_NAME, KEYCLOAK_CLIENT_SECRET_PARAM_VALUE).when().post(KEYCLOAK_ACCESS_TOKEN_PATH).as(AccessTokenResponse.class).getToken();
assertNotNull(accessToken);
final List<String> executionIds = new ArrayList<>();
final int expectedExecutions = KOGITO_SERVICE_PAYLOADS.size();
LOGGER.info("Invoke Decision endpoint to generate LIME explanations...");
KOGITO_SERVICE_PAYLOADS.forEach(json -> given().port(kogitoService.getFirstMappedPort()).contentType("application/json").body(json).when().post("/Traffic Violation").then().statusCode(200));
LOGGER.info("Check Decisions executed...");
await().atLeast(5, SECONDS).atMost(30, SECONDS).with().pollInterval(5, SECONDS).untilAsserted(() -> {
ExecutionsResponse executionsResponse = given().port(trustyService.getFirstMappedPort()).auth().oauth2(accessToken).when().get(String.format("/executions?limit=%d", expectedExecutions)).then().statusCode(200).extract().as(ExecutionsResponse.class);
assertSame(expectedExecutions, executionsResponse.getHeaders().size());
executionsResponse.getHeaders().forEach(h -> executionIds.add(h.getExecutionId()));
});
LOGGER.info("Check LIME explanations generated...");
await().atLeast(5, SECONDS).atMost(60, SECONDS).with().pollInterval(5, SECONDS).untilAsserted(() -> {
executionIds.forEach(executionId -> {
SalienciesResponse salienciesResponse = given().port(trustyService.getFirstMappedPort()).auth().oauth2(accessToken).when().get("/executions/decisions/" + executionId + "/explanations/saliencies").then().statusCode(200).extract().as(SalienciesResponse.class);
assertEquals("SUCCEEDED", salienciesResponse.getStatus());
});
});
LOGGER.info("Request Counterfactuals for each execution and check responses generated...");
executionIds.forEach(executionId -> {
await().atLeast(500, MILLISECONDS).atMost(60, SECONDS).with().pollInterval(500, MILLISECONDS).until(doCounterfactualRequests(trustyService, accessToken, executionId));
await().atLeast(500, MILLISECONDS).atMost(60, SECONDS).with().pollInterval(500, MILLISECONDS).until(doCounterfactualResponses(trustyService, accessToken, executionId));
});
}
}
use of org.kie.kogito.trusty.service.common.responses.ExecutionsResponse in project kogito-apps by kiegroup.
the class ExecutionsApiV1IT method givenRequestWithoutLimitAndOffsetParametersWhenExecutionEndpointIsCalledThenTheDefaultValuesAreCorrect.
@Test
void givenRequestWithoutLimitAndOffsetParametersWhenExecutionEndpointIsCalledThenTheDefaultValuesAreCorrect() {
Mockito.when(executionService.getExecutionHeaders(any(OffsetDateTime.class), any(OffsetDateTime.class), any(Integer.class), any(Integer.class), any(String.class))).thenReturn(new MatchedExecutionHeaders(new ArrayList<>(), 0));
ExecutionsResponse response = given().contentType(ContentType.JSON).when().get("/executions?from=2000-01-01T00:00:00Z&to=2021-01-01T00:00:00Z").as(ExecutionsResponse.class);
Assertions.assertEquals(100, response.getLimit());
Assertions.assertEquals(0, response.getOffset());
Assertions.assertEquals(0, response.getHeaders().size());
}
use of org.kie.kogito.trusty.service.common.responses.ExecutionsResponse in project kogito-apps by kiegroup.
the class ExecutionsApiV1 method getExecutions.
/**
* Gets all the headers of the executions that were evaluated within a specified time range.
*
* @param from The start datetime.
* @param to The end datetime.
* @param limit The maximum (non-negative) number of items to be returned.
* @param offset The non-negative pagination offset.
* @param prefix The executionId prefix to be matched in the search.
* @return The execution headers that satisfy the time range, pagination and prefix conditions.
*/
@GET
@APIResponses(value = { @APIResponse(description = "Returns the execution headers.", responseCode = "200", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(type = SchemaType.OBJECT, implementation = ExecutionsResponse.class))), @APIResponse(description = "Bad Request", responseCode = "400", content = @Content(mediaType = MediaType.TEXT_PLAIN)) })
@Operation(summary = "Gets the execution headers", description = "Gets the execution headers.")
@Produces(MediaType.APPLICATION_JSON)
public Response getExecutions(@Parameter(name = "from", description = "Start datetime for the lookup. Date in the format \"yyyy-MM-dd'T'HH:mm:ssZ\"", required = false, schema = @Schema(implementation = String.class)) @DefaultValue("yesterday") @QueryParam("from") String from, @Parameter(name = "to", description = "End datetime for the lookup. Date in the format \"yyyy-MM-dd'T'HH:mm:ssZ\"", required = false, schema = @Schema(implementation = String.class)) @DefaultValue("now") @QueryParam("to") String to, @Parameter(name = "limit", description = "Maximum number of results to return.", required = false, schema = @Schema(implementation = Integer.class)) @DefaultValue("100") @QueryParam("limit") int limit, @Parameter(name = "offset", description = "Offset for the pagination.", required = false, schema = @Schema(implementation = Integer.class)) @DefaultValue("0") @QueryParam("offset") int offset, @Parameter(name = "search", description = "Execution ID prefix to be matched", required = false, schema = @Schema(implementation = String.class)) @DefaultValue("") @QueryParam("search") String prefix) {
if (limit < 0 || offset < 0) {
return Response.status(Response.Status.BAD_REQUEST.getStatusCode(), "Pagination parameters can not have negative values.").build();
}
OffsetDateTime fromDate;
OffsetDateTime toDate;
try {
fromDate = parseParameterDate(from, true);
toDate = parseParameterDate(to, false);
} catch (DateTimeParseException e) {
LOGGER.warn("Invalid date", e);
return Response.status(Response.Status.BAD_REQUEST.getStatusCode(), "Date format should be yyyy-MM-dd'T'HH:mm:ssZ").build();
}
MatchedExecutionHeaders result = trustyService.getExecutionHeaders(fromDate, toDate, limit, offset, prefix);
List<ExecutionHeaderResponse> headersResponses = new ArrayList<>();
result.getExecutions().forEach(x -> headersResponses.add(ResponseUtils.executionHeaderResponseFrom(x)));
return Response.ok(new ExecutionsResponse(result.getAvailableResults(), limit, offset, headersResponses)).build();
}
Aggregations