diff --git a/.config/checkstyle.xml b/.config/checkstyle.xml
index 36317a0e73..4770219683 100644
--- a/.config/checkstyle.xml
+++ b/.config/checkstyle.xml
@@ -249,7 +249,9 @@ page at http://checkstyle.sourceforge.net/config.html -->
-
+
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2d2022cfd..2a6d85254c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,10 +9,9 @@ _**For better traceability add the corresponding GitHub issue number in each cha
## [Unreleased]
### Changed
-- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService return existing resource if it exists in
- EDC
+- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService return existing resource if it exists in EDC
- Added AssetAdministrationShellDescriptor specificAssetIds support for externalSubjectId required for data provisioning
-
+- Registering a job - aspects array is now accepting full urn of aspect model instead of name only, eg. 'urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt' instead 'SingleLevelBomAsBuilt'. #439
## [4.7.0] - 2024-03-04
### Added
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 1893f87a66..d29917d525 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -62,6 +62,7 @@ maven/mavencentral/com.typesafe.akka/akka-slf4j_2.13/2.6.20, Apache-2.0, approve
maven/mavencentral/com.typesafe.scala-logging/scala-logging_2.13/3.9.5, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.typesafe/config/1.4.2, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.vaadin.external.google/android-json/0.0.20131108.vaadin1, Apache-2.0, approved, CQ21310
+maven/mavencentral/com.vdurmont/semver4j/3.1.0, MIT, approved, clearlydefined
maven/mavencentral/commons-beanutils/commons-beanutils/1.9.4, Apache-2.0, approved, CQ12654
maven/mavencentral/commons-codec/commons-codec/1.15, Apache-2.0 AND BSD-3-Clause AND LicenseRef-Public-Domain, approved, CQ22641
maven/mavencentral/commons-collections/commons-collections/3.2.2, Apache-2.0, approved, CQ10385
@@ -436,7 +437,6 @@ maven/mavencentral/org.springframework.boot/spring-boot-starter-json/3.1.9, Apac
maven/mavencentral/org.springframework.boot/spring-boot-starter-log4j2/3.1.9, Apache-2.0, approved, #8800
maven/mavencentral/org.springframework.boot/spring-boot-starter-logging/3.1.9, Apache-2.0, approved, #9343
maven/mavencentral/org.springframework.boot/spring-boot-starter-oauth2-client/3.1.9, Apache-2.0, approved, #8806
-maven/mavencentral/org.springframework.boot/spring-boot-starter-oauth2-resource-server/3.1.9, Apache-2.0, approved, #8804
maven/mavencentral/org.springframework.boot/spring-boot-starter-security/3.1.9, Apache-2.0, approved, #9337
maven/mavencentral/org.springframework.boot/spring-boot-starter-test/3.1.9, Apache-2.0, approved, #9353
maven/mavencentral/org.springframework.boot/spring-boot-starter-tomcat/3.1.9, Apache-2.0, approved, #9351
@@ -453,7 +453,6 @@ maven/mavencentral/org.springframework.security/spring-security-crypto/6.1.7, Ap
maven/mavencentral/org.springframework.security/spring-security-oauth2-client/6.1.7, Apache-2.0, approved, #9740
maven/mavencentral/org.springframework.security/spring-security-oauth2-core/6.1.7, Apache-2.0, approved, #9741
maven/mavencentral/org.springframework.security/spring-security-oauth2-jose/6.1.7, Apache-2.0, approved, #9345
-maven/mavencentral/org.springframework.security/spring-security-oauth2-resource-server/6.1.7, Apache-2.0, approved, #8798
maven/mavencentral/org.springframework.security/spring-security-test/6.1.7, Apache-2.0, approved, #10674
maven/mavencentral/org.springframework.security/spring-security-web/6.1.7, Apache-2.0, approved, #9800
maven/mavencentral/org.springframework/spring-aop/6.0.17, Apache-2.0, approved, #5940
diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml
index 3d360986dd..f44c23df41 100644
--- a/docs/src/api/irs-api.yaml
+++ b/docs/src/api/irs-api.yaml
@@ -3,7 +3,7 @@ info:
description: The API of the Item Relationship Service (IRS) for retrieving item
graphs along the value chain of CATENA-X partners.
title: IRS API
- version: "4.7.0"
+ version: 4.7.0
servers:
- url: http://localhost:8080
security:
@@ -994,8 +994,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1045,8 +1045,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1127,7 +1127,7 @@ components:
semanticId:
keys:
- type: Submodel
- value: urn:bamm:com.catenax.vehicle:0.1.1#PartDetails
+ value: urn:bamm:io.catenax.vehicle:0.1.1#PartDetails
type: ModelReference
submodels:
- aspectType: supply_chain_impacted
@@ -1171,8 +1171,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1250,10 +1250,10 @@ components:
semanticId:
keys:
- type: Submodel
- value: urn:bamm:com.catenax.vehicle:0.1.1#PartDetails
+ value: urn:bamm:io.catenax.vehicle:0.1.1#PartDetails
type: ModelReference
submodels:
- - aspectType: urn:bamm:io.catenax.single_level_bom_as_built:1.0.0
+ - aspectType: urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
contractAgreementId: f253718e-a270-4367-901b-9d50d9bd8462
identification: urn:uuid:fc784d2a-5506-4e61-8e34-21600f8cdeff
payload:
@@ -1325,8 +1325,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1363,8 +1363,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1441,9 +1441,9 @@ components:
type: ModelReference
keys:
- type: Submodel
- value: urn:bamm:com.catenax.vehicle:0.1.1#PartDetails
+ value: urn:bamm:io.catenax.vehicle:0.1.1#PartDetails
submodels:
- - aspectType: urn:bamm:io.catenax.single_level_bom_as_built:1.0.0
+ - aspectType: urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
contractAgreementId: f253718e-a270-4367-901b-9d50d9bd8462
identification: urn:uuid:fc784d2a-5506-4e61-8e34-21600f8cdeff
payload:
@@ -1481,8 +1481,8 @@ components:
lastModifiedOn: 2022-02-03T14:48:54.709Z
parameter:
aspects:
- - SerialPart
- - AddressAspect
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
+ - urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
auditContractNegotiation: false
bomLifecycle: asBuilt
collectAspects: false
@@ -1503,16 +1503,16 @@ components:
value:
lastUpdated: 2023-02-13T08:18:11.990659500Z
models:
- - urn: urn:bamm:io.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt
+ - urn: urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
name: SingleLevelBomAsBuilt
status: RELEASED
type: BAMM
- version: 1.0.0
- - urn: urn:bamm:io.catenax.serial_part:1.0.0#SerialPart
+ version: 2.0.0
+ - urn: urn:bamm:io.catenax.serial_part:1.0.1#SerialPart
name: SerialPart
status: RELEASED
type: BAMM
- version: 1.0.0
+ version: 1.0.1
schemas:
AdministrativeInformation:
type: object
@@ -2367,9 +2367,15 @@ components:
properties:
aspects:
type: array
+ description: List of aspect names that will be collected if \
+ flag is set to true.
+ example:
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
items:
type: string
+ pattern: ^(urn:[bs]amm:.*\d\.\d\.\d)?(#)?(\w+)?$
maxItems: 2147483647
+ pattern: ^(urn:[bs]amm:.*\d\.\d\.\d)?(#)?(\w+)?$
batchSize:
type: integer
format: int32
@@ -2511,7 +2517,6 @@ components:
description: The requested job definition.
properties:
bomLifecycle:
- example: asPlanned
type: string
description: The lifecycle context in which the child part was assembled
into the parent part.
@@ -2519,6 +2524,7 @@ components:
- asBuilt
- asPlanned
- asSpecified
+ example: asPlanned
callbackUrl:
type: string
description: "Callback url to notify requestor when job processing is finished.\
@@ -2529,10 +2535,14 @@ components:
$ref: '#/components/schemas/PartChainIdentificationKey'
incidentBPNSs:
type: array
+ description: Array of BPNS numbers.
+ example:
+ - BPNS000000000DDD
items:
type: string
pattern: "(BPN)[LSA][\\w\\d]{10}[\\w\\d]{2}"
maxItems: 2147483647
+ pattern: "(BPN)[LSA][\\w\\d]{10}[\\w\\d]{2}"
required:
- incidentBPNSs
- key
@@ -2545,9 +2555,13 @@ components:
type: array
description: List of aspect names that will be collected if \
flag is set to true.
+ example:
+ - urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt
items:
type: string
+ pattern: ^(urn:[bs]amm:.*\d\.\d\.\d)?(#)?(\w+)?$
maxItems: 2147483647
+ pattern: ^(urn:[bs]amm:.*\d\.\d\.\d)?(#)?(\w+)?$
auditContractNegotiation:
type: boolean
description: Flag enables and disables auditing, including provisioning
diff --git a/docs/src/uml-diagrams/cross-cutting/json-response-model.puml b/docs/src/uml-diagrams/cross-cutting/json-response-model.puml
index c3978b9bfa..dda48e443b 100644
--- a/docs/src/uml-diagrams/cross-cutting/json-response-model.puml
+++ b/docs/src/uml-diagrams/cross-cutting/json-response-model.puml
@@ -108,7 +108,7 @@ skinparam shadowing false
"identification": "dae4d249-6d66-4818-b576-bf52f3b9ae90",
"semanticId": {
"value": [
- "urn:bamm:com.catenax.vehicle:0.1.1#PartDetails"
+ "urn:bamm:io.catenax.vehicle:0.1.1#PartDetails"
]
},
"endpoints": [
diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/OpenApiExamples.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/OpenApiExamples.java
index 2e04d95ba3..38d65986ec 100644
--- a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/OpenApiExamples.java
+++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/OpenApiExamples.java
@@ -60,7 +60,6 @@
import org.eclipse.tractusx.irs.component.assetadministrationshell.Reference;
import org.eclipse.tractusx.irs.component.assetadministrationshell.SemanticId;
import org.eclipse.tractusx.irs.component.assetadministrationshell.SubmodelDescriptor;
-import org.eclipse.tractusx.irs.component.enums.AspectType;
import org.eclipse.tractusx.irs.component.enums.BomLifecycle;
import org.eclipse.tractusx.irs.component.enums.Direction;
import org.eclipse.tractusx.irs.component.enums.JobState;
@@ -92,6 +91,8 @@ public class OpenApiExamples {
private static final String SUPPLY_CHAIN_IMPACTED_ASPECT_TYPE = "supply_chain_impacted";
private static final String SUPPLY_CHAIN_IMPACTED_KEY = "supplyChainImpacted";
private static final String SUPPLY_CHAIN_IMPACTER_RESULT = "YES";
+ private static final String SINGLE_LEVEL_BOM_AS_BUILT_ASPECT = "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt";
+ private static final String SERIAL_PART_ASPECT = "urn:bamm:io.catenax.serial_part:1.0.1#SerialPart";
private static final int FETCHED_ITEMS_SIZE = 3;
private static final int NO_RUNNING_OR_FAILED_ITEMS = 0;
private static final int SENT_NOTIFICATIONS_SIZE = 6;
@@ -136,15 +137,15 @@ public void createExamples(final Components components) {
private Example createAspectModelsResult() {
final AspectModel assemblyPartRelationship = AspectModel.builder()
.name("SingleLevelBomAsBuilt")
- .urn("urn:bamm:io.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt")
- .version("1.0.0")
+ .urn(SINGLE_LEVEL_BOM_AS_BUILT_ASPECT)
+ .version("2.0.0")
.status("RELEASED")
.type("BAMM")
.build();
final AspectModel serialPart = AspectModel.builder()
.name("SerialPart")
- .urn("urn:bamm:io.catenax.serial_part:1.0.0#SerialPart")
- .version("1.0.0")
+ .urn(SERIAL_PART_ASPECT)
+ .version("1.0.1")
.status("RELEASED")
.type("BAMM")
.build();
@@ -207,7 +208,7 @@ private JobParameter createJobParameter() {
return JobParameter.builder()
.bomLifecycle(BomLifecycle.AS_BUILT)
.depth(1)
- .aspects(List.of(AspectType.SERIAL_PART.toString(), AspectType.ADDRESS_ASPECT.toString()))
+ .aspects(List.of(SINGLE_LEVEL_BOM_AS_BUILT_ASPECT, SERIAL_PART_ASPECT))
.direction(Direction.DOWNWARD)
.collectAspects(false)
.build();
@@ -345,20 +346,20 @@ private Example createCanceledJobResponse() {
private Submodel createSubmodel() {
return Submodel.builder()
.contractAgreementId(EXAMPLE_ID)
- .aspectType("urn:bamm:io.catenax.single_level_bom_as_built:1.0.0")
+ .aspectType(SINGLE_LEVEL_BOM_AS_BUILT_ASPECT)
.identification(SUBMODEL_IDENTIFICATION)
- .payload(createAssemblyPartRelationshipPayloadMap())
+ .payload(createSingleLevelBomAsBuiltPayloadMap())
.build();
}
- private Map createAssemblyPartRelationshipPayloadMap() {
- final String assemblyPartRelationshipPayload =
+ private Map createSingleLevelBomAsBuiltPayloadMap() {
+ final String singleLevelBomAsBuiltPayload =
"{\"catenaXId\": \"urn:uuid:d9bec1c6-e47c-4d18-ba41-0a5fe8b7f447\", "
+ "\"childItems\": [ { \"createdOn\": \"2022-02-03T14:48:54.709Z\", \"catenaXId\": \"urn:uuid:d9bec1c6-e47c-4d18-ba41-0a5fe8b7f447\", "
+ "\"lastModifiedOn\": \"2022-02-03T14:48:54.709Z\", \"lifecycleContext\": \"AsBuilt\", \"quantity\": "
+ "{\"measurementUnit\": {\"datatypeURI\": \"urn:bamm:io.openmanufacturing:meta-model:1.0.0#piece\",\"lexicalValue\": \"piece\"},\"quantityNumber\": 1}}]}";
- return new JsonUtil().fromString(assemblyPartRelationshipPayload, Map.class);
+ return new JsonUtil().fromString(singleLevelBomAsBuiltPayload, Map.class);
}
private Tombstone createTombstone() {
@@ -468,7 +469,7 @@ private SubmodelDescriptor createPartSubmodelDescriptor() {
.semanticId(Reference.builder()
.keys(List.of(SemanticId.builder()
.type("Submodel")
- .value("urn:bamm:com.catenax.vehicle:0.1.1#PartDetails")
+ .value("urn:bamm:io.catenax.vehicle:0.1.1#PartDetails")
.build()))
.type("ModelReference")
.build())
diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/semanticshub/SemanticsHubClient.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/semanticshub/SemanticsHubClient.java
index 9bfb528a7a..c284e3a68e 100644
--- a/irs-api/src/main/java/org/eclipse/tractusx/irs/semanticshub/SemanticsHubClient.java
+++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/semanticshub/SemanticsHubClient.java
@@ -92,10 +92,10 @@ public List getAllAspectModels() {
return List.of(
new AspectModel("urn:bamm:io.catenax.serial_part:1.0.1#SerialPart", "1.0.1",
"SerialPart", MODEL_TYPE, MODEL_STATUS),
- new AspectModel("urn:bamm:com.catenax.esr_certificates.esr_certificate:1.0.0#EsrCertificate", "1.0.0",
+ new AspectModel("urn:bamm:io.catenax.esr_certificates.esr_certificate:1.0.0#EsrCertificate", "1.0.0",
"EsrCertificate", MODEL_TYPE, MODEL_STATUS),
- new AspectModel("urn:bamm:io.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt",
- "1.0.0", "SingleLevelBomAsBuilt", MODEL_TYPE, MODEL_STATUS),
+ new AspectModel("urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt",
+ "2.0.0", "SingleLevelBomAsBuilt", MODEL_TYPE, MODEL_STATUS),
new AspectModel("urn:bamm:io.catenax.part_as_specified:2.0.0#PartAsSpecified",
"2.0.0", "PartAsSpecified", MODEL_TYPE, MODEL_STATUS),
new AspectModel("urn:bamm:io.catenax.part_as_planned:1.0.1#PartAsPlanned",
diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java
index c8510d6849..498d3f09eb 100644
--- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java
+++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java
@@ -198,14 +198,12 @@ private void validateAspectTypeValues(final List aspectTypeValues) {
semanticsHubFacade.getAllAspectModels().models());
log.debug("Number of available AspectModels: '{}'", availableModels.size());
log.debug("Provided AspectModels: '{}'", aspectTypeValues);
- final Set availableNames = new HashSet<>(availableModels.stream().map(AspectModel::name).toList());
final Set availableUrns = new HashSet<>(availableModels.stream().map(AspectModel::urn).toList());
final List invalidAspectTypes = aspectTypeValues.stream()
.filter(s -> !availableUrns.contains(s)
- && !availableNames.contains(s)
|| !s.matches(
- "^(urn:bamm:.*\\d\\.\\d\\.\\d)?(#)?(\\w+)?$"))
+ "^(urn:[bs]amm:.*\\d\\.\\d\\.\\d)?(#)?(\\w+)?$"))
.toList();
if (!invalidAspectTypes.isEmpty()) {
throw new IllegalArgumentException(
@@ -287,7 +285,7 @@ public Jobs getJobForJobId(final MultiTransferJob multiJob, final boolean includ
public void updateJobsInJobStoreMetrics() {
final List jobs = jobStore.findAll();
final long numberOfJobs = jobs.size();
- log.debug("Number(s) of job in JobStore: {}", numberOfJobs);
+ log.trace("Number(s) of job in JobStore: {}", numberOfJobs);
meterRegistryService.setNumberOfJobsInJobStore(numberOfJobs);
final Map stateCount = jobs.stream()
diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/MeterRegistryService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/MeterRegistryService.java
index 8b5cd0b963..b53c39e590 100644
--- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/MeterRegistryService.java
+++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/MeterRegistryService.java
@@ -169,7 +169,7 @@ public void recordJobStateMetric(final JobState state) {
public void setNumberOfJobsInJobStore(final Long size) {
this.numbersOfJobsInJobStore.set(size);
- log.debug("Current size of Job in JobStore is {}", size);
+ log.trace("Current size of Job in JobStore is {}", size);
}
public void setMeasuredMethodExecutionTime(final String tag, final long duration) {
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java
index 5595090752..04d6bddfc3 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java
@@ -40,6 +40,8 @@
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.RegisterJob;
import org.eclipse.tractusx.irs.component.enums.JobState;
+import org.eclipse.tractusx.irs.configuration.security.ApiKeyAuthentication;
+import org.eclipse.tractusx.irs.configuration.security.ApiKeyAuthority;
import org.eclipse.tractusx.irs.controllers.IrsController;
import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService;
import org.eclipse.tractusx.irs.testing.containers.MinioContainer;
@@ -58,7 +60,6 @@
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.support.TestPropertySourceUtils;
@@ -100,7 +101,7 @@ void shouldStartJobAndRetrieveResult() {
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("http://localhost/discovery"));
- thereIsJwtAuthentication();
+ thereIsAuthentication();
final JobHandle jobHandle = controller.registerJobForGlobalAssetId(registerJob);
final Optional finishedJob = Awaitility.await()
@@ -130,7 +131,7 @@ void shouldFillSummaryWithoutBPNLookup() {
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("http://localhost/discovery"));
- thereIsJwtAuthentication();
+ thereIsAuthentication();
final JobHandle jobHandle = controller.registerJobForGlobalAssetId(registerJob);
final Optional finishedJob = Awaitility.await()
@@ -156,7 +157,7 @@ void shouldFillSummaryWithBPNLookup() {
final RegisterJob registerJob = TestMother.registerJobWithLookupBPNs();
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("http://localhost/discovery"));
- thereIsJwtAuthentication();
+ thereIsAuthentication();
final JobHandle jobHandle = controller.registerJobForGlobalAssetId(registerJob);
final Optional finishedJob = Awaitility.await()
@@ -177,28 +178,22 @@ void shouldFillSummaryWithBPNLookup() {
assertThat(finishedJob.get().getJob().getSummary().getBpnLookups().getFailed()).isZero();
}
- private void thereIsJwtAuthentication() {
- final JwtAuthenticationToken jwtAuthenticationToken = new JwtAuthenticationToken(jwt(),
- List.of(new SimpleGrantedAuthority(IrsRoles.VIEW_IRS)));
+ private void thereIsAuthentication() {
+ final ApiKeyAuthentication jwtAuthenticationToken = new ApiKeyAuthentication(new
+ ApiKeyAuthority("apiKey", List.of(new SimpleGrantedAuthority(IrsRoles.VIEW_IRS))));
jwtAuthenticationToken.setAuthenticated(true);
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
when(securityContext.getAuthentication()).thenReturn(jwtAuthenticationToken);
SecurityContextHolder.setContext(securityContext);
}
- Jwt jwt() {
- return new Jwt("token", Instant.now(), Instant.now().plusSeconds(30), Map.of("alg", "none"),
- Map.of(SUB, "sub", "clientId", "clientId", "bpn", "BPNL00000001CRHK"));
- }
-
@NotNull
private Callable> getJobDetails(final JobHandle jobHandle) {
return () -> {
try {
- thereIsJwtAuthentication();
+ thereIsAuthentication();
return Optional.ofNullable(controller.getJobById(jobHandle.getId(), true).getBody());
} catch (Exception e) {
- e.printStackTrace();
return Optional.empty();
}
};
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java
index 2d9a98bdf6..185d74a8b4 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java
@@ -44,6 +44,7 @@
import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockSupport.PATH_NEGOTIATE;
import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockSupport.PATH_STATE;
import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockSupport.PATH_TRANSFER;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
import java.time.Duration;
import java.util.List;
@@ -150,7 +151,7 @@ void shouldStartApplicationAndCollectSemanticModels() throws SchemaNotFoundExcep
final AspectModels allAspectModels = semanticHubService.getAllAspectModels();
// Assert
- assertThat(allAspectModels.models()).hasSize(78);
+ assertThat(allAspectModels.models()).hasSize(79);
}
@Test
@@ -288,7 +289,7 @@ private void successfulRegistryAndDataRequest(final String globalAssetId, final
"urn:samm:io.catenax.batch:2.0.0#Batch", batchFileName);
final String singleLevelBomAsBuilt = WiremockSupport.submodelRequest(edcAssetId, "SingleLevelBomAsBuilt",
- "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt", sbomFileName);
+ singleLevelBomAsBuiltAspectName, sbomFileName);
final List submodelDescriptors = List.of(batch, singleLevelBomAsBuilt);
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java
index 9698272e7c..5146e44de5 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java
@@ -31,6 +31,8 @@
import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockSupport.DATAPLANE_PUBLIC_URL;
import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockSupport.submodelDescriptor;
import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.responseWithStatus;
+import static org.eclipse.tractusx.irs.util.TestMother.batchAspectName;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@@ -79,7 +81,7 @@ static RegisterJob jobRequest(final String globalAssetId, final String bpn, fina
return RegisterJob.builder()
.key(PartChainIdentificationKey.builder().bpn(bpn).globalAssetId(globalAssetId).build())
.depth(depth)
- .aspects(List.of("Batch", "SingleLevelBomAsBuilt"))
+ .aspects(List.of(batchAspectName, singleLevelBomAsBuiltAspectName))
.collectAspects(true)
.lookupBPNs(true)
.direction(Direction.DOWNWARD)
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java
index 7d446883d4..62159f16b2 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java
@@ -25,10 +25,11 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.tractusx.irs.util.TestMother.jobParameter;
-import static org.eclipse.tractusx.irs.util.TestMother.jobParameterCollectAspects;
import static org.eclipse.tractusx.irs.util.TestMother.jobParameterUpward;
import static org.eclipse.tractusx.irs.util.TestMother.shell;
import static org.eclipse.tractusx.irs.util.TestMother.shellDescriptor;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelUsageAsBuiltAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithDspEndpoint;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -62,9 +63,6 @@ class RelationshipDelegateTest {
final RelationshipDelegate relationshipDelegate = new RelationshipDelegate(null, submodelFacade,
connectorEndpointsService, jsonUtil);
- final String singleLevelBomAsBuiltAspectName = "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt";
- final String singleLevelUsageAsBuiltAspectName = "urn:bamm:io.catenax.single_level_usage_as_built:2.0.0#SingleLevelUsageAsBuilt";
-
@Test
void shouldFillItemContainerWithRelationshipAndAddChildIdsToProcess()
throws EdcClientException, URISyntaxException, IOException {
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java
index e80ecdf3b1..efba84d9a8 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java
@@ -26,8 +26,10 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.tractusx.irs.util.TestMother.jobParameterCollectAspects;
import static org.eclipse.tractusx.irs.util.TestMother.jobParameterFilter;
+import static org.eclipse.tractusx.irs.util.TestMother.serialPartAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.shell;
import static org.eclipse.tractusx.irs.util.TestMother.shellDescriptor;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptor;
import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithDspEndpoint;
import static org.mockito.ArgumentMatchers.any;
@@ -71,10 +73,10 @@ void shouldFilterSubmodelDescriptorsByAspectTypeFilter() {
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.serial_part_typization:1.0.0#SerialPartTypization",
+ serialPartAspectName,
"testSerialPartTypizationEndpoint"),
submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.assembly_part_relationship:1.0.0#AssemblyPartRelationship",
+ singleLevelBomAsBuiltAspectName,
"testAssemblyPartRelationshipEndpoint")))));
// when
@@ -92,10 +94,10 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws SchemaNotFoundExcepti
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart",
+ serialPartAspectName,
"testSerialPartEndpoint"),
submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt",
+ singleLevelBomAsBuiltAspectName,
"testSingleLevelBomAsBuiltEndpoint")))));
// when
@@ -117,10 +119,10 @@ void shouldPutTombstoneForMissingBpn() {
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart",
+ serialPartAspectName,
"testSerialPartEndpoint"),
submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt",
+ singleLevelBomAsBuiltAspectName,
"testSingleLevelBomAsBuiltEndpoint")))));
// when
@@ -143,10 +145,10 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart",
+ serialPartAspectName,
"testSerialPartEndpoint"),
submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt",
+ singleLevelBomAsBuiltAspectName,
"testSingleLevelBomAsBuiltEndpoint")))));
// when
@@ -170,7 +172,7 @@ void shouldRequestForAllEndpoints() throws EdcClientException, InvalidSchemaExce
final ItemContainer.ItemContainerBuilder itemContainerShellWithOneSubmodel = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptor(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart",
+ serialPartAspectName,
"testSerialPartEndpoint",
"")))));
@@ -188,8 +190,7 @@ void shouldRequestForAllEndpoints() throws EdcClientException, InvalidSchemaExce
// then
assertThat(result).isNotNull();
assertThat(result.getSubmodels()).hasSize(1);
- assertThat(result.getSubmodels().get(0).getAspectType()).isEqualTo(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart");
+ assertThat(result.getSubmodels().get(0).getAspectType()).isEqualTo(serialPartAspectName);
assertThat(result.getSubmodels().get(0).getContractAgreementId()).isNull();
assertThat(result.getTombstones()).isEmpty();
}
@@ -200,10 +201,10 @@ void shouldCatchRestClientExceptionAndPutTombstone() throws SchemaNotFoundExcept
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart",
+ serialPartAspectName,
"testSerialPartEndpoint"),
submodelDescriptorWithDspEndpoint(
- "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt",
+ singleLevelBomAsBuiltAspectName,
"testSingleLevelBomAsBuiltEndpoint")))));
// when
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/dto/assetadministrationshell/AssetAdministrationShellDescriptorTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptorTest.java
similarity index 82%
rename from irs-api/src/test/java/org/eclipse/tractusx/irs/dto/assetadministrationshell/AssetAdministrationShellDescriptorTest.java
rename to irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptorTest.java
index 6a2b0ecb62..668cce01e4 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/dto/assetadministrationshell/AssetAdministrationShellDescriptorTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptorTest.java
@@ -21,30 +21,28 @@
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-package org.eclipse.tractusx.irs.dto.assetadministrationshell;
+package org.eclipse.tractusx.irs.component.assetadministrationshell;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.eclipse.tractusx.irs.util.TestMother.serialPartAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.shellDescriptor;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithoutHref;
import java.util.List;
-import org.eclipse.tractusx.irs.component.assetadministrationshell.AssetAdministrationShellDescriptor;
-import org.eclipse.tractusx.irs.component.assetadministrationshell.SubmodelDescriptor;
import org.junit.jupiter.api.Test;
class AssetAdministrationShellDescriptorTest {
final String singleLevelBomAsBuiltId = "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0";
- final String singleLevelBomAsBuiltIdWithAspectName = "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt";
final String serialPartId = "urn:bamm:com.catenax.serial_part:1.0.0";
- final String serialPartIdWithAspectName = "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart";
@Test
void shouldFilterByAspectTypeWhenEndingWithAspectName() {
// Arrange
final AssetAdministrationShellDescriptor shellDescriptor = shellDescriptor(
- List.of(submodelDescriptorWithoutHref(singleLevelBomAsBuiltIdWithAspectName)));
+ List.of(submodelDescriptorWithoutHref(singleLevelBomAsBuiltAspectName)));
final List aspectTypeFilter = List.of("SingleLevelBomAsBuilt");
// Act
@@ -52,7 +50,7 @@ void shouldFilterByAspectTypeWhenEndingWithAspectName() {
// Assert
assertThat(result).hasSize(1);
- assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(singleLevelBomAsBuiltIdWithAspectName);
+ assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(singleLevelBomAsBuiltAspectName);
}
@Test
@@ -74,7 +72,7 @@ void shouldFilterByAspectTypeWhenNotEndingWithAspectName() {
void shouldFilterByAspectTypeWhenWithDifferentAspects() {
// Arrange
final AssetAdministrationShellDescriptor shellDescriptor = shellDescriptor(
- List.of(submodelDescriptorWithoutHref(serialPartIdWithAspectName),
+ List.of(submodelDescriptorWithoutHref(serialPartAspectName),
submodelDescriptorWithoutHref(singleLevelBomAsBuiltId)));
final List aspectTypeFilter = List.of("SerialPart");
@@ -84,26 +82,26 @@ void shouldFilterByAspectTypeWhenWithDifferentAspects() {
// Assert
assertThat(result).hasSize(1);
- assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(serialPartIdWithAspectName);
+ assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(serialPartAspectName);
}
@Test
void shouldFilterByAspectTypeForUrnFormat() {
// Arrange
final AssetAdministrationShellDescriptor shellDescriptor = shellDescriptor(
- List.of(submodelDescriptorWithoutHref(serialPartIdWithAspectName),
- submodelDescriptorWithoutHref(singleLevelBomAsBuiltIdWithAspectName)));
+ List.of(submodelDescriptorWithoutHref(serialPartAspectName),
+ submodelDescriptorWithoutHref(singleLevelBomAsBuiltAspectName)));
- final List aspectTypeFilter = List.of(serialPartIdWithAspectName,
- singleLevelBomAsBuiltIdWithAspectName);
+ final List aspectTypeFilter = List.of(serialPartAspectName,
+ singleLevelBomAsBuiltAspectName);
// Act
final List result = shellDescriptor.filterDescriptorsByAspectTypes(aspectTypeFilter);
// Assert
assertThat(result).hasSize(2);
- assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(serialPartIdWithAspectName);
- assertThat(result.get(1).getSemanticId().getKeys().get(0).getValue()).isEqualTo(singleLevelBomAsBuiltIdWithAspectName);
+ assertThat(result.get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo(serialPartAspectName);
+ assertThat(result.get(1).getSemanticId().getKeys().get(0).getValue()).isEqualTo(singleLevelBomAsBuiltAspectName);
}
}
\ No newline at end of file
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptorTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptorTest.java
new file mode 100644
index 0000000000..5da1488f80
--- /dev/null
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptorTest.java
@@ -0,0 +1,72 @@
+/********************************************************************************
+ * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License, Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ ********************************************************************************/
+package org.eclipse.tractusx.irs.component.assetadministrationshell;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithoutHref;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class SubmodelDescriptorTest {
+
+ @ParameterizedTest
+ @MethodSource
+ void shouldValidateByFilterAspect(final String aspectFilter, final boolean expected) {
+ // Arrange
+ final String singleLevelBomTwoZeroVersion = "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt";
+ final SubmodelDescriptor submodelDescriptor = submodelDescriptorWithoutHref(singleLevelBomTwoZeroVersion);
+
+ // Act
+ final boolean result = submodelDescriptor.isAspect(aspectFilter);
+
+ // Assert
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static Stream shouldValidateByFilterAspect() {
+ return Stream.of(
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.0.1#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.0.22#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.1.0#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.17.1#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.22.0#SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:2.0.0", true),
+ Arguments.of("SingleLevelBomAsBuilt", true),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:1.9.0#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:1.9.9#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:3.4.1#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:io.catenax.single_level_bom_as_built:17.0.1#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:samm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:com.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt", false),
+ Arguments.of("urn:bamm:com.catenax.single_level_bom_as_built", false),
+ Arguments.of("urn:bamm:io.catenax.serial_part:1.0.1#SerialPart", false),
+ Arguments.of("SerialPart", false),
+ Arguments.of("", false),
+ Arguments.of(null, false)
+ );
+ }
+
+}
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java
index 94bc7fa710..3e287de5b4 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java
@@ -25,15 +25,17 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.given;
+import static org.eclipse.tractusx.irs.util.TestMother.productDescriptionAspectName;
import static org.eclipse.tractusx.irs.util.TestMother.registerJob;
import static org.eclipse.tractusx.irs.util.TestMother.registerJobWithDepthAndAspect;
import static org.eclipse.tractusx.irs.util.TestMother.registerJobWithDepthAndAspectAndCollectAspects;
import static org.eclipse.tractusx.irs.util.TestMother.registerJobWithDirection;
import static org.eclipse.tractusx.irs.util.TestMother.registerJobWithoutDepth;
+import static org.eclipse.tractusx.irs.util.TestMother.serialPartAspectName;
+import static org.eclipse.tractusx.irs.util.TestMother.singleLevelBomAsBuiltAspectName;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.time.ZonedDateTime;
@@ -70,11 +72,6 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.server.ResponseStatusException;
@@ -104,18 +101,12 @@ class IrsItemGraphQueryServiceSpringBootTest {
@MockBean
private ConnectorEndpointsService connectorEndpointsService;
- private static AspectModel getAspectModel(final String aspect, final String urn) {
- return AspectModel.builder().name(aspect).urn(urn).build();
- }
-
@BeforeEach
void setUp() throws SchemaNotFoundException {
final List models = List.of(
- getAspectModel(AspectType.SERIAL_PART.toString(), "urn:bamm:io.catenax.serial_part:1.0.0#SerialPart"),
- getAspectModel(AspectType.PRODUCT_DESCRIPTION.toString(),
- "urn:bamm:io.catenax.vehicle.product_description:2.0.0#ProductDescription"),
- getAspectModel(AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString(),
- "urn:bamm:io.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt"));
+ getAspectModel(AspectType.SERIAL_PART.toString(), serialPartAspectName),
+ getAspectModel(AspectType.PRODUCT_DESCRIPTION.toString(), productDescriptionAspectName),
+ getAspectModel(AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString(), singleLevelBomAsBuiltAspectName));
final AspectModels aspectModels = new AspectModels(models, "2023-02-13T08:18:11.990659500Z");
when(semanticsHubFacade.getAllAspectModels()).thenReturn(aspectModels);
}
@@ -144,8 +135,8 @@ void registerJobWithCollectAspectsShouldIncludeSubmodels() throws InvalidSchemaE
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("https://connector.endpoint.nl"));
final RegisterJob registerJob = registerJob("urn:uuid:8ddd8fe0-1b4f-44b4-90f3-a8f68e551ac7", 100,
- List.of(AspectType.SERIAL_PART.toString(), AspectType.PRODUCT_DESCRIPTION.toString(),
- AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()), true, false, Direction.DOWNWARD);
+ List.of(serialPartAspectName, productDescriptionAspectName, singleLevelBomAsBuiltAspectName),
+ true, false, Direction.DOWNWARD);
when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn(
List.of("singleLevelBomAsBuilt"));
@@ -167,7 +158,7 @@ void registerJobShouldCreateTombstonesWhenNotPassingJsonSchemaValidation() throw
List.of("https://connector.endpoint.nl"));
final RegisterJob registerJob = registerJobWithDepthAndAspectAndCollectAspects(3,
- List.of(AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()));
+ List.of(singleLevelBomAsBuiltAspectName));
when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn(
List.of("singleLevelBomAsBuilt"));
@@ -184,10 +175,9 @@ void registerJobShouldCreateTombstonesWhenNotPassingJsonSchemaValidation() throw
@Test
void registerJobWithDepthShouldBuildTreeUntilGivenDepth() {
// given
- final RegisterJob registerJob = registerJobWithDepthAndAspect(1, null);
+ final RegisterJob registerJob = registerJobWithDepthAndAspect(1, List.of());
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("http://localhost/discovery"));
- setSecurityContext();
// when
final JobHandle registeredJob = service.registerItemJob(registerJob);
@@ -239,8 +229,6 @@ void cancelJobById() {
jobStore.create(multiTransferJob);
- setSecurityContext();
-
assertThat(service.cancelJobById(jobId)).isNotNull();
final Optional fetchedJob = jobStore.find(idAsString);
@@ -256,8 +244,7 @@ void cancelJobById() {
@Test
void registerJobWithoutAspectsShouldUseDefault() {
// given
- final List emptyAspectTypeFilterList = List.of();
- final RegisterJob registerJob = registerJobWithDepthAndAspect(null, emptyAspectTypeFilterList);
+ final RegisterJob registerJob = registerJobWithDepthAndAspect(10, List.of());
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(
List.of("http://localhost/discovery"));
@@ -292,23 +279,10 @@ void shouldThrowIllegalArgumentExceptionForLifecycleAsSpecifiedAndDirectionUpwar
}
private int getRelationshipsSize(final UUID jobId) {
- setSecurityContext();
return service.getJobForJobId(jobId, false).getRelationships().size();
}
- private static void setSecurityContext() {
- JwtAuthenticationToken jwtAuthenticationToken = mock(JwtAuthenticationToken.class);
- Jwt token = mock(Jwt.class);
- when(jwtAuthenticationToken.getAuthorities()).thenReturn(List.of(new SimpleGrantedAuthority("admin_irs")));
- when(jwtAuthenticationToken.getToken()).thenReturn(token);
- when(token.getClaim("clientId")).thenReturn("test-client-id");
- SecurityContext securityContext = mock(SecurityContext.class);
- when(securityContext.getAuthentication()).thenReturn(jwtAuthenticationToken);
- SecurityContextHolder.setContext(securityContext);
- }
-
private int getSubmodelsSize(final UUID jobId) {
- setSecurityContext();
return service.getJobForJobId(jobId, false).getSubmodels().size();
}
@@ -334,8 +308,11 @@ void checkMetricsRecordingTest() {
}
private int getTombstonesSize(final UUID jobId) {
- setSecurityContext();
return service.getJobForJobId(jobId, false).getTombstones().size();
}
+ private static AspectModel getAspectModel(final String aspect, final String urn) {
+ return AspectModel.builder().name(aspect).urn(urn).build();
+ }
+
}
\ No newline at end of file
diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java
index 9d9ac34dee..cb612a7ee7 100644
--- a/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java
+++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java
@@ -52,7 +52,6 @@
import org.eclipse.tractusx.irs.component.assetadministrationshell.Reference;
import org.eclipse.tractusx.irs.component.assetadministrationshell.SemanticId;
import org.eclipse.tractusx.irs.component.assetadministrationshell.SubmodelDescriptor;
-import org.eclipse.tractusx.irs.component.enums.AspectType;
import org.eclipse.tractusx.irs.component.enums.BomLifecycle;
import org.eclipse.tractusx.irs.component.enums.Direction;
import org.eclipse.tractusx.irs.component.enums.JobState;
@@ -72,6 +71,13 @@
*/
public class TestMother {
+ public static final String singleLevelBomAsBuiltAspectName = "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt";
+ public static final String singleLevelUsageAsBuiltAspectName = "urn:bamm:io.catenax.single_level_usage_as_built:2.0.0#SingleLevelUsageAsBuilt";
+ public static final String serialPartAspectName = "urn:bamm:io.catenax.serial_part:1.0.1#SerialPart";
+ public static final String batchAspectName = "urn:samm:io.catenax.batch:2.0.0#Batch";
+ public static final String materialForRecyclingAspectName = "urn:bamm:io.catenax.material_for_recycling:1.1.0#MaterialForRecycling";
+ public static final String productDescriptionAspectName = "urn:bamm:io.catenax.vehicle.product_description:2.0.0#ProductDescription";
+
Faker faker = new Faker();
public static RegisterJob registerJobWithoutDepthAndAspect() {
@@ -79,7 +85,7 @@ public static RegisterJob registerJobWithoutDepthAndAspect() {
}
public static RegisterJob registerJobWithoutDepth() {
- return registerJobWithDepthAndAspect(null, List.of(AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()));
+ return registerJobWithDepthAndAspect(null, List.of(singleLevelBomAsBuiltAspectName));
}
public static RegisterJob registerJobWithDepthAndAspect(final Integer depth, final List aspectTypes) {
@@ -106,7 +112,7 @@ public static RegisterJob registerJobWithDepthAndAspectAndCollectAspects(final I
public static RegisterJob registerJobWithLookupBPNs() {
return registerJob("urn:uuid:8ddd8fe0-1b4f-44b4-90f3-a8f68e551ac7", null,
- List.of(AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()), false, true, Direction.DOWNWARD);
+ List.of(singleLevelBomAsBuiltAspectName), false, true, Direction.DOWNWARD);
}
public static RegisterJob registerJob(final String globalAssetId, final Integer depth,
@@ -153,8 +159,7 @@ public static JobParameter jobParameter() {
.depth(5)
.bomLifecycle(BomLifecycle.AS_BUILT)
.direction(Direction.DOWNWARD)
- .aspects(List.of(AspectType.SERIAL_PART.toString(),
- AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()))
+ .aspects(List.of(serialPartAspectName, singleLevelBomAsBuiltAspectName))
.auditContractNegotiation(false)
.build();
}
@@ -164,8 +169,7 @@ public static JobParameter jobParameterUpward() {
.depth(0)
.bomLifecycle(BomLifecycle.AS_BUILT)
.direction(Direction.UPWARD)
- .aspects(List.of(AspectType.SERIAL_PART.toString(),
- AspectType.SINGLE_LEVEL_USAGE_AS_BUILT.toString()))
+ .aspects(List.of(serialPartAspectName, singleLevelBomAsBuiltAspectName))
.build();
}
@@ -173,8 +177,7 @@ public static JobParameter jobParameterCollectAspects() {
return JobParameter.builder()
.depth(0)
.bomLifecycle(BomLifecycle.AS_BUILT)
- .aspects(List.of(AspectType.SERIAL_PART.toString(),
- AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()))
+ .aspects(List.of(serialPartAspectName, singleLevelBomAsBuiltAspectName))
.collectAspects(true)
.build();
}
@@ -183,7 +186,7 @@ public static JobParameter jobParameterFilter() {
return JobParameter.builder()
.depth(0)
.bomLifecycle(BomLifecycle.AS_BUILT)
- .aspects(List.of(AspectType.MATERIAL_FOR_RECYCLING.toString()))
+ .aspects(List.of(materialForRecyclingAspectName))
.build();
}
@@ -192,8 +195,7 @@ public static JobParameter jobParameterCollectBpns() {
.depth(0)
.bomLifecycle(BomLifecycle.AS_BUILT)
.direction(Direction.DOWNWARD)
- .aspects(List.of(AspectType.SERIAL_PART.toString(),
- AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()))
+ .aspects(List.of(serialPartAspectName, singleLevelBomAsBuiltAspectName))
.lookupBPNs(true)
.build();
}
@@ -203,8 +205,7 @@ public static JobParameter jobParameterAuditContractNegotiation() {
.depth(5)
.bomLifecycle(BomLifecycle.AS_BUILT)
.direction(Direction.DOWNWARD)
- .aspects(List.of(AspectType.SERIAL_PART.toString(),
- AspectType.SINGLE_LEVEL_BOM_AS_BUILT.toString()))
+ .aspects(List.of(serialPartAspectName, singleLevelBomAsBuiltAspectName))
.auditContractNegotiation(true)
.build();
}
diff --git a/irs-api/src/test/resources/__files/semantichub/all-models-page-IT.json b/irs-api/src/test/resources/__files/semantichub/all-models-page-IT.json
index 36d2bd6a4a..482990f61a 100644
--- a/irs-api/src/test/resources/__files/semantichub/all-models-page-IT.json
+++ b/irs-api/src/test/resources/__files/semantichub/all-models-page-IT.json
@@ -532,6 +532,13 @@
"type": "BAMM",
"status": "DEPRECATED"
},
+ {
+ "urn": "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt",
+ "version": "2.0.0",
+ "name": "SingleLevelBomAsBuilt",
+ "type": "BAMM",
+ "status": "RELEASED"
+ },
{
"urn": "urn:samm:io.catenax.batch:2.0.0#Batch",
"version": "2.0.0",
diff --git a/irs-common/pom.xml b/irs-common/pom.xml
index 8af8b54cc3..3264382522 100644
--- a/irs-common/pom.xml
+++ b/irs-common/pom.xml
@@ -53,10 +53,6 @@
org.springframework.boot
spring-boot-starter-security
-
- org.springframework.boot
- spring-boot-starter-oauth2-resource-server
-
io.github.resilience4j
diff --git a/irs-models/pom.xml b/irs-models/pom.xml
index c66b493ff3..7c8585f3d3 100644
--- a/irs-models/pom.xml
+++ b/irs-models/pom.xml
@@ -77,6 +77,11 @@
snakeyaml
${snakeyaml.version}
+
+ com.vdurmont
+ semver4j
+ 3.1.0
+
org.projectlombok
lombok
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBatchOrder.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBatchOrder.java
index a70188eec8..9a436a6b4f 100644
--- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBatchOrder.java
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBatchOrder.java
@@ -55,6 +55,7 @@
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.Pattern;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -79,6 +80,8 @@
})
public class RegisterBatchOrder {
+ private static final String ASPECT_MODEL_REGEX = "^(urn:[bs]amm:.*\\d\\.\\d\\.\\d)?(#)?(\\w+)?$";
+
@NotEmpty
@Valid
@ArraySchema(schema = @Schema(description = "Keys array contains required attributes for identify part chain entry node ", implementation = PartChainIdentificationKey.class), maxItems = Integer.MAX_VALUE)
@@ -87,8 +90,10 @@ public class RegisterBatchOrder {
@Schema(description = "BoM Lifecycle of the result tree.", implementation = BomLifecycle.class)
private BomLifecycle bomLifecycle;
- @ArraySchema(schema = @Schema(implementation = String.class), maxItems = Integer.MAX_VALUE)
- private List aspects;
+ @ArraySchema(arraySchema = @Schema(description = "List of aspect names that will be collected if \\ flag is set to true.",
+ example = "[\"urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt\"]",
+ implementation = String.class, pattern = ASPECT_MODEL_REGEX), maxItems = Integer.MAX_VALUE)
+ private List<@Pattern(regexp = ASPECT_MODEL_REGEX) String> aspects;
@Schema(implementation = Integer.class, minimum = MIN_TREE_DEPTH_DESC, maximum = MAX_TREE_DEPTH_DESC,
description = "Max depth of the item graph returned. If no depth is set item graph with max depth is returned.")
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBpnInvestigationJob.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBpnInvestigationJob.java
index 7d66c465af..bc3495d7e6 100644
--- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBpnInvestigationJob.java
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterBpnInvestigationJob.java
@@ -57,7 +57,7 @@ public class RegisterBpnInvestigationJob {
private PartChainIdentificationKey key;
@NotEmpty
- @ArraySchema(schema = @Schema(description = "Array of BPNS numbers.", example = "BPNS000000000DDD",
+ @ArraySchema(arraySchema = @Schema(description = "Array of BPNS numbers.", example = "[\"BPNS000000000DDD\"]",
implementation = String.class, pattern = BPN_REGEX), maxItems = Integer.MAX_VALUE)
private List<@Pattern(regexp = BPN_REGEX) String> incidentBPNSs;
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterJob.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterJob.java
index 82b978ab50..edcb0a4eaa 100644
--- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterJob.java
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/RegisterJob.java
@@ -31,6 +31,7 @@
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -53,7 +54,7 @@ public class RegisterJob {
private static final String MAX_TREE_DEPTH_DESC = "100";
private static final int MIN_TREE_DEPTH = 1;
private static final int MAX_TREE_DEPTH = 100;
- private static final String ASPECT_MODEL_REGEX = "^(urn:bamm:.*\\d\\.\\d\\.\\d)?(#)?(\\w+)?$";
+ private static final String ASPECT_MODEL_REGEX = "^(urn:[bs]amm:.*\\d\\.\\d\\.\\d)?(#)?(\\w+)?$";
@NotNull
@Valid
@@ -63,8 +64,10 @@ public class RegisterJob {
@Schema(description = "BoM Lifecycle of the result tree.", implementation = BomLifecycle.class)
private BomLifecycle bomLifecycle;
- @ArraySchema(arraySchema = @Schema(implementation = String.class, description = "List of aspect names that will be collected if \\ flag is set to true."), maxItems = Integer.MAX_VALUE)
- private List aspects;
+ @ArraySchema(arraySchema = @Schema(description = "List of aspect names that will be collected if \\ flag is set to true.",
+ example = "[\"urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt\"]",
+ implementation = String.class, pattern = ASPECT_MODEL_REGEX), maxItems = Integer.MAX_VALUE)
+ private List<@Pattern(regexp = ASPECT_MODEL_REGEX) String> aspects;
@Schema(implementation = Integer.class, minimum = MIN_TREE_DEPTH_DESC, maximum = MAX_TREE_DEPTH_DESC,
description = "Max depth of the item graph returned. If no depth is set item graph with max depth is returned.")
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptor.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptor.java
index 8867d83e0d..f9c29d5329 100644
--- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptor.java
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/AssetAdministrationShellDescriptor.java
@@ -25,7 +25,6 @@
import java.util.Collection;
import java.util.List;
-import java.util.Locale;
import java.util.Optional;
import io.swagger.v3.oas.annotations.media.ArraySchema;
@@ -91,10 +90,10 @@ public class AssetAdministrationShellDescriptor {
* @return ManufacturerId value from Specific Asset Ids
*/
public Optional findManufacturerId() {
- return this.specificAssetIds.stream()
- .filter(assetId -> "ManufacturerId".equalsIgnoreCase(assetId.getName()))
- .map(IdentifierKeyValuePair::getValue)
- .findFirst();
+ return specificAssetIds.stream()
+ .filter(assetId -> "ManufacturerId".equalsIgnoreCase(assetId.getName()))
+ .map(IdentifierKeyValuePair::getValue)
+ .findFirst();
}
/**
@@ -102,7 +101,7 @@ public Optional findManufacturerId() {
* @return AssetAdministrationShellDescriptor with filtered submodel descriptors
*/
public AssetAdministrationShellDescriptor withFilteredSubmodelDescriptors(final List aspectTypes) {
- this.setSubmodelDescriptors(this.filterDescriptorsByAspectTypes(aspectTypes));
+ setSubmodelDescriptors(filterDescriptorsByAspectTypes(aspectTypes));
return this;
}
@@ -125,29 +124,9 @@ public List findRelationshipEndpointAddresses(final AspectType relatio
*/
public List filterDescriptorsByAspectTypes(final List aspectTypes) {
log.info("Filtering for Aspect Types '{}'", aspectTypes);
- return this.submodelDescriptors.stream()
- .filter(submodelDescriptor -> aspectTypes.stream()
- .anyMatch(type -> isMatching(
- submodelDescriptor, type)))
-
- .toList();
- }
-
- private boolean isMatching(final SubmodelDescriptor submodelDescriptor, final String aspectTypeFilter) {
- final Optional submodelAspectType = Optional.ofNullable(submodelDescriptor.getSemanticId().getKeys())
- .flatMap(key -> key.stream().findFirst())
- .map(SemanticId::getValue);
- return submodelAspectType.map(
- semanticId -> semanticId.endsWith("#" + aspectTypeFilter) || contains(semanticId, aspectTypeFilter)
- || semanticId.equals(aspectTypeFilter)).orElse(false);
- }
-
- private boolean contains(final String semanticId, final String aspectTypeFilter) {
- // https://stackoverflow.com/a/3752693
- final String[] split = aspectTypeFilter.split("(?=\\p{Lu})");
- final String join = String.join("_", split).toLowerCase(Locale.ROOT);
- log.debug("lower case aspect: '{}'", join);
- return semanticId.contains(join);
+ return submodelDescriptors.stream()
+ .filter(submodelDescriptor -> aspectTypes.stream().anyMatch(submodelDescriptor::isAspect))
+ .toList();
}
}
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SemanticModel.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SemanticModel.java
new file mode 100644
index 0000000000..be09941e4b
--- /dev/null
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SemanticModel.java
@@ -0,0 +1,51 @@
+/********************************************************************************
+ * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License, Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ ********************************************************************************/
+package org.eclipse.tractusx.irs.component.assetadministrationshell;
+
+import com.vdurmont.semver4j.Semver;
+
+record SemanticModel(String urn, String type, String name, Semver version) {
+
+ private static final int VALID_SEMANTIC_ID_LENGTH = 4;
+
+ static SemanticModel parse(final String semanticId) {
+ final String[] parts = semanticId.split(":");
+ if (parts.length != VALID_SEMANTIC_ID_LENGTH) {
+ throw new IllegalArgumentException("Invalid semanticId value, cant parse: " + semanticId);
+ }
+
+ final String version = parts[3].split("#")[0];
+ return new SemanticModel(parts[0], parts[1], parts[2], new Semver(version));
+ }
+
+ boolean matches(final SemanticModel model) {
+ return urn.equals(model.urn)
+ && type.equals(model.type)
+ && name.equals(model.name)
+ && versionIsInRange(model);
+ }
+
+ private boolean versionIsInRange(final SemanticModel model) {
+ final Semver nextMajor = model.version.nextMajor();
+ final Semver minMajor = new Semver(model.version.getMajor() + ".0.0");
+
+ return version.isGreaterThanOrEqualTo(minMajor) && version.isLowerThan(nextMajor);
+ }
+}
diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptor.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptor.java
index ee20cce9e1..0392407168 100644
--- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptor.java
+++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/assetadministrationshell/SubmodelDescriptor.java
@@ -24,12 +24,16 @@
package org.eclipse.tractusx.irs.component.assetadministrationshell;
import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.vdurmont.semver4j.SemverException;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;
+import org.springframework.util.StringUtils;
/**
* SubmodelDescriptor
@@ -72,7 +76,29 @@ public class SubmodelDescriptor {
*/
@JsonIgnore
public String getAspectType() {
- return this.getSemanticId().getKeys().stream().findFirst().map(SemanticId::getValue).orElse(null);
+ return getSemanticId().getKeys().stream().findFirst().map(SemanticId::getValue).orElse(null);
}
+ /* package */ boolean isAspect(final String filterSemanticId) {
+ return Optional.ofNullable(getAspectType())
+ .filter(aspect -> StringUtils.hasLength(filterSemanticId))
+ .map(aspect -> aspect.contains(lowerCaseNameWithUnderscores(filterSemanticId))
+ || semanticModelNamesMatchAndVersionIsInRange(aspect, filterSemanticId))
+ .orElse(false);
+ }
+
+ private String lowerCaseNameWithUnderscores(final String filterSemanticId) {
+ return String.join("_", filterSemanticId.split("(?=[A-Z])")).toLowerCase(Locale.ROOT);
+ }
+
+ private boolean semanticModelNamesMatchAndVersionIsInRange(final String semanticId, final String filterSemanticId) {
+ try {
+ final SemanticModel submodel = SemanticModel.parse(semanticId);
+ final SemanticModel filter = SemanticModel.parse(filterSemanticId);
+
+ return filter.matches(submodel);
+ } catch (final IllegalArgumentException | SemverException e) {
+ return false;
+ }
+ }
}
diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreator.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreator.java
index 7d83cb19d9..4c0316fbab 100644
--- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreator.java
+++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreator.java
@@ -114,53 +114,53 @@ public AssetAdministrationShellDescriptor createDummyAssetAdministrationShellDes
}
private SubmodelDescriptor createSingleLevelBomAsBuiltSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_built:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt",
"singleLevelBomAsBuilt");
}
private SubmodelDescriptor createSingleLevelUsageAsBuiltSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_usage_as_built:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_usage_as_built:2.0.0#SingleLevelUsageAsBuilt",
"singleLevelUsageAsBuilt");
}
private SubmodelDescriptor createSingleLevelBomAsSpecifiedSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_specified:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_specified:1.0.0#SingleLevelBomAsSpecified",
"singleLevelBomAsSpecified");
}
private SubmodelDescriptor createSerialPartSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.serial_part:1.0.0", "serialPart");
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.serial_part:1.0.1#SerialPart", "serialPart");
}
private SubmodelDescriptor createSingleLevelBomAsPlannedSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_planned:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.single_level_bom_as_planned:2.0.0#SingleLevelBomAsPlanned",
"singleLevelBomAsPlanned");
}
private SubmodelDescriptor createPartAsPlannedSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.part_as_planned:1.0.0", "partAsPlanned");
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.part_as_planned:1.0.1#PartAsPlanned", "partAsPlanned");
}
private SubmodelDescriptor createBatchSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.batch:1.0.0", "batch");
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.batch:2.0.0#Batch", "batch");
}
private SubmodelDescriptor createMaterialForRecyclingSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.material_for_recycling:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.material_for_recycling:1.1.0#MaterialForRecycling",
"materialForRecycling");
}
private SubmodelDescriptor createProductDescriptionSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.product_description:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.product_description:1.0.0#ProductDescription",
"productDescription");
}
private SubmodelDescriptor createPhysicalDimensionSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.physical_dimension:1.0.0", "physicalDimension");
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.physical_dimension:1.0.0#PhysicalDimension", "physicalDimension");
}
private SubmodelDescriptor createPartAsSpecifiedSubmodelDescriptor(final String catenaXId) {
- return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.part_as_specified:1.0.0",
+ return createSubmodelDescriptor(catenaXId, "urn:bamm:io.catenax.part_as_specified:2.0.0#PartAsSpecified",
"partAsSpecified");
}
diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreatorTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreatorTest.java
index 52d9f91433..acc0ed5269 100644
--- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreatorTest.java
+++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/AssetAdministrationShellTestdataCreatorTest.java
@@ -64,8 +64,8 @@ void shouldReturnAssetAdministrationShellDescriptorWhenRequestingWithCatenaXId()
assertThat(endpointAddress).isEqualTo("singleLevelBomAsBuilt");
assertThat(aasDescriptor.getSubmodelDescriptors().get(0).getEndpoints().get(0).getProtocolInformation().getSubprotocolBody()).contains(catenaXId);
- assertThat(aasDescriptor.getSubmodelDescriptors().get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo("urn:bamm:io.catenax.single_level_bom_as_built:1.0.0");
- assertThat(aasDescriptor.getSubmodelDescriptors().get(1).getSemanticId().getKeys().get(0).getValue()).isEqualTo("urn:bamm:io.catenax.serial_part:1.0.0");
+ assertThat(aasDescriptor.getSubmodelDescriptors().get(0).getSemanticId().getKeys().get(0).getValue()).isEqualTo("urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt");
+ assertThat(aasDescriptor.getSubmodelDescriptors().get(1).getSemanticId().getKeys().get(0).getValue()).isEqualTo("urn:bamm:io.catenax.serial_part:1.0.1#SerialPart");
}
@Test
diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/CentralDigitalTwinRegistryServiceTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/CentralDigitalTwinRegistryServiceTest.java
index 0d88ade1b3..96919bc530 100644
--- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/CentralDigitalTwinRegistryServiceTest.java
+++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/central/CentralDigitalTwinRegistryServiceTest.java
@@ -57,8 +57,8 @@
@ExtendWith(MockitoExtension.class)
class CentralDigitalTwinRegistryServiceTest extends LocalTestDataConfigurationAware {
- private final String singleLevelBomAsBuiltURN = "urn:bamm:io.catenax.single_level_bom_as_built:1.0.0";
- private final String serialPartURN = "urn:bamm:io.catenax.serial_part:1.0.0";
+ private final String singleLevelBomAsBuiltURN = "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt";
+ private final String serialPartURN = "urn:bamm:io.catenax.serial_part:1.0.1#SerialPart";
private DigitalTwinRegistryService digitalTwinRegistryService;
@Mock
private DigitalTwinRegistryClient dtRegistryClientMock;