Skip to content

Commit

Permalink
feature(irs-edc-client): #536 Specific exception thrown when id of cr…
Browse files Browse the repository at this point in the history
…eated resource already exists
  • Loading branch information
ds-ext-sceronik committed Mar 10, 2024
1 parent e9ca14a commit a75957b
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@
import org.eclipse.tractusx.irs.edc.client.asset.model.NotificationType;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.CreateEdcAssetException;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.DeleteEdcAssetException;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.EdcAssetAlreadyExistsException;
import org.eclipse.tractusx.irs.edc.client.transformer.EdcTransformer;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down Expand Up @@ -95,15 +97,13 @@ private String sendRequest(final Asset request) throws CreateEdcAssetException {
transformedPayload.toString(), String.class);
final HttpStatusCode responseCode = createEdcDataAssetResponse.getStatusCode();

if (responseCode.value() == HttpStatus.CONFLICT.value()) {
log.info("{} asset already exists in the EDC", request.getId());
return request.getId();
}

if (responseCode.value() == HttpStatus.OK.value()) {
return request.getId();
}
} catch (RestClientException e) {
} catch (HttpClientErrorException e) {
if (e.getStatusCode().value() == HttpStatus.CONFLICT.value()) {
throw new EdcAssetAlreadyExistsException("asset already exists in the EDC");
}
throw new CreateEdcAssetException(e);
}
throw new CreateEdcAssetException("Failed to create asset %s".formatted(request.getId()));
Expand All @@ -127,11 +127,10 @@ private Asset createNotificationAssetRequest(final String assetName, final Strin
final NotificationMethod notificationMethod, final NotificationType notificationType) {
final String assetId = UUID.randomUUID().toString();
final Map<String, Object> properties = Map.of(ASSET_CREATION_PROPERTY_DESCRIPTION, assetName,
ASSET_CREATION_PROPERTY_CONTENT_TYPE, DEFAULT_CONTENT_TYPE,
ASSET_CREATION_PROPERTY_POLICY_ID, DEFAULT_POLICY_ID, ASSET_CREATION_PROPERTY_TYPE,
notificationType.getValue(), ASSET_CREATION_PROPERTY_NOTIFICATION_TYPE,
notificationType.getValue(), ASSET_CREATION_PROPERTY_NOTIFICATION_METHOD,
notificationMethod.getValue());
ASSET_CREATION_PROPERTY_CONTENT_TYPE, DEFAULT_CONTENT_TYPE, ASSET_CREATION_PROPERTY_POLICY_ID,
DEFAULT_POLICY_ID, ASSET_CREATION_PROPERTY_TYPE, notificationType.getValue(),
ASSET_CREATION_PROPERTY_NOTIFICATION_TYPE, notificationType.getValue(),
ASSET_CREATION_PROPERTY_NOTIFICATION_METHOD, notificationMethod.getValue());

final DataAddress dataAddress = DataAddress.Builder.newInstance()
.type(HTTP_DATA)
Expand All @@ -152,8 +151,8 @@ private Asset createNotificationAssetRequest(final String assetName, final Strin
}

private Asset createDtrAssetRequest(final String assetId, final String baseUrl) {
final Map<String, Object> properties = Map.of(ASSET_CREATION_PROPERTY_DESCRIPTION, "Digital Twin Registry Asset", ASSET_CREATION_PROPERTY_TYPE,
"data.core.digitalTwinRegistry");
final Map<String, Object> properties = Map.of(ASSET_CREATION_PROPERTY_DESCRIPTION,
"Digital Twin Registry Asset", ASSET_CREATION_PROPERTY_TYPE, "data.core.digitalTwinRegistry");

final DataAddress dataAddress = DataAddress.Builder.newInstance()
.type("DataAddress")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* 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.edc.client.asset.model.exception;

/**
* EdcAssetAlreadyExistsException used when asset already exists
*/

public class EdcAssetAlreadyExistsException extends RuntimeException {
public EdcAssetAlreadyExistsException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* 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.edc.client.contract.model.exception;

/**
* EdcContractDefinitionAlreadyExists used when contract definition already exists
*/

public class EdcContractDefinitionAlreadyExists extends RuntimeException {
public EdcContractDefinitionAlreadyExists(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@

import static org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration.NAMESPACE_EDC;

import java.util.UUID;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.edc.client.EdcConfiguration;
import org.eclipse.tractusx.irs.edc.client.asset.model.EdcContext;
import org.eclipse.tractusx.irs.edc.client.contract.model.EdcContractDefinitionCriteria;
import org.eclipse.tractusx.irs.edc.client.contract.model.EdcCreateContractDefinitionRequest;
import org.eclipse.tractusx.irs.edc.client.contract.model.exception.CreateEdcContractDefinitionException;
import org.eclipse.tractusx.irs.edc.client.contract.model.exception.EdcContractDefinitionAlreadyExists;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

/**
Expand All @@ -52,8 +55,9 @@ public class EdcContractDefinitionService {

public String createContractDefinition(final String assetId, final String policyId)
throws CreateEdcContractDefinitionException {
final String contractId = UUID.randomUUID().toString();
final EdcCreateContractDefinitionRequest createContractDefinitionRequest = createContractDefinitionRequest(
assetId, policyId);
assetId, policyId, contractId);
final ResponseEntity<String> createContractDefinitionResponse;
try {
createContractDefinitionResponse = restTemplate.postForEntity(
Expand All @@ -62,19 +66,16 @@ public String createContractDefinition(final String assetId, final String policy

final HttpStatusCode responseCode = createContractDefinitionResponse.getStatusCode();

if (responseCode.value() == HttpStatus.CONFLICT.value()) {
log.info("{} contract definition already exists in the EDC", policyId);

return policyId;
}

if (responseCode.value() == HttpStatus.OK.value()) {
return policyId;
}

throw new CreateEdcContractDefinitionException(
"Failed to create EDC contract definition for %s notification asset id".formatted(assetId));
} catch (RestClientException e) {
"Failed to create EDC contract definition for %s asset id".formatted(assetId));
} catch (HttpClientErrorException e) {
if (e.getStatusCode().value() == HttpStatus.CONFLICT.value()) {
throw new EdcContractDefinitionAlreadyExists("Contract definition already exists in the EDC");
}
log.error(
"Failed to create edc contract definition for {} notification asset and {} policy definition id. Reason: ",
assetId, policyId, e);
Expand All @@ -85,7 +86,7 @@ public String createContractDefinition(final String assetId, final String policy
}

public EdcCreateContractDefinitionRequest createContractDefinitionRequest(final String assetId,
final String accessPolicyId) {
final String accessPolicyId, final String contractId) {
final EdcContractDefinitionCriteria edcContractDefinitionCriteria = EdcContractDefinitionCriteria.builder()
.type(ASSET_SELECTOR_TYPE)
.operandLeft(
Expand All @@ -102,7 +103,7 @@ public EdcCreateContractDefinitionRequest createContractDefinitionRequest(final
.edcContext(edcContext)
.type(CONTRACT_DEFINITION_TYPE)
.accessPolicyId(accessPolicyId)
.contractDefinitionId(accessPolicyId)
.contractDefinitionId(contractId)
.assetsSelector(edcContractDefinitionCriteria)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* 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.edc.client.policy.model.exception;

/**
* EdcPolicyDefinitionAlreadyExists used when policy already exists
*/

public class EdcPolicyDefinitionAlreadyExists extends RuntimeException {
public EdcPolicyDefinitionAlreadyExists(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
import org.eclipse.tractusx.irs.edc.client.policy.model.EdcPolicyPermissionConstraintExpression;
import org.eclipse.tractusx.irs.edc.client.policy.model.exception.CreateEdcPolicyDefinitionException;
import org.eclipse.tractusx.irs.edc.client.policy.model.exception.DeleteEdcPolicyDefinitionException;
import org.eclipse.tractusx.irs.edc.client.policy.model.exception.EdcPolicyDefinitionAlreadyExists;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down Expand Up @@ -80,20 +82,16 @@ public String createAccessPolicy(final EdcCreatePolicyDefinitionRequest policyRe
try {
createPolicyDefinitionResponse = restTemplate.postForEntity(
config.getControlplane().getEndpoint().getPolicyDefinition(), policyRequest, String.class);
} catch (RestClientException e) {
log.error("Failed to create EDC notification asset policy. Reason: ", e);

} catch (HttpClientErrorException e) {
log.error("Failed to create EDC policy definition. Reason: ", e);
if (e.getStatusCode().value() == HttpStatus.CONFLICT.value()) {
throw new EdcPolicyDefinitionAlreadyExists("Policy definition already exists in the EDC");
}
throw new CreateEdcPolicyDefinitionException(e);
}

final HttpStatusCode responseCode = createPolicyDefinitionResponse.getStatusCode();

if (responseCode.value() == HttpStatus.CONFLICT.value()) {
log.info("Notification asset policy definition already exists in the EDC");

return policyRequest.getPolicyDefinitionId();
}

if (responseCode.value() == HttpStatus.OK.value()) {
return policyRequest.getPolicyDefinitionId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.eclipse.tractusx.irs.edc.client.asset.model.NotificationType;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.CreateEdcAssetException;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.DeleteEdcAssetException;
import org.eclipse.tractusx.irs.edc.client.asset.model.exception.EdcAssetAlreadyExistsException;
import org.eclipse.tractusx.irs.edc.client.transformer.EdcTransformer;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -57,7 +58,9 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

Expand Down Expand Up @@ -93,8 +96,10 @@ void setUp() {
@Test
void testAssetCreateRequestStructure() throws JSONException, JsonProcessingException {

Map<String, Object> properties = Map.of("https://w3id.org/edc/v0.0.1/ns/description", "endpoint to qualityinvestigation receive",
"https://w3id.org/edc/v0.0.1/ns/contenttype", "application/json", "https://w3id.org/edc/v0.0.1/ns/policy-id", "use-eu", "https://w3id.org/edc/v0.0.1/ns/type", "receive", "https://w3id.org/edc/v0.0.1/ns/notificationtype",
Map<String, Object> properties = Map.of("https://w3id.org/edc/v0.0.1/ns/description",
"endpoint to qualityinvestigation receive", "https://w3id.org/edc/v0.0.1/ns/contenttype",
"application/json", "https://w3id.org/edc/v0.0.1/ns/policy-id", "use-eu",
"https://w3id.org/edc/v0.0.1/ns/type", "receive", "https://w3id.org/edc/v0.0.1/ns/notificationtype",
"qualityinvestigation", "https://w3id.org/edc/v0.0.1/ns/notificationmethod", "receive");

DataAddress dataAddress = DataAddress.Builder.newInstance()
Expand Down Expand Up @@ -224,33 +229,33 @@ void givenDeleteAsset_whenOk_ThenReturnCreatedAssetId() throws DeleteEdcAssetExc
}

@Test
void givenCreateDtrAsset_whenOK_ThenThrowException() {
void givenCreateDtrAsset_whenBadRequest_ThenThrowException() {
// given
when(edcConfiguration.getControlplane()).thenReturn(controlplaneConfig);
when(controlplaneConfig.getEndpoint()).thenReturn(endpointConfig);
when(endpointConfig.getAsset()).thenReturn("/management/v2/assets");
String baseUrl = "http://test.test";
String assetName = "asset1";
doThrow(new RestClientException("Surprise")).when(restTemplate)
.postForEntity(any(String.class), any(String.class), any());
doThrow(HttpClientErrorException.create("Surprise", HttpStatus.BAD_REQUEST, "", null, null, null)).when(
restTemplate).postForEntity(any(String.class), any(String.class), any());

// when/then
assertThrows(CreateEdcAssetException.class, () -> service.createDtrAsset(baseUrl, assetName));
}

@Test
void givenCreateDtrAsset_whenTemplateException_ThenThrowException() {
void givenCreateDtrAsset_whenConflict_ThenThrowException() {
// given
when(edcConfiguration.getControlplane()).thenReturn(controlplaneConfig);
when(controlplaneConfig.getEndpoint()).thenReturn(endpointConfig);
when(endpointConfig.getAsset()).thenReturn("/management/v2/assets");
String baseUrl = "http://test.test";
String assetName = "asset1";
doThrow(new RestClientException("Surprise")).when(restTemplate)
.postForEntity(any(String.class), any(String.class), any());
doThrow(HttpClientErrorException.create("Surprise", HttpStatus.CONFLICT, "", null, null, null)).when(
restTemplate).postForEntity(any(String.class), any(String.class), any());

// when/then
assertThrows(CreateEdcAssetException.class, () -> service.createDtrAsset(baseUrl, assetName));
assertThrows(EdcAssetAlreadyExistsException.class, () -> service.createDtrAsset(baseUrl, assetName));
}

@Test
Expand Down
Loading

0 comments on commit a75957b

Please sign in to comment.