Skip to content

Commit

Permalink
Merge pull request #857 from catenax-ng/feature/#357-Update-Semantic-…
Browse files Browse the repository at this point in the history
…Models-of-IndustryCore

Feature/#357 update semantic models of industry core
  • Loading branch information
ds-jhartmann authored Apr 10, 2024
2 parents aff4fff + 88d5ea9 commit c47d641
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ _**For better traceability add the corresponding GitHub issue number in each cha
## [UNRELEASED]

### Added
- SAMM models can now be added locally #488
- Introduced new Cucumber Tests to cover Industry Core 2.0.0 compatibility #488

### Changed

Expand Down
30 changes: 27 additions & 3 deletions COMPATIBILITY_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

Full changelog of IRS: [changelog](CHANGELOG.md)

## [Unreleased]

| Dependency | Version | Helm | Comments |
|----------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
| EDC PostgresSQL | 15.1.0-debian-11-r12 | 12.1.6 | Optional |
| MIW | 0.1.0 | 0.1.0 | REST connection |
| Semantics Hub | 0.1.29 | v0.2.11-M1 | REST connection |
| DTR | 0.3.14-M1 | 0.3.22 | REST connection |
| Minio | RELEASE.2022-11-11T03-44-20Z | 5.0.1 | |
| SingleLevelBomAsBuilt | 2.0.0 | - | Model version |
| SingleLevelBomAsPlanned | 2.0.0 | - | Model version |
| SingleLevelBomAsSpecified | 1.0.0 | - | Model version |
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |
| PartAsPlanned | 2.0.0 | - | Model Version |
| SingleLevelBomAsPlanned | 3.0.0 | - | Model Version |
| SerialPart | 3.0.0 | - | Model Version |
| Batch | 3.0.0 | - | Model Version |
| JustInSequencePart | 3.0.0 | - | Model Version |
| SingleLevelBomAsBuilt | 3.0.0 | - | Model Version |
| PartSiteInformationAsBuilt | 1.0.0 | - | Model Version |

## [4.9.0] - 2024-04-03

| Dependency | Version | Helm | Comments |
Expand All @@ -18,6 +40,7 @@ Full changelog of IRS: [changelog](CHANGELOG.md)
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |

## [4.8.0] - 2024-03-18

| Dependency | Version | Helm | Comments |
|---------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
Expand All @@ -31,8 +54,8 @@ Full changelog of IRS: [changelog](CHANGELOG.md)
| SingleLevelBomAsSpecified | 1.0.0 | - | Model version |
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |


## [4.7.0] - 2024-03-04

| Dependency | Version | Helm | Comments |
|---------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
Expand All @@ -46,8 +69,8 @@ Full changelog of IRS: [changelog](CHANGELOG.md)
| SingleLevelBomAsSpecified | 1.0.0 | - | Model version |
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |


## [4.6.0] - 2024-02-20

| Dependency | Version | Helm | Comments |
|---------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
Expand All @@ -61,8 +84,8 @@ Full changelog of IRS: [changelog](CHANGELOG.md)
| SingleLevelBomAsSpecified | 1.0.0 | - | Model version |
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |


## [4.2.0] - 2023-11-28

| Dependency | Version | Helm | Comments |
|---------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
Expand All @@ -77,6 +100,7 @@ Full changelog of IRS: [changelog](CHANGELOG.md)
| SingleLevelUsageAsBuilt | 2.0.0 | - | Model version |

## [4.1.0] - 2023-11-15

| Dependency | Version | Helm | Comments |
|---------------------------|------------------------------|------------|-----------------|
| EDC | 0.5.3 | 0.5.3 | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ public List<AspectModel> getAllAspectModels() {
@Profile({ "!local && !test" })
class SemanticsHubClientImpl implements SemanticsHubClient {

public static final String LOCAL_MODEL_TYPE = "BAMM";
public static final String LOCAL_MODEL_TYPE_BAMM = "BAMM";
public static final String LOCAL_MODEL_TYPE_SAMM = "SAMM";
public static final String LOCAL_MODEL_STATUS = "PROVIDED";
private static final String PLACEHOLDER_URN = "urn";
private final SemanticsHubConfiguration config;
Expand Down Expand Up @@ -182,11 +183,12 @@ private String getDecodedString(final String urnBase64) {

private Optional<AspectModel> createAspectModel(final String urn) {
log.debug("Extracting aspect information for urn: '{}'", urn);
final Matcher matcher = Pattern.compile("^urn:bamm:.*:(\\d\\.\\d\\.\\d)#(\\w+)$").matcher(urn);
final Matcher matcher = Pattern.compile("^urn:[sb]amm:.*:(\\d\\.\\d\\.\\d)#(\\w+)$").matcher(urn);
if (matcher.find()) {
final String version = matcher.group(1);
final String name = matcher.group(2);
return Optional.of(new AspectModel(urn, version, name, LOCAL_MODEL_TYPE, LOCAL_MODEL_STATUS));
final String localModelType = urn.contains("samm") ? LOCAL_MODEL_TYPE_SAMM : LOCAL_MODEL_TYPE_BAMM;
return Optional.of(new AspectModel(urn, version, name, localModelType, LOCAL_MODEL_STATUS));
}
log.warn("Could not extract aspect information from urn: '{}'", urn);
return Optional.empty();
Expand Down Expand Up @@ -257,7 +259,7 @@ private Optional<String> readFromSemanticHub(final String urn) {
}

private String normalize(final String urn) {
return Base64.getEncoder().encodeToString(FilenameUtils.getName(urn).getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().withoutPadding().encodeToString(FilenameUtils.getName(urn).getBytes(StandardCharsets.UTF_8));
}

private String decode(final String urnBase64) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ void shouldReadJsonSchemaFromFilesystemOnly() throws SchemaNotFoundException {
assertThat(resultJsonSchema).isNotBlank().contains("http://json-schema.org/draft-04/schema");
}

@Test
void shouldReadJsonSchemaFromFilesystemWithUrlSafeFileName() throws SchemaNotFoundException {
final String path = Objects.requireNonNull(
getClass().getResource("/json-schema/dXJuOnNhbW06aW8uY2F0ZW5heC5zaW5nbGVfbGV2ZWxfYm9tX2FzX3BsYW5uZWQ6My4wLjAjU2luZ2xlTGV2ZWxCb21Bc1BsYW5uZWQ")).getPath();

final var testee = new SemanticsHubClientImpl(restTemplate, config("", new File(path).getParent()));

final String resultJsonSchema = testee.getModelJsonSchema("urn:samm:io.catenax.single_level_bom_as_planned:3.0.0#SingleLevelBomAsPlanned");

assertThat(resultJsonSchema).isNotBlank().contains("http://json-schema.org/draft-04/schema");
}

@Test
void shouldReadJsonSchemaFromSemanticHubThenFilesystem() throws SchemaNotFoundException {
final String path = Objects.requireNonNull(
Expand Down Expand Up @@ -163,14 +175,18 @@ void shouldGetAllModelsFromFilesystemOnly() throws SchemaNotFoundException {
final var testee = new SemanticsHubClientImpl(restTemplate, config("", new File(path).getPath()));
final AspectModel serialPartTypization = new AspectModel(
"urn:bamm:io.catenax.serial_part_typization:1.0.0#SerialPartTypization", "1.0.0",
"SerialPartTypization", SemanticsHubClientImpl.LOCAL_MODEL_TYPE,
"SerialPartTypization", SemanticsHubClientImpl.LOCAL_MODEL_TYPE_BAMM,
SemanticsHubClientImpl.LOCAL_MODEL_STATUS);
final AspectModel singleLevelBomAsBuilt = new AspectModel(
"urn:samm:io.catenax.single_level_bom_as_planned:3.0.0#SingleLevelBomAsPlanned", "3.0.0",
"SingleLevelBomAsPlanned", SemanticsHubClientImpl.LOCAL_MODEL_TYPE_SAMM,
SemanticsHubClientImpl.LOCAL_MODEL_STATUS);

// Act
final List<AspectModel> allAspectModels = testee.getAllAspectModels();

// Assert
assertThat(allAspectModels).hasSize(1).contains(serialPartTypization);
assertThat(allAspectModels).hasSize(2).contains(serialPartTypization).contains(singleLevelBomAsBuilt);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"description" : "The single-level bill of material (BoM)represents one sub-level of an assembly and does not include any lower-level subassemblies. In the As-Planned lifecycle state all variants are covered (\"120% BoM\").\nIf multiple versions of child parts exist that can be assembled into the same parent part, all versions of the child part are included in the BoM.\nIf there are multiple suppliers for the same child part, each supplier has an entry for their child part in the BoM.",
"type" : "object",
"components" : {
"schemas" : {
"urn_samm_io.catenax.shared.uuid_2.0.0_UuidV4Trait" : {
"type" : "string",
"description" : "The provided regular expression ensures that the UUID is composed of five groups of characters separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 hexadecimal characters and 4 hyphens), optionally prefixed by \"urn:uuid:\" to make it an IRI.",
"pattern" : "(^[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}$)|(^urn:uuid:[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}$)"
},
"urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_DateTimeTrait" : {
"type" : "string",
"description" : "Regular Expression to enable UTC and Timezone formats and the possibility to exclude time information.",
"pattern" : "^-?([1-9][0-9]{3,}|0[0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?|(24:00:00(\\.0+)?))(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?$"
},
"urn_samm_io.catenax.shared.quantity_2.0.0_QuantityValueCharacteristic" : {
"type" : "number",
"description" : "The quantity value associated with the unit expressed as float."
},
"urn_samm_io.catenax.shared.quantity_2.0.0_ItemUnitEnumeration" : {
"type" : "string",
"pattern" : "[a-zA-Z]*:[a-zA-Z]+",
"description" : "Enumeration for common item units.",
"enum" : [ "unit:piece", "unit:set", "unit:pair", "unit:page", "unit:cycle", "unit:kilowattHour", "unit:gram", "unit:kilogram", "unit:tonneMetricTon", "unit:tonUsOrShortTonUkorus", "unit:ounceAvoirdupois", "unit:pound", "unit:metre", "unit:centimetre", "unit:kilometre", "unit:inch", "unit:foot", "unit:yard", "unit:squareCentimetre", "unit:squareMetre", "unit:squareInch", "unit:squareFoot", "unit:squareYard", "unit:cubicCentimetre", "unit:cubicMetre", "unit:cubicInch", "unit:cubicFoot", "unit:cubicYard", "unit:litre", "unit:millilitre", "unit:hectolitre", "unit:secondUnitOfTime", "unit:minuteUnitOfTime", "unit:hourUnitOfTime", "unit:day" ]
},
"urn_samm_io.catenax.shared.quantity_2.0.0_ItemQuantityCharacteristic" : {
"description" : "Characteristic for measurements of an item (mass, count, linear, area, volume, misc).",
"type" : "object",
"properties" : {
"value" : {
"description" : "The quantity value associated with the unit.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.quantity_2.0.0_QuantityValueCharacteristic"
},
"unit" : {
"description" : "The unit of an item. Common units may be related to mass, count, linear, area, volume or misc.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.quantity_2.0.0_ItemUnitEnumeration"
}
},
"required" : [ "value", "unit" ]
},
"urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_ValidityPeriodCharacteristic" : {
"description" : "Characteristic for a validity period defined by an (optional)start and an (optional)end timestamp.",
"type" : "object",
"properties" : {
"validFrom" : {
"description" : "Start date of validity period.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_DateTimeTrait"
},
"validTo" : {
"description" : "End date of validity period.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_DateTimeTrait"
}
}
},
"urn_samm_io.catenax.shared.business_partner_number_2.0.0_BpnlTrait" : {
"type" : "string",
"description" : "The provided regular expression ensures that the BPNL is composed of prefix 'BPNL', 10 digits and two alphanumeric letters.",
"pattern" : "^BPNL[a-zA-Z0-9]{12}$"
},
"urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_ChildData" : {
"description" : "Catena-X ID and meta data of the assembled child item.",
"type" : "object",
"properties" : {
"createdOn" : {
"description" : "Timestamp when the relation between the parent part and the child part was created",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_DateTimeTrait"
},
"quantity" : {
"description" : "Quantity of which the child part will be assembled into the parent part.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.quantity_2.0.0_ItemQuantityCharacteristic"
},
"lastModifiedOn" : {
"description" : "Timestamp when the relationship between parent part and child part was last modified.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_DateTimeTrait"
},
"validityPeriod" : {
"description" : "The period of time during which the parent-child relation is valid. This relates to whether a child part can be built into the parent part at a given time.\nIf no validity period is given the relation is considered valid at any point in time.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_ValidityPeriodCharacteristic"
},
"businessPartner" : {
"description" : "The supplier of the given child item.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.business_partner_number_2.0.0_BpnlTrait"
},
"catenaXId" : {
"description" : "The Catena-X ID of the given part (e.g. the component), valid for the Catena-X dataspace.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.uuid_2.0.0_UuidV4Trait"
}
},
"required" : [ "createdOn", "quantity", "businessPartner", "catenaXId" ]
},
"urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_SetOfChildItemsCharacteristic" : {
"description" : "Set of child items the parent object will be assembled by (one structural level down).",
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_ChildData"
},
"uniqueItems" : true
}
}
},
"properties" : {
"catenaXId" : {
"description" : "The Catena-X ID of the given part (e.g. the component), valid for the Catena-X dataspace.",
"$ref" : "#/components/schemas/urn_samm_io.catenax.shared.uuid_2.0.0_UuidV4Trait"
},
"childItems" : {
"description" : "Set of child items in As-Planned lifecycle phase, of which the given parent object is assembled by (one structural level down).",
"$ref" : "#/components/schemas/urn_samm_io.catenax.single_level_bom_as_planned_3.0.0_SetOfChildItemsCharacteristic"
}
},
"required" : [ "catenaXId", "childItems" ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"submodels": [
{
"identification": "urn:uuid:39eb0751-bc99-48ee-8fd8-dbf233badb5f",
"aspectType": "urn:samm:io.catenax.just_in_sequence_part:3.0.0#JustInSequencePart",
"contractAgreementId": "MmVjYjQ1YzEtN2QxNy00NTMxLWFlMmItNDhiYjQwYzA5MTcw:dXJuOnV1aWQ6MjIwZGI2NmQtM2VmMi00Yzg1LWFiYzgtZDlhNDhkMDZiMDNh:YzQzYzUyY2MtNjA4ZC00M2E0LTliNWYtMjcxZDE0NDMwOTUw",
"payload": {
"localIdentifiers": [
{
"value": "82227044FBE",
"key": "jisNumber"
}
],
"manufacturingInformation": {
"date": "2022-02-04T14:48:54",
"country": "HUR",
"sites": [
{
"catenaXsiteId": "BPNS00000000BJTL",
"function": "production"
}
]
},
"catenaXId": "urn:uuid:c6d2d642-a055-4ddf-87e3-1a3b02c689e3",
"partTypeInformation": {
"manufacturerPartId": "123-0.740-3434-A",
"customerPartId": "PRT-12345",
"partClassification": [
{
"classificationDescription": "Standard data element types with associated classification scheme for electric components.",
"classificationStandard": "IEC",
"classificationID": "61360- 2:2012 "
}
],
"nameAtManufacturer": "Mirror left",
"nameAtCustomer": "side element A"
}
}
},
{
"identification": "urn:uuid:ec9ba5fc-339e-4142-89be-872650c6ab2f",
"aspectType": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart",
"contractAgreementId": "MDBmZDcyMDktYTE2MS00OWM5LWFiMzAtMmUwMDllNWE3MDAw:dXJuOnV1aWQ6Njc1NWMyZTAtNzc5Ni00NTYzLWE1NjktYTk3NmZjZTNiYjQ3:MjhhN2VlY2EtMDQwNi00ZjQ4LWI2NDktMjhiYzU0NzcyNTcx",
"payload": {
"localIdentifiers": [
{
"value": "BPNL00000000BJTL",
"key": "manufacturerId"
},
{
"value": "95657762-59",
"key": "manufacturerPartId"
},
{
"value": "NO-073366714159387479576634",
"key": "partInstanceId"
}
],
"manufacturingInformation": {
"date": "2022-02-04T14:48:54",
"country": "DEU",
"sites": [
{
"catenaXsiteId": "BPNS00000003CSGV",
"function": "production"
}
]
},
"catenaXId": "urn:uuid:c6d2d642-a055-4ddf-87e3-1a3b02c689e3",
"partTypeInformation": {
"manufacturerPartId": "95657762-59",
"customerPartId": "95657762-59",
"partClassification": [
{
"classificationDescription": "Standard data element types with associated classification scheme for electric components.",
"classificationStandard": "IEC",
"classificationID": "61360- 2:2012 "
}
],
"nameAtManufacturer": "Door Key",
"nameAtCustomer": "Door Key"
},
"itemVersion": "05"
}
}
]
}
Loading

0 comments on commit c47d641

Please sign in to comment.