diff --git a/Dockerfile b/Dockerfile
index 2c152c5efd..9692903d52 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,9 +10,6 @@ COPY .mvn .mvn
COPY settings.xml .
COPY pom.xml .
-COPY connector/pom.xml connector/pom.xml
-COPY connector/edc-recursive-job connector/edc-recursive-job
-COPY connector/irs-connector-parent connector/irs-connector-parent
COPY integration-tests integration-tests
COPY irs-api irs-api
COPY irs-common irs-common
diff --git a/api/irs-v1.0.yaml b/api/irs-v1.0.yaml
index 81c20625d6..696f8e57b3 100644
--- a/api/irs-v1.0.yaml
+++ b/api/irs-v1.0.yaml
@@ -609,7 +609,7 @@ components:
type: string
format: date-time
exception:
- $ref: '#/components/schemas/JobException'
+ $ref: '#/components/schemas/JobErrorDetails'
globalAssetId:
$ref: '#/components/schemas/GlobalAssetIdentification'
jobCompleted:
@@ -651,7 +651,7 @@ components:
- globalAssetId
- jobId
- jobState
- JobException:
+ JobErrorDetails:
type: object
description: Exception state for this job.
properties:
diff --git a/ci/checkstyle-suppressions.xml b/ci/checkstyle-suppressions.xml
index 33616c8977..dcbb0a35aa 100644
--- a/ci/checkstyle-suppressions.xml
+++ b/ci/checkstyle-suppressions.xml
@@ -1,7 +1,7 @@
+ "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
+ "https://checkstyle.org/dtds/suppressions_1_2.dtd">
diff --git a/connector/README.md b/connector/README.md
deleted file mode 100644
index 539adac767..0000000000
--- a/connector/README.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Provider & Consumer Connector
-
-## Git token
-
-Create a [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) in GitHub, limited to **read:packages** scope.
-
-Configure the following GitHub *repository secrets*:
-
-- IRS_EDC_PKG_USERNAME (your_github_username)
-- IRS_EDC_PKG_PASSWORD (your_github_pat_token)
-
-## Local build
-
-Copy `settings.xml` into your `~/.m2/` folder (or merge it with a file already there), and replace the environment variable references with the following:
-
-```xml
-your_github_username
-your_github_pat_token
-```
-
-## Docker build
-
-See `run-integration-test.sh` file.
-
-## Running tests
-
-Download certificate for the IRS Connector Consumer to communicate with its Key Vault to local filesystem. In the `cd/terraform-identities` directory run:
-
-```sh
-terraform init
-az keyvault secret download --file ../../dev/local/cert.pfx --vault-name "$(terraform output -raw vault_name)" --name "$(terraform output -raw irs_connector_consumer_cert_name)" --encoding base64
-```
-
-Set environment variables for GitHub access:
-
-```bash
-export IRS_EDC_PKG_USERNAME=your_github_username
-export IRS_EDC_PKG_PASSWORD=your_github_pat_token
-```
-Make sure you have configured the env properties. It can be done by creating .env file and copying content of the .env.example file into it.
-Run integration tests:
-
-```bash
-./run-integration-test.sh
-```
-
-### Debugging connectors from IDE
-
-Download certificate for the IRS Connector Consumer as explained in the previous section.
-
-Create empty file for the Provider Connector filesystem vault (FsVault):
-
-```bash
-touch ../dev/local/dataspaceconnector-vault.properties
-```
-
-Import run configurations in the `dev/ide` folder into your IDE and use these to debug the consumer and provider connectors. As default the provider connector will try to use a local IRS running at `localhost:8080`, make sure to previously start the IRS api at that port as well.
-
-Send a request to the local consumer connector by issuing:
-```bash
-curl -f -X POST http://localhost:9191/api/v0.1/retrievePartsTree -H "Content-type:application/json" -d '{"byObjectIdRequest": {"oneIDManufacturer": "BMW MUC", "objectIDManufacturer": "YS3DD78N4X7055320", "view": "AS_BUILT", "aspect": "MATERIAL", "depth": 2}}'
-```
-
-## Prometheus endpoint
-
-- Download latest jar from https://github.com/prometheus/jmx_exporter/releases
-
-- Config is available at location cd/jmx_prometheus_config.yml
-
-- Attach jmx prometheus jar as a java agent to running process.
-
-```bash
--javaagent:./jmx_prometheus_javaagent-.jar=:cd/jmx_prometheus_config.yml
-```
-
-- Metric endpoint will be available on http://localhost:/metrics
diff --git a/connector/edc-recursive-job/README.md b/connector/edc-recursive-job/README.md
deleted file mode 100644
index 039e06c300..0000000000
--- a/connector/edc-recursive-job/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# edc-recursive-job
-
-The logic to orchestate multiple transfers (to build a IRS parts tree out of recursive calls to IRS API endpoints in multiple dataspace partitions) is factored out into a generic framework to manage jobs (in this module), that allows plugging in a custom handler to provide the logic, in our case to parse the output of one IRS API call to determine the next endpoints to call.
-
-We are in discussions with the EDC team to determine if this module could be integrated upstream.
diff --git a/connector/edc-recursive-job/pom.xml b/connector/edc-recursive-job/pom.xml
deleted file mode 100644
index 788eb90974..0000000000
--- a/connector/edc-recursive-job/pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
- 4.0.0
-
-
- net.catenax.irs
- irs-connector-parent
- ${revision}
- ../irs-connector-parent
-
-
- net.catenax.irs
- edc-recursive-job
-
- Recursive Job Module
- Module for recursive job management
-
-
-
- org.projectlombok
- lombok
- 1.18.24
- true
-
-
- com.google.code.findbugs
- annotations
- 3.0.1u2
- provided
-
-
- org.jetbrains
- annotations
- 23.0.0
- provided
-
-
- org.slf4j
- slf4j-api
- 1.7.36
- provided
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
- 2.13.2
- provided
-
-
-
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobException.java b/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobException.java
deleted file mode 100644
index 0cddd12159..0000000000
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
-//
-// See the AUTHORS file(s) distributed with this work for additional
-// information regarding authorship.
-//
-// See the LICENSE file(s) distributed with this work for
-// additional information regarding license terms.
-//
-package net.catenax.irs.connector.job;
-
-/**
- * Exception related to Job problems
- */
-public class JobException extends RuntimeException {
-
- public JobException(final String message) {
- super(message);
- }
-
- public JobException(final Throwable throwable) {
- super(throwable);
- }
-}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobState.java b/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobState.java
deleted file mode 100644
index 39f94b355d..0000000000
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobState.java
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
-//
-// See the AUTHORS file(s) distributed with this work for additional
-// information regarding authorship.
-//
-// See the LICENSE file(s) distributed with this work for
-// additional information regarding license terms.
-//
-package net.catenax.irs.connector.job;
-
-/**
- * Represents the state of a {@link MultiTransferJob}.
- */
-public enum JobState {
- UNSAVED,
- INITIAL,
- IN_PROGRESS,
- TRANSFERS_FINISHED,
- COMPLETED,
- CANCELED,
- ERROR
-}
diff --git a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java b/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java
deleted file mode 100644
index bd58dddca5..0000000000
--- a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-package net.catenax.irs.connector.job;
-
-import com.github.javafaker.Faker;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-class InMemoryJobStoreTest {
-
- InMemoryJobStore sut = new InMemoryJobStore();
- Faker faker = new Faker();
- TestMother generate = new TestMother();
- MultiTransferJob job = generate.job(JobState.UNSAVED);
- MultiTransferJob job2 = generate.job(JobState.UNSAVED);
- MultiTransferJob originalJob = job.toBuilder().build();
- String otherJobId = faker.lorem().characters();
- TransferProcess process1 = generate.transfer();
- TransferProcess process2 = generate.transfer();
- String processId1 = process1.getId();
- String processId2 = process2.getId();
- String errorDetail = faker.lorem().sentence();
-
- @Test
- void find_WhenNotFound() {
- assertThat(sut.find(otherJobId)).isEmpty();
- }
-
- @Test
- void findByProcessId_WhenFound() {
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.create(job2);
- sut.addTransferProcess(job2.getJobId(), processId2);
-
- refreshJob();
- assertThat(sut.findByProcessId(processId1)).contains(job);
- }
-
- @Test
- void findByProcessId_WhenNotFound() {
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
-
- assertThat(sut.findByProcessId(processId2)).isEmpty();
- }
-
- @Test
- void create_and_find() {
- sut.create(job);
- assertThat(sut.find(job.getJobId())).isPresent()
- .get()
- .usingRecursiveComparison()
- .isEqualTo(originalJob.toBuilder().state(JobState.INITIAL).build());
- assertThat(sut.find(otherJobId)).isEmpty();
- }
-
- @Test
- void addTransferProcess() {
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- refreshJob();
- assertThat(job.getTransferProcessIds()).containsExactly(processId1);
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
- }
-
- @Test
- void completeTransferProcess_WhenJobNotFound() {
- sut.completeTransferProcess(otherJobId, process1);
- }
-
- @Test
- void completeTransferProcess_WhenTransferFound() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
-
- // Act
- sut.completeTransferProcess(job.getJobId(), process1);
-
- // Assert
- assertThat(job.getTransferProcessIds()).isEmpty();
- }
-
- @Test
- void completeTransferProcess_WhenTransferNotFound() {
- // Act
- sut.completeTransferProcess(job.getJobId(), process1);
-
- // Assert
- assertThat(job.getTransferProcessIds()).isEmpty();
- }
-
- @Test
- void completeTransferProcess_WhenTransferAlreadyCompleted() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
-
- // Act
- assertThatExceptionOfType(IllegalStateException.class)
- .isThrownBy(() -> sut.completeTransferProcess(job.getJobId(), process1));
-
- // Assert
- refreshJob();
- assertThat(job.getTransferProcessIds()).isEmpty();
- }
-
- @Test
- void completeTransferProcess_WhenNotLastTransfer_DoesNotTransitionJob() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.addTransferProcess(job.getJobId(), processId2);
-
- // Act
- sut.completeTransferProcess(job.getJobId(), process1);
-
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
- }
-
- @Test
- void completeTransferProcess_WhenLastTransfer_TransitionsJob() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.addTransferProcess(job.getJobId(), processId2);
-
- // Act
- sut.completeTransferProcess(job.getJobId(), process1);
- sut.completeTransferProcess(job.getJobId(), process2);
-
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.TRANSFERS_FINISHED);
- }
-
- @Test
- void completeJob_WhenJobNotFound() {
- // Arrange
- sut.create(job);
- // Act
- sut.completeJob(otherJobId);
- refreshJob();
- // Assert
- assertThat(job.getState()).isEqualTo(JobState.INITIAL);
- }
-
- @Test
- void completeJob_WhenJobInInitialState() {
- // Arrange
- sut.create(job);
- sut.create(job2);
- // Act
- sut.completeJob(job.getJobId());
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.COMPLETED);
- assertTrue(job.getCompletionDate().isPresent());
- assertThat(job2.getState()).isEqualTo(JobState.UNSAVED);
- }
-
- @Test
- void completeJob_WhenJobInTransfersCompletedState() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
- // Act
- sut.completeJob(job.getJobId());
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.COMPLETED);
- assertTrue(job.getCompletionDate().isPresent());
- }
-
- @Test
- void completeJob_WhenJobInTransfersInProgressState() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- // Act
- assertThatExceptionOfType(IllegalStateException.class)
- .isThrownBy(() -> sut.completeJob(job.getJobId()));
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
- }
-
- @Test
- void markJobInError_WhenJobNotFound() {
- // Arrange
- sut.create(job);
- // Act
- sut.markJobInError(otherJobId, errorDetail);
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.INITIAL);
- }
-
- @Test
- void markJobInError_WhenJobInInitialState() {
- // Arrange
- sut.create(job);
- sut.create(job2);
- // Act
- sut.markJobInError(job.getJobId(), errorDetail);
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertThat(job2.getState()).isEqualTo(JobState.UNSAVED);
- assertThat(job.getErrorDetail()).isEqualTo(errorDetail);
- assertTrue(job.getCompletionDate().isPresent());
- }
-
- @Test
- void markJobInError_WhenJobInTransfersCompletedState() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
- // Act
- sut.markJobInError(job.getJobId(), errorDetail);
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertTrue(job.getCompletionDate().isPresent());
- }
-
- @Test
- void markJobInError_WhenJobInTransfersInProgressState() {
- // Arrange
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- // Act
- sut.markJobInError(job.getJobId(), errorDetail);
- // Assert
- refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertTrue(job.getCompletionDate().isPresent());
- }
-
- @Test
- void shouldFindCompletedJobsOlderThanFiveHours() {
- // Arrange
- final LocalDateTime nowPlusFiveHours = LocalDateTime.now().plusHours(5);
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
- sut.completeJob(job.getJobId());
- // Act
- final List completedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.COMPLETED, nowPlusFiveHours);
- // Assert
- assertThat(completedJobs.size()).isEqualTo(1);
- assertThat(completedJobs.get(0).getState()).isEqualTo(JobState.COMPLETED);
- assertTrue(completedJobs.get(0).getCompletionDate().isPresent());
- }
-
- @Test
- void shouldFindFailedJobsOlderThanFiveHours() {
- // Arrange
- final LocalDateTime nowPlusFiveHours = LocalDateTime.now().plusHours(5);
- sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.markJobInError(job.getJobId(), errorDetail);
- // Act
- final List failedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.ERROR, nowPlusFiveHours);
- // Assert
- assertThat(failedJobs.size()).isEqualTo(1);
- assertThat(failedJobs.get(0).getState()).isEqualTo(JobState.ERROR);
- assertTrue(failedJobs.get(0).getCompletionDate().isPresent());
- }
-
- @Test
- void shouldDeleteJobById() {
- // Arrange
- sut.create(job);
- // Act
- sut.deleteJob(job.getJobId());
- // Assert
- assertThat(sut.find(job.getJobId())).isEmpty();
- }
-
- @Test
- void shouldFindJobsByCompletedJobState() {
- // Arrange
- sut.create(job);
- sut.completeJob(job.getJobId());
- sut.create(job2);
- // Act
- final List foundJobs = sut.findByStates(List.of(JobState.COMPLETED));
- // Assert
- assertThat(foundJobs.size()).isEqualTo(1);
- assertThat(foundJobs.get(0).getJobId()).isEqualTo(job.getJobId());
- }
-
- @Test
- void shouldFindJobsByErrorJobState() {
- // Arrange
- sut.create(job);
- sut.markJobInError(job.getJobId(), "errorDetail");
- // Act
- final List foundJobs = sut.findByStates(List.of(JobState.ERROR));
- // Assert
- assertThat(foundJobs.size()).isEqualTo(1);
- assertThat(foundJobs.get(0).getJobId()).isEqualTo(job.getJobId());
- }
-
- private void refreshJob() {
- job = sut.find(job.getJobId()).get();
- }
-}
\ No newline at end of file
diff --git a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/TestMother.java b/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/TestMother.java
deleted file mode 100644
index e064c72b75..0000000000
--- a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/TestMother.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.catenax.irs.connector.job;
-
-import com.github.javafaker.Faker;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-/**
- * Base object mother class to create objects for testing.
- *
- * @see
- * https://martinfowler.com/bliki/ObjectMother.html
- */
-class TestMother {
-
- Faker faker = new Faker();
-
- MultiTransferJob job() {
- return job(faker.options().option(JobState.class));
- }
-
- MultiTransferJob job(JobState jobState) {
- return MultiTransferJob.builder()
- .jobId(faker.lorem().characters())
- .jobData(Map.of(
- faker.lorem().characters(),
- faker.lorem().characters(),
- faker.lorem().characters(),
- faker.lorem().characters()
- ))
- .state(jobState)
- .build();
- }
-
- DataRequest dataRequest() {
- return new DataRequest() {
- };
- }
-
- TransferInitiateResponse okResponse() {
- return response(ResponseStatus.OK);
- }
-
- TransferInitiateResponse response(ResponseStatus status) {
- return TransferInitiateResponse.builder()
- .transferId(UUID.randomUUID().toString())
- .status(status)
- .build();
- }
-
- TransferProcess transfer() {
- final String characters = faker.lorem().characters();
- return () -> characters;
- }
-
- public Stream dataRequests(int count) {
- return IntStream.range(0, count).mapToObj(i -> dataRequest());
- }
-}
\ No newline at end of file
diff --git a/connector/irs-connector-parent/pom.xml b/connector/irs-connector-parent/pom.xml
deleted file mode 100644
index 7643aa8897..0000000000
--- a/connector/irs-connector-parent/pom.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
- 4.0.0
-
-
- net.catenax.irs
- irs-parent
- ${revision}
- ../../irs-parent
-
-
- net.catenax.irs
- irs-connector-parent
- pom
-
- IRS Connector parent
- Parent Module for EDC Connectors
-
-
- ../../ci/pmd-rules.xml
- 11
- 3.0.0
- 0.0.1-SNAPSHOT.Agera.1553242392
- 2.12.4
- 3.0.0
- 7.0.1.Final
- 1.18.22
- 1.8.0
-
-
-
-
- central
- Maven Central
- default
- https://repo1.maven.org/maven2
-
- false
-
-
-
-
-
-
- org.junit.jupiter
- junit-jupiter-engine
- ${junit.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-params
- ${junit.version}
- test
-
-
- net.javacrumbs.json-unit
- json-unit-assertj
- ${json-unit-assertj.version}
- test
-
-
- org.mockito
- mockito-junit-jupiter
- ${mockito-junit-jupiter.version}
- test
-
-
- com.github.javafaker
- javafaker
- ${javafaker.version}
- test
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.10.1
-
-
- ${javaVersion}
- true
- lines,vars,source
-
-
-
-
-
diff --git a/connector/pom.xml b/connector/pom.xml
deleted file mode 100644
index 22eb69fca8..0000000000
--- a/connector/pom.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 4.0.0
-
- net.catenax.irs
- item-relationship-service-connector-root
- ${revision}
- pom
-
- IRS Connector Root
- Root module containing connector modules.
-
-
- irs-connector-parent
- edc-recursive-job
-
-
diff --git a/connector/run-integration-test.sh b/connector/run-integration-test.sh
deleted file mode 100644
index a203f8f7c9..0000000000
--- a/connector/run-integration-test.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-cd ..
-
-if [ ! -f dev/local/cert.pfx ]; then
- echo "Missing file cert.pfx"
- exit 1
-fi
-
-export DOCKER_BUILDKIT=1
-docker-compose --profile connector build --build-arg IRS_EDC_PKG_USERNAME=$IRS_EDC_PKG_USERNAME --build-arg IRS_EDC_PKG_PASSWORD=$IRS_EDC_PKG_PASSWORD
-docker-compose --profile connector --profile irs up --exit-code-from=connector-integration-test --abort-on-container-exit
diff --git a/irs-api/pom.xml b/irs-api/pom.xml
index 85bd9a99c4..fae4c554f4 100644
--- a/irs-api/pom.xml
+++ b/irs-api/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
@@ -83,12 +84,6 @@
${json-unit-assertj.version}
test
-
- net.catenax.irs
- edc-recursive-job
- ${project.version}
- compile
-
org.awaitility
awaitility
diff --git a/irs-api/src/main/java/net/catenax/irs/aaswrapper/job/AASRecursiveJobHandler.java b/irs-api/src/main/java/net/catenax/irs/aaswrapper/job/AASRecursiveJobHandler.java
index 268f8b1384..af607a5ba9 100644
--- a/irs-api/src/main/java/net/catenax/irs/aaswrapper/job/AASRecursiveJobHandler.java
+++ b/irs-api/src/main/java/net/catenax/irs/aaswrapper/job/AASRecursiveJobHandler.java
@@ -9,6 +9,9 @@
//
package net.catenax.irs.aaswrapper.job;
+import static net.catenax.irs.dtos.IrsCommonConstants.DEPTH_ID_KEY;
+import static net.catenax.irs.dtos.IrsCommonConstants.ROOT_ITEM_ID_KEY;
+
import java.util.Map;
import java.util.stream.Stream;
@@ -21,15 +24,6 @@
*/
@Slf4j
public class AASRecursiveJobHandler implements RecursiveJobHandler {
- /**
- * Job Data key for root item ID
- */
- public static final String ROOT_ITEM_ID_KEY = "root.item.id.key";
-
- /**
- * Expected depth of the tree
- */
- public static final String DEPTH_ID_KEY = "depth.id.key";
private final TreeRecursiveLogic logic;
@@ -39,7 +33,7 @@ public AASRecursiveJobHandler(final TreeRecursiveLogic logic) {
@Override
public Stream initiate(final MultiTransferJob job) {
- log.info("Initiating request for job {}", job.getJobId());
+ log.info("Initiating request for job {}", job.getJob().getJobId().toString());
final var partId = job.getJobData().get(ROOT_ITEM_ID_KEY);
final var dataRequest = ItemDataRequest.rootNode(partId);
return Stream.of(dataRequest);
@@ -47,7 +41,7 @@ public Stream initiate(final MultiTransferJob job) {
@Override
public Stream recurse(final MultiTransferJob job, final AASTransferProcess transferProcess) {
- log.info("Starting recursive request for job {}", job.getJobId());
+ log.info("Starting recursive request for job {}", job.getJob().getJobId().toString());
final Integer expectedDepth = getExpectedTreeDepth(job.getJobData());
final Integer currentDepth = transferProcess.getDepth();
@@ -65,14 +59,14 @@ public Stream recurse(final MultiTransferJob job, final AASTran
@Override
public void complete(final MultiTransferJob job) {
- log.info("Completed retrieval for Job {}", job.getJobId());
+ log.info("Completed retrieval for Job {}", job.getJob().getJobId().toString());
final var completedTransfers = job.getCompletedTransfers();
- final var targetBlobName = job.getJobId();
- logic.assemblePartialItemGraphBlobs(completedTransfers, targetBlobName);
+ final var targetBlobName = job.getJob().getJobId();
+ logic.assemblePartialItemGraphBlobs(completedTransfers, targetBlobName.toString());
}
private Integer getExpectedTreeDepth(final Map jobData) {
- return Integer.parseInt(jobData.get(AASRecursiveJobHandler.DEPTH_ID_KEY));
+ return Integer.parseInt(jobData.get(DEPTH_ID_KEY));
}
private boolean expectedDepthOfTreeIsNotReached(final Integer expectedDepth, final Integer currentDepth) {
diff --git a/irs-api/src/main/java/net/catenax/irs/aaswrapper/submodel/domain/SubmodelFacade.java b/irs-api/src/main/java/net/catenax/irs/aaswrapper/submodel/domain/SubmodelFacade.java
index 6ca65ffb9c..35b3d59b9e 100644
--- a/irs-api/src/main/java/net/catenax/irs/aaswrapper/submodel/domain/SubmodelFacade.java
+++ b/irs-api/src/main/java/net/catenax/irs/aaswrapper/submodel/domain/SubmodelFacade.java
@@ -44,8 +44,8 @@ public AssemblyPartRelationshipDTO getSubmodel(final String submodelEndpointAddr
.build()));
return AssemblyPartRelationshipDTO.builder()
- .withCatenaXId(submodel.getCatenaXId())
- .withChildParts(childParts)
+ .catenaXId(submodel.getCatenaXId())
+ .childParts(childParts)
.build();
}
diff --git a/irs-api/src/main/java/net/catenax/irs/configuration/IrsConfiguration.java b/irs-api/src/main/java/net/catenax/irs/configuration/IrsConfiguration.java
index 569f850159..cfd404a867 100644
--- a/irs-api/src/main/java/net/catenax/irs/configuration/IrsConfiguration.java
+++ b/irs-api/src/main/java/net/catenax/irs/configuration/IrsConfiguration.java
@@ -9,12 +9,12 @@
//
package net.catenax.irs.configuration;
+import java.net.URL;
+
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
-import java.net.URL;
-
/**
* IRS configuration settings. Automatically populated by Spring from application.yml
* and other configuration sources.
diff --git a/irs-api/src/main/java/net/catenax/irs/configuration/OpenApiExamples.java b/irs-api/src/main/java/net/catenax/irs/configuration/OpenApiExamples.java
index e06be51812..457b8c741f 100644
--- a/irs-api/src/main/java/net/catenax/irs/configuration/OpenApiExamples.java
+++ b/irs-api/src/main/java/net/catenax/irs/configuration/OpenApiExamples.java
@@ -24,7 +24,7 @@
import net.catenax.irs.component.Endpoint;
import net.catenax.irs.component.GlobalAssetIdentification;
import net.catenax.irs.component.Job;
-import net.catenax.irs.component.JobException;
+import net.catenax.irs.component.JobErrorDetails;
import net.catenax.irs.component.JobHandle;
import net.catenax.irs.component.Jobs;
import net.catenax.irs.component.MeasurementUnit;
@@ -61,10 +61,10 @@ public void createExamples(final Components components) {
components.addExamples("job-handle", toExample(createJobHandle(JOB_HANDLE_ID_1)));
components.addExamples("error-response", toExample(ErrorResponse.builder()
.withErrors(List.of("TimeoutException",
- "ParsingException"))
+ "ParsingException"))
.withMessage("Some errors occured")
.withStatusCode(
- HttpStatus.INTERNAL_SERVER_ERROR)
+ HttpStatus.INTERNAL_SERVER_ERROR)
.build()));
components.addExamples("complete-job-result", createCompleteJobResult());
components.addExamples("job-result-without-uncompleted-result-tree", createJobResultWithoutTree());
@@ -134,8 +134,8 @@ private Summary createSummary() {
.build();
}
- private JobException createJobException() {
- return new JobException("IrsTimeoutException", "Timeout while requesting Digital Registry", EXAMPLE_INSTANT);
+ private JobErrorDetails createJobException() {
+ return new JobErrorDetails("IrsTimeoutException", "Timeout while requesting Digital Registry", EXAMPLE_INSTANT);
}
private Example createJobResultWithoutTree() {
@@ -199,7 +199,7 @@ private Quantity createQuantity() {
.quantityNumber(1)
.measurementUnit(MeasurementUnit.builder()
.datatypeURI(
- "urn:bamm:io.openmanufacturing:meta-model:1.0.0#piece")
+ "urn:bamm:io.openmanufacturing:meta-model:1.0.0#piece")
.lexicalValue("piece")
.build())
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java b/irs-api/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java
similarity index 87%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java
index 41aa1c8563..2664039ee6 100644
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/BaseJobStore.java
@@ -9,7 +9,7 @@
//
package net.catenax.irs.connector.job;
-import java.time.LocalDateTime;
+import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@@ -21,6 +21,7 @@
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
+import net.catenax.irs.component.enums.JobState;
import org.jetbrains.annotations.Nullable;
/**
@@ -55,19 +56,22 @@ public Optional find(final String jobId) {
@Override
public List findByStateAndCompletionDateOlderThan(final JobState jobState,
- final LocalDateTime localDateTime) {
+ final Instant dateTime) {
return readLock(() -> getAll().stream()
.filter(hasState(jobState))
- .filter(isCompletionDateBefore(localDateTime))
+ .filter(isCompletionDateBefore(dateTime))
.collect(Collectors.toList()));
}
private Predicate hasState(final JobState jobState) {
- return job -> job.getState().equals(jobState);
+ return job -> job.getJob().getJobState().equals(jobState);
}
- private Predicate isCompletionDateBefore(final LocalDateTime localDateTime) {
- return job -> job.getCompletionDate().isPresent() && job.getCompletionDate().get().isBefore(localDateTime);
+ private Predicate isCompletionDateBefore(final Instant localDateTime) {
+ return job -> {
+ final Instant completed = job.getJob().getJobCompleted();
+ return completed != null && completed.isBefore(localDateTime);
+ };
}
@Override
@@ -79,7 +83,8 @@ public Optional findByProcessId(final String processId) {
public void create(final MultiTransferJob job) {
writeLock(() -> {
final var newJob = job.toBuilder().transitionInitial().build();
- put(job.getJobId(), newJob);
+ log.info("Add the job into jobstore here {}", newJob);
+ put(job.getJob().getJobId().toString(), newJob);
return null;
});
}
@@ -123,7 +128,7 @@ public List findByStates(final List jobStates) {
}
private Predicate hasState(final List jobStates) {
- return job -> jobStates.contains(job.getState());
+ return job -> jobStates.contains(job.getJob().getJobState());
}
@Override
@@ -145,7 +150,7 @@ private void modifyJob(final String jobId, final UnaryOperator
log.warn("Job not found: {}", jobId);
} else {
final MultiTransferJob multiTransferJob = job.get();
- put(multiTransferJob.getJobId(), action.apply(multiTransferJob));
+ put(multiTransferJob.getJob().getJobId().toString(), action.apply(multiTransferJob));
}
return null;
});
@@ -163,7 +168,7 @@ private T readLock(final Supplier work) {
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- throw new JobException(e);
+ throw new JobException("Job Interrupted", e);
}
}
@@ -179,7 +184,7 @@ private T writeLock(final Supplier work) {
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- throw new JobException(e);
+ throw new JobException("Job Interrupted", e);
}
}
}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/DataRequest.java b/irs-api/src/main/java/net/catenax/irs/connector/job/DataRequest.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/DataRequest.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/DataRequest.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java b/irs-api/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java
similarity index 94%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java
index 961e272dc8..4029d023e2 100644
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/InMemoryJobStore.java
@@ -22,6 +22,10 @@
*/
@Slf4j
@RequiredArgsConstructor
+@SuppressWarnings({ "PMD.TooManyMethods",
+ "PMD.PreserveStackTrace"
+})
+
public class InMemoryJobStore extends BaseJobStore {
/**
diff --git a/irs-api/src/main/java/net/catenax/irs/connector/job/JobException.java b/irs-api/src/main/java/net/catenax/irs/connector/job/JobException.java
new file mode 100644
index 0000000000..1d4c53e26a
--- /dev/null
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/JobException.java
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
+//
+// See the AUTHORS file(s) distributed with this work for additional
+// information regarding authorship.
+//
+// See the LICENSE file(s) distributed with this work for
+// additional information regarding license terms.
+//
+package net.catenax.irs.connector.job;
+
+import java.time.Instant;
+
+import lombok.Getter;
+import net.catenax.irs.component.JobErrorDetails;
+
+/**
+ * Job Exception with embedded JobErrorDetails
+ */
+public class JobException extends RuntimeException {
+ private static final String DEFAULT_ERROR_MESSAGE = "Critical error occur!!";
+
+ @Getter
+ private final JobErrorDetails jobErrorDetails;
+
+ public JobException() {
+ super(DEFAULT_ERROR_MESSAGE);
+ jobErrorDetails = JobErrorDetails.builder()
+ .exception(ResponseStatus.FATAL_ERROR.toString())
+ .errorDetail(DEFAULT_ERROR_MESSAGE)
+ .exceptionDate(Instant.now())
+ .build();
+ }
+
+ public JobException(final String message) {
+ super(message);
+ jobErrorDetails = JobErrorDetails.builder()
+ .exception(message)
+ .errorDetail(DEFAULT_ERROR_MESSAGE)
+ .exceptionDate(Instant.now())
+ .build();
+ }
+
+ public JobException(final String message, final Throwable cause) {
+ super(message, cause);
+ jobErrorDetails = JobErrorDetails.builder()
+ .exception(cause.getMessage())
+ .errorDetail(message)
+ .exceptionDate(Instant.now())
+ .build();
+ }
+}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobInitiateResponse.java b/irs-api/src/main/java/net/catenax/irs/connector/job/JobInitiateResponse.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobInitiateResponse.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/JobInitiateResponse.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java b/irs-api/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java
similarity index 56%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java
index efac2d8739..bcb93d535d 100644
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/JobOrchestrator.java
@@ -9,28 +9,34 @@
//
package net.catenax.irs.connector.job;
-import static java.util.UUID.randomUUID;
+import static net.catenax.irs.dtos.IrsCommonConstants.ROOT_ITEM_ID_KEY;
-import java.time.LocalDateTime;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import lombok.Builder;
-import lombok.Value;
import lombok.extern.slf4j.Slf4j;
+import net.catenax.irs.component.GlobalAssetIdentification;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.enums.JobState;
+import org.apache.commons.lang3.StringUtils;
/**
* Orchestrator service for recursive {@link MultiTransferJob}s that potentially
* comprise multiple transfers.
*/
-@SuppressWarnings("PMD.AvoidCatchingGenericException") // Handle RuntimeException from callbacks
+@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.TooManyMethods" })
+// Handle RuntimeException from callbacks
@Slf4j
public class JobOrchestrator {
private static final int TTL_CLEANUP_COMPLETED_JOBS_HOURS = 1;
+
private static final int TTL_CLEANUP_FAILED_JOBS_HOURS = 24;
/**
@@ -57,7 +63,8 @@ public class JobOrchestrator {
* @param handler Recursive job handler.
*/
public JobOrchestrator(final TransferProcessManager processManager, final JobStore jobStore,
- final RecursiveJobHandler handler) {
+ final RecursiveJobHandler handler) {
+
this.processManager = processManager;
this.jobStore = jobStore;
this.handler = handler;
@@ -70,35 +77,40 @@ public JobOrchestrator(final TransferProcessManager processManager, final
* @return response.
*/
public JobInitiateResponse startJob(final Map jobData) {
- final var job = MultiTransferJob.builder()
- .jobId(randomUUID().toString())
- .jobData(jobData)
- .state(JobState.UNSAVED)
- .build();
-
- jobStore.create(job);
+ final Job job = createJob(jobData.get(ROOT_ITEM_ID_KEY));
+ final var multiJob = MultiTransferJob.builder().job(job).jobData(jobData).build();
+ jobStore.create(multiJob);
final Stream requests;
try {
- requests = handler.initiate(job);
+ requests = handler.initiate(multiJob);
} catch (RuntimeException e) {
- markJobInError(job, e, "Handler method failed");
- return JobInitiateResponse.builder().jobId(job.getJobId()).status(ResponseStatus.FATAL_ERROR).build();
+ markJobInError(multiJob, e, "Handler method failed");
+ return JobInitiateResponse.builder()
+ .jobId(multiJob.getJob().getJobId().toString())
+ .status(ResponseStatus.FATAL_ERROR)
+ .build();
}
long transferCount;
try {
- transferCount = startTransfers(job, requests);
+ transferCount = startTransfers(multiJob, requests);
} catch (JobException e) {
- return JobInitiateResponse.builder().jobId(job.getJobId()).status(e.getStatus()).build();
+ return JobInitiateResponse.builder()
+ .jobId(multiJob.getJob().getJobId().toString())
+ .status(convertMessage(e.getJobErrorDetails().getException()))
+ .build();
}
// If no transfers are requested, job is already complete
if (transferCount == 0) {
- completeJob(job);
+ completeJob(multiJob);
}
- return JobInitiateResponse.builder().jobId(job.getJobId()).status(ResponseStatus.OK).build();
+ return JobInitiateResponse.builder()
+ .jobId(multiJob.getJob().getJobId().toString())
+ .status(ResponseStatus.OK)
+ .build();
}
/**
@@ -114,8 +126,9 @@ public JobInitiateResponse startJob(final Map jobData) {
}
final var job = jobEntry.get();
- if (job.getState() != JobState.IN_PROGRESS) {
- log.info("Ignoring transfer complete event for job {} in state {}", job.getJobId(), job.getState());
+ if (job.getJob().getJobState() != JobState.RUNNING) {
+ log.info("Ignoring transfer complete event for job {} in state {} ", job.getJob().getJobId(),
+ job.getJob().getJobState());
return;
}
@@ -134,37 +147,36 @@ public JobInitiateResponse startJob(final Map jobData) {
return;
}
- jobStore.completeTransferProcess(job.getJobId(), process);
+ jobStore.completeTransferProcess(job.getJob().getJobId().toString(), process);
- callCompleteHandlerIfFinished(job.getJobId());
+ callCompleteHandlerIfFinished(job.getJob().getJobId().toString());
}
public List findAndCleanupCompletedJobs() {
- final LocalDateTime currentDateMinusHours = LocalDateTime.now().minusHours(TTL_CLEANUP_COMPLETED_JOBS_HOURS);
+ final Instant currentDateMinusSeconds = Instant.now().minus(TTL_CLEANUP_COMPLETED_JOBS_HOURS, ChronoUnit.HOURS);
final List completedJobs = jobStore.findByStateAndCompletionDateOlderThan(JobState.COMPLETED,
- currentDateMinusHours);
+ currentDateMinusSeconds);
return deleteJobs(completedJobs);
}
public List findAndCleanupFailedJobs() {
- final LocalDateTime currentDateMinusHours = LocalDateTime.now().minusHours(TTL_CLEANUP_FAILED_JOBS_HOURS);
+ final Instant currentDateMinusSeconds = Instant.now().minus(TTL_CLEANUP_FAILED_JOBS_HOURS, ChronoUnit.HOURS);
final List failedJobs = jobStore.findByStateAndCompletionDateOlderThan(JobState.ERROR,
- currentDateMinusHours);
-
+ currentDateMinusSeconds);
return deleteJobs(failedJobs);
}
private List deleteJobs(final List jobs) {
return jobs.stream()
- .map(job -> jobStore.deleteJob(job.getJobId()))
+ .map(job -> jobStore.deleteJob(job.getJob().getJobId().toString()))
.flatMap(Optional::stream)
.collect(Collectors.toList());
}
private void callCompleteHandlerIfFinished(final String jobId) {
jobStore.find(jobId).ifPresent(job -> {
- if (job.getState() != JobState.TRANSFERS_FINISHED) {
+ if (job.getJob().getJobState() != JobState.TRANSFERS_FINISHED) {
return;
}
completeJob(job);
@@ -178,39 +190,50 @@ private void completeJob(final MultiTransferJob job) {
markJobInError(job, e, "Handler method failed");
return;
}
- jobStore.completeJob(job.getJobId());
+ jobStore.completeJob(job.getJob().getJobId().toString());
}
private void markJobInError(final MultiTransferJob job, final Throwable exception, final String message) {
+
log.error(message, exception);
- jobStore.markJobInError(job.getJobId(), message);
+ jobStore.markJobInError(job.getJob().getJobId().toString(), message);
}
- private long startTransfers(final MultiTransferJob job, final Stream dataRequests) /* throws JobException */ {
+ private long startTransfers(final MultiTransferJob job, final Stream dataRequests) /* throws JobErrorDetails */ {
return dataRequests.map(r -> startTransfer(job, r)).collect(Collectors.counting());
}
private TransferInitiateResponse startTransfer(final MultiTransferJob job,
- final T dataRequest) /* throws JobException */ {
+ final T dataRequest) /* throws JobErrorDetails */ {
final var response = processManager.initiateRequest(dataRequest,
- transferId -> jobStore.addTransferProcess(job.getJobId(), transferId), this::transferProcessCompleted);
+ transferId -> jobStore.addTransferProcess(job.getJob().getJobId().toString(), transferId),
+ this::transferProcessCompleted);
if (response.getStatus() != ResponseStatus.OK) {
- throw JobException.builder().status(response.getStatus()).build();
+ throw new JobException(response.getStatus().toString());
}
+ jobStore.addTransferProcess(job.getJob().getJobId().toString(), response.getTransferId());
return response;
}
- /**
- * Exception used to stop creating additional transfers if one transfer creation fails.
- */
- @Value
- @Builder
- private static class JobException extends RuntimeException {
- /**
- * The status of the transfer in error.
- */
- private final ResponseStatus status;
+ private Job createJob(final String globalAssetId) {
+
+ if (StringUtils.isEmpty(globalAssetId)) {
+ throw new JobException("GlobalAsset Identifier cannot be null or empty string");
+ }
+
+ return Job.builder()
+ .jobId(UUID.randomUUID())
+ .globalAssetId(GlobalAssetIdentification.builder().globalAssetId(globalAssetId).build())
+ .createdOn(Instant.now())
+ .lastModifiedOn(Instant.now())
+ .jobState(JobState.UNSAVED)
+ .build();
}
+
+ private ResponseStatus convertMessage(final String message) {
+ return ResponseStatus.valueOf(message);
+ }
+
}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobStore.java b/irs-api/src/main/java/net/catenax/irs/connector/job/JobStore.java
similarity index 87%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobStore.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/JobStore.java
index 4331960b77..811b57cdc6 100644
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/JobStore.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/JobStore.java
@@ -9,12 +9,13 @@
//
package net.catenax.irs.connector.job;
-import org.jetbrains.annotations.Nullable;
-
-import java.time.LocalDateTime;
+import java.time.Instant;
import java.util.List;
import java.util.Optional;
+import net.catenax.irs.component.enums.JobState;
+import org.jetbrains.annotations.Nullable;
+
/**
* Manages storage of {@link MultiTransferJob} state.
*/
@@ -25,7 +26,7 @@ public interface JobStore {
*
* @param jobId the identifier of the job to retrieve.
* @return the job if found, otherwise empty.
- * @see MultiTransferJob#getJobId()
+ * @see MultiTransferJob#getJob()
*/
Optional find(String jobId);
@@ -33,13 +34,14 @@ public interface JobStore {
* Retrieve jobs by state with completion date older than requested date
*
* @param jobState the job state
- * @param localDateTime requested date
+ * @param dateTime requested date
* @return found jobs
*/
- List findByStateAndCompletionDateOlderThan(JobState jobState, LocalDateTime localDateTime);
+ List findByStateAndCompletionDateOlderThan(JobState jobState, Instant dateTime);
/**
* Retrieve jobs with requested states
+ *
* @param jobStates requested job states
* @return found jobs
*/
@@ -73,8 +75,8 @@ public interface JobStore {
/**
* Mark transfer process completed for the job.
*
- * @param jobId the job identifier.
- * @param process transfer process to mark completed.
+ * @param jobId the job identifier.
+ * @param process transfer process to mark completed.
*/
void completeTransferProcess(String jobId, TransferProcess process);
@@ -104,10 +106,11 @@ public interface JobStore {
Optional deleteJob(String jobId);
/**
- * Set the job status to canceled.
+ * Cancel the job with identifier
*
- * @param jobId the job identifier.
- * @return canceled MultiTransferJob
+ * @param jobId
+ * @return cancel job (if it existed)
*/
Optional cancelJob(String jobId);
+
}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java b/irs-api/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java
similarity index 70%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java
index 30e8dd2c22..c56561d477 100644
--- a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/MultiTransferJob.java
@@ -11,21 +11,24 @@
import static java.lang.String.format;
-import java.time.LocalDateTime;
+import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Getter;
+import lombok.NonNull;
import lombok.Singular;
import lombok.ToString;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.JobErrorDetails;
+import net.catenax.irs.component.enums.JobState;
import org.jetbrains.annotations.Nullable;
/**
@@ -37,42 +40,31 @@
public class MultiTransferJob {
/**
- * Job identifier.
+ * The attached job.
*/
+ @NonNull
@Getter
- private final String jobId;
+ private Job job;
+
/**
* Collection of transfer IDs that have not yet completed for the job.
*/
@Singular
private final Set transferProcessIds;
- /**
- * Job state.
- */
- @Getter
- private JobState state;
+
/**
* Arbitrary data attached to the job.
*/
@Getter
@Singular("jobDatum")
private Map jobData;
- /**
- * Error detail, potentially set if {@link #getState() state} is {@link JobState#ERROR}.
- */
- @Getter
- private String errorDetail;
+
/**
* Collection of transfers that have completed for the job.
*/
@Getter
@Singular
private List completedTransfers;
- /**
- * Sets completion date for jobs with {@link JobState#COMPLETED} and {@link JobState#ERROR} state.
- */
- @Getter
- private Optional completionDate;
public Collection getTransferProcessIds() {
return Collections.unmodifiableSet(this.transferProcessIds);
@@ -91,34 +83,39 @@ public static class MultiTransferJobBuilder {
}
/**
- * Transition the job to the {@link JobState#IN_PROGRESS} state.
+ * Transition the job to the {@link JobState#RUNNING} state.
*/
/* package */ MultiTransferJobBuilder transitionInProgress() {
- return transition(JobState.IN_PROGRESS, JobState.INITIAL, JobState.IN_PROGRESS);
+ return transition(JobState.RUNNING, JobState.INITIAL, JobState.RUNNING);
}
/**
* Transition the job to the {@link JobState#TRANSFERS_FINISHED} state.
*/
/* package */ MultiTransferJobBuilder transitionTransfersFinished() {
- return transition(JobState.TRANSFERS_FINISHED, JobState.IN_PROGRESS);
+ return transition(JobState.TRANSFERS_FINISHED, JobState.RUNNING);
}
/**
* Transition the job to the {@link JobState#COMPLETED} state.
*/
/* package */ MultiTransferJobBuilder transitionComplete() {
- return transition(JobState.COMPLETED, JobState.TRANSFERS_FINISHED, JobState.INITIAL)
- .completionDate(Optional.of(LocalDateTime.now()));
+ return transition(JobState.COMPLETED, JobState.TRANSFERS_FINISHED, JobState.INITIAL).job(
+ job.toBuilder().jobCompleted(Instant.now()).build());
}
/**
* Transition the job to the {@link JobState#ERROR} state.
*/
/* package */ MultiTransferJobBuilder transitionError(final @Nullable String errorDetail) {
- this.state = JobState.ERROR;
- this.completionDate = Optional.of(LocalDateTime.now());
- this.errorDetail = errorDetail;
+ this.job = this.job.toBuilder()
+ .jobState(JobState.ERROR)
+ .jobCompleted(Instant.now())
+ .exception(JobErrorDetails.builder()
+ .errorDetail(errorDetail)
+ .exceptionDate(Instant.now())
+ .build())
+ .build();
return this;
}
@@ -126,14 +123,16 @@ public static class MultiTransferJobBuilder {
* Transition the job to the {@link JobState#CANCELED} state.
*/
/* package */ MultiTransferJobBuilder transitionCancel() {
- return transition(JobState.CANCELED, JobState.UNSAVED, JobState.INITIAL, JobState.IN_PROGRESS);
+ return transition(JobState.CANCELED, JobState.UNSAVED, JobState.INITIAL, JobState.RUNNING);
}
private MultiTransferJobBuilder transition(final JobState end, final JobState... starts) {
- if (Arrays.stream(starts).noneMatch(s -> s == state)) {
- throw new IllegalStateException(format("Cannot transition from state %s to %s", state, end));
+ if (Arrays.stream(starts).noneMatch(s -> s == job.getJobState())) {
+ throw new IllegalStateException(
+ format("Cannot transition from state %s to %s", job.getJobState(), end));
}
- this.state = end;
+
+ job = job.toBuilder().jobState(end).build();
return this;
}
}
diff --git a/irs-api/src/main/java/net/catenax/irs/connector/job/PersistentJobStore.java b/irs-api/src/main/java/net/catenax/irs/connector/job/PersistentJobStore.java
index 5cb65548e2..c09930f056 100644
--- a/irs-api/src/main/java/net/catenax/irs/connector/job/PersistentJobStore.java
+++ b/irs-api/src/main/java/net/catenax/irs/connector/job/PersistentJobStore.java
@@ -9,12 +9,6 @@
//
package net.catenax.irs.connector.job;
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.catenax.irs.persistence.BlobPersistence;
@@ -22,6 +16,12 @@
import net.catenax.irs.util.JsonUtil;
import org.springframework.stereotype.Service;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
/**
* Stores Job data using persistent blob storage.
*/
@@ -64,7 +64,7 @@ protected Collection getAll() {
protected void put(final String jobId, final MultiTransferJob job) {
final byte[] blob = toBlob(job);
try {
- blobStore.putBlob(toBlobId(job.getJobId()), blob);
+ blobStore.putBlob(toBlobId(jobId), blob);
} catch (BlobPersistenceException e) {
log.error("Cannot create job in BlobStore", e);
}
@@ -77,7 +77,7 @@ protected Optional remove(final String jobId) {
blobStore.delete(toBlobId(jobId));
return blob.map(this::toJob);
} catch (BlobPersistenceException e) {
- throw new JobException(e);
+ throw new JobException("Blob persistence error", e);
}
}
@@ -93,4 +93,5 @@ private byte[] toBlob(final MultiTransferJob job) {
private String toBlobId(final String jobId) {
return JOB_PREFIX + jobId;
}
+
}
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/RecursiveJobHandler.java b/irs-api/src/main/java/net/catenax/irs/connector/job/RecursiveJobHandler.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/RecursiveJobHandler.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/RecursiveJobHandler.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/ResponseStatus.java b/irs-api/src/main/java/net/catenax/irs/connector/job/ResponseStatus.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/ResponseStatus.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/ResponseStatus.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferInitiateResponse.java b/irs-api/src/main/java/net/catenax/irs/connector/job/TransferInitiateResponse.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferInitiateResponse.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/TransferInitiateResponse.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferProcess.java b/irs-api/src/main/java/net/catenax/irs/connector/job/TransferProcess.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferProcess.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/TransferProcess.java
diff --git a/connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferProcessManager.java b/irs-api/src/main/java/net/catenax/irs/connector/job/TransferProcessManager.java
similarity index 100%
rename from connector/edc-recursive-job/src/main/java/net/catenax/irs/connector/job/TransferProcessManager.java
rename to irs-api/src/main/java/net/catenax/irs/connector/job/TransferProcessManager.java
diff --git a/irs-api/src/main/java/net/catenax/irs/dto/AssemblyPartRelationshipDTO.java b/irs-api/src/main/java/net/catenax/irs/dto/AssemblyPartRelationshipDTO.java
index 70f1f6ceb7..da782183e1 100644
--- a/irs-api/src/main/java/net/catenax/irs/dto/AssemblyPartRelationshipDTO.java
+++ b/irs-api/src/main/java/net/catenax/irs/dto/AssemblyPartRelationshipDTO.java
@@ -22,7 +22,7 @@
* AssemblyPartRelationshipDTO model used for internal application use
*/
@Data
-@Builder(toBuilder = true, setterPrefix = "with")
+@Builder(toBuilder = true)
@JsonDeserialize(builder = AssemblyPartRelationshipDTO.AssemblyPartRelationshipDTOBuilder.class)
public class AssemblyPartRelationshipDTO {
/**
@@ -38,7 +38,7 @@ public class AssemblyPartRelationshipDTO {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class AssemblyPartRelationshipDTOBuilder {
}
diff --git a/irs-api/src/main/java/net/catenax/irs/dto/ChildDataDTO.java b/irs-api/src/main/java/net/catenax/irs/dto/ChildDataDTO.java
index 9ede426c74..06365a704b 100644
--- a/irs-api/src/main/java/net/catenax/irs/dto/ChildDataDTO.java
+++ b/irs-api/src/main/java/net/catenax/irs/dto/ChildDataDTO.java
@@ -36,7 +36,7 @@ public class ChildDataDTO {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class ChildDataDTOBuilder {
}
diff --git a/irs-api/src/main/java/net/catenax/irs/exceptions/AspectNotSupportedException.java b/irs-api/src/main/java/net/catenax/irs/exceptions/AspectNotSupportedException.java
index fd79088022..7a256e51b9 100644
--- a/irs-api/src/main/java/net/catenax/irs/exceptions/AspectNotSupportedException.java
+++ b/irs-api/src/main/java/net/catenax/irs/exceptions/AspectNotSupportedException.java
@@ -9,7 +9,7 @@
//
package net.catenax.irs.exceptions;
-import net.catenax.irs.connector.annotations.ExcludeFromCodeCoverageGeneratedReport;
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
import net.catenax.irs.controllers.ApiErrorsConstants;
/**
diff --git a/irs-api/src/main/java/net/catenax/irs/exceptions/EntityNotFoundException.java b/irs-api/src/main/java/net/catenax/irs/exceptions/EntityNotFoundException.java
index f3bc57eabb..76cb080bd5 100644
--- a/irs-api/src/main/java/net/catenax/irs/exceptions/EntityNotFoundException.java
+++ b/irs-api/src/main/java/net/catenax/irs/exceptions/EntityNotFoundException.java
@@ -9,7 +9,7 @@
//
package net.catenax.irs.exceptions;
-import net.catenax.irs.connector.annotations.ExcludeFromCodeCoverageGeneratedReport;
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
/**
* General entity not found exception.
diff --git a/irs-api/src/main/java/net/catenax/irs/exceptions/MaxDepthTooLargeException.java b/irs-api/src/main/java/net/catenax/irs/exceptions/MaxDepthTooLargeException.java
index 1f039c1d1b..a449933e78 100644
--- a/irs-api/src/main/java/net/catenax/irs/exceptions/MaxDepthTooLargeException.java
+++ b/irs-api/src/main/java/net/catenax/irs/exceptions/MaxDepthTooLargeException.java
@@ -9,8 +9,8 @@
//
package net.catenax.irs.exceptions;
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
import net.catenax.irs.configuration.IrsConfiguration;
-import net.catenax.irs.connector.annotations.ExcludeFromCodeCoverageGeneratedReport;
/**
* Exception thrown by the service when the {@link net.catenax.irs.component.RegisterJob#getDepth()}
@@ -20,6 +20,7 @@
public class MaxDepthTooLargeException extends RuntimeException {
/**
* Generate a new instance of a {@link MaxDepthTooLargeException}
+ *
* @param message Exception message.
*/
public MaxDepthTooLargeException(final String message) {
diff --git a/irs-api/src/main/java/net/catenax/irs/persistence/MinioBlobPersistence.java b/irs-api/src/main/java/net/catenax/irs/persistence/MinioBlobPersistence.java
index da110d1aea..f1158969e5 100644
--- a/irs-api/src/main/java/net/catenax/irs/persistence/MinioBlobPersistence.java
+++ b/irs-api/src/main/java/net/catenax/irs/persistence/MinioBlobPersistence.java
@@ -10,17 +10,6 @@
package net.catenax.irs.persistence;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
@@ -47,11 +36,22 @@
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
/**
* BlobPersistence implementation using the min.io library
*/
@Slf4j
-@SuppressWarnings("PMD.ExcessiveImports")
+@SuppressWarnings({"PMD.ExcessiveImports", "PMD.PreserveStackTrace"})
public class MinioBlobPersistence implements BlobPersistence {
private static final Integer EXPIRE_AFTER_DAYS = 7;
@@ -59,7 +59,7 @@ public class MinioBlobPersistence implements BlobPersistence {
private final String bucketName;
public MinioBlobPersistence(final String endpoint, final String accessKey, final String secretKey,
- final String bucketName) throws BlobPersistenceException {
+ final String bucketName) throws BlobPersistenceException {
this(bucketName, createClient(endpoint, accessKey, secretKey));
}
@@ -103,10 +103,10 @@ public void putBlob(final String targetBlobName, final byte[] blob) throws BlobP
try {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(blob);
minioClient.putObject(PutObjectArgs.builder()
- .bucket(bucketName)
- .object(targetBlobName)
- .stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
- .build());
+ .bucket(bucketName)
+ .object(targetBlobName)
+ .stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
+ .build());
} catch (ServerException | InsufficientDataException | ErrorResponseException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) {
throw new BlobPersistenceException("Encountered error while trying to store blob", e);
}
@@ -130,6 +130,7 @@ public Optional getBlob(final String sourceBlobName) throws BlobPersiste
} catch (IOException e) {
throw createLoadFailedException(e);
}
+
}
private BlobPersistenceException createLoadFailedException(final Throwable cause) {
@@ -142,10 +143,10 @@ public Collection findBlobByPrefix(final String prefix) {
ListObjectsArgs.builder().prefix(prefix).bucket(bucketName).build());
return StreamSupport.stream(results.spliterator(), false)
- .flatMap(this::getItem)
- .map(Item::objectName)
- .flatMap(this::getBlobIfPresent)
- .collect(Collectors.toList());
+ .flatMap(this::getItem)
+ .map(Item::objectName)
+ .flatMap(this::getBlobIfPresent)
+ .collect(Collectors.toList());
}
@Override
diff --git a/irs-api/src/main/java/net/catenax/irs/services/IrsItemGraphQueryService.java b/irs-api/src/main/java/net/catenax/irs/services/IrsItemGraphQueryService.java
index d3ede6feaf..571d0225df 100644
--- a/irs-api/src/main/java/net/catenax/irs/services/IrsItemGraphQueryService.java
+++ b/irs-api/src/main/java/net/catenax/irs/services/IrsItemGraphQueryService.java
@@ -9,8 +9,10 @@
//
package net.catenax.irs.services;
+import static net.catenax.irs.dtos.IrsCommonConstants.DEPTH_ID_KEY;
+import static net.catenax.irs.dtos.IrsCommonConstants.ROOT_ITEM_ID_KEY;
+
import java.nio.charset.StandardCharsets;
-import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -23,10 +25,10 @@
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import net.catenax.irs.aaswrapper.job.AASRecursiveJobHandler;
import net.catenax.irs.aaswrapper.job.AASTransferProcess;
import net.catenax.irs.aaswrapper.job.ItemContainer;
import net.catenax.irs.aaswrapper.job.ItemDataRequest;
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
import net.catenax.irs.component.ChildItem;
import net.catenax.irs.component.GlobalAssetIdentification;
import net.catenax.irs.component.Job;
@@ -36,7 +38,6 @@
import net.catenax.irs.component.Relationship;
import net.catenax.irs.component.enums.BomLifecycle;
import net.catenax.irs.component.enums.JobState;
-import net.catenax.irs.connector.annotations.ExcludeFromCodeCoverageGeneratedReport;
import net.catenax.irs.connector.job.JobInitiateResponse;
import net.catenax.irs.connector.job.JobOrchestrator;
import net.catenax.irs.connector.job.JobStore;
@@ -69,7 +70,7 @@ public class IrsItemGraphQueryService implements IIrsItemGraphQueryService {
@Override
public JobHandle registerItemJob(final @NonNull RegisterJob request) {
final String uuid = request.getGlobalAssetId().substring(IrsApiConstants.URN_PREFIX_SIZE);
- final var params = Map.of(AASRecursiveJobHandler.ROOT_ITEM_ID_KEY, uuid, AASRecursiveJobHandler.DEPTH_ID_KEY, String.valueOf(request.getDepth()));
+ final var params = Map.of(ROOT_ITEM_ID_KEY, uuid, DEPTH_ID_KEY, String.valueOf(request.getDepth()));
final JobInitiateResponse jobInitiateResponse = orchestrator.startJob(params);
if (jobInitiateResponse.getStatus().equals(ResponseStatus.OK)) {
@@ -88,10 +89,9 @@ public Jobs jobLifecycle(final @NonNull String jobId) {
@Override
public List getJobsByJobState(final @NonNull List jobStates) {
- final List jobs = jobStore.findByStates(
- jobStates.stream().map(this::convert).collect(Collectors.toList()));
+ final List jobs = jobStore.findByStates(jobStates);
- return jobs.stream().map(MultiTransferJob::getJobId).map(UUID::fromString).collect(Collectors.toList());
+ return jobs.stream().map(x -> x.getJob().getJobId()).collect(Collectors.toList());
}
@Override
@@ -102,7 +102,7 @@ public Job cancelJobById(final @NonNull UUID jobId) {
if (canceled.isPresent()) {
final MultiTransferJob job = canceled.get();
- return Job.builder().jobId(jobId).jobState(convert(job.getState())).build();
+ return job.getJob();
} else {
throw new EntityNotFoundException("No job exists with id " + jobId);
}
@@ -112,18 +112,13 @@ public Job cancelJobById(final @NonNull UUID jobId) {
public Jobs getJobForJobId(final UUID jobId) {
final Optional multiTransferJob = jobStore.find(jobId.toString());
if (multiTransferJob.isPresent()) {
- final MultiTransferJob job = multiTransferJob.get();
- final Job.JobBuilder builder = Job.builder()
- .jobId(UUID.fromString(job.getJobId()))
- .jobState(convert(job.getState()));
- job.getCompletionDate().ifPresent(date -> builder.jobCompleted(date.toInstant(ZoneOffset.UTC)));
- final Job jobToReturn = builder.build();
+ final MultiTransferJob multiJob = multiTransferJob.get();
final var relationships = new ArrayList();
try {
- final Optional blob = blobStore.getBlob(job.getJobId());
+ final Optional blob = blobStore.getBlob(multiJob.getJob().getJobId().toString());
final byte[] bytes = blob.orElseThrow(
- () -> new EntityNotFoundException("Could not find stored data for job with id " + jobId));
+ () -> new EntityNotFoundException("Could not find stored data for multiJob with id " + jobId));
final ItemContainer itemContainer = new JsonUtil().fromString(new String(bytes, StandardCharsets.UTF_8),
ItemContainer.class);
final List assemblyPartRelationships = itemContainer.getAssemblyPartRelationships();
@@ -131,7 +126,7 @@ public Jobs getJobForJobId(final UUID jobId) {
} catch (BlobPersistenceException e) {
log.error("Unable to read blob", e);
}
- return Jobs.builder().job(jobToReturn).relationships(relationships).build();
+ return Jobs.builder().job(multiJob.getJob()).relationships(relationships).build();
} else {
throw new EntityNotFoundException("No job exists with id " + jobId);
}
@@ -159,41 +154,4 @@ private Stream convert(final AssemblyPartRelationshipDTO dto) {
.build())
.build());
}
-
- private JobState convert(final net.catenax.irs.connector.job.JobState state) {
- switch (state) {
- case COMPLETED:
- return JobState.COMPLETED;
- case IN_PROGRESS:
- return JobState.RUNNING;
- case ERROR:
- return JobState.ERROR;
- case INITIAL:
- return JobState.INITIAL;
- case TRANSFERS_FINISHED:
- return JobState.TRANSFERS_FINISHED;
- case CANCELED:
- return JobState.CANCELED;
- default:
- throw new IllegalArgumentException("Cannot convert JobState of type " + state);
- }
- }
-
- private net.catenax.irs.connector.job.JobState convert(final JobState state) {
- switch (state) {
- case COMPLETED:
- return net.catenax.irs.connector.job.JobState.COMPLETED;
- case RUNNING:
- return net.catenax.irs.connector.job.JobState.IN_PROGRESS;
- case ERROR:
- return net.catenax.irs.connector.job.JobState.ERROR;
- case INITIAL:
- return net.catenax.irs.connector.job.JobState.INITIAL;
- case TRANSFERS_FINISHED:
- return net.catenax.irs.connector.job.JobState.TRANSFERS_FINISHED;
- default:
- throw new IllegalArgumentException("Cannot convert JobState of type " + state);
- }
- }
-
}
diff --git a/irs-api/src/test/java/net/catenax/irs/IrsApplicationTests.java b/irs-api/src/test/java/net/catenax/irs/IrsApplicationTests.java
index a2289b3199..fc07dcf17e 100644
--- a/irs-api/src/test/java/net/catenax/irs/IrsApplicationTests.java
+++ b/irs-api/src/test/java/net/catenax/irs/IrsApplicationTests.java
@@ -1,8 +1,8 @@
package net.catenax.irs;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static net.catenax.irs.aaswrapper.job.AASRecursiveJobHandler.DEPTH_ID_KEY;
-import static net.catenax.irs.aaswrapper.job.AASRecursiveJobHandler.ROOT_ITEM_ID_KEY;
+import static net.catenax.irs.dtos.IrsCommonConstants.DEPTH_ID_KEY;
+import static net.catenax.irs.dtos.IrsCommonConstants.ROOT_ITEM_ID_KEY;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
@@ -12,11 +12,10 @@
import net.catenax.irs.aaswrapper.job.AASTransferProcess;
import net.catenax.irs.aaswrapper.job.ItemDataRequest;
+import net.catenax.irs.component.enums.JobState;
import net.catenax.irs.connector.job.JobInitiateResponse;
import net.catenax.irs.connector.job.JobOrchestrator;
-import net.catenax.irs.connector.job.JobState;
import net.catenax.irs.connector.job.JobStore;
-import net.catenax.irs.connector.job.MultiTransferJob;
import net.catenax.irs.connector.job.ResponseStatus;
import net.catenax.irs.persistence.BlobPersistence;
import org.awaitility.Awaitility;
@@ -32,8 +31,7 @@
import org.springframework.test.context.ActiveProfiles;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
-@ActiveProfiles(profiles = { "local",
- "test"
+@ActiveProfiles(profiles = { "local", "test"
})
class IrsApplicationTests {
@@ -59,7 +57,7 @@ void contextLoads() {
@Test
void generatedOpenApiMatchesContract() throws Exception {
final String generatedYaml = this.restTemplate.getForObject("http://localhost:" + port + "/api/api-docs.yaml",
- String.class);
+ String.class);
final String fixedYaml = Files.readString(new File("../api/irs-v1.0.yaml").toPath(), UTF_8);
assertThat(generatedYaml).isEqualToNormalizingNewlines(fixedYaml);
}
@@ -75,7 +73,7 @@ void shouldStoreBlobResultWhenRunningJob() throws Exception {
.atMost(10, TimeUnit.SECONDS)
.pollInterval(100, TimeUnit.MILLISECONDS)
.until(() -> jobStore.find(response.getJobId())
- .map(MultiTransferJob::getState)
+ .map(s -> s.getJob().getJobState())
.map(state -> state == JobState.COMPLETED)
.orElse(false));
diff --git a/irs-api/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java b/irs-api/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java
new file mode 100644
index 0000000000..76a3004452
--- /dev/null
+++ b/irs-api/src/test/java/net/catenax/irs/connector/job/InMemoryJobStoreTest.java
@@ -0,0 +1,447 @@
+package net.catenax.irs.connector.job;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.net.URL;
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import com.github.javafaker.Faker;
+import net.catenax.irs.component.GlobalAssetIdentification;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.JobErrorDetails;
+import net.catenax.irs.component.enums.JobState;
+import net.catenax.irs.util.TestMother;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpMethod;
+
+class InMemoryJobStoreTest {
+ final int TTL_IN_HOUR_SECONDS = 3600;
+ InMemoryJobStore sut = new InMemoryJobStore();
+ Faker faker = new Faker();
+ TestMother generate = new TestMother();
+ MultiTransferJob job = generate.job(JobState.UNSAVED);
+ MultiTransferJob job2 = generate.job(JobState.UNSAVED);
+ MultiTransferJob originalJob = job.toBuilder().build();
+ String otherJobId = faker.lorem().characters();
+ TransferProcess process1 = generate.transfer();
+ TransferProcess process2 = generate.transfer();
+ String processId1 = process1.getId();
+ String processId2 = process2.getId();
+ String errorDetail = faker.lorem().sentence();
+
+ @Test
+ void find_WhenNotFound() {
+ assertThat(sut.find(otherJobId)).isEmpty();
+ }
+
+ @Test
+ void findByProcessId_WhenFound() {
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.create(job2);
+ sut.addTransferProcess(job2.getJob().getJobId().toString(), processId2);
+
+ refreshJob();
+ assertThat(sut.findByProcessId(processId1)).contains(job);
+ }
+
+ @Test
+ void findByProcessId_WhenNotFound() {
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+
+ assertThat(sut.findByProcessId(processId2)).isEmpty();
+ }
+
+ @Test
+ void create_and_find() {
+
+ sut.create(job);
+ assertThat(sut.find(job.getJob().getJobId().toString())).isPresent()
+ .get()
+ .usingRecursiveComparison()
+ .isEqualTo(originalJob.toBuilder().transitionInitial().build());
+ assertThat(sut.find(otherJobId)).isEmpty();
+ }
+
+ @Test
+ void addTransferProcess() {
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ refreshJob();
+ assertThat(job.getTransferProcessIds()).containsExactly(processId1);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
+ }
+
+ @Test
+ void completeTransferProcess_WhenJobNotFound() {
+ sut.completeTransferProcess(otherJobId, process1);
+ }
+
+ @Test
+ void completeTransferProcess_WhenTransferFound() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+
+ // Act
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+
+ // Assert
+ assertThat(job.getTransferProcessIds()).isEmpty();
+ }
+
+ @Test
+ void completeTransferProcess_WhenTransferNotFound() {
+ // Act
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+
+ // Assert
+ assertThat(job.getTransferProcessIds()).isEmpty();
+ }
+
+ @Test
+ void completeTransferProcess_WhenTransferAlreadyCompleted() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+
+ // Act
+ assertThatExceptionOfType(IllegalStateException.class).isThrownBy(
+ () -> sut.completeTransferProcess(job.getJob().getJobId().toString(), process1));
+
+ // Assert
+ refreshJob();
+ assertThat(job.getTransferProcessIds()).isEmpty();
+ }
+
+ @Test
+ void completeTransferProcess_WhenNotLastTransfer_DoesNotTransitionJob() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId2);
+
+ // Act
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
+ }
+
+ @Test
+ void completeTransferProcess_WhenLastTransfer_TransitionsJob() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId2);
+
+ // Act
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process2);
+
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.TRANSFERS_FINISHED);
+ }
+
+ @Test
+ void completeJob_WhenJobNotFound() {
+ // Arrange
+ sut.create(job);
+ // Act
+ sut.completeJob(otherJobId);
+ refreshJob();
+ // Assert
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ }
+
+ @Test
+ void completeJob_WhenJobInInitialState() {
+ // Arrange
+ sut.create(job);
+ sut.create(job2);
+ // Act
+ sut.completeJob(job.getJob().getJobId().toString());
+ // Assert
+ refreshJob();
+ refreshJob2();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertTrue(Optional.ofNullable(job.getJob().getJobCompleted()).isPresent());
+ assertThat(job2.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ }
+
+ @Test
+ void completeJob_WhenJobInTransfersCompletedState() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ // Act
+ sut.completeJob(job.getJob().getJobId().toString());
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertTrue(Optional.ofNullable(job.getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void completeJob_WhenJobInTransfersInProgressState() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ // Act
+ assertThatExceptionOfType(IllegalStateException.class).isThrownBy(
+ () -> sut.completeJob(job.getJob().getJobId().toString()));
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
+ }
+
+ @Test
+ void markJobInError_WhenJobNotFound() {
+ // Arrange
+ sut.create(job);
+ // Act
+ sut.markJobInError(otherJobId, errorDetail);
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ }
+
+ @Test
+ void markJobInError_WhenJobInInitialState() {
+ // Arrange
+ sut.create(job);
+ sut.create(job2);
+ // Act
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
+ // Assert
+ refreshJob();
+ refreshJob2();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertThat(job2.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ assertThat(job.getJob().getException().getErrorDetail()).isEqualTo(errorDetail);
+ assertTrue(Optional.ofNullable(job.getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void markJobInError_WhenJobInTransfersCompletedState() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ // Act
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertTrue(Optional.ofNullable(job.getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void markJobInError_WhenJobInTransfersInProgressState() {
+ // Arrange
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ // Act
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
+ // Assert
+ refreshJob();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertTrue(Optional.ofNullable(job.getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void shouldFindCompletedJobsOlderThanFiveHours() {
+ // Arrange
+ final Instant nowPlusFiveHours = Instant.now().plusSeconds(TTL_IN_HOUR_SECONDS * 5);
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ sut.completeJob(job.getJob().getJobId().toString());
+ // Act
+ final List completedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.COMPLETED,
+ nowPlusFiveHours);
+ // Assert
+ assertThat(completedJobs.size()).isEqualTo(1);
+ assertThat(completedJobs.get(0).getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertTrue(Optional.ofNullable(completedJobs.get(0).getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void shouldFindFailedJobsOlderThanFiveHours() {
+ // Arrange
+ final Instant nowPlusFiveHours = Instant.now().plusSeconds(TTL_IN_HOUR_SECONDS * 5);
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
+ // Act
+ final List failedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.ERROR,
+ nowPlusFiveHours);
+ // Assert
+ assertThat(failedJobs.size()).isEqualTo(1);
+ assertThat(failedJobs.get(0).getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertTrue(Optional.ofNullable(failedJobs.get(0).getJob().getJobCompleted()).isPresent());
+ }
+
+ @Test
+ void shouldDeleteJobById() {
+ // Arrange
+ sut.create(job);
+ // Act
+ sut.deleteJob(job.getJob().getJobId().toString());
+ // Assert
+ assertThat(sut.find(job.getJob().getJobId().toString())).isEmpty();
+ }
+
+ @Test
+ void jobStateIsInitial() {
+ sut.create(job);
+ final Optional multiTransferJob = sut.get(job.getJob().getJobId().toString());
+ assertThat(multiTransferJob).isPresent();
+ assertThat(multiTransferJob.get().getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ }
+
+ @Test
+ void jobStateIsInProgress() {
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ final Optional multiTransferJob = sut.get(job.getJob().getJobId().toString());
+ assertThat(multiTransferJob).isPresent();
+ assertThat(multiTransferJob.get().getJob().getJobState()).isEqualTo(JobState.RUNNING);
+ }
+
+ @Test
+ void shouldFindJobsByCompletedJobState() {
+ // Arrange
+ sut.create(job);
+ sut.completeJob(job.getJob().getJobId().toString());
+ sut.create(job2);
+ // Act
+ final List foundJobs = sut.findByStates(List.of(JobState.COMPLETED));
+ // Assert
+ assertThat(foundJobs.size()).isEqualTo(1);
+ assertThat(foundJobs.get(0).getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ }
+
+ @Test
+ void shouldFindJobsByErrorJobState() {
+ // Arrange
+ sut.create(job);
+ sut.markJobInError(job.getJob().getJobId().toString(), "errorDetail");
+ // Act
+ final List foundJobs = sut.findByStates(List.of(JobState.ERROR));
+ // Assert
+ assertThat(foundJobs.size()).isEqualTo(1);
+ assertThat(foundJobs.get(0).getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ }
+
+ private void refreshJob() {
+ job = sut.find(job.getJob().getJobId().toString()).get();
+ }
+
+ private void refreshJob2() {
+ job2 = sut.find(job2.getJob().getJobId().toString()).get();
+ }
+
+ private Job createJob() {
+ GlobalAssetIdentification globalAssetId = GlobalAssetIdentification.builder()
+ .globalAssetId(UUID.randomUUID().toString())
+ .build();
+
+ return Job.builder()
+ .globalAssetId(globalAssetId)
+ .jobId(UUID.randomUUID())
+ .jobState(JobState.INITIAL)
+ .createdOn(Instant.now())
+ .lastModifiedOn(Instant.now())
+ .requestUrl(fakeURL())
+ .action(HttpMethod.POST.toString())
+ .build();
+ }
+
+ private URL fakeURL() {
+ try {
+ return new URL("http://localhost:8888/fake/url");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Test
+ void shouldStoreAndLoadJob() {
+ // arrange
+ final var jobId = UUID.randomUUID().toString();
+ final MultiTransferJob job = createJob(jobId);
+
+ // act
+ sut.create(job);
+ final Optional multiTransferJob = sut.find(jobId);
+
+ // assert
+ assertThat(multiTransferJob).isPresent();
+
+ final MultiTransferJob storedJob = multiTransferJob.get();
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(storedJob.getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ softly.assertThat(storedJob.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ softly.assertThat(storedJob.getJob().getException().getErrorDetail())
+ .isEqualTo(job.getJob().getException().getErrorDetail());
+ softly.assertThat(storedJob.getJob().getJobCompleted()).isEqualTo(job.getJob().getJobCompleted());
+ softly.assertThat(storedJob.getJobData()).isEqualTo(job.getJobData());
+ softly.assertThat(storedJob.getCompletedTransfers()).isEqualTo(job.getCompletedTransfers());
+ });
+
+ }
+
+ private MultiTransferJob createJob(final String jobId) {
+ return MultiTransferJob.builder()
+ .job(Job.builder()
+ .jobId(UUID.fromString(jobId))
+ .jobState(JobState.UNSAVED)
+ .jobCompleted(Instant.now())
+ .exception(JobErrorDetails.builder()
+ .exception("SomeError")
+ .exceptionDate(Instant.now())
+ .build())
+ .build())
+ .jobData(Map.of("dataKey", "dataValue"))
+ .build();
+ }
+
+ @Test
+ void shouldTransitionJobToComplete() {
+ // arrange
+ final var jobId = UUID.randomUUID().toString();
+ final MultiTransferJob job = createJob(jobId);
+
+ // act
+ sut.create(job);
+ sut.completeJob(jobId);
+ final Optional multiTransferJob = sut.find(jobId);
+
+ // assert
+ assertThat(multiTransferJob).isPresent();
+
+ final MultiTransferJob storedJob = multiTransferJob.get();
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(storedJob.getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ softly.assertThat(storedJob.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ softly.assertThat(storedJob.getJob().getException().getErrorDetail())
+ .isEqualTo(job.getJob().getException().getErrorDetail());
+ softly.assertThat(storedJob.getJobData()).isEqualTo(job.getJobData());
+ softly.assertThat(storedJob.getCompletedTransfers()).isEqualTo(job.getCompletedTransfers());
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java b/irs-api/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java
similarity index 57%
rename from connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java
rename to irs-api/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java
index f8675959fb..2cc7c720dc 100644
--- a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java
+++ b/irs-api/src/test/java/net/catenax/irs/connector/job/JobOrchestratorTest.java
@@ -1,20 +1,5 @@
package net.catenax.irs.connector.job;
-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.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE;
import static org.mockito.ArgumentMatchers.any;
@@ -27,6 +12,30 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import java.net.URL;
+import java.time.Instant;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Consumer;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import com.github.javafaker.Faker;
+import net.catenax.irs.component.GlobalAssetIdentification;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.enums.JobState;
+import net.catenax.irs.util.TestMother;
+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.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpMethod;
+
@ExtendWith(MockitoExtension.class)
class JobOrchestratorTest {
@@ -47,28 +56,31 @@ class JobOrchestratorTest {
Pattern uuid = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}");
TestMother generate = new TestMother();
- MultiTransferJob job = generate.job(JobState.IN_PROGRESS);
+ MultiTransferJob job = generate.job(JobState.RUNNING);
DataRequest dataRequest = generate.dataRequest();
DataRequest dataRequest2 = generate.dataRequest();
TransferInitiateResponse okResponse = generate.okResponse();
TransferInitiateResponse okResponse2 = generate.okResponse();
TransferProcess transfer = generate.transfer();
+ Faker faker = new Faker();
+ GlobalAssetIdentification globalAssetId = GlobalAssetIdentification.builder()
+ .globalAssetId(faker.lorem().characters())
+ .build();
@Test
void startJob_storesJobWithDataAndState() {
- assertThat(startJob())
- .usingRecursiveComparison()
- .ignoringFields("jobId")
- .isEqualTo(MultiTransferJob.builder()
- .jobData(job.getJobData())
- .state(JobState.UNSAVED)
- .build());
+ MultiTransferJob job2 = startJob();
+ assertThat(job2).usingRecursiveComparison()
+ .ignoringFields("job.job.jobId")
+ .isEqualTo(MultiTransferJob.builder()
+ .jobData(job.getJobData())
+ .job(job2.getJob().toBuilder().jobState(JobState.UNSAVED).build())
+ .build());
}
@Test
void startJob_storesJobWithUuidAsIdentifier() {
- assertThat(startJob().getJobId())
- .matches(uuid);
+ assertThat(startJob().getJob().getJobId().toString()).matches(uuid.asPredicate());
}
@Test
@@ -86,11 +98,11 @@ void startJob_callsHandlerWithJob() {
void startJob_WithTwoDataRequests_StartsTransfers() {
// Arrange
when(handler.initiate(any(MultiTransferJob.class)))
- .thenReturn(Stream.of(dataRequest, dataRequest2));
+ .thenReturn(Stream.of(dataRequest, dataRequest2));
when(processManager.initiateRequest(eq(dataRequest), any(), any()))
- .thenReturn(okResponse);
+ .thenReturn(okResponse);
when(processManager.initiateRequest(eq(dataRequest2), any(), any()))
- .thenReturn(okResponse2);
+ .thenReturn(okResponse2);
// Act
var newJob = startJob();
@@ -103,40 +115,40 @@ void startJob_WithTwoDataRequests_StartsTransfers() {
@Test
void startJob_WithZeroDataRequest_CompletesJob() {
// Arrange
- when(handler.initiate(any(MultiTransferJob.class)))
- .thenReturn(Stream.empty());
+ when(handler.initiate(any(MultiTransferJob.class))).thenReturn(Stream.empty());
- // Act
var response = sut.startJob(job.getJobData());
var newJob = getStartedJob();
// Assert
verifyNoInteractions(processManager);
- verify(jobStore).completeJob(newJob.getJobId());
+ verify(jobStore).completeJob(newJob.getJob().getJobId().toString());
verifyNoMoreInteractions(jobStore);
verify(handler).complete(newJob);
- assertThat(response)
- .isEqualTo(
- JobInitiateResponse.builder().jobId(newJob.getJobId()).status(ResponseStatus.OK).build());
+ assertThat(response).isEqualTo(JobInitiateResponse.builder()
+ .jobId(newJob.getJob().getJobId().toString())
+ .status(ResponseStatus.OK)
+ .build());
}
@Test
void startJob_WithSuccessfulTransferStarts_ReturnsOk() {
// Arrange
when(handler.initiate(any(MultiTransferJob.class)))
- .thenReturn(Stream.of(dataRequest));
+ .thenReturn(Stream.of(dataRequest));
when(processManager.initiateRequest(eq(dataRequest), any(), any()))
- .thenReturn(okResponse);
+ .thenReturn(okResponse);
// Act
var response = sut.startJob(job.getJobData());
// Assert
var newJob = getStartedJob();
- assertThat(response)
- .isEqualTo(
- JobInitiateResponse.builder().jobId(newJob.getJobId()).status(ResponseStatus.OK).build());
+ assertThat(response).isEqualTo(JobInitiateResponse.builder()
+ .jobId(newJob.getJob().getJobId().toString())
+ .status(ResponseStatus.OK)
+ .build());
}
@ParameterizedTest
@@ -144,9 +156,9 @@ void startJob_WithSuccessfulTransferStarts_ReturnsOk() {
void startJob_WhenTransferStartUnsuccessful_Abort(ResponseStatus status) {
// Arrange
when(handler.initiate(any()))
- .thenReturn(Stream.of(dataRequest, dataRequest2));
+ .thenReturn(Stream.of(dataRequest, dataRequest2));
when(processManager.initiateRequest(eq(dataRequest), any(), any()))
- .thenReturn(generate.response(status));
+ .thenReturn(generate.response(status));
// Act
var response = sut.startJob(job.getJobData());
@@ -159,46 +171,46 @@ void startJob_WhenTransferStartUnsuccessful_Abort(ResponseStatus status) {
verify(jobStore).create(jobCaptor.capture());
verifyNoMoreInteractions(jobStore);
- assertThat(response)
- .isEqualTo(
- JobInitiateResponse.builder().jobId(jobCaptor.getValue().getJobId()).status(status).build());
+ assertThat(response).isEqualTo(JobInitiateResponse.builder()
+ .jobId(jobCaptor.getValue().getJob().getJobId().toString())
+ .status(status)
+ .build());
}
-
@Test
void startJob_WhenHandlerInitiateThrows_StopJob() {
// Arrange
- when(handler.initiate(any(MultiTransferJob.class)))
- .thenThrow(new RuntimeException());
+ when(handler.initiate(any(MultiTransferJob.class))).thenThrow(new RuntimeException());
// Act
var response = sut.startJob(job.getJobData());
// Assert
verify(jobStore).create(jobCaptor.capture());
- verify(jobStore).markJobInError(jobCaptor.getValue().getJobId(), "Handler method failed");
+ verify(jobStore).markJobInError(jobCaptor.getValue().getJob().getJobId().toString(), "Handler method failed");
verifyNoMoreInteractions(jobStore);
verifyNoInteractions(processManager);
- assertThat(response)
- .isEqualTo(
- JobInitiateResponse.builder().jobId(jobCaptor.getValue().getJobId()).status(ResponseStatus.FATAL_ERROR).build());
+ assertThat(response).isEqualTo(JobInitiateResponse.builder()
+ .jobId(jobCaptor.getValue().getJob().getJobId().toString())
+ .status(ResponseStatus.FATAL_ERROR)
+ .build());
}
@Test
void transferProcessCompleted_WhenCalledBackForCompletedTransfer_RunsNextTransfers() {
// Arrange
when(processManager.initiateRequest(eq(dataRequest), any(), any()))
- .thenReturn(okResponse);
+ .thenReturn(okResponse);
when(processManager.initiateRequest(eq(dataRequest2), any(), any()))
- .thenReturn(okResponse2);
-
+ .thenReturn(okResponse2);
// Act
callCompleteAndReturnNextTransfers(Stream.of(dataRequest, dataRequest2));
// Assert
verify(processManager).initiateRequest(eq(dataRequest), any(), any());
- verify(jobStore).completeTransferProcess(job.getJobId(), transfer);
+ verify(jobStore).completeTransferProcess(job.getJob().getJobId().toString(), transfer);
+
}
@Test
@@ -207,8 +219,8 @@ void transferProcessCompleted_WhenCalledBackForCompletedTransfer_WithoutNextTran
callCompleteAndReturnNextTransfers(Stream.empty());
// Assert
- verify(jobStore).completeTransferProcess(job.getJobId(), transfer);
- verify(jobStore).find(job.getJobId());
+ verify(jobStore).completeTransferProcess(job.getJob().getJobId().toString(), transfer);
+ verify(jobStore).find(job.getJob().getJobId().toString());
verifyNoInteractions(processManager);
verifyNoMoreInteractions(jobStore);
}
@@ -219,8 +231,8 @@ void transferProcessCompleted_WhenJobNotCompleted_DoesNotCallComplete() {
callCompleteAndReturnNextTransfers(Stream.empty());
// Assert
- verify(jobStore).completeTransferProcess(job.getJobId(), transfer);
- verify(jobStore).find(job.getJobId());
+ verify(jobStore).completeTransferProcess(job.getJob().getJobId().toString(), transfer);
+ verify(jobStore).find(job.getJob().getJobId().toString());
verifyNoMoreInteractions(jobStore);
verifyNoMoreInteractions(handler);
}
@@ -228,34 +240,32 @@ void transferProcessCompleted_WhenJobNotCompleted_DoesNotCallComplete() {
@Test
void transferProcessCompleted_WhenJobCompleted_CallsComplete() {
// Arrange
- doAnswer(i -> byCompletingJob())
- .when(jobStore).completeTransferProcess(job.getJobId(), transfer);
+ doAnswer(i -> byCompletingJob()).when(jobStore)
+ .completeTransferProcess(job.getJob().getJobId().toString(), transfer);
// Act
callCompleteAndReturnNextTransfers(Stream.empty());
// Assert
verify(handler).complete(job);
- verify(jobStore).completeJob(job.getJobId());
+ verify(jobStore).completeJob(job.getJob().getJobId().toString());
}
-
@Test
void transferProcessCompleted_WhenHandlerCompleteThrows_StopJob() {
// Arrange
- doAnswer(i -> byCompletingJob())
- .when(jobStore).completeTransferProcess(job.getJobId(), transfer);
+ doAnswer(i -> byCompletingJob()).when(jobStore)
+ .completeTransferProcess(job.getJob().getJobId().toString(), transfer);
doAnswer(i -> {
- throw new RuntimeException();
- })
- .when(handler).complete(any());
+ throw new JobException();
+ }).when(handler).complete(any());
// Act
callCompleteAndReturnNextTransfers(Stream.empty());
// Assert
- verify(jobStore).markJobInError(job.getJobId(), "Handler method failed");
- verify(jobStore).find(job.getJobId());
+ verify(jobStore).markJobInError(job.getJob().getJobId().toString(), "Handler method failed");
+ verify(jobStore).find(job.getJob().getJobId().toString());
verifyNoMoreInteractions(jobStore);
verifyNoInteractions(processManager);
}
@@ -263,8 +273,7 @@ void transferProcessCompleted_WhenHandlerCompleteThrows_StopJob() {
@Test
void transferProcessCompleted_WhenJobNotFound_Ignore() {
// Arrange
- when(jobStore.findByProcessId(transfer.getId()))
- .thenReturn(Optional.empty());
+ when(jobStore.findByProcessId(transfer.getId())).thenReturn(Optional.empty());
// Act
callTransferProcessCompletedViaCallback();
@@ -275,14 +284,13 @@ void transferProcessCompleted_WhenJobNotFound_Ignore() {
}
@ParameterizedTest
- @EnumSource(value = JobState.class, names = "IN_PROGRESS", mode = EXCLUDE)
+ @EnumSource(value = JobState.class, names = "RUNNING", mode = EXCLUDE)
void transferProcessCompleted_WhenJobNotInProgress_Ignore(JobState state) {
// Arrange
- job = job.toBuilder().state(state).build();
+ job = job.toBuilder().job(generate.fakeJob(state)).build();
// Act
- when(jobStore.findByProcessId(transfer.getId()))
- .thenReturn(Optional.of(job));
+ when(jobStore.findByProcessId(transfer.getId())).thenReturn(Optional.of(job));
callTransferProcessCompletedViaCallback();
// Assert
@@ -295,7 +303,7 @@ void transferProcessCompleted_WhenJobNotInProgress_Ignore(JobState state) {
void transferProcessCompleted_WhenNextTransferStartUnsuccessful_Abort(ResponseStatus status) {
// Arrange
when(processManager.initiateRequest(eq(dataRequest), any(), any()))
- .thenReturn(generate.response(status));
+ .thenReturn(generate.response(status));
// Act
callCompleteAndReturnNextTransfers(Stream.of(dataRequest, dataRequest2));
@@ -305,31 +313,28 @@ void transferProcessCompleted_WhenNextTransferStartUnsuccessful_Abort(ResponseSt
verify(processManager, never()).initiateRequest(eq(dataRequest2), any(), any());
// temporarily created job should be deleted
- verify(jobStore).markJobInError(job.getJobId(), "Failed to start a transfer");
+ verify(jobStore).markJobInError(job.getJob().getJobId().toString(), "Failed to start a transfer");
verifyNoMoreInteractions(jobStore);
}
@Test
void transferProcessCompleted_WhenHandlerRecurseThrows_StopJob() {
// Arrange
- when(jobStore.findByProcessId(transfer.getId()))
- .thenReturn(Optional.of(job));
- when(handler.recurse(job, transfer))
- .thenThrow(new RuntimeException());
+ when(jobStore.findByProcessId(transfer.getId())).thenReturn(Optional.of(job));
+ when(handler.recurse(job, transfer)).thenThrow(new RuntimeException());
// Act
callTransferProcessCompletedViaCallback();
// Assert
- verify(jobStore).markJobInError(job.getJobId(), "Handler method failed");
+ verify(jobStore).markJobInError(job.getJob().getJobId().toString(), "Handler method failed");
verifyNoMoreInteractions(jobStore);
verifyNoInteractions(processManager);
}
private Object byCompletingJob() {
job = job.toBuilder().transitionTransfersFinished().build();
- lenient().when(jobStore.find(job.getJobId()))
- .thenReturn(Optional.of(job));
+ lenient().when(jobStore.find(job.getJob().getJobId().toString())).thenReturn(Optional.of(job));
return null;
}
@@ -344,16 +349,37 @@ private MultiTransferJob getStartedJob() {
}
private void callCompleteAndReturnNextTransfers(Stream dataRequestStream) {
- when(jobStore.findByProcessId(transfer.getId()))
- .thenReturn(Optional.of(job));
- lenient().when(jobStore.find(job.getJobId()))
- .thenReturn(Optional.of(job));
- when(handler.recurse(job, transfer))
- .thenReturn(dataRequestStream);
+ when(jobStore.findByProcessId(transfer.getId())).thenReturn(Optional.of(job));
+ lenient().when(jobStore.find(job.getJob().getJobId().toString())).thenReturn(Optional.of(job));
+ when(handler.recurse(job, transfer)).thenReturn(dataRequestStream);
callTransferProcessCompletedViaCallback();
}
private void callTransferProcessCompletedViaCallback() {
sut.transferProcessCompleted(transfer);
}
+
+ private Job createJob() {
+ GlobalAssetIdentification globalAssetId = GlobalAssetIdentification.builder()
+ .globalAssetId(UUID.randomUUID().toString())
+ .build();
+
+ return Job.builder()
+ .globalAssetId(globalAssetId)
+ .jobId(UUID.randomUUID())
+ .jobState(JobState.UNSAVED)
+ .createdOn(Instant.now())
+ .lastModifiedOn(Instant.now())
+ .requestUrl(fakeURL())
+ .action(HttpMethod.POST.toString())
+ .build();
+ }
+
+ private URL fakeURL() {
+ try {
+ return new URL("http://localhost:8888/fake/url");
+ } catch (Exception e) {
+ return null;
+ }
+ }
}
diff --git a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java b/irs-api/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java
similarity index 95%
rename from connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java
rename to irs-api/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java
index 4a92c32b73..20d9de1176 100644
--- a/connector/edc-recursive-job/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java
+++ b/irs-api/src/test/java/net/catenax/irs/connector/job/MultiTransferJobTest.java
@@ -1,10 +1,11 @@
package net.catenax.irs.connector.job;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
import com.github.javafaker.Faker;
+import net.catenax.irs.util.TestMother;
import org.junit.jupiter.api.Test;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-
class MultiTransferJobTest {
Faker faker = new Faker();
@@ -27,4 +28,6 @@ void getJobData_Immutable() {
faker.lorem().word(),
faker.lorem().word()));
}
+
+
}
\ No newline at end of file
diff --git a/irs-api/src/test/java/net/catenax/irs/connector/job/PersistentJobStoreTest.java b/irs-api/src/test/java/net/catenax/irs/connector/job/PersistentJobStoreTest.java
index cf0c7df198..d0a9d6c638 100644
--- a/irs-api/src/test/java/net/catenax/irs/connector/job/PersistentJobStoreTest.java
+++ b/irs-api/src/test/java/net/catenax/irs/connector/job/PersistentJobStoreTest.java
@@ -3,18 +3,22 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
-import java.time.LocalDateTime;
+import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.UUID;
import com.github.javafaker.Faker;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.JobErrorDetails;
+import net.catenax.irs.component.enums.JobState;
import net.catenax.irs.persistence.BlobPersistenceException;
import net.catenax.irs.persistence.MinioBlobPersistence;
import net.catenax.irs.testing.containers.MinioContainer;
+import net.catenax.irs.util.JsonUtil;
import net.catenax.irs.util.TestMother;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.AfterAll;
@@ -28,6 +32,7 @@
class PersistentJobStoreTest {
private static final String ACCESS_KEY = "accessKey";
private static final String SECRET_KEY = "secretKey";
+ final int TTL_IN_HOUR_SECONDS = 3600;
private static final MinioContainer minioContainer = new MinioContainer(
new MinioContainer.CredentialsProvider(ACCESS_KEY, SECRET_KEY)).withReuse(true);
@@ -72,9 +77,9 @@ void find_WhenNotFound() {
@Test
void findByProcessId_WhenFound() {
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
sut.create(job2);
- sut.addTransferProcess(job2.getJobId(), processId2);
+ sut.addTransferProcess(job2.getJob().getJobId().toString(), processId2);
refreshJob();
assertThat(sut.findByProcessId(processId1)).isPresent().get().usingRecursiveComparison().isEqualTo(job);
@@ -83,7 +88,7 @@ void findByProcessId_WhenFound() {
@Test
void findByProcessId_WhenNotFound() {
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
assertThat(sut.findByProcessId(processId2)).isEmpty();
}
@@ -91,23 +96,22 @@ void findByProcessId_WhenNotFound() {
@Test
void create_and_find() {
sut.create(job);
- assertThat(sut.find(job.getJobId())).isPresent()
- .get()
- .usingRecursiveComparison()
- .isEqualTo(originalJob.toBuilder()
- .completionDate(Optional.empty())
- .state(JobState.INITIAL)
- .build());
+ assertThat(sut.find(job.getJob().getJobId().toString())).isPresent()
+ .get()
+ .usingRecursiveComparison()
+ .isEqualTo(originalJob.toBuilder()
+ .transitionInitial()
+ .build());
assertThat(sut.find(otherJobId)).isEmpty();
}
@Test
void addTransferProcess() {
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
refreshJob();
assertThat(job.getTransferProcessIds()).containsExactly(processId1);
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
}
@Test
@@ -115,14 +119,23 @@ void completeTransferProcess_WhenJobNotFound() {
sut.completeTransferProcess(otherJobId, process1);
}
+ @Test
+ void shouldSerializeAndDeserializeMultiTransferJob() {
+ final JsonUtil jsonUtil = new JsonUtil();
+ final String firstSerialization = jsonUtil.asString(job);
+ final MultiTransferJob result = jsonUtil.fromString(firstSerialization, MultiTransferJob.class);
+ final String secondSerialization = jsonUtil.asString(result);
+ assertThat(firstSerialization).isEqualTo(secondSerialization);
+ }
+
@Test
void completeTransferProcess_WhenTransferFound() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
// Act
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Assert
assertThat(job.getTransferProcessIds()).isEmpty();
@@ -131,7 +144,7 @@ void completeTransferProcess_WhenTransferFound() {
@Test
void completeTransferProcess_WhenTransferNotFound() {
// Act
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Assert
assertThat(job.getTransferProcessIds()).isEmpty();
@@ -141,12 +154,12 @@ void completeTransferProcess_WhenTransferNotFound() {
void completeTransferProcess_WhenTransferAlreadyCompleted() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Act
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(
- () -> sut.completeTransferProcess(job.getJobId(), process1));
+ () -> sut.completeTransferProcess(job.getJob().getJobId().toString(), process1));
// Assert
refreshJob();
@@ -157,31 +170,31 @@ void completeTransferProcess_WhenTransferAlreadyCompleted() {
void completeTransferProcess_WhenNotLastTransfer_DoesNotTransitionJob() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.addTransferProcess(job.getJobId(), processId2);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId2);
// Act
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
}
@Test
void completeTransferProcess_WhenLastTransfer_TransitionsJob() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.addTransferProcess(job.getJobId(), processId2);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId2);
// Act
- sut.completeTransferProcess(job.getJobId(), process1);
- sut.completeTransferProcess(job.getJobId(), process2);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process2);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.TRANSFERS_FINISHED);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.TRANSFERS_FINISHED);
}
@Test
@@ -192,7 +205,7 @@ void completeJob_WhenJobNotFound() {
sut.completeJob(otherJobId);
refreshJob();
// Assert
- assertThat(job.getState()).isEqualTo(JobState.INITIAL);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.INITIAL);
}
@Test
@@ -201,38 +214,40 @@ void completeJob_WhenJobInInitialState() {
sut.create(job);
sut.create(job2);
// Act
- sut.completeJob(job.getJobId());
+ sut.completeJob(job.getJob().getJobId().toString());
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.COMPLETED);
- assertThat(job.getCompletionDate()).isPresent();
- assertThat(job2.getState()).isEqualTo(JobState.UNSAVED);
+ refreshJob2();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertThat(Optional.of(job.getJob().getJobCompleted())).isPresent();
+ assertThat(job2.getJob().getJobState()).isEqualTo(JobState.INITIAL);
}
@Test
void completeJob_WhenJobInTransfersCompletedState() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Act
- sut.completeJob(job.getJobId());
+ sut.completeJob(job.getJob().getJobId().toString());
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.COMPLETED);
- assertThat(job.getCompletionDate()).isPresent();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertThat(Optional.of(job.getJob().getJobCompleted())).isPresent();
}
@Test
void completeJob_WhenJobInTransfersInProgressState() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
// Act
- assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> sut.completeJob(job.getJobId()));
+ assertThatExceptionOfType(IllegalStateException.class).isThrownBy(
+ () -> sut.completeJob(job.getJob().getJobId().toString()));
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.IN_PROGRESS);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.RUNNING);
}
@Test
@@ -243,7 +258,7 @@ void markJobInError_WhenJobNotFound() {
sut.markJobInError(otherJobId, errorDetail);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.INITIAL);
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.INITIAL);
}
@Test
@@ -252,78 +267,83 @@ void markJobInError_WhenJobInInitialState() {
sut.create(job);
sut.create(job2);
// Act
- sut.markJobInError(job.getJobId(), errorDetail);
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertThat(job2.getState()).isEqualTo(JobState.UNSAVED);
- assertThat(job.getErrorDetail()).isEqualTo(errorDetail);
- assertThat(job.getCompletionDate()).isPresent();
+ refreshJob2();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertThat(job2.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ assertThat(job.getJob().getException().getErrorDetail()).isEqualTo(errorDetail);
+ assertThat(Optional.of(job.getJob().getJobCompleted())).isPresent();
}
@Test
void markJobInError_WhenJobInTransfersCompletedState() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
// Act
- sut.markJobInError(job.getJobId(), errorDetail);
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertThat(job.getCompletionDate()).isPresent();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertThat(Optional.of(job.getJob().getJobCompleted())).isPresent();
}
@Test
void markJobInError_WhenJobInTransfersInProgressState() {
// Arrange
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
// Act
- sut.markJobInError(job.getJobId(), errorDetail);
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
// Assert
refreshJob();
- assertThat(job.getState()).isEqualTo(JobState.ERROR);
- assertThat(job.getCompletionDate()).isPresent();
+ assertThat(job.getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertThat(Optional.of(job.getJob().getJobCompleted())).isPresent();
}
@Test
void shouldFindCompletedJobsOlderThanFiveHours() {
// Arrange
- final LocalDateTime nowPlusFiveHours = LocalDateTime.now().plusHours(5);
+ final Instant nowPlusFiveHours = Instant.now().plusSeconds(TTL_IN_HOUR_SECONDS * 5);
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.completeTransferProcess(job.getJobId(), process1);
- sut.completeJob(job.getJobId());
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.completeTransferProcess(job.getJob().getJobId().toString(), process1);
+ sut.completeJob(job.getJob().getJobId().toString());
// Act
final List completedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.COMPLETED,
nowPlusFiveHours);
// Assert
assertThat(completedJobs).hasSize(1);
- assertThat(completedJobs.get(0).getState()).isEqualTo(JobState.COMPLETED);
- assertThat(completedJobs.get(0).getCompletionDate()).isPresent();
+ assertThat(completedJobs.get(0).getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ assertThat(Optional.of(completedJobs.get(0).getJob().getJobCompleted())).isPresent();
}
@Test
void shouldFindFailedJobsOlderThanFiveHours() {
// Arrange
- final LocalDateTime nowPlusFiveHours = LocalDateTime.now().plusHours(5);
+ final Instant nowPlusFiveHours = Instant.now().plusSeconds(3600 * 5);
sut.create(job);
- sut.addTransferProcess(job.getJobId(), processId1);
- sut.markJobInError(job.getJobId(), errorDetail);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ sut.markJobInError(job.getJob().getJobId().toString(), errorDetail);
// Act
final List failedJobs = sut.findByStateAndCompletionDateOlderThan(JobState.ERROR,
nowPlusFiveHours);
// Assert
assertThat(failedJobs).isNotEmpty();
final Optional foundJob = failedJobs.stream()
- .filter(failedJob -> failedJob.getJobId()
- .equals(job.getJobId()))
+ .filter(failedJob -> failedJob.getJob()
+ .getJobId()
+ .toString()
+ .equals(job.getJob()
+ .getJobId()
+ .toString()))
.findFirst();
assertThat(foundJob).isPresent();
- assertThat(foundJob.get().getState()).isEqualTo(JobState.ERROR);
- assertThat(foundJob.get().getCompletionDate()).isPresent();
+ assertThat(foundJob.get().getJob().getJobState()).isEqualTo(JobState.ERROR);
+ assertThat(Optional.of(foundJob.get().getJob().getJobCompleted())).isPresent();
}
@Test
@@ -331,9 +351,9 @@ void shouldDeleteJobById() {
// Arrange
sut.create(job);
// Act
- sut.deleteJob(job.getJobId());
+ sut.deleteJob(job.getJob().getJobId().toString());
// Assert
- assertThat(sut.find(job.getJobId())).isEmpty();
+ assertThat(sut.find(job.getJob().getJobId().toString())).isEmpty();
}
@Test
@@ -345,7 +365,6 @@ void shouldThrowExceptionWhenDeleteJobByIllegalId() {
assertThatExceptionOfType(JobException.class).isThrownBy(() -> sut.deleteJob(illegalId));
}
-
@Test
void shouldThrowExceptionWhenFindJobByIllegalId() {
// Arrange
@@ -358,11 +377,10 @@ void shouldThrowExceptionWhenFindJobByIllegalId() {
assertThat(job).isEmpty();
}
-
@Test
void shouldStoreAndLoadJob() {
// arrange
- final var jobId = faker.lorem().characters(36);
+ final var jobId = UUID.randomUUID().toString();
final MultiTransferJob job = createJob(jobId);
// act
@@ -374,10 +392,11 @@ void shouldStoreAndLoadJob() {
final MultiTransferJob storedJob = multiTransferJob.get();
SoftAssertions.assertSoftly(softly -> {
- softly.assertThat(storedJob.getJobId()).isEqualTo(job.getJobId());
- softly.assertThat(storedJob.getState()).isEqualTo(JobState.INITIAL);
- softly.assertThat(storedJob.getErrorDetail()).isEqualTo(job.getErrorDetail());
- softly.assertThat(storedJob.getCompletionDate()).isEqualTo(job.getCompletionDate());
+ softly.assertThat(storedJob.getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ softly.assertThat(storedJob.getJob().getJobState()).isEqualTo(JobState.INITIAL);
+ softly.assertThat(storedJob.getJob().getException().getErrorDetail())
+ .isEqualTo(job.getJob().getException().getErrorDetail());
+ softly.assertThat(storedJob.getJob().getJobCompleted()).isEqualTo(job.getJob().getJobCompleted());
softly.assertThat(storedJob.getJobData()).isEqualTo(job.getJobData());
softly.assertThat(storedJob.getCompletedTransfers()).isEqualTo(job.getCompletedTransfers());
});
@@ -386,18 +405,23 @@ void shouldStoreAndLoadJob() {
private MultiTransferJob createJob(final String jobId) {
return MultiTransferJob.builder()
- .jobId(jobId)
+ .job(Job.builder()
+ .jobId(UUID.fromString(jobId))
+ .jobState(JobState.UNSAVED)
+ .jobCompleted(Instant.now())
+ .exception(JobErrorDetails.builder()
+ .exception("SomeError")
+ .exceptionDate(Instant.now())
+ .build())
+ .build())
.jobData(Map.of("dataKey", "dataValue"))
- .state(JobState.UNSAVED)
- .errorDetail("SomeError")
- .completionDate(Optional.empty())
.build();
}
@Test
void shouldTransitionJobToComplete() {
// arrange
- final var jobId = faker.lorem().characters(36);
+ final var jobId = UUID.randomUUID().toString();
final MultiTransferJob job = createJob(jobId);
// act
@@ -405,34 +429,47 @@ void shouldTransitionJobToComplete() {
sut.completeJob(jobId);
final Optional multiTransferJob = sut.find(jobId);
- // assert
+ // assertec
assertThat(multiTransferJob).isPresent();
final MultiTransferJob storedJob = multiTransferJob.get();
SoftAssertions.assertSoftly(softly -> {
- softly.assertThat(storedJob.getJobId()).isEqualTo(job.getJobId());
- softly.assertThat(storedJob.getState()).isEqualTo(JobState.COMPLETED);
- softly.assertThat(storedJob.getErrorDetail()).isEqualTo(job.getErrorDetail());
- softly.assertThat(storedJob.getCompletionDate()).isPresent();
+ softly.assertThat(storedJob.getJob().getJobId().toString()).isEqualTo(job.getJob().getJobId().toString());
+ softly.assertThat(storedJob.getJob().getJobState()).isEqualTo(JobState.COMPLETED);
+ softly.assertThat(storedJob.getJob().getException().getErrorDetail())
+ .isEqualTo(job.getJob().getException().getErrorDetail());
softly.assertThat(storedJob.getJobData()).isEqualTo(job.getJobData());
softly.assertThat(storedJob.getCompletedTransfers()).isEqualTo(job.getCompletedTransfers());
});
}
private void refreshJob() {
- job = sut.find(job.getJobId()).get();
+ job = sut.find(job.getJob().getJobId().toString()).get();
+ }
+
+ private void refreshJob2() {
+ job2 = sut.find(job2.getJob().getJobId().toString()).get();
}
@Test
void shouldThrowExceptionWhenCreatingJob() throws BlobPersistenceException {
// Arrange
final var ex = new BlobPersistenceException("test", new RuntimeException());
- doThrow(ex).when(blobStoreSpy).putBlob(anyString(), any());
+ doThrow(ex).when(blobStoreSpy).putBlob(any(), any());
// Act
sut.create(job);
// Assert
- assertThat(sut.find(job.getJobId())).isEmpty();
+ assertThat(sut.find(job.getJob().getJobId().toString())).isEmpty();
+ }
+
+ @Test
+ void jobStateIsInProgress() {
+ sut.create(job);
+ sut.addTransferProcess(job.getJob().getJobId().toString(), processId1);
+ final Optional multiTransferJob = sut.get(job.getJob().getJobId().toString());
+ assertThat(multiTransferJob).isPresent();
+ assertThat(multiTransferJob.get().getJob().getJobState()).isEqualTo(JobState.RUNNING);
}
}
\ No newline at end of file
diff --git a/irs-api/src/test/java/net/catenax/irs/services/IrsItemGraphQueryServiceTest.java b/irs-api/src/test/java/net/catenax/irs/services/IrsItemGraphQueryServiceTest.java
index 11a33846be..a237bf07d0 100644
--- a/irs-api/src/test/java/net/catenax/irs/services/IrsItemGraphQueryServiceTest.java
+++ b/irs-api/src/test/java/net/catenax/irs/services/IrsItemGraphQueryServiceTest.java
@@ -4,7 +4,6 @@
import static net.catenax.irs.util.TestMother.registerJobWithoutDepth;
import static org.awaitility.Awaitility.await;
import static org.awaitility.Awaitility.given;
-//import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -12,13 +11,16 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Duration;
+import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import net.catenax.irs.TestConfig;
import net.catenax.irs.component.JobHandle;
import net.catenax.irs.component.RegisterJob;
-import net.catenax.irs.connector.job.JobState;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.JobErrorDetails;
+import net.catenax.irs.component.enums.JobState;
import net.catenax.irs.connector.job.JobStore;
import net.catenax.irs.connector.job.MultiTransferJob;
import net.catenax.irs.exceptions.EntityNotFoundException;
@@ -90,9 +92,16 @@ void getJobsByProcessingState() {
void cancelJobById() {
final String idAsString = String.valueOf(jobId);
final MultiTransferJob multiTransferJob = MultiTransferJob.builder()
- .jobId(idAsString)
- .state(JobState.UNSAVED)
- .errorDetail("Job should be canceled")
+ .job(Job.builder()
+ .jobId(UUID.fromString(idAsString))
+ .jobState(JobState.UNSAVED)
+ .exception(JobErrorDetails.builder()
+ .errorDetail(
+ "Job should be canceled")
+ .exceptionDate(
+ Instant.now())
+ .build())
+ .build())
.build();
jobStore.create(multiTransferJob);
@@ -100,7 +109,7 @@ void cancelJobById() {
assertNotNull(service.cancelJobById(jobId));
assertFalse(jobStore.find(idAsString).isEmpty());
- final JobState state = jobStore.find(idAsString).get().getState();
+ final JobState state = jobStore.find(idAsString).get().getJob().getJobState();
assertEquals(state, JobState.CANCELED);
}
diff --git a/irs-api/src/test/java/net/catenax/irs/util/TestMother.java b/irs-api/src/test/java/net/catenax/irs/util/TestMother.java
index 84fc6fa234..699f49e12d 100644
--- a/irs-api/src/test/java/net/catenax/irs/util/TestMother.java
+++ b/irs-api/src/test/java/net/catenax/irs/util/TestMother.java
@@ -1,5 +1,9 @@
package net.catenax.irs.util;
+import static net.catenax.irs.dtos.IrsCommonConstants.ROOT_ITEM_ID_KEY;
+
+import java.net.URL;
+import java.time.Instant;
import java.util.Map;
import java.util.UUID;
import java.util.stream.IntStream;
@@ -8,11 +12,13 @@
import com.github.javafaker.Faker;
import net.catenax.irs.component.RegisterJob;
import net.catenax.irs.connector.job.DataRequest;
-import net.catenax.irs.connector.job.JobState;
import net.catenax.irs.connector.job.MultiTransferJob;
import net.catenax.irs.connector.job.ResponseStatus;
import net.catenax.irs.connector.job.TransferInitiateResponse;
import net.catenax.irs.connector.job.TransferProcess;
+import net.catenax.irs.component.GlobalAssetIdentification;
+import net.catenax.irs.component.Job;
+import net.catenax.irs.component.enums.JobState;
/**
* Base object mother class to create objects for testing.
@@ -24,21 +30,29 @@ public class TestMother {
Faker faker = new Faker();
+ public Job fakeJob(JobState state) {
+ return Job.builder()
+ .jobId(UUID.randomUUID())
+ .globalAssetId(
+ GlobalAssetIdentification.builder().globalAssetId(UUID.randomUUID().toString()).build())
+ .jobState(state)
+ .createdOn(Instant.now())
+ .owner(faker.lorem().characters())
+ .lastModifiedOn(Instant.now())
+ .requestUrl(fakeURL())
+ .build();
+ }
+
public MultiTransferJob job() {
return job(faker.options().option(JobState.class));
}
public MultiTransferJob job(JobState jobState) {
return MultiTransferJob.builder()
- .jobId(faker.lorem().characters(36))
- .jobData(Map.of(
- faker.lorem().characters(),
- faker.lorem().characters(),
- faker.lorem().characters(),
- faker.lorem().characters()
- ))
- .state(jobState)
- .build();
+ .job(fakeJob(jobState))
+ .jobData(Map.of(ROOT_ITEM_ID_KEY, faker.lorem().characters(),
+ faker.lorem().characters(), faker.lorem().characters()))
+ .build();
}
public DataRequest dataRequest() {
@@ -66,6 +80,14 @@ public Stream dataRequests(int count) {
return IntStream.range(0, count).mapToObj(i -> dataRequest());
}
+ private URL fakeURL() {
+ try {
+ return new URL("http://localhost:8888/fake/url");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
public static RegisterJob registerJobWithoutDepth() {
return registerJobWithDepth(null);
}
diff --git a/irs-common/pom.xml b/irs-common/pom.xml
index 3cd209a782..4e0f82ce86 100644
--- a/irs-common/pom.xml
+++ b/irs-common/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
diff --git a/irs-common/src/main/java/net/catenax/irs/dtos/IrsCommonConstants.java b/irs-common/src/main/java/net/catenax/irs/dtos/IrsCommonConstants.java
new file mode 100644
index 0000000000..ef88cf351b
--- /dev/null
+++ b/irs-common/src/main/java/net/catenax/irs/dtos/IrsCommonConstants.java
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
+//
+// See the AUTHORS file(s) distributed with this work for additional
+// information regarding authorship.
+//
+// See the LICENSE file(s) distributed with this work for
+// additional information regarding license terms.
+//
+package net.catenax.irs.dtos;
+
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
+
+/**
+ * Common constant used in IRS
+ */
+@ExcludeFromCodeCoverageGeneratedReport
+public class IrsCommonConstants {
+ /**
+ * Job Data key for root item ID
+ */
+ public static final String ROOT_ITEM_ID_KEY = "root.item.id.key";
+
+ /**
+ * Expected depth of the tree
+ */
+ public static final String DEPTH_ID_KEY = "depth.id.key";
+
+}
diff --git a/irs-models/pom.xml b/irs-models/pom.xml
index d7e4d1c7f4..f08db14161 100644
--- a/irs-models/pom.xml
+++ b/irs-models/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
diff --git a/irs-models/src/main/java/net/catenax/irs/connector/annotations/ExcludeFromCodeCoverageGeneratedReport.java b/irs-models/src/main/java/net/catenax/irs/annotations/ExcludeFromCodeCoverageGeneratedReport.java
similarity index 88%
rename from irs-models/src/main/java/net/catenax/irs/connector/annotations/ExcludeFromCodeCoverageGeneratedReport.java
rename to irs-models/src/main/java/net/catenax/irs/annotations/ExcludeFromCodeCoverageGeneratedReport.java
index 9c4b99b0a7..b053e1d91a 100644
--- a/irs-models/src/main/java/net/catenax/irs/connector/annotations/ExcludeFromCodeCoverageGeneratedReport.java
+++ b/irs-models/src/main/java/net/catenax/irs/annotations/ExcludeFromCodeCoverageGeneratedReport.java
@@ -8,7 +8,7 @@
// additional information regarding license terms.
//
-package net.catenax.irs.connector.annotations;
+package net.catenax.irs.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -22,6 +22,6 @@
* the string "Generated" in its name.
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.TYPE})
+@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface ExcludeFromCodeCoverageGeneratedReport {
}
diff --git a/irs-models/src/main/java/net/catenax/irs/annotations/ValueOfEnum.java b/irs-models/src/main/java/net/catenax/irs/annotations/ValueOfEnum.java
index 0d68763b1a..61b0c8f722 100644
--- a/irs-models/src/main/java/net/catenax/irs/annotations/ValueOfEnum.java
+++ b/irs-models/src/main/java/net/catenax/irs/annotations/ValueOfEnum.java
@@ -9,22 +9,22 @@
//
package net.catenax.irs.annotations;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import net.catenax.irs.validators.ValueOfEnumValidator;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+import net.catenax.irs.validators.ValueOfEnumValidator;
/**
* Custom annotation to validate input for enum.
*/
-@Target({FIELD})
+@Target({ FIELD })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
@@ -32,7 +32,10 @@
@ExcludeFromCodeCoverageGeneratedReport
public @interface ValueOfEnum {
Class extends Enum>> enumClass();
+
String message() default "must be any of enum {enumClass}";
- Class>[] groups() default {};
- Class extends Payload>[] payload() default {};
+
+ Class>[] groups() default { };
+
+ Class extends Payload>[] payload() default { };
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/AsyncFetchedItems.java b/irs-models/src/main/java/net/catenax/irs/component/AsyncFetchedItems.java
index 5be0520577..30527a36af 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/AsyncFetchedItems.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/AsyncFetchedItems.java
@@ -42,7 +42,7 @@ public class AsyncFetchedItems {
* User to build async fetched items
*/
@Schema(description = "User to build async fetched items")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class AsyncFetchedItemsBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/ChildItem.java b/irs-models/src/main/java/net/catenax/irs/component/ChildItem.java
index 2a022eebfb..5a8abf93ec 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/ChildItem.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/ChildItem.java
@@ -49,7 +49,7 @@ public class ChildItem {
* Builder for ChildItem class
*/
@Schema(description = "Builder to to build child items")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class ChildItemBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/Description.java b/irs-models/src/main/java/net/catenax/irs/component/Description.java
index e168cec1eb..a0607cb665 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/Description.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/Description.java
@@ -38,7 +38,7 @@ public class Description {
/**
* Builder for Description class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class DescriptionBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/FilteredSubmodel.java b/irs-models/src/main/java/net/catenax/irs/component/FilteredSubmodel.java
index 66091f63cc..d2c7f708c0 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/FilteredSubmodel.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/FilteredSubmodel.java
@@ -35,7 +35,7 @@ public class FilteredSubmodel {
/**
* Builder for FilteredSubmodel class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class FilteredSubmodelBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/GenericDescription.java b/irs-models/src/main/java/net/catenax/irs/component/GenericDescription.java
index 224f80d1ca..897c5cd2f0 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/GenericDescription.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/GenericDescription.java
@@ -39,6 +39,4 @@ public class GenericDescription {
@Schema(description = "Description")
private List descriptions;
-
-
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/GlobalAssetIdentification.java b/irs-models/src/main/java/net/catenax/irs/component/GlobalAssetIdentification.java
index fd0d3df707..cf1a8647bc 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/GlobalAssetIdentification.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/GlobalAssetIdentification.java
@@ -24,31 +24,31 @@
* Global unique identifier for asset
*/
-
@Schema(description = "Represents a CatenaX id in the format urn:uuid:.")
@Value
-@Builder
+@Builder(toBuilder = true)
@JsonSerialize(using = ToStringSerializer.class)
-@JsonDeserialize(builder = GlobalAssetIdentification.GlobalAssetIdBuilder.class)
+@JsonDeserialize(builder = GlobalAssetIdentification.GlobalAssetIdentificationBuilder.class)
@ExcludeFromCodeCoverageGeneratedReport
public class GlobalAssetIdentification {
private static final int GLOBAL_ASSET_ID_LENGTH = 45;
-
@Valid
- @Schema(description = "Global unique C-X identifier.", example = "urn:uuid:6c311d29-5753-46d4-b32c-19b918ea93b0", minLength = GLOBAL_ASSET_ID_LENGTH, maxLength = GLOBAL_ASSET_ID_LENGTH)
+ @Schema(description = "Global unique C-X identifier.", example = "urn:uuid:6c311d29-5753-46d4-b32c-19b918ea93b0",
+ minLength = GLOBAL_ASSET_ID_LENGTH, maxLength = GLOBAL_ASSET_ID_LENGTH)
private String globalAssetId;
+ @Override
+ public String toString() {
+ return globalAssetId;
+ }
+
/**
* Builder for GlobalAssetIdBuilder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
- public static class GlobalAssetIdBuilder {
+ @JsonPOJOBuilder(withPrefix = "")
+ public static class GlobalAssetIdentificationBuilder {
}
- @Override
- public String toString() {
- return globalAssetId;
- }
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/IrsPartRelationshipsWithInfos.java b/irs-models/src/main/java/net/catenax/irs/component/IrsPartRelationshipsWithInfos.java
index ed02b4f34a..fad47cbe78 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/IrsPartRelationshipsWithInfos.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/IrsPartRelationshipsWithInfos.java
@@ -48,7 +48,7 @@ public class IrsPartRelationshipsWithInfos {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class IrsPartRelationshipsWithInfosBuilder {
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/Job.java b/irs-models/src/main/java/net/catenax/irs/component/Job.java
index 3682b26766..8e72e91c4d 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/Job.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/Job.java
@@ -20,6 +20,7 @@
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
+import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -47,7 +48,7 @@ public class Job {
@Size(min = INPUT_FIELD_MIN_LENGTH, max = JOB_ID_FIELD_MAX_LENGTH)
@Schema(description = "Job ID for the requested item.", minLength = INPUT_FIELD_MIN_LENGTH,
maxLength = JOB_ID_FIELD_MAX_LENGTH, implementation = UUID.class)
- private final UUID jobId;
+ private UUID jobId;
/**
* globalAssetId
@@ -56,14 +57,15 @@ public class Job {
@Size(min = INPUT_FIELD_MIN_LENGTH, max = JOB_ID_FIELD_MAX_LENGTH)
@Schema(description = "Part global unique Id", minLength = INPUT_FIELD_MIN_LENGTH,
maxLength = JOB_ID_FIELD_MAX_LENGTH, implementation = GlobalAssetIdentification.class)
- private final GlobalAssetIdentification globalAssetId;
+ @JsonUnwrapped
+ private GlobalAssetIdentification globalAssetId;
@NotBlank
@Schema()
private JobState jobState;
- @Schema(description = "Exception state for this job.", implementation = JobException.class)
- private JobException exception;
+ @Schema(description = "Exception state for this job.", implementation = JobErrorDetails.class)
+ private JobErrorDetails exception;
/**
* Timestamp when the job was created
@@ -117,7 +119,7 @@ public class Job {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class JobBuilder {
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/JobErrorDetails.java b/irs-models/src/main/java/net/catenax/irs/component/JobErrorDetails.java
new file mode 100644
index 0000000000..02d44473ca
--- /dev/null
+++ b/irs-models/src/main/java/net/catenax/irs/component/JobErrorDetails.java
@@ -0,0 +1,98 @@
+//
+// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
+//
+// See the AUTHORS file(s) distributed with this work for additional
+// information regarding authorship.
+//
+// See the LICENSE file(s) distributed with this work for
+// additional information regarding license terms.
+//
+package net.catenax.irs.component;
+
+import java.time.Instant;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
+
+/**
+ * Exception container for job
+ */
+@Getter
+@Setter
+@Builder(toBuilder = true)
+@JsonDeserialize(builder = JobErrorDetails.JobErrorDetailsBuilder.class)
+@NoArgsConstructor
+@AllArgsConstructor
+@SuppressWarnings({ "PMD.ShortClassName", "PMD.MethodArgumentCouldBeFinal" })
+@ExcludeFromCodeCoverageGeneratedReport
+public class JobErrorDetails {
+
+ public static final int EXCEPTION_NAME_MAX_LENGTH = 100;
+ public static final int ERROR_DETAIL_MAX_LENGTH = 4000;
+
+ @Schema(description = "Name of the exception occurred.", implementation = String.class,
+ maxLength = EXCEPTION_NAME_MAX_LENGTH)
+ private String exception;
+
+ @Schema(description = "Detail information for the error occurred.", implementation = String.class,
+ maxLength = ERROR_DETAIL_MAX_LENGTH)
+ private String errorDetail;
+
+ @Schema(description = "Datetime when error occurred.", implementation = Instant.class)
+ private Instant exceptionDate;
+
+ @Override
+ public String toString() {
+ return "JobErrorDetails{" + "exception='" + exception + '\''
+ + ", errorDetail='" + errorDetail + '\''
+ + ", exceptionDate=" + exceptionDate
+ + '}';
+ }
+
+ /**
+ * Builder class
+ */
+ @JsonPOJOBuilder(withPrefix = "")
+ public static final class JobErrorDetailsBuilder {
+
+ private final JobErrorDetails errorDetails;
+
+ private JobErrorDetailsBuilder() {
+ errorDetails = new JobErrorDetails();
+ }
+
+ @JsonCreator
+ public static JobErrorDetailsBuilder instance() {
+ return new JobErrorDetailsBuilder();
+ }
+
+ public JobErrorDetailsBuilder exception(String exception) {
+ errorDetails.exception = exception;
+ return this;
+ }
+
+ public JobErrorDetailsBuilder errorDetail(String errorDetail) {
+ errorDetails.errorDetail = errorDetail;
+ return this;
+ }
+
+ public JobErrorDetailsBuilder exceptionDate(Instant exceptionDate) {
+ errorDetails.exceptionDate = exceptionDate;
+ return this;
+ }
+
+ public JobErrorDetails build() {
+ return this.errorDetails;
+ }
+
+ }
+
+}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/JobException.java b/irs-models/src/main/java/net/catenax/irs/component/JobException.java
deleted file mode 100644
index 91ba6bda19..0000000000
--- a/irs-models/src/main/java/net/catenax/irs/component/JobException.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) 2021 Copyright Holder (Catena-X Consortium)
-//
-// See the AUTHORS file(s) distributed with this work for additional
-// information regarding authorship.
-//
-// See the LICENSE file(s) distributed with this work for
-// additional information regarding license terms.
-//
-package net.catenax.irs.component;
-
-import java.time.Instant;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Value;
-import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
-
-/**
- * Exception container for job
- */
-@Value
-@Builder(toBuilder = true)
-@JsonDeserialize(builder = JobException.JobExceptionBuilder.class)
-@AllArgsConstructor
-@SuppressWarnings("PMD.ShortClassName")
-@ExcludeFromCodeCoverageGeneratedReport
-public class JobException {
-
- public static final int EXCEPTION_NAME_MAX_LENGTH = 100;
- public static final int ERROR_DETAIL_MAX_LENGTH = 4000;
-
- @Schema(description = "Name of the exception occurred.", implementation = String.class, maxLength = EXCEPTION_NAME_MAX_LENGTH)
- private String exception;
-
- @Schema(description = "Detail information for the error occurred.", implementation = String.class, maxLength = ERROR_DETAIL_MAX_LENGTH)
- private String errorDetail;
-
- @Schema(description = "Datetime when error occurred.", implementation = Instant.class)
- private Instant exceptionDate;
-
- /**
- * Builder class
- */
- @JsonPOJOBuilder(withPrefix = "with")
- public static class JobExceptionBuilder {
- }
-
-}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/Jobs.java b/irs-models/src/main/java/net/catenax/irs/component/Jobs.java
index 543d972dfc..551ba3e21c 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/Jobs.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/Jobs.java
@@ -45,7 +45,7 @@ public class Jobs {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class JobsBuilder {
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/QueryParameter.java b/irs-models/src/main/java/net/catenax/irs/component/QueryParameter.java
index 224073daff..033b4ab68b 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/QueryParameter.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/QueryParameter.java
@@ -52,7 +52,7 @@ public class QueryParameter {
* Builder for QueryParameter class
*/
@Schema(description = "Builder to to build query parameters")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class QueryParameterBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/SemanticId.java b/irs-models/src/main/java/net/catenax/irs/component/SemanticId.java
index 3d20ae0002..43d08d9c33 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/SemanticId.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/SemanticId.java
@@ -38,7 +38,7 @@ public class SemanticId {
* User to build SemanticId
*/
@Schema(description = "User to build async fetched items")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class SemanticIdBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/Shell.java b/irs-models/src/main/java/net/catenax/irs/component/Shell.java
index 00137f30b9..0629523320 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/Shell.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/Shell.java
@@ -58,7 +58,7 @@ public class Shell {
* User to build Shell
*/
@Schema(description = "User to build shell items")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class ShellBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/SubmodelDescriptor.java b/irs-models/src/main/java/net/catenax/irs/component/SubmodelDescriptor.java
index c00552b477..e37d8506f6 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/SubmodelDescriptor.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/SubmodelDescriptor.java
@@ -51,7 +51,7 @@ public class SubmodelDescriptor {
* User to build SubmodelDescriptor
*/
@Schema(description = "User to build async fetched items")
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class SubmodelDescriptorBuilder {
}
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/Summary.java b/irs-models/src/main/java/net/catenax/irs/component/Summary.java
index 19594d0506..a429a6a783 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/Summary.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/Summary.java
@@ -35,7 +35,7 @@ public class Summary {
/**
* Builder class
*/
- @JsonPOJOBuilder(withPrefix = "with")
+ @JsonPOJOBuilder(withPrefix = "")
public static class SummaryBuilder {
}
diff --git a/irs-models/src/main/java/net/catenax/irs/component/enums/Direction.java b/irs-models/src/main/java/net/catenax/irs/component/enums/Direction.java
index 59b143233c..d38f2c4e3e 100644
--- a/irs-models/src/main/java/net/catenax/irs/component/enums/Direction.java
+++ b/irs-models/src/main/java/net/catenax/irs/component/enums/Direction.java
@@ -21,8 +21,8 @@
@Schema(description = "Direction in which the tree shall be traversed.")
@ExcludeFromCodeCoverageGeneratedReport
public enum Direction {
- //@Schema(description = "The tree is traversed in upward direction.") UPWARD("upward"),
- @Schema(description = "The tree is traversed in downward direction.") DOWNWARD(DirectionConstants.DOWNWARD);
+ //@Schema(description = "The tree is traversed in upward direction.") UPWARD("upward"),
+ @Schema(description = "The tree is traversed in downward direction.") DOWNWARD(DirectionConstants.DOWNWARD);
private final String value;
diff --git a/irs-models/src/main/java/net/catenax/irs/dtos/ErrorResponse.java b/irs-models/src/main/java/net/catenax/irs/dtos/ErrorResponse.java
index d6322eeaba..b4758b8191 100644
--- a/irs-models/src/main/java/net/catenax/irs/dtos/ErrorResponse.java
+++ b/irs-models/src/main/java/net/catenax/irs/dtos/ErrorResponse.java
@@ -9,6 +9,8 @@
//
package net.catenax.irs.dtos;
+import java.util.List;
+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -16,8 +18,6 @@
import lombok.Value;
import org.springframework.http.HttpStatus;
-import java.util.List;
-
/*** API error response. */
@Schema(description = "Error response.")
@Value
diff --git a/irs-models/src/main/java/net/catenax/irs/dtos/ItemLifecycleStage.java b/irs-models/src/main/java/net/catenax/irs/dtos/ItemLifecycleStage.java
index 5e69f6d9f7..55d76bc693 100644
--- a/irs-models/src/main/java/net/catenax/irs/dtos/ItemLifecycleStage.java
+++ b/irs-models/src/main/java/net/catenax/irs/dtos/ItemLifecycleStage.java
@@ -22,9 +22,7 @@
@Schema(description = "Stage defining whether changes apply to the AS_BUILT or AS_MAINTAINED BOM views.")
@SuppressWarnings("PMD.CommentRequired")
public enum ItemLifecycleStage {
- @Schema(description = "The time the part is built.")
- BUILD,
+ @Schema(description = "The time the part is built.") BUILD,
- @Schema(description = "The time after the part is built.")
- MAINTENANCE
+ @Schema(description = "The time after the part is built.") MAINTENANCE
}
diff --git a/irs-models/src/main/java/net/catenax/irs/dtos/ItemsTreeView.java b/irs-models/src/main/java/net/catenax/irs/dtos/ItemsTreeView.java
index 2212e213ca..22189ac3da 100644
--- a/irs-models/src/main/java/net/catenax/irs/dtos/ItemsTreeView.java
+++ b/irs-models/src/main/java/net/catenax/irs/dtos/ItemsTreeView.java
@@ -20,9 +20,7 @@
@ExcludeFromCodeCoverageGeneratedReport
@Schema(description = "View defining which data of the PartsTree is retrieved.")
public enum ItemsTreeView {
- @Schema(description = "The view of the PartsTree as the vehicle was assembled.")
- AS_BUILT,
+ @Schema(description = "The view of the PartsTree as the vehicle was assembled.") AS_BUILT,
- @Schema(description = "The view of the PartsTree that accounts for all updates during the vehicle lifecycle.")
- AS_MAINTAINED
+ @Schema(description = "The view of the PartsTree that accounts for all updates during the vehicle lifecycle.") AS_MAINTAINED
}
diff --git a/irs-models/src/main/java/net/catenax/irs/validators/ValueOfEnumValidator.java b/irs-models/src/main/java/net/catenax/irs/validators/ValueOfEnumValidator.java
index b96f33731a..d3ad26f2bb 100644
--- a/irs-models/src/main/java/net/catenax/irs/validators/ValueOfEnumValidator.java
+++ b/irs-models/src/main/java/net/catenax/irs/validators/ValueOfEnumValidator.java
@@ -9,21 +9,22 @@
//
package net.catenax.irs.validators;
-import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
-import net.catenax.irs.annotations.ValueOfEnum;
-
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+import net.catenax.irs.annotations.ExcludeFromCodeCoverageGeneratedReport;
+import net.catenax.irs.annotations.ValueOfEnum;
+
/**
* Generic validator for Enum values.
* This validator was added so that we can use String data type in place of Enum for API input request object. As spring BindException details are not that user-friendly when mapping an input which is not value of the Enum.
*/
@ExcludeFromCodeCoverageGeneratedReport
-@SuppressWarnings({"PMD.CommentSize", "PMD.BeanMembersShouldSerialize"})
+@SuppressWarnings({ "PMD.CommentSize", "PMD.BeanMembersShouldSerialize" })
public class ValueOfEnumValidator implements ConstraintValidator {
/**
@@ -34,8 +35,8 @@ public class ValueOfEnumValidator implements ConstraintValidator
-
+
4.0.0
net.catenax.irs
@@ -12,7 +13,6 @@
irs-testing
- connector
irs-api
irs-common
irs-models