From 5a6cbdde0b5bf47e0693216df8237e057c30c3ad Mon Sep 17 00:00:00 2001 From: Jonas Bulcke <127748878+jobulcke@users.noreply.github.com> Date: Thu, 12 Sep 2024 10:31:46 +0200 Subject: [PATCH] feat: processing service (#7) * feat: small refactor + init of processor service * feat: processing service finished * feat: processing service implemented * feat: bugfixes and cleanup of new service * feat: additional test added * docs: little remark added * fix: invalid logging levels * feat: PR remarks * feat: small improvements * fix: broken ci pipeline --- README.md | 140 +++++++++++++----- docker/scriplets/validate-ldes.xml | 50 +++++++ .../gitb/ReplicationProcessingService.java | 77 ++++++++++ .../ldes/gitb/ShaclValidationService.java | 72 +++++++++ .../ldes/gitb/ValidationServiceImpl.java | 94 ------------ .../ldes/gitb/config/ServiceConfig.java | 21 ++- .../gitb/ldio/LdesClientStatusManager.java | 75 ++-------- .../gitb/rdfrepo/RepositoryValidator.java | 10 +- .../DestroyPipelineProcessExecutor.java | 39 +++++ .../HaltWhenReplicatedProcessExecutor.java | 68 +++++++++ .../services/replication/ProcessExecutor.java | 13 ++ .../replication/ProcessExecutors.java | 25 ++++ .../StartReplicatingProcessExecutor.java | 43 ++++++ .../suppliers}/TarSupplier.java | 16 +- .../ldes/gitb/shacl/ShaclValidator.java | 50 ------- .../valueobjects/ValidationParameters.java | 13 -- .../severitylevels/ErrorSeverityLevel.java | 2 +- .../severitylevels/InfoSeverityLevel.java | 2 +- .../severitylevels/WarningSeverityLevel.java | 2 +- .../ldes/gitb/valueobjects/Message.java | 37 +++++ .../valueobjects/ParameterDefinition.java | 33 +++++ .../gitb/valueobjects/ProcessParameters.java | 30 ++++ .../ldes/gitb/valueobjects/ProcessResult.java | 44 ++++++ .../ldes/gitb/valueobjects/SessionId.java | 44 ++++++ .../valueobjects/ValidationParameters.java | 37 +++++ .../ReplicationProcessingServiceTest.java | 114 ++++++++++++++ ...t.java => ShaclValidationServiceTest.java} | 29 +--- .../ldio/LdesClientStatusManagerTest.java | 33 ++--- .../ldio/LdioPipelineManagerTest.java | 5 +- .../ldio/ldes}/EventStreamFetcherTest.java | 4 +- .../ValidationPipelineSupplierTest.java | 5 +- .../rdfrepo/RepositoryValidatorTest.java | 9 +- .../DestroyPipelineProcessExecutorTest.java | 44 ++++++ ...HaltWhenReplicatedProcessExecutorTest.java | 87 +++++++++++ .../replication/ProcessExecutorsTest.java | 72 +++++++++ .../StartReplicatingProcessExecutorTest.java | 48 ++++++ .../valueobjects/ValidationReportTest.java | 2 +- .../ldes/shacl/ShaclValidatorTest.java | 52 ------- .../soap-requests/process-request.xml | 11 ++ .../{ => soap-requests}/validate-request.xml | 4 - 40 files changed, 1159 insertions(+), 397 deletions(-) create mode 100644 docker/scriplets/validate-ldes.xml create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingService.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationService.java delete mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImpl.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutor.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutor.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutor.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutors.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutor.java rename src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/{shacl/services => services/suppliers}/TarSupplier.java (67%) delete mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/ShaclValidator.java delete mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/ValidationParameters.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/Message.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ParameterDefinition.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessParameters.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessResult.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/SessionId.java create mode 100644 src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationParameters.java create mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingServiceTest.java rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/{ValidationServiceImplTest.java => ShaclValidationServiceTest.java} (61%) rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ => gitb}/ldio/LdesClientStatusManagerTest.java (62%) rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ => gitb}/ldio/LdioPipelineManagerTest.java (93%) rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ldes/valueobjects => gitb/ldio/ldes}/EventStreamFetcherTest.java (85%) rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ => gitb}/ldio/pipeline/ValidationPipelineSupplierTest.java (84%) rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ => gitb}/rdfrepo/RepositoryValidatorTest.java (95%) create mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutorTest.java create mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutorTest.java create mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutorsTest.java create mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutorTest.java rename src/test/java/be/vlaanderen/informatievlaanderen/ldes/{ => gitb}/valueobjects/ValidationReportTest.java (97%) delete mode 100644 src/test/java/be/vlaanderen/informatievlaanderen/ldes/shacl/ShaclValidatorTest.java create mode 100644 src/test/resources/soap-requests/process-request.xml rename src/test/resources/{ => soap-requests}/validate-request.xml (85%) diff --git a/README.md b/README.md index 4d5e0be..d603b61 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,74 @@ # VSDS TestBed Shacl Validator - * [VSDS TestBed Shacl Validator](#vsds-testbed-shacl-validator) - * [Introduction](#introduction) - * [Validation service implementation](#validation-service-implementation) + * [Introduction](#introduction) + * [ReplicationProcesssingService](#replicationprocesssingservice) + * [startReplicating](#startreplicating) + * [haltWhenReplicated](#haltwhenreplicated) + * [destroyPipeline](#destroypipeline) + * [ShaclValidationService](#shaclvalidationservice) + * [How to run in Docker](#how-to-run-in-docker) * [Prerequisites](#prerequisites) - * [Building and running](#building-and-running) - * [Live reload for development](#live-reload-for-development) - * [Packaging using Docker](#packaging-using-docker) - + * [Steps to use the TestBed Shacl Validator](#steps-to-use-the-testbed-shacl-validator) + * [interact](#interact) + * [call](#call) + * [Building and running the project](#building-and-running-the-project) + * [Live reload for development](#live-reload-for-development) + * [Packaging using Docker](#packaging-using-docker) - ## Introduction This application implements the [GITB test service APIs](https://www.itb.ec.europa.eu/docs/services/latest/) in a [Spring Boot](https://spring.io/projects/spring-boot) web application that is meant to support [GITB TDL test cases](https://www.itb.ec.europa.eu/docs/tdl/latest/) running in the Interoperability Test Bed. -### Validation service implementation +## ReplicationProcesssingService + +This service is responsible for creating an LDIO pipeline, checking if the LDES Client is still REPLACTING and +destroying the pipeline afterwards. It is available through the endpoint's +WSDL: http://localhost:8080/services/process?wsdl. This processing service has three operations: + +#### startReplicating + +This operation is responsible for creating the pipeline, which immediately starts the replication process. + +Input parameters: + +| Name | Description | Required | +|:--------:|---------------------------------|----------| +| ldes-url | the url of the LDES to validate | true | + +#### haltWhenReplicated + +This operation is responsible for polling and returning the status of the LDES Client + +#### destroyPipeline + +This operation is resonsible for deleting the LDIO pipeline, as well the GraphDB repository + +More information about processing services can be +found [here](https://www.itb.ec.europa.eu/docs/services/latest/processing/) + +## ShaclValidationService -The sample validation service validates a text against an (also provided) expected value. The user of the service can -also select whether he/she wants to have a mismatch reported as an error or a warning. Finally, an information message -is also returned in case values match but when ignoring casing. +This service is responsible for executing the SHACL validation and is accessible through the endpoint's +WSDL: http://localhost:8080/services/validation?wsdl -Once running, the validation endpoint's WDSL is available at http://localhost:8080/services/validation?WSDL. See -[here](https://www.itb.ec.europa.eu/docs/services/latest/validation/) for further information on processing service -implementations. +Input parameters: + +| Name | Description | Required | +|:-----------:|---------------------------------------------------------------------|----------| +| shacl-shape | the shacl shape that will be used to validate the server against to | true | This validation services requires in the validation call two parameters: 1. **ldes-url**: the url of the LDES to validate 2. **shacl-shape**: the shacl shape that will be used to validate the server against to +More information about validation services can be +found [here](https://www.itb.ec.europa.eu/docs/services/latest/validation/) + ## How to run in Docker ### Prerequisites @@ -75,6 +111,8 @@ In this specific tutorial, this would result in the following config: - SERVER_PORT=8080 ``` +This service has already been added to the provided `docker-compose.yaml` file. + 2. Start up all the services ```shell @@ -92,10 +130,24 @@ First of all, make a folder that will contain all required files for the test su ```shell mkdir validate_ldes_to_shacl_shape cd validate_ldes_to_shacl_shape +``` + +Secondly, a scriptlet will be added to the test suite, which contains all the required logic to create the necessary +LDIO pipelines, check the LDES Client status and so on. + +```shell +mkdir scriptlets +``` + +In this directory, place the [`validate-ldes.xml`](./docker/scriplets/validate-ldes.xml) file. + +Now, the test cases can be written and added to the test suite. First, a new folder must be created. + +```shell mkdir test_cases ``` -Secondly, test case xml file can be added to the `test_cases` folder. +Now, `test_case.xml` file can be added to the newly created folder ```xml @@ -111,20 +163,20 @@ Secondly, test case xml file can be added to the `test_cases` folder. - - + + - "Starting shacl validation test" - - - - $validationData{ldes} - $validationData{shaclShape} - - "shacl verification finished" + concat($validationData{pollingInterval}, '000') + "http://testbed-shacl-validator:8080/services/process?wsdl" + "http://testbed-shacl-validator:8080/services/validation?wsdl" + + $validationData{ldesUrl} + $validationData{shaclShape} + $delayDuration + $addresses + @@ -145,21 +197,27 @@ Some interesting things we see in this test case, are the `interact` block, as w #### interact This block is responsible for prompting the user/tester to enter some data that will be used for the test. In this -specific case, it will be the URL of the LDES that must be validated. +specific case, it will be the URL of the LDES that must be validated, a SHACL shape file and a polling interval on which +the LDES Client status must be checked. + +| Name of the parameter | Description | +|:---------------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ldesUrl | URL of the LDES to be validated | +| SHACL shape | SHACL shape that will be used to validate the LDES | +| pollingInterval | Interval in which the LDES Client status will be checked in seconds. Keep in mind if the LDES to validate contains 1M members, it can take a very long time to replicate. Therefore, it can be better to configure a larger interval (e.g. an hour or even half a day) | -#### verify +#### call -This block is responsible for the verifying the LDES by calling the external service, which is this TestBed Shacl -Validator service. The most important part to notice here is the `handler` attribute, where the external TestBed Shacl -Validator service will be set. In this case, the docker compose service name must be used, followed by the port. After -that, the "fixed" uri is placed, which will call the right validation service, which is in this case -`/services/validation?wsdl` +This block is responsible for executing the scriptlet, which is responsible for creating an LDIO pipeline, checking when +the LDES Client has finished with REPLICATING, performing the SHACL validation and destroying the pipeline afterward. -Another thing that can be noticed here, are the input parameters. These two parameters are required to let the test run. +Another thing that can be noticed here, are the input parameters. These three parameters are required to let the test +run. -1. `ldes-url`: the url of the LDES that must be validated. The value here is fetched from the prompted input -2. `shacl-shape`: the SHACL shape that will be used to validate all the members against to. Here is the value also +1. `ldesUrl`: the url of the LDES that must be validated. The value here is fetched from the prompted input +2. `shaclShape`: the SHACL shape that will be used to validate all the members against to. Here is the value also fetched from the prompted input +3. `delayDuration`: the amount of seconds on which the LDES Client must be checked To finish up this step, a test suite itself must be added as well. This can be done by adding `test_suite.xml` to the `validate_ldes_to_shacl_shape` folder. @@ -206,11 +264,13 @@ This is how the file should look like: Most important to notice here, is that de test case declared in the `test_cases` folder, must be referred from this file by adding the `test case` tag with as attribute the id that has been assigned to the test case in its file. -4. Compress the `validate_ldes_to_shacl_shape` folder to a zip and upload it to TestBed +4. Add the Test Suite to the TestBed instance + +Create a ZIP file contains all the items that are in `validate_ldes_to_shacl_shape` folder. This can be uploaded to +TestBed now. This can be done either by the UI, or via the REST API. If you choose to do it via the REST API, the -If everything is set up, the folder containing everything must be zipped. After that, it can be uploaded to TestBed. This can be done either by the UI, or via the REST API. If you choose to do it via the REST API, the ```shell -curl -F updateSpecification=true -F specification= -F testSuite=@test_shacl_validator.zip --header "ITB_API_KEY: " -X POST http://localhost:9000/api/rest/testsuite/deploy; +curl -F updateSpecification=true -F specification= -F testSuite=@test_shacl_validator.zip --header "ITB_API_KEY: " -X POST http://localhost:9000/api/rest/testsuite/deploy; ``` 5. Run the test via the TestBed UI diff --git a/docker/scriplets/validate-ldes.xml b/docker/scriplets/validate-ldes.xml new file mode 100644 index 0000000..c2800ba --- /dev/null +++ b/docker/scriplets/validate-ldes.xml @@ -0,0 +1,50 @@ + + + + + + + 60000 + + + + + + startReplicating + $ldesUrl + + "Waiting for the LDES Client status to be available" + + delay + 5000 + + + "Start checking LDES Client status" + + + + + delay + $delayDuration + + + haltWhenReplicated + + $replicationOutput{STATUS} + + $replicationOutput{STATUS} = 'REPLICATING' + + "Starting shacl validation" + + + $shaclShape + + "shacl verification finished" + + + + $validatorOutput + + \ No newline at end of file diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingService.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingService.java new file mode 100644 index 0000000..720883a --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingService.java @@ -0,0 +1,77 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication.ProcessExecutors; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ParameterDefinition; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import com.gitb.core.ConfigurationParameters; +import com.gitb.core.Metadata; +import com.gitb.core.TypedParameters; +import com.gitb.ps.Void; +import com.gitb.ps.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class ReplicationProcessingService implements ProcessingService { + private static final String SERVICE_NAME = "ReplicationProcessingService"; + private static final Logger log = LoggerFactory.getLogger(ReplicationProcessingService.class); + private final ProcessExecutors processExecutors; + + public ReplicationProcessingService(ProcessExecutors processExecutors) { + this.processExecutors = processExecutors; + } + + @Override + public GetModuleDefinitionResponse getModuleDefinition(Void parameters) { + final ProcessingModule processingModule = new ProcessingModule(); + processingModule.setId(SERVICE_NAME); + + final Metadata metadata = new Metadata(); + metadata.setName(SERVICE_NAME); + processingModule.setMetadata(metadata); + + processingModule.setConfigs(new ConfigurationParameters()); + + processExecutors.getProcessExecutors().stream() + .map(processExecutor -> { + final var processingOperation = new ProcessingOperation(); + final var typedParameters = new TypedParameters(); + processingOperation.setName(processExecutor.getName()); + typedParameters.getParam().addAll(processExecutor + .getParameterDefinitions() + .stream() + .map(ParameterDefinition::convertToTypedParameter) + .toList()); + processingOperation.setInputs(typedParameters); + return processingOperation; + }) + .forEach(processingModule.getOperation()::add); + + final GetModuleDefinitionResponse getModuleDefinitionResponse = new GetModuleDefinitionResponse(); + getModuleDefinitionResponse.setModule(processingModule); + return getModuleDefinitionResponse; + } + + @Override + public ProcessResponse process(ProcessRequest parameters) { + log.info("Received 'process' command with '{}' operation from test bed for session [{}]", parameters.getOperation(), parameters.getSessionId()); + return processExecutors.getProcessExecutor(parameters.getOperation()) + .map(processExecutor -> processExecutor.execute(new ProcessParameters(parameters.getSessionId(), parameters.getInput()))) + .orElseGet(() -> ProcessResult.invalidOperation(parameters.getOperation())) + .convertToResponse(); + } + + @Override + public BeginTransactionResponse beginTransaction(BeginTransactionRequest parameters) { + return new BeginTransactionResponse(); + } + + @Override + public Void endTransaction(BasicRequest parameters) { + return new Void(); + } + + +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationService.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationService.java new file mode 100644 index 0000000..a25587b --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationService.java @@ -0,0 +1,72 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.RepositoryValidator; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.ValidationReportToTarMapper; +import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationReport; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.SessionId; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ValidationParameters; +import com.gitb.core.Metadata; +import com.gitb.core.TypedParameter; +import com.gitb.core.TypedParameters; +import com.gitb.core.ValidationModule; +import com.gitb.vs.Void; +import com.gitb.vs.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import static be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ValidationParameters.SHACL_SHAPE_KEY; + +/** + * Spring component that realises the validation service. + */ +@Component +public class ShaclValidationService implements ValidationService { + + private static final Logger LOG = LoggerFactory.getLogger(ShaclValidationService.class); + private static final String SERVICE_NAME = "LdesMemberShaclValidator"; + + private final RepositoryValidator repositoryValidator; + + public ShaclValidationService(RepositoryValidator repositoryValidator) { + this.repositoryValidator = repositoryValidator; + } + + @Override + public GetModuleDefinitionResponse getModuleDefinition(Void parameters) { + final var validationModule = new ValidationModule(); + validationModule.setId(SERVICE_NAME); + validationModule.setOperation("V"); + + final var metadata = new Metadata(); + metadata.setName(SERVICE_NAME); + validationModule.setMetadata(metadata); + + final var shaclShapeParam = new TypedParameter(); + shaclShapeParam.setName(SHACL_SHAPE_KEY); + shaclShapeParam.setType("string"); + + final var inputs = new TypedParameters(); + inputs.getParam().add(shaclShapeParam); + validationModule.setInputs(inputs); + + final GetModuleDefinitionResponse response = new GetModuleDefinitionResponse(); + response.setModule(validationModule); + return response; + } + + @Override + public ValidationResponse validate(ValidateRequest validateRequest) { + final SessionId sessionId = SessionId.from(validateRequest.getSessionId()); + LOG.info("Received 'validate' command from test bed for session [{}]", sessionId); + final ValidationReport validationReport = repositoryValidator.validate(new ValidationParameters(sessionId, validateRequest.getInput())); + LOG.atInfo().log("Validation for session [{}] completed with report: {}", sessionId, validationReport); + return buildValidationResult(validationReport); + } + + private ValidationResponse buildValidationResult(ValidationReport validationReport) { + final ValidationResponse result = new ValidationResponse(); + result.setReport(ValidationReportToTarMapper.mapToTar(validationReport)); + return result; + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImpl.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImpl.java deleted file mode 100644 index d793d6d..0000000 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.gitb; - -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.ShaclValidator; -import be.vlaanderen.informatievlaanderen.ldes.gitb.services.RDFConverter; -import be.vlaanderen.informatievlaanderen.ldes.gitb.services.ValidationReportToTarMapper; -import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.Parameters; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationReport; -import com.gitb.core.Metadata; -import com.gitb.core.TypedParameter; -import com.gitb.core.TypedParameters; -import com.gitb.core.ValidationModule; -import com.gitb.vs.Void; -import com.gitb.vs.*; -import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.rio.RDFFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.UUID; - -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.LDES_URL_KEY; -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.SHACL_SHAPE_KEY; - -/** - * Spring component that realises the validation service. - */ -@Component -public class ValidationServiceImpl implements ValidationService { - - private static final Logger LOG = LoggerFactory.getLogger(ValidationServiceImpl.class); - private static final String SERVICE_NAME = "LdesMemberShaclValidator"; - - private final ShaclValidator shaclValidator; - - public ValidationServiceImpl(ShaclValidator shaclValidator) { - this.shaclValidator = shaclValidator; - } - - @Override - public GetModuleDefinitionResponse getModuleDefinition(Void parameters) { - final var validationModule = new ValidationModule(); - validationModule.setId(SERVICE_NAME); - validationModule.setOperation("V"); - - final var metadata = new Metadata(); - metadata.setName(SERVICE_NAME); - validationModule.setMetadata(metadata); - - final var ldesServerParam = new TypedParameter(); - ldesServerParam.setName(LDES_URL_KEY); - ldesServerParam.setType("string"); - - final var shaclShapeParam = new TypedParameter(); - shaclShapeParam.setName(SHACL_SHAPE_KEY); - shaclShapeParam.setType("string"); - - final var inputs = new TypedParameters(); - inputs.getParam().addAll(List.of(ldesServerParam, shaclShapeParam)); - validationModule.setInputs(inputs); - - GetModuleDefinitionResponse response = new GetModuleDefinitionResponse(); - response.setModule(validationModule); - return response; - } - - @Override - public ValidationResponse validate(ValidateRequest validateRequest) { - final ValidationParameters validationParams = extractValidationParamsFromRequest(validateRequest); - LOG.info("Received 'validate' command from test bed for session [{}]", validationParams.sessionId()); - final ValidationReport validationReport = shaclValidator.validate(validationParams); - LOG.atInfo().log("Validation for session [{}] completed with report: {}", validationParams.sessionId(), validationReport); - return buildValidationResult(validationReport); - } - - private ValidationParameters extractValidationParamsFromRequest(ValidateRequest validateRequest) { - final Parameters params = new Parameters(validateRequest.getInput()); - final String sessionId = validateRequest.getSessionId() != null ? validateRequest.getSessionId() : UUID.randomUUID().toString(); - String shacl = params.getStringForName(SHACL_SHAPE_KEY); - String url = params.getStringForName(LDES_URL_KEY); - final Model shaclShape = RDFConverter.readModel(shacl, RDFFormat.TURTLE); - return new ValidationParameters(url, shaclShape, sessionId); - } - - private ValidationResponse buildValidationResult(ValidationReport validationReport) { - final ValidationResponse result = new ValidationResponse(); - result.setReport(ValidationReportToTarMapper.mapToTar(validationReport)); - return result; - } - - -} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/config/ServiceConfig.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/config/ServiceConfig.java index 29498bf..6cba958 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/config/ServiceConfig.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/config/ServiceConfig.java @@ -1,6 +1,7 @@ package be.vlaanderen.informatievlaanderen.ldes.gitb.config; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ValidationServiceImpl; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ReplicationProcessingService; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ShaclValidationService; import org.apache.cxf.Bus; import org.apache.cxf.jaxws.EndpointImpl; import org.springframework.context.annotation.Bean; @@ -14,18 +15,22 @@ @Configuration public class ServiceConfig { - /** - * The CXF endpoint that will serve validation service calls. - * - * @return The endpoint. - */ @Bean - public EndpointImpl validationService(Bus cxfBus, ValidationServiceImpl validationServiceImplementation) { - EndpointImpl endpoint = new EndpointImpl(cxfBus, validationServiceImplementation); + public EndpointImpl validationService(Bus cxfBus, ShaclValidationService shaclValidationService) { + EndpointImpl endpoint = new EndpointImpl(cxfBus, shaclValidationService); endpoint.setServiceName(new QName("http://www.gitb.com/vs/v1/", "ValidationService")); endpoint.setEndpointName(new QName("http://www.gitb.com/vs/v1/", "ValidationServicePort")); endpoint.publish("/validation"); return endpoint; } + @Bean + public EndpointImpl processingService(Bus cxfBus, ReplicationProcessingService replicationProcessingService) { + EndpointImpl endpoint = new EndpointImpl(cxfBus, replicationProcessingService); + endpoint.setServiceName(new QName("http://www.gitb.com/ps/v1/", "ProcessingServiceService")); + endpoint.setEndpointName(new QName("http://www.gitb.com/ps/v1/", "ProcessingServicePort")); + endpoint.publish("/process"); + return endpoint; + } + } diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManager.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManager.java index cd58fb8..ec1194e 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManager.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManager.java @@ -12,82 +12,27 @@ import org.springframework.stereotype.Service; import java.io.IOException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; @Service public class LdesClientStatusManager { - private static final Logger log = LoggerFactory.getLogger(LdesClientStatusManager.class); - private static final int POLLING_PERIOD_IN_SECONDS = 5; - private static final int CLIENT_STATUS_FETCHING_RETRIES = 5; private final RequestExecutor requestExecutor; private final LdioConfigProperties ldioConfigProperties; - + private final ObjectMapper objectMapper; public LdesClientStatusManager(RequestExecutor requestExecutor, LdioConfigProperties ldioConfigProperties) { this.requestExecutor = requestExecutor; this.ldioConfigProperties = ldioConfigProperties; + objectMapper = new ObjectMapper(); } - public void waitUntilReplicated(String pipelineName) { - log.atInfo().log("Waiting for the LDES client to complete REPLICATING"); - CompletableFuture future = new CompletableFuture<>(); - final String ldesClientStatusPollingUrl = ldioConfigProperties.getLdioLdesClientStatusUrlTemplate().formatted(pipelineName); - ReplicationTask replicationTask = new ReplicationTask(ldesClientStatusPollingUrl, requestExecutor, future); - Timer timer = new Timer(); - timer.schedule(replicationTask, 0, 5000); - future.exceptionally(e -> { - log.atError().log("Something went wrong while waiting for LDES client to be fully replicated: {}", e.getMessage()); - return false; - }).thenAccept(replicated -> timer.cancel()).join(); - } - - - static class ReplicationTask extends TimerTask { - private final ObjectMapper objectMapper; - private final String pollingUrl; - private final RequestExecutor requestExecutor; - private final CompletableFuture future; - private final AtomicInteger retryCount; - - public ReplicationTask(String pollingUrl, RequestExecutor requestExecutor, CompletableFuture future) { - this.pollingUrl = pollingUrl; - this.requestExecutor = requestExecutor; - this.future = future; - retryCount = new AtomicInteger(); - objectMapper = new ObjectMapper(); - } - - @Override - public void run() { - try { - final ClientStatus clientStatus = getClientStatus(); - retryCount.set(0); - log.atDebug().log("Checking for LDES client status"); - if (ClientStatus.isSuccessfullyReplicated(clientStatus)) { - log.atInfo().log("LDES client status is now {}", clientStatus.toString()); - future.complete(true); - } - } catch (LdesClientStatusUnavailableException e) { - if (retryCount.incrementAndGet() == CLIENT_STATUS_FETCHING_RETRIES) { - future.completeExceptionally(e); - } - log.atWarn().log("LDES client status for {} is not available yet at attempt {}, trying again in {} seconds ...", pollingUrl, retryCount.get() + 1, POLLING_PERIOD_IN_SECONDS); - } catch (Exception e) { - future.completeExceptionally(e); - } - } - - public ClientStatus getClientStatus() { - final HttpResponse response = requestExecutor.execute(new GetRequest(pollingUrl), 200, 404); - final String json = response.getBody().orElseThrow(LdesClientStatusUnavailableException::new); - try { - return objectMapper.readValue(json, ClientStatus.class); - } catch (IOException e) { - throw new IllegalStateException("Invalid client status received from %s".formatted(pollingUrl)); - } + public ClientStatus getClientStatus(String pipelineName) { + final String pollingUrl = ldioConfigProperties.getLdioLdesClientStatusUrlTemplate().formatted(pipelineName); + final HttpResponse response = requestExecutor.execute(new GetRequest(pollingUrl), 200, 404); + final String json = response.getBody().orElseThrow(LdesClientStatusUnavailableException::new); + try { + return objectMapper.readValue(json, ClientStatus.class); + } catch (IOException e) { + throw new IllegalStateException("Invalid client status received from %s".formatted(pollingUrl)); } } } diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidator.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidator.java index 1584036..aefc907 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidator.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidator.java @@ -3,6 +3,8 @@ import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.PostRequest; import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.config.LdioConfigProperties; +import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationReport; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ValidationParameters; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.rio.Rio; @@ -27,7 +29,11 @@ public RepositoryValidator(RequestExecutor requestExecutor, LdioConfigProperties this.repositoryValidationUrlTemplate = ldioProperties.getRepositoryValidationUrlTemplate(); } - public Model validate(String repositoryId, Model shaclShape) { + public ValidationReport validate(ValidationParameters validationParameters) { + return validate(validationParameters.pipelineName(), validationParameters.shaclShape()); + } + + public ValidationReport validate(String repositoryId, Model shaclShape) { log.atInfo().log("Validating repository ..."); final StringWriter shaclShapeWriter = new StringWriter(); Rio.write(shaclShape, shaclShapeWriter, CONTENT_TYPE); @@ -39,7 +45,7 @@ public Model validate(String repositoryId, Model shaclShape) { .map(StringReader::new) .orElseThrow(() -> new IllegalStateException("Unable to read validation report from response: missing report")); try { - return Rio.parse(content, CONTENT_TYPE); + return new ValidationReport(Rio.parse(content, CONTENT_TYPE)); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutor.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutor.java new file mode 100644 index 0000000..4777e21 --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutor.java @@ -0,0 +1,39 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ParameterDefinition; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component(DestroyPipelineProcessExecutor.NAME) +public class DestroyPipelineProcessExecutor implements ProcessExecutor { + public static final String NAME = "destroyPipeline"; + private final LdioPipelineManager ldioPipelineManager; + private final Rdf4jRepositoryManager rdf4jRepositoryManager; + + public DestroyPipelineProcessExecutor(LdioPipelineManager ldioPipelineManager, Rdf4jRepositoryManager rdf4jRepositoryManager) { + this.ldioPipelineManager = ldioPipelineManager; + this.rdf4jRepositoryManager = rdf4jRepositoryManager; + } + + @Override + public String getName() { + return NAME; + } + + @Override + public List getParameterDefinitions() { + return List.of(); + } + + @Override + public ProcessResult execute(ProcessParameters processParameters) { + ldioPipelineManager.deletePipeline(processParameters.getPipelineName()); + rdf4jRepositoryManager.deleteRepository(processParameters.getPipelineName()); + return ProcessResult.infoMessage("Pipeline '%s' is deleted".formatted(processParameters.getPipelineName())); + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutor.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutor.java new file mode 100644 index 0000000..766d95a --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutor.java @@ -0,0 +1,68 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.excpeptions.LdesClientStatusUnavailableException; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.valuebojects.ClientStatus; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.Message; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ParameterDefinition; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import com.gitb.tr.TestResultType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component(HaltWhenReplicatedProcessExecutor.NAME) +public class HaltWhenReplicatedProcessExecutor implements ProcessExecutor { + public static final String NAME = "haltWhenReplicated"; + private static final Logger log = LoggerFactory.getLogger(HaltWhenReplicatedProcessExecutor.class); + private final LdesClientStatusManager ldesClientStatusManager; + private final LdioPipelineManager ldioPipelineManager; + + public HaltWhenReplicatedProcessExecutor(LdesClientStatusManager ldesClientStatusManager, LdioPipelineManager ldioPipelineManager) { + this.ldesClientStatusManager = ldesClientStatusManager; + this.ldioPipelineManager = ldioPipelineManager; + } + + @Override + public String getName() { + return NAME; + } + + @Override + public List getParameterDefinitions() { + return List.of(); + } + + @Override + public ProcessResult execute(ProcessParameters processParameters) { + final ClientStatus status; + try { + status = ldesClientStatusManager.getClientStatus(processParameters.getPipelineName()); + } catch (LdesClientStatusUnavailableException e) { + log.atWarn().log("Client status unavailable"); + return new ProcessResult( + TestResultType.FAILURE, + Message.error(e.getMessage()) + ); + } + if(ClientStatus.isSuccessfullyReplicated(status)) { + ldioPipelineManager.haltPipeline(processParameters.getPipelineName()); + log.atInfo().log("REPLICATING has been finished for pipeline {}", processParameters.getPipelineName()); + return new ProcessResult( + TestResultType.SUCCESS, + Message.statusMessage(status), + new Message("MESSAGE", "PIPELINE will be PAUSED soon") + ); + } + log.atDebug().log("Pipeline {} is still REPLICATING", processParameters.getPipelineName()); + return new ProcessResult( + TestResultType.SUCCESS, + Message.statusMessage(status), + new Message("MESSAGE", "CLIENT is not %s or %s yet".formatted(ClientStatus.SYNCHRONISING, ClientStatus.COMPLETED)) + ); + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutor.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutor.java new file mode 100644 index 0000000..c56cf81 --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutor.java @@ -0,0 +1,13 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ParameterDefinition; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; + +import java.util.List; + +public interface ProcessExecutor { + String getName(); + List getParameterDefinitions(); + ProcessResult execute(ProcessParameters processParameters); +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutors.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutors.java new file mode 100644 index 0000000..9ad944c --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutors.java @@ -0,0 +1,25 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +@Component +public class ProcessExecutors { + private final Map processExecutorBeans; + + public ProcessExecutors(ApplicationContext applicationContext) { + processExecutorBeans = applicationContext.getBeansOfType(ProcessExecutor.class); + } + + public Optional getProcessExecutor(String name) { + return Optional.ofNullable(processExecutorBeans.get(name)); + } + + public Collection getProcessExecutors() { + return processExecutorBeans.values(); + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutor.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutor.java new file mode 100644 index 0000000..2da2a96 --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutor.java @@ -0,0 +1,43 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ParameterDefinition; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component(StartReplicatingProcessExecutor.NAME) +public class StartReplicatingProcessExecutor implements ProcessExecutor { + public static final String NAME = "startReplicating"; + + private final LdioPipelineManager ldioPipelineManager; + private final Rdf4jRepositoryManager repositoryManager; + + public StartReplicatingProcessExecutor(LdioPipelineManager ldioPipelineManager, Rdf4jRepositoryManager repositoryManager) { + this.ldioPipelineManager = ldioPipelineManager; + this.repositoryManager = repositoryManager; + } + + @Override + public String getName() { + return NAME; + } + + @Override + public List getParameterDefinitions() { + return List.of( + new ParameterDefinition("ldes-url", "string", true, "URL of the LDES to validate") + ); + } + + @Override + public ProcessResult execute(ProcessParameters processParameters) { + final String pipelineName = processParameters.getPipelineName(); + repositoryManager.createRepository(pipelineName); + ldioPipelineManager.initPipeline(processParameters.getLdesUrl(), pipelineName); + return ProcessResult.infoMessage("Pipeline '%s' created".formatted(pipelineName)); + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/services/TarSupplier.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/suppliers/TarSupplier.java similarity index 67% rename from src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/services/TarSupplier.java rename to src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/suppliers/TarSupplier.java index 8ae52fd..508e042 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/services/TarSupplier.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/suppliers/TarSupplier.java @@ -1,6 +1,7 @@ -package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.services; +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.suppliers; import com.gitb.core.AnyContent; +import com.gitb.core.ValueEmbeddingEnumeration; import com.gitb.tr.TAR; import com.gitb.tr.TestResultType; @@ -11,16 +12,23 @@ public class TarSupplier implements Supplier { private final TestResultType testResultType; + private final AnyContent context; - private TarSupplier(TestResultType testResultType) { + public TarSupplier(TestResultType testResultType, AnyContent context) { this.testResultType = testResultType; + this.context = context; + } + + public TarSupplier(TestResultType testResultType) { + this.testResultType = testResultType; + this.context = new AnyContent(); + this.context.setType("string"); + this.context.setEmbeddingMethod(ValueEmbeddingEnumeration.STRING); } @Override public TAR get() { final TAR tar = new TAR(); - final AnyContent context = new AnyContent(); - context.setType("map"); tar.setContext(context); tar.setResult(testResultType); try { diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/ShaclValidator.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/ShaclValidator.java deleted file mode 100644 index 4535b7e..0000000 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/ShaclValidator.java +++ /dev/null @@ -1,50 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl; - -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.RepositoryValidator; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationReport; -import org.eclipse.rdf4j.model.Model; -import org.springframework.stereotype.Component; - -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; - -@Component -public class ShaclValidator { - private final LdioPipelineManager ldioPipelineManager; - private final LdesClientStatusManager clientStatusManager; - private final Rdf4jRepositoryManager repositoryManager; - private final RepositoryValidator validator; - - public ShaclValidator(LdioPipelineManager ldioPipelineManager, LdesClientStatusManager clientStatusManager, Rdf4jRepositoryManager repositoryManager, RepositoryValidator validator) { - this.ldioPipelineManager = ldioPipelineManager; - this.clientStatusManager = clientStatusManager; - this.repositoryManager = repositoryManager; - this.validator = validator; - } - - public ValidationReport validate(ValidationParameters params) { - setupPipelineAndTripleStore(params); - haltPipelineWhenReady(params); - final Model shaclValidationReport = validator.validate(params.pipelineName(), params.shaclShape()); - cleanup(params); - return new ValidationReport(shaclValidationReport); - } - - private void setupPipelineAndTripleStore(ValidationParameters params) { - repositoryManager.createRepository(params.pipelineName()); - ldioPipelineManager.initPipeline(params.ldesUrl(), params.pipelineName()); - } - - private void haltPipelineWhenReady(ValidationParameters params) { - clientStatusManager.waitUntilReplicated(PIPELINE_NAME_TEMPLATE.formatted(params.sessionId())); - ldioPipelineManager.haltPipeline(params.pipelineName()); - } - - private void cleanup(ValidationParameters params) { - repositoryManager.deleteRepository(params.pipelineName()); - ldioPipelineManager.deletePipeline(params.pipelineName()); - } -} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/ValidationParameters.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/ValidationParameters.java deleted file mode 100644 index 0cd4309..0000000 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/ValidationParameters.java +++ /dev/null @@ -1,13 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects; - -import org.eclipse.rdf4j.model.Model; - -public record ValidationParameters(String ldesUrl, Model shaclShape, String sessionId) { - public static final String LDES_URL_KEY = "ldes-url"; - public static final String SHACL_SHAPE_KEY = "shacl-shape"; - public static final String PIPELINE_NAME_TEMPLATE = "validation-pipeline-%s"; - - public String pipelineName() { - return PIPELINE_NAME_TEMPLATE.formatted(sessionId); - } -} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/ErrorSeverityLevel.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/ErrorSeverityLevel.java index 25f203c..9f7f250 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/ErrorSeverityLevel.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/ErrorSeverityLevel.java @@ -1,6 +1,6 @@ package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.severitylevels; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.services.TarSupplier; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.suppliers.TarSupplier; import com.gitb.tr.TAR; import com.gitb.tr.TestAssertionReportType; import jakarta.xml.bind.JAXBElement; diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/InfoSeverityLevel.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/InfoSeverityLevel.java index fae0ec0..3450625 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/InfoSeverityLevel.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/InfoSeverityLevel.java @@ -1,6 +1,6 @@ package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.severitylevels; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.services.TarSupplier; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.suppliers.TarSupplier; import com.gitb.tr.TAR; import com.gitb.tr.TestAssertionReportType; import jakarta.xml.bind.JAXBElement; diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/WarningSeverityLevel.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/WarningSeverityLevel.java index 3855a1f..c0f020f 100644 --- a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/WarningSeverityLevel.java +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/shacl/valueobjects/severitylevels/WarningSeverityLevel.java @@ -1,6 +1,6 @@ package be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.severitylevels; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.services.TarSupplier; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.suppliers.TarSupplier; import com.gitb.tr.TAR; import com.gitb.tr.TestAssertionReportType; import jakarta.xml.bind.JAXBElement; diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/Message.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/Message.java new file mode 100644 index 0000000..4f5ca4f --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/Message.java @@ -0,0 +1,37 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.valuebojects.ClientStatus; +import com.gitb.core.AnyContent; +import com.gitb.core.ValueEmbeddingEnumeration; + +public class Message { + private final String name; + private final String value; + + public Message(String name, String value) { + this.name = name; + this.value = value; + } + + public AnyContent convertToAnyContent() { + final AnyContent message = new AnyContent(); + message.setName(name); + message.setValue(value); + message.setEmbeddingMethod(ValueEmbeddingEnumeration.STRING); + message.setType("string"); + return message; + } + + public static Message error(String value) { + return new Message("ERROR", value); + } + + public static Message info(String value) { + return new Message("MESSAGE", value); + } + + public static Message statusMessage(ClientStatus status) { + return new Message("STATUS", status.name()); + } + +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ParameterDefinition.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ParameterDefinition.java new file mode 100644 index 0000000..c5237e2 --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ParameterDefinition.java @@ -0,0 +1,33 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import com.gitb.core.ConfigurationType; +import com.gitb.core.TypedParameter; +import com.gitb.core.UsageEnumeration; + +public class ParameterDefinition { + private final String name; + private final String type; + private final boolean required; + private final String description; + + public ParameterDefinition(String name, String type, boolean required, String description) { + this.name = name; + this.type = type; + this.required = required; + this.description = description; + } + + public String getName() { + return name; + } + + public TypedParameter convertToTypedParameter() { + final TypedParameter typedParameter = new TypedParameter(); + typedParameter.setName(name); + typedParameter.setType(type); + typedParameter.setUse(required ? UsageEnumeration.R : UsageEnumeration.O); + typedParameter.setDesc(description); + typedParameter.setKind(ConfigurationType.SIMPLE); + return typedParameter; + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessParameters.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessParameters.java new file mode 100644 index 0000000..2392fee --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessParameters.java @@ -0,0 +1,30 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import com.gitb.core.AnyContent; + +import java.util.List; + +public class ProcessParameters { + public static final String LDES_URL_KEY = "ldes-url"; + private final SessionId sessionId; + private final Parameters parameters; + + public ProcessParameters(SessionId sessionId, Parameters parameters) { + this.sessionId = sessionId; + this.parameters = parameters; + } + + public ProcessParameters(String sessionId, List items) { + this(SessionId.from(sessionId), new Parameters(items)); + } + + public String getPipelineName() { + return sessionId.getPipelineName(); + } + + public String getLdesUrl() { + return parameters.getStringForName(LDES_URL_KEY); + } + + +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessResult.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessResult.java new file mode 100644 index 0000000..fcb2ec7 --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ProcessResult.java @@ -0,0 +1,44 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.suppliers.TarSupplier; +import com.gitb.core.AnyContent; +import com.gitb.core.ValueEmbeddingEnumeration; +import com.gitb.ps.ProcessResponse; +import com.gitb.tr.TestResultType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +public class ProcessResult { + private static final Logger log = LoggerFactory.getLogger(ProcessResult.class); + private final TestResultType type; + private final Message[] messages; + + public ProcessResult(TestResultType type, Message... messages) { + this.type = type; + this.messages = messages; + } + + public ProcessResponse convertToResponse() { + final ProcessResponse response = new ProcessResponse(); + final AnyContent context = new AnyContent(); + context.setEmbeddingMethod(ValueEmbeddingEnumeration.STRING); + context.setType("string"); + context.getItem().addAll(Arrays.stream(messages).map(Message::convertToAnyContent).toList()); + response.setReport(new TarSupplier(type, context).get()); + response.getOutput().addAll(Arrays.stream(messages).map(Message::convertToAnyContent).toList()); + return response; + } + + public static ProcessResult invalidOperation(String name) { + final String value = "No such operation available: %s".formatted(name); + log.atInfo().log(value); + return new ProcessResult(TestResultType.FAILURE, Message.error(value)); + } + + public static ProcessResult infoMessage(String messageValue) { + return new ProcessResult(TestResultType.SUCCESS, Message.info(messageValue)); + } + +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/SessionId.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/SessionId.java new file mode 100644 index 0000000..d7eaf1e --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/SessionId.java @@ -0,0 +1,44 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import java.util.Objects; +import java.util.UUID; + +public class SessionId { + public static final String PIPELINE_NAME_TEMPLATE = "validation-pipeline-%s"; + + private final String uuid; + + private SessionId(String uuid) { + this.uuid = uuid; + } + + public String getId() { + return uuid; + } + + public String getPipelineName() { + return PIPELINE_NAME_TEMPLATE.formatted(uuid); + } + + public static SessionId from(String uuid) { + return new SessionId(uuid == null ? UUID.randomUUID().toString() : uuid); + } + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SessionId sessionId)) return false; + + return Objects.equals(uuid, sessionId.uuid); + } + + @Override + public int hashCode() { + return Objects.hashCode(uuid); + } + + @Override + public String toString() { + return uuid; + } +} diff --git a/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationParameters.java b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationParameters.java new file mode 100644 index 0000000..58b752d --- /dev/null +++ b/src/main/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationParameters.java @@ -0,0 +1,37 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.RDFConverter; +import com.gitb.core.AnyContent; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.rio.RDFFormat; + +import java.util.List; + +public final class ValidationParameters { + public static final String SHACL_SHAPE_KEY = "shacl-shape"; + public static final String PIPELINE_NAME_TEMPLATE = "validation-pipeline-%s"; + private final SessionId sessionId; + private final Parameters parameters; + + public ValidationParameters(SessionId sessionId, Parameters parameters) { + this.sessionId = sessionId; + this.parameters = parameters; + } + + public ValidationParameters(SessionId sessionId, List items) { + this(sessionId, new Parameters(items)); + } + + public String sessionId() { + return sessionId.getId(); + } + + public String pipelineName() { + return sessionId.getPipelineName(); + } + + public Model shaclShape() { + String shacl = parameters.getStringForName(SHACL_SHAPE_KEY); + return RDFConverter.readModel(shacl, RDFFormat.TURTLE); + } +} diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingServiceTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingServiceTest.java new file mode 100644 index 0000000..c7e7265 --- /dev/null +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ReplicationProcessingServiceTest.java @@ -0,0 +1,114 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.config.ServiceConfig; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication.DestroyPipelineProcessExecutor; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication.HaltWhenReplicatedProcessExecutor; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication.ProcessExecutor; +import be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication.StartReplicatingProcessExecutor; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.SessionId; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.util.ResourceUtils; + +import java.io.IOException; +import java.nio.file.Files; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.assertArg; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +@EnableAutoConfiguration +@SpringBootTest(properties = {"ldio.host=http://ldio-workbench:8080", "ldio.sparql-host=http://graph-db:7200"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = ServiceConfig.class) +@ComponentScan(value = {"be.vlaanderen.informatievlaanderen.ldes"}) +class ReplicationProcessingServiceTest { + private static final String TEST_PIPELINE_UUID = "test-session-uuid"; + private static final SessionId TEST_PIPELINE_SESSION_ID = SessionId.from(TEST_PIPELINE_UUID); + @MockBean(name = StartReplicatingProcessExecutor.NAME) + private ProcessExecutor startReplicatingProcessExecutor; + @MockBean(name = HaltWhenReplicatedProcessExecutor.NAME) + private ProcessExecutor checkReplicatingProcessExecutor; + @MockBean(name = DestroyPipelineProcessExecutor.NAME) + private ProcessExecutor destroyPipelineProcessExecutor; + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void test_StartReplicating() throws IOException { + final String content = """ + startReplicating + + http://ldes-server:8080/verkeersmetingen + + """; + restTemplate.postForEntity("/services/process?wsdl", createRequest(content), String.class); + + verify(startReplicatingProcessExecutor).execute(assertArg(params -> + assertThat(params) + .extracting("sessionId") + .isEqualTo(TEST_PIPELINE_SESSION_ID) + )); + } + + @Test + void test_HaltWhenReplicated() throws IOException { + final String content = "haltWhenReplicated"; + restTemplate.postForEntity("/services/process?wsdl", createRequest(content), String.class); + + verify(checkReplicatingProcessExecutor).execute(assertArg(params -> assertThat(params) + .extracting("sessionId") + .isEqualTo(TEST_PIPELINE_SESSION_ID) + )); + } + + @Test + void test_DestroyPipeline() throws IOException { + final String content = "destroyPipeline"; + restTemplate.postForEntity("/services/process?wsdl", createRequest(content), String.class); + + verify(destroyPipelineProcessExecutor).execute(assertArg(params -> assertThat(params) + .extracting("sessionId") + .isEqualTo(TEST_PIPELINE_SESSION_ID) + )); + } + + @Test + void test_InvalidStartReplicatingRequest() throws IOException { + final String content = """ + start-replicating + + http://ldes-server:8080/verkeersmetingen + + """; + final HttpEntity request = createRequest(content); + + restTemplate.postForEntity("/services/process?wsdl", request, String.class); + + verifyNoInteractions(startReplicatingProcessExecutor, checkReplicatingProcessExecutor); + } + + private static HttpEntity createRequest(String content) throws IOException { + final HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_XML); + final String requestPayload = readPayload(content); + return new HttpEntity<>(requestPayload, headers); + } + + private static String readPayload(String content) throws IOException { + final String payLoadTemplate = Files.readString(ResourceUtils.getFile("classpath:soap-requests/process-request.xml").toPath()); + return payLoadTemplate.replace("", content); + } + + +} \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImplTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationServiceTest.java similarity index 61% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImplTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationServiceTest.java index 4ed7643..aa4307a 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ValidationServiceImplTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ShaclValidationServiceTest.java @@ -3,10 +3,7 @@ import be.vlaanderen.informatievlaanderen.ldes.gitb.config.ServiceConfig; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.HttpResponse; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; -import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.DeleteRequest; -import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.GetRequest; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.PostRequest; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -28,7 +25,6 @@ import java.nio.file.Files; import java.util.stream.Stream; -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -36,15 +32,9 @@ @SpringBootTest(properties = {"ldio.host=http://ldio-workbench:8080", "ldio.sparql-host=http://graph-db:7200"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration(classes = ServiceConfig.class) @ComponentScan(value = {"be.vlaanderen.informatievlaanderen.ldes"}) -class ValidationServiceImplTest { - private static final String LDIO_HOST = "http://ldio-workbench:8080"; - private static final String PIPELINE_UUID = "test-pipeline-uuid"; - private static final String LDIO_LDES_CLIENT_STATUS_URL = LDIO_HOST + "/admin/api/v1/pipeline/ldes-client/validation-pipeline-" + PIPELINE_UUID; - private static final String LDES_SERVER_URL = "http://ldes-server:8080/verkeersmetingen"; +class ShaclValidationServiceTest { @MockBean private RequestExecutor requestExecutor; - @MockBean - private Rdf4jRepositoryManager rdf4jRepositoryManager; @Autowired private TestRestTemplate restTemplate; @@ -58,16 +48,6 @@ static Stream provideShaclShapes() { @ParameterizedTest @MethodSource("provideShaclShapes") void test_ValidationServiceImpl(String fileName, String expectedShaclConformity) throws IOException { - when(requestExecutor.execute(new GetRequest(LDES_SERVER_URL))) - .thenReturn(createResponse(ResourceUtils.getFile("classpath:event-stream.ttl"))); - when(requestExecutor.execute(any(PostRequest.class), eq(201))) - .thenReturn(new HttpResponse(201, null)); - when(requestExecutor.execute(new GetRequest(LDIO_LDES_CLIENT_STATUS_URL), 200, 404)) - .thenReturn(new HttpResponse(404, null)) - .thenReturn(new HttpResponse(200, "\"REPLICATING\"")) - .thenReturn(new HttpResponse(200, "\"SYNCHRONISING\"")); - when(requestExecutor.execute(any(DeleteRequest.class), eq(202), eq(204))) - .thenReturn(new HttpResponse(202, null)); when(requestExecutor.execute(any(PostRequest.class))) .thenReturn(createResponse(ResourceUtils.getFile("classpath:" + fileName))); @@ -76,10 +56,7 @@ void test_ValidationServiceImpl(String fileName, String expectedShaclConformity) assertThat(result) .extracting(HttpEntity::getBody, InstanceOfAssertFactories.STRING) .contains(expectedShaclConformity); - verify(rdf4jRepositoryManager).createRepository(PIPELINE_NAME_TEMPLATE.formatted(PIPELINE_UUID)); - verify(rdf4jRepositoryManager).deleteRepository(PIPELINE_NAME_TEMPLATE.formatted(PIPELINE_UUID)); - verify(requestExecutor).execute(any(PostRequest.class), eq(201)); - verify(requestExecutor).execute(any(DeleteRequest.class), eq(202), eq(204)); + verify(requestExecutor).execute(any(PostRequest.class)); } private static HttpResponse createResponse(File file) throws IOException { @@ -89,7 +66,7 @@ private static HttpResponse createResponse(File file) throws IOException { private static HttpEntity createRequest() throws IOException { final HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.TEXT_XML); - final String requestPayload = Files.readString(ResourceUtils.getFile("classpath:validate-request.xml").toPath()); + final String requestPayload = Files.readString(ResourceUtils.getFile("classpath:soap-requests/validate-request.xml").toPath()); return new HttpEntity<>(requestPayload, headers); } } \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdesClientStatusManagerTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManagerTest.java similarity index 62% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdesClientStatusManagerTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManagerTest.java index f1f227c..1b2c25b 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdesClientStatusManagerTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdesClientStatusManagerTest.java @@ -1,17 +1,19 @@ -package be.vlaanderen.informatievlaanderen.ldes.ldio; +package be.vlaanderen.informatievlaanderen.ldes.gitb.ldio; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.config.LdioConfigProperties; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.valuebojects.ClientStatus; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.HttpResponse; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.GetRequest; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.config.LdioConfigProperties; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.valuebojects.ClientStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -30,26 +32,15 @@ void setUp() { ldesClientStatusManager = new LdesClientStatusManager(requestExecutor, ldioConfigProperties); } - @Test - void test_WaitUntilReplicated() { - when(requestExecutor.execute(any(), eq(expectedStatusCodes))) - .thenReturn(createEmptyResponse()) - .thenReturn(createResponse(ClientStatus.REPLICATING)) - .thenReturn(createResponse(ClientStatus.REPLICATING)) - .thenReturn(createResponse(ClientStatus.SYNCHRONISING)); - - ldesClientStatusManager.waitUntilReplicated(PIPELINE_NAME); - - verify(requestExecutor, timeout(15000).times(4)).execute(any(), eq(expectedStatusCodes)); - } - @Test - void test_WaitUntilReplicated_when_StatusUnavailable() { - when(requestExecutor.execute(any(GetRequest.class), eq(200), eq(404))).thenReturn(createEmptyResponse()); + @ParameterizedTest + @EnumSource(ClientStatus.class) + void test_GetClientStatus(ClientStatus status) { + when(requestExecutor.execute(any(GetRequest.class), eq(expectedStatusCodes))).thenReturn(createResponse(status)); - ldesClientStatusManager.waitUntilReplicated(PIPELINE_NAME); + final ClientStatus actual = ldesClientStatusManager.getClientStatus(PIPELINE_NAME); - verify(requestExecutor, times(5)).execute(any(GetRequest.class), eq(200), eq(404)); + assertThat(actual).isEqualTo(status); } private static HttpResponse createEmptyResponse() { diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdioPipelineManagerTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdioPipelineManagerTest.java similarity index 93% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdioPipelineManagerTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdioPipelineManagerTest.java index c405a5c..bc7a559 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/LdioPipelineManagerTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/LdioPipelineManagerTest.java @@ -1,7 +1,6 @@ -package be.vlaanderen.informatievlaanderen.ldes.ldio; +package be.vlaanderen.informatievlaanderen.ldes.gitb.ldio; import be.vlaanderen.informatievlaanderen.ldes.PostRequestAssert; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.DeleteRequest; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.requests.PostRequest; @@ -21,7 +20,7 @@ import java.io.IOException; -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; +import static be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.assertArg; import static org.mockito.ArgumentMatchers.eq; diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldes/valueobjects/EventStreamFetcherTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/ldes/EventStreamFetcherTest.java similarity index 85% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldes/valueobjects/EventStreamFetcherTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/ldes/EventStreamFetcherTest.java index a3c741d..32f8c47 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldes/valueobjects/EventStreamFetcherTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/ldes/EventStreamFetcherTest.java @@ -1,9 +1,7 @@ -package be.vlaanderen.informatievlaanderen.ldes.ldes.valueobjects; +package be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.ldes; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.HttpResponse; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.ldes.EventStreamFetcher; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.ldes.EventStreamProperties; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/pipeline/ValidationPipelineSupplierTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/pipeline/ValidationPipelineSupplierTest.java similarity index 84% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/pipeline/ValidationPipelineSupplierTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/pipeline/ValidationPipelineSupplierTest.java index 1810311..fb4bb22 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/ldio/pipeline/ValidationPipelineSupplierTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/ldio/pipeline/ValidationPipelineSupplierTest.java @@ -1,7 +1,6 @@ -package be.vlaanderen.informatievlaanderen.ldes.ldio.pipeline; +package be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.pipeline; import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.ldes.EventStreamProperties; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.pipeline.ValidationPipelineSupplier; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; @@ -9,7 +8,7 @@ import java.io.IOException; -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; +import static be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; import static org.assertj.core.api.Assertions.assertThat; class ValidationPipelineSupplierTest { diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/rdfrepo/RepositoryValidatorTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidatorTest.java similarity index 95% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/rdfrepo/RepositoryValidatorTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidatorTest.java index 544e909..d836c12 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/rdfrepo/RepositoryValidatorTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/rdfrepo/RepositoryValidatorTest.java @@ -1,9 +1,8 @@ -package be.vlaanderen.informatievlaanderen.ldes.rdfrepo; +package be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.RepositoryValidator; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.config.LdioConfigProperties; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.HttpResponse; import be.vlaanderen.informatievlaanderen.ldes.gitb.requestexecutor.RequestExecutor; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.config.LdioConfigProperties; import org.assertj.core.api.InstanceOfAssertFactories; import org.eclipse.rdf4j.model.Literal; import org.eclipse.rdf4j.model.Model; @@ -55,7 +54,7 @@ void given_ValidRepo_when_Validate_then_ReturnEmptyModel() throws IOException { final String validationReport = Files.readString(ResourceUtils.getFile("classpath:validation-report/valid.ttl").toPath()); when(requestExecutor.execute(any())).thenReturn(new HttpResponse(200, validationReport)); - final Model result = repoValidator.validate(REPOSITORY_ID, shaclShape); + final Model result = repoValidator.validate(REPOSITORY_ID, shaclShape).shaclReport(); assertThat(result) .filteredOn(statement -> statement.getPredicate().toString().equals(SHACL_CONFORMS_URI)) @@ -70,7 +69,7 @@ void given_InvalidRepo_when_Validate_then_ReturnNonEmptyModel() throws IOExcepti final String validationReport = Files.readString(ResourceUtils.getFile("classpath:validation-report/invalid.ttl").toPath()); when(requestExecutor.execute(any())).thenReturn(new HttpResponse(200, validationReport)); - final Model result = repoValidator.validate(REPOSITORY_ID, shaclShape); + final Model result = repoValidator.validate(REPOSITORY_ID, shaclShape).shaclReport(); assertThat(result) .filteredOn(statement -> statement.getPredicate().toString().equals(SHACL_CONFORMS_URI)) diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutorTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutorTest.java new file mode 100644 index 0000000..1a5bed4 --- /dev/null +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/DestroyPipelineProcessExecutorTest.java @@ -0,0 +1,44 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.Message; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.SessionId; +import com.gitb.tr.TestResultType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + + +@ExtendWith(MockitoExtension.class) +class DestroyPipelineProcessExecutorTest { + private static final String SESSION_UUID = "my-test-session-uuid"; + @Mock + private LdioPipelineManager ldioPipelineManager; + @Mock + private Rdf4jRepositoryManager rdf4jRepositoryManager; + @InjectMocks + private DestroyPipelineProcessExecutor destroyPipelineProcessExecutor; + + @Test + void test_Execute() { + final String pipelineName = SessionId.from(SESSION_UUID).getPipelineName(); + final ProcessResult expected = new ProcessResult(TestResultType.SUCCESS, new Message("MESSAGE", "Pipeline '%s' is deleted".formatted(pipelineName))); + final var actual = destroyPipelineProcessExecutor.execute(new ProcessParameters(SESSION_UUID, List.of())); + + verify(ldioPipelineManager).deletePipeline(pipelineName); + verify(rdf4jRepositoryManager).deleteRepository(pipelineName); + assertThat(actual) + .usingRecursiveComparison() + .isEqualTo(expected); + } +} \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutorTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutorTest.java new file mode 100644 index 0000000..37aea92 --- /dev/null +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/HaltWhenReplicatedProcessExecutorTest.java @@ -0,0 +1,87 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.excpeptions.LdesClientStatusUnavailableException; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.valuebojects.ClientStatus; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.Message; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessResult; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.SessionId; +import com.gitb.tr.TestResultType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class HaltWhenReplicatedProcessExecutorTest { + private static final String SESSION_UUID = "my-test-session-uuid"; + private static final SessionId SESSION_ID = SessionId.from(SESSION_UUID); + @Mock + private LdesClientStatusManager ldesClientStatusManager; + @Mock + private LdioPipelineManager ldioPipelineManager; + @InjectMocks + private HaltWhenReplicatedProcessExecutor haltWhenReplicatedProcessExecutor; + + @Test + void given_ReplicatingStatus_testExecute() { + final ProcessResult expected = new ProcessResult( + TestResultType.SUCCESS, + new Message("STATUS", "REPLICATING"), + new Message("MESSAGE", "CLIENT is not SYNCHRONISING or COMPLETED yet") + ); + when(ldesClientStatusManager.getClientStatus(anyString())).thenReturn(ClientStatus.REPLICATING); + + final ProcessResult processResult = haltWhenReplicatedProcessExecutor.execute(new ProcessParameters(SESSION_UUID, List.of())); + + assertThat(processResult) + .usingRecursiveComparison() + .isEqualTo(expected); + verifyNoInteractions(ldioPipelineManager); + } + + @EnumSource(value = ClientStatus.class, names = {"COMPLETED", "SYNCHRONISING"}, mode = EnumSource.Mode.INCLUDE) + @ParameterizedTest + void given_ClientStatus_test_Execute(ClientStatus clientStatus) { + final ProcessResult expected = new ProcessResult( + TestResultType.SUCCESS, + new Message("STATUS", clientStatus.name()), + new Message("MESSAGE", "PIPELINE will be PAUSED soon") + ); + when(ldesClientStatusManager.getClientStatus(anyString())).thenReturn(clientStatus); + + final ProcessResult processResult = haltWhenReplicatedProcessExecutor.execute(new ProcessParameters(SESSION_UUID, List.of())); + + assertThat(processResult) + .usingRecursiveComparison() + .isEqualTo(expected); + verify(ldioPipelineManager).haltPipeline(SESSION_ID.getPipelineName()); + } + + @Test + void given_ClientStatusUnavailable_test_Execute() { + final ProcessResult expected = new ProcessResult( + TestResultType.FAILURE, + new Message("ERROR", "Ldes client status not available.") + ); + when(ldesClientStatusManager.getClientStatus(anyString())).thenThrow(LdesClientStatusUnavailableException.class); + + final ProcessResult actual = haltWhenReplicatedProcessExecutor.execute(new ProcessParameters(SESSION_UUID, List.of())); + + assertThat(actual) + .usingRecursiveComparison() + .isEqualTo(expected); + verifyNoInteractions(ldioPipelineManager); + } +} \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutorsTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutorsTest.java new file mode 100644 index 0000000..fd01173 --- /dev/null +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/ProcessExecutorsTest.java @@ -0,0 +1,72 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +class ProcessExecutorsTest { + private ApplicationContextRunner runner; + + @BeforeEach + void setUp() { + runner = new ApplicationContextRunner() + .withBean(HaltWhenReplicatedProcessExecutor.class, mock(LdesClientStatusManager.class), mock(LdioPipelineManager.class)) + .withBean(StartReplicatingProcessExecutor.class, mock(LdioPipelineManager.class), mock(Rdf4jRepositoryManager.class)); + } + + @Test + void test_GetExecutors() { + runner.run(context -> { + final Collection executors = new ProcessExecutors(context).getProcessExecutors(); + + assertThat(executors) + .hasSize(2) + .map(ProcessExecutor::getName) + .containsExactlyInAnyOrder(StartReplicatingProcessExecutor.NAME, HaltWhenReplicatedProcessExecutor.NAME); + }); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("expectedBeans") + void test_Get(String name, Class beanClass, int numOfParameterDefinitions) { + runner.run(context -> { + final Optional actualProcessExecutor = new ProcessExecutors(context).getProcessExecutor(name); + + assertThat(actualProcessExecutor) + .containsInstanceOf(beanClass) + .get() + .extracting(ProcessExecutor::getParameterDefinitions, InstanceOfAssertFactories.LIST) + .hasSize(numOfParameterDefinitions); + }); + } + + @Test + void test_InvalidGet() { + runner.run(context -> { + final Optional actualProcessExecutor = new ProcessExecutors(context).getProcessExecutor("fantasy"); + + assertThat(actualProcessExecutor).isEmpty(); + }); + } + + static Stream expectedBeans() { + return Stream.of( + Arguments.of(HaltWhenReplicatedProcessExecutor.NAME, HaltWhenReplicatedProcessExecutor.class, 0), + Arguments.of(StartReplicatingProcessExecutor.NAME, StartReplicatingProcessExecutor.class, 1) + ); + } +} \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutorTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutorTest.java new file mode 100644 index 0000000..abdb0ed --- /dev/null +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/services/replication/StartReplicatingProcessExecutorTest.java @@ -0,0 +1,48 @@ +package be.vlaanderen.informatievlaanderen.ldes.gitb.services.replication; + +import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; +import be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.*; +import com.gitb.tr.TestResultType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InOrder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects.ProcessParameters.LDES_URL_KEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class StartReplicatingProcessExecutorTest { + private static final SessionId SESSION_ID = SessionId.from("my-test-session-uuid"); + private static final String LDES_URL = "http://ldes-server:8080/collection/view"; + private static final String PIPELINE_NAME = SESSION_ID.getPipelineName(); + @Mock + private Rdf4jRepositoryManager repositoryManager; + @Mock + private LdioPipelineManager ldioPipelineManager; + @InjectMocks + private StartReplicatingProcessExecutor startReplicatingProcessExecutor; + + @Test + void test_Process() { + final ProcessResult expected = new ProcessResult(TestResultType.SUCCESS, Message.info("Pipeline 'validation-pipeline-my-test-session-uuid' created")); + final Parameters parameters = mock(); + when(parameters.getStringForName(LDES_URL_KEY)).thenReturn(LDES_URL); + + final ProcessResult result = startReplicatingProcessExecutor.execute(new ProcessParameters(SESSION_ID, parameters)); + + assertThat(result) + .usingRecursiveComparison() + .isEqualTo(expected); + + + final InOrder inOrder = inOrder(repositoryManager, ldioPipelineManager); + inOrder.verify(repositoryManager).createRepository(PIPELINE_NAME); + inOrder.verify(ldioPipelineManager).initPipeline(LDES_URL, PIPELINE_NAME); + inOrder.verifyNoMoreInteractions(); + } +} \ No newline at end of file diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/valueobjects/ValidationReportTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationReportTest.java similarity index 97% rename from src/test/java/be/vlaanderen/informatievlaanderen/ldes/valueobjects/ValidationReportTest.java rename to src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationReportTest.java index 26067cf..2722ba1 100644 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/valueobjects/ValidationReportTest.java +++ b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/gitb/valueobjects/ValidationReportTest.java @@ -1,4 +1,4 @@ -package be.vlaanderen.informatievlaanderen.ldes.valueobjects; +package be.vlaanderen.informatievlaanderen.ldes.gitb.valueobjects; import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationReport; import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.severitylevels.SeverityLevels; diff --git a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/shacl/ShaclValidatorTest.java b/src/test/java/be/vlaanderen/informatievlaanderen/ldes/shacl/ShaclValidatorTest.java deleted file mode 100644 index 3def5ad..0000000 --- a/src/test/java/be/vlaanderen/informatievlaanderen/ldes/shacl/ShaclValidatorTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.shacl; - -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.ShaclValidator; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdesClientStatusManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.ldio.LdioPipelineManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.Rdf4jRepositoryManager; -import be.vlaanderen.informatievlaanderen.ldes.gitb.rdfrepo.RepositoryValidator; -import be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters; -import org.eclipse.rdf4j.model.impl.LinkedHashModel; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InOrder; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static be.vlaanderen.informatievlaanderen.ldes.gitb.shacl.valueobjects.ValidationParameters.PIPELINE_NAME_TEMPLATE; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.inOrder; - -@ExtendWith(MockitoExtension.class) -class ShaclValidatorTest { - private static final String LDES_SERVER_URL = "http://ldes-server:8080/collection"; - private static final String PIPELINE_UUID = "test-pipeline-uuid"; - private static final String PIPELINE_NAME = PIPELINE_NAME_TEMPLATE.formatted(PIPELINE_UUID); - @Mock - private Rdf4jRepositoryManager repositoryManager; - @Mock - private LdioPipelineManager ldioPipelineManager; - @Mock - private LdesClientStatusManager ldesClientStatusManager; - @Mock - private RepositoryValidator repositoryValidator; - - @InjectMocks - private ShaclValidator shaclValidator; - - @Test - void test() { - shaclValidator.validate(new ValidationParameters(LDES_SERVER_URL, new LinkedHashModel(), PIPELINE_UUID)); - - final InOrder inOrder = inOrder(ldioPipelineManager, ldesClientStatusManager, repositoryManager, repositoryValidator); - inOrder.verify(repositoryManager).createRepository(anyString()); - inOrder.verify(ldioPipelineManager).initPipeline(LDES_SERVER_URL, PIPELINE_NAME); - inOrder.verify(ldesClientStatusManager).waitUntilReplicated(PIPELINE_NAME); - inOrder.verify(ldioPipelineManager).haltPipeline(PIPELINE_NAME); - inOrder.verify(repositoryValidator).validate(PIPELINE_NAME, new LinkedHashModel()); - inOrder.verify(repositoryManager).deleteRepository(anyString()); - inOrder.verify(ldioPipelineManager).deletePipeline(PIPELINE_NAME); - inOrder.verifyNoMoreInteractions(); - } -} \ No newline at end of file diff --git a/src/test/resources/soap-requests/process-request.xml b/src/test/resources/soap-requests/process-request.xml new file mode 100644 index 0000000..31dbd7c --- /dev/null +++ b/src/test/resources/soap-requests/process-request.xml @@ -0,0 +1,11 @@ + + + + + test-session-uuid + + + + \ No newline at end of file diff --git a/src/test/resources/validate-request.xml b/src/test/resources/soap-requests/validate-request.xml similarity index 85% rename from src/test/resources/validate-request.xml rename to src/test/resources/soap-requests/validate-request.xml index bf67b2f..18b2edc 100644 --- a/src/test/resources/validate-request.xml +++ b/src/test/resources/soap-requests/validate-request.xml @@ -4,10 +4,6 @@ test-pipeline-uuid - - - http://ldes-server:8080/verkeersmetingen - .