Skip to content

Commit

Permalink
Merge pull request #346 from achtzig20/feat/planned-production-edc-as…
Browse files Browse the repository at this point in the history
…sets

Feat/Submodel registration and production SAMM
  • Loading branch information
tom-rm-meyer-ISST authored Apr 26, 2024
2 parents afda9fe + 076a9a5 commit 5a3a496
Show file tree
Hide file tree
Showing 22 changed files with 709 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.model;

import jakarta.persistence.Entity;
import lombok.ToString;

@Entity
@ToString(callSuper = true)
public class DeliveryContractMapping extends ContractMapping {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.model;

import jakarta.persistence.Entity;
import lombok.ToString;

@Entity
@ToString(callSuper = true)
public class DemandContractMapping extends ContractMapping {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.model;

import jakarta.persistence.Entity;
import lombok.ToString;

@Entity
@ToString(callSuper = true)
public class ProductionContractMapping extends ContractMapping {
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
public enum SubmodelType {
DTR("none", "none"),
ITEM_STOCK("urn:samm:io.catenax.item_stock:2.0.0#ItemStock", "$value"),
PRODUCTION("urn:samm:io.catenax.planned_production_output:2.0.0#PlannedProductionOutput", "$value"),
DEMAND("urn:samm:io.catenax.short_term_material_demand:1.0.0#ShortTermMaterialDemand", "$value"),
DELIVERY("urn:samm:io.catenax.delivery_information:2.0.0#DeliveryInformation", "$value"),
PART_TYPE_INFORMATION("urn:samm:io.catenax.part_type_information:1.0.0#PartTypeInformation", "$value");

public final String URN_SEMANTIC_ID;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.repository;

import org.eclipse.tractusx.puris.backend.common.edc.domain.model.ContractMapping;
import org.eclipse.tractusx.puris.backend.common.edc.domain.model.DeliveryContractMapping;
import org.springframework.stereotype.Repository;

@Repository
public interface DeliveryContractMappingRepository extends GeneralContractMappingRepository<DeliveryContractMapping> {

@Override
default Class<? extends ContractMapping> getType() {
return DeliveryContractMapping.class;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.repository;

import org.eclipse.tractusx.puris.backend.common.edc.domain.model.ContractMapping;
import org.eclipse.tractusx.puris.backend.common.edc.domain.model.DemandContractMapping;
import org.springframework.stereotype.Repository;

@Repository
public interface DemandContractMappingRepository extends GeneralContractMappingRepository<DemandContractMapping> {

@Override
default Class<? extends ContractMapping> getType() {
return DemandContractMapping.class;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Volkswagen AG
* Copyright (c) 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.puris.backend.common.edc.domain.repository;

import org.eclipse.tractusx.puris.backend.common.edc.domain.model.ContractMapping;
import org.eclipse.tractusx.puris.backend.common.edc.domain.model.ProductionContractMapping;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductionContractMappingRepository extends GeneralContractMappingRepository<ProductionContractMapping> {

@Override
default Class<? extends ContractMapping> getType() {
return ProductionContractMapping.class;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ public class EdcAdapterService {
@Autowired
private EdcContractMappingService edcContractMappingService;

private Pattern urnPattern = PatternStore.URN_OR_UUID_PATTERN;

private Pattern urlPattern = PatternStore.URL_PATTERN;

public EdcAdapterService(ObjectMapper objectMapper) {
Expand Down Expand Up @@ -130,7 +128,26 @@ public boolean registerAssetsInitially() {
boolean assetRegistration;
log.info("Registration of DTR Asset successful {}", (assetRegistration = registerDtrAsset()));
result &= assetRegistration;
log.info("Registration of ItemStock 2.0.0 submodel successful {}", (assetRegistration = registerItemStockSubmodel()));
log.info("Registration of ItemStock 2.0.0 submodel successful {}", (assetRegistration = registerSubmodelAsset(
variablesService.getItemStockSubmodelApiAssetId(),
variablesService.getItemStockSubmodelEndpoint(),
SubmodelType.ITEM_STOCK.URN_SEMANTIC_ID
)));
log.info("Registration of Planned Production 2.0.0 submodel successful {}", (assetRegistration = registerSubmodelAsset(
variablesService.getProductionSubmodelApiAssetId(),
variablesService.getProductionSubmodelEndpoint(),
SubmodelType.PRODUCTION.URN_SEMANTIC_ID
)));
log.info("Registration of Short Term Material Demand 1.0.0 submodel successful {}", (assetRegistration = registerSubmodelAsset(
variablesService.getDemandSubmodelApiAssetId(),
variablesService.getDemandSubmodelEndpoint(),
SubmodelType.DEMAND.URN_SEMANTIC_ID
)));
log.info("Registration of Delivery Information 2.0.0 submodel successful {}", (assetRegistration = registerSubmodelAsset(
variablesService.getDeliverySubmodelApiAssetId(),
variablesService.getDeliverySubmodelEndpoint(),
SubmodelType.DELIVERY.URN_SEMANTIC_ID
)));
result &= assetRegistration;
log.info("Registration of PartTypeInformation 1.0.0 submodel successful {}", (assetRegistration = registerPartTypeInfoSubmodelAsset()));
result &= assetRegistration;
Expand All @@ -147,25 +164,27 @@ public boolean registerAssetsInitially() {
*/
public boolean createPolicyAndContractDefForPartner(Partner partner) {
boolean result = createBpnlAndMembershipPolicyDefinitionForPartner(partner);
result &= createItemStockSubmodelContractDefinitionForPartner(partner);
result &= createSubmodelContractDefinitionForPartner(SubmodelType.ITEM_STOCK.URN_SEMANTIC_ID, variablesService.getItemStockSubmodelApiAssetId(), partner);
result &= createSubmodelContractDefinitionForPartner(SubmodelType.PRODUCTION.URN_SEMANTIC_ID, variablesService.getProductionSubmodelApiAssetId(), partner);
result &= createSubmodelContractDefinitionForPartner(SubmodelType.DEMAND.URN_SEMANTIC_ID, variablesService.getDemandSubmodelApiAssetId(), partner);
result &= createSubmodelContractDefinitionForPartner(SubmodelType.DELIVERY.URN_SEMANTIC_ID, variablesService.getDeliverySubmodelApiAssetId(), partner);
result &= createDtrContractDefinitionForPartner(partner);
return createPartTypeInfoContractDefForPartner(partner) && result;

return createSubmodelContractDefinitionForPartner(SubmodelType.PART_TYPE_INFORMATION.URN_SEMANTIC_ID, variablesService.getPartTypeSubmodelApiAssetId(), partner) && result;
}

private boolean createItemStockSubmodelContractDefinitionForPartner(Partner partner) {
var body = edcRequestBodyBuilder.buildItemStockSubmodelContractDefinitionWithBpnRestrictedPolicy(partner);
private boolean createSubmodelContractDefinitionForPartner(String semanticId, String assetId, Partner partner) {
var body = edcRequestBodyBuilder.buildSubmodelContractDefinitionWithBpnRestrictedPolicy(assetId, partner);
try (var response = sendPostRequest(body, List.of("v2", "contractdefinitions"))) {
if (!response.isSuccessful()) {
log.warn("Contract definition registration failed for partner " + partner.getBpnl() + " and ItemStock Submodel");
log.warn("Contract definition registration failed for partner " + partner.getBpnl() + " and {} Submodel", semanticId);
if (response.body() != null) {
log.warn("Response: \n" + response.body().string());
}
return false;
}
return true;
} catch (Exception e) {
log.error("Contract definition registration failed for partner " + partner.getBpnl() + " and ItemStock Submodel");
log.error("Contract definition registration failed for partner " + partner.getBpnl() + " and {} Submodel", semanticId);
return false;
}
}
Expand All @@ -184,22 +203,6 @@ private boolean createDtrContractDefinitionForPartner(Partner partner) {
}
}

private boolean createPartTypeInfoContractDefForPartner(Partner partner) {
var body = edcRequestBodyBuilder.buildPartTypeInfoContractDefinitionForPartner(partner);
try (var response = sendPostRequest(body, List.of("v2", "contractdefinitions"))) {
if (!response.isSuccessful()) {
log.warn("Contract definition registration failed for partner " + partner.getBpnl() + " and PartTypeInfo asset");
return false;
}
log.info("Contract definition successful for PartTypeAsset and partner " + partner.getBpnl());
return true;
} catch (Exception e) {
log.error("Contract definition registration failed for partner " + partner.getBpnl() + " and PartTypeInfo asset", e);
return false;
}
}


/**
* Registers a policy definition that evaluates to true in case all the following conditions apply:
* 1. The BPNL of the requesting connector is equal to the BPNL of the partner
Expand Down Expand Up @@ -283,24 +286,23 @@ private boolean registerPartTypeInfoSubmodelAsset() {
}
}

private boolean registerItemStockSubmodel() {
var body = edcRequestBodyBuilder.buildItemStockSubmodelRegistrationBody();
private boolean registerSubmodelAsset(String assetId, String endpoint, String semanticId) {
var body = edcRequestBodyBuilder.buildSubmodelRegistrationBody(assetId, endpoint, semanticId);
try (var response = sendPostRequest(body, List.of("v3", "assets"))) {
if (!response.isSuccessful()) {
log.warn("ItemStock Submodel Asset registration failed");
log.warn("{} Submodel Asset registration failed", semanticId);
if (response.body() != null) {
log.warn("Response: \n" + response.body().string());
}
return false;
}
return true;
} catch (Exception e) {
log.error("Failed to register ItemStock Submodel", e);
log.error("Failed to register {} Submodel", semanticId, e);
return false;
}
}


/**
* Retrieve the response to an unfiltered catalog request from the partner
* with the given dspUrl
Expand Down Expand Up @@ -489,7 +491,10 @@ private JsonNode getSubmodelFromPartner(MaterialPartnerRelation mpr, SubmodelTyp
Partner partner = mpr.getPartner();
SubmodelData submodelData = switch (type) {
case DTR -> throw new IllegalArgumentException("DTR not supported");
case ITEM_STOCK -> fetchItemStockSubmodelData(mpr, direction);
case ITEM_STOCK -> fetchSubmodelDataByDirection(mpr, SubmodelType.ITEM_STOCK.URN_SEMANTIC_ID, direction);
case PRODUCTION -> fetchSubmodelDataByDirection(mpr, SubmodelType.PRODUCTION.URN_SEMANTIC_ID, direction);
case DEMAND -> fetchSubmodelDataByDirection(mpr, SubmodelType.DEMAND.URN_SEMANTIC_ID, direction);
case DELIVERY -> fetchSubmodelDataByDirection(mpr, SubmodelType.DELIVERY.URN_SEMANTIC_ID, direction);
case PART_TYPE_INFORMATION -> fetchPartTypeSubmodelData(mpr);
};
boolean failed = true;
Expand Down Expand Up @@ -627,7 +632,7 @@ private boolean negotiateForPartnerDtr(Partner partner) {
}
}

private SubmodelData fetchItemStockSubmodelData(MaterialPartnerRelation mpr, DirectionCharacteristic direction) {
private SubmodelData fetchSubmodelDataByDirection(MaterialPartnerRelation mpr, String semanticId, DirectionCharacteristic direction) {
String manufacturerPartId = switch (direction) {
case INBOUND -> mpr.getMaterial().getOwnMaterialNumber();
case OUTBOUND -> mpr.getPartnerMaterialNumber();
Expand All @@ -636,7 +641,7 @@ private SubmodelData fetchItemStockSubmodelData(MaterialPartnerRelation mpr, Dir
case INBOUND -> variablesService.getOwnBpnl();
case OUTBOUND -> mpr.getPartner().getBpnl();
};
return fetchSubmodelData(mpr, "urn:samm:io.catenax.item_stock:2.0.0#ItemStock", manufacturerPartId, manufacturerId);
return fetchSubmodelData(mpr, semanticId, manufacturerPartId, manufacturerId);
}

private SubmodelData fetchPartTypeSubmodelData(MaterialPartnerRelation mpr) {
Expand Down Expand Up @@ -789,7 +794,10 @@ private boolean negotiateForSubmodel(MaterialPartnerRelation mpr, SubmodelType t
Partner partner = mpr.getPartner();
SubmodelData submodelData = switch (type) {
case DTR -> throw new IllegalArgumentException("DTR not supported");
case ITEM_STOCK -> fetchItemStockSubmodelData(mpr, direction);
case ITEM_STOCK -> fetchSubmodelDataByDirection(mpr, SubmodelType.ITEM_STOCK.URN_SEMANTIC_ID, direction);
case PRODUCTION -> fetchSubmodelDataByDirection(mpr, SubmodelType.PRODUCTION.URN_SEMANTIC_ID, direction);
case DEMAND -> fetchSubmodelDataByDirection(mpr, SubmodelType.DEMAND.URN_SEMANTIC_ID, direction);
case DELIVERY -> fetchSubmodelDataByDirection(mpr, SubmodelType.DELIVERY.URN_SEMANTIC_ID, direction);
case PART_TYPE_INFORMATION -> fetchPartTypeSubmodelData(mpr);
};
try {
Expand Down
Loading

0 comments on commit 5a3a496

Please sign in to comment.