diff --git a/DEPENDENCIES b/DEPENDENCIES index 8f6d18a4d..2c23bcd70 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -452,52 +452,52 @@ maven/mavencentral/org.testcontainers/vault/1.19.1, MIT, approved, #10852 maven/mavencentral/org.yaml/snakeyaml/2.0, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #7275 maven/mavencentral/org.yaml/snakeyaml/2.2, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #10232 maven/mavencentral/software.amazon.awssdk/annotations/2.20.146, Apache-2.0, approved, #8598 -maven/mavencentral/software.amazon.awssdk/annotations/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/annotations/2.21.5, Apache-2.0, approved, #11137 maven/mavencentral/software.amazon.awssdk/apache-client/2.20.146, Apache-2.0, approved, #8609 -maven/mavencentral/software.amazon.awssdk/apache-client/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/apache-client/2.21.5, Apache-2.0, approved, #11133 maven/mavencentral/software.amazon.awssdk/arns/2.20.146, Apache-2.0, approved, #8616 -maven/mavencentral/software.amazon.awssdk/arns/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/arns/2.21.5, Apache-2.0, approved, #11143 maven/mavencentral/software.amazon.awssdk/auth/2.20.146, Apache-2.0, approved, #8602 -maven/mavencentral/software.amazon.awssdk/auth/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/auth/2.21.5, Apache-2.0, approved, #11139 maven/mavencentral/software.amazon.awssdk/aws-core/2.20.146, Apache-2.0, approved, #8612 -maven/mavencentral/software.amazon.awssdk/aws-core/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/aws-core/2.21.5, Apache-2.0, approved, #11126 maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.20.146, Apache-2.0, approved, #8629 -maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.21.5, Apache-2.0, approved, #11123 maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.20.146, Apache-2.0, approved, #8624 -maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.21.5, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/checksums-spi/2.21.5, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/checksums/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.21.5, Apache-2.0, approved, #11124 +maven/mavencentral/software.amazon.awssdk/checksums-spi/2.21.5, Apache-2.0, approved, #11131 +maven/mavencentral/software.amazon.awssdk/checksums/2.21.5, Apache-2.0, approved, #11134 maven/mavencentral/software.amazon.awssdk/crt-core/2.20.146, Apache-2.0, approved, #8627 -maven/mavencentral/software.amazon.awssdk/crt-core/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/crt-core/2.21.5, Apache-2.0, approved, #11130 maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.20.146, Apache-2.0, approved, #8604 -maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.21.5, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/http-auth-aws/2.21.5, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/http-auth-spi/2.21.5, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/http-auth/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.21.5, Apache-2.0, approved, #11118 +maven/mavencentral/software.amazon.awssdk/http-auth-aws/2.21.5, Apache-2.0, approved, #11145 +maven/mavencentral/software.amazon.awssdk/http-auth-spi/2.21.5, Apache-2.0, approved, #11128 +maven/mavencentral/software.amazon.awssdk/http-auth/2.21.5, Apache-2.0, approved, #11120 maven/mavencentral/software.amazon.awssdk/http-client-spi/2.20.146, Apache-2.0, approved, #8608 -maven/mavencentral/software.amazon.awssdk/http-client-spi/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/http-client-spi/2.21.5, Apache-2.0, approved, #11132 maven/mavencentral/software.amazon.awssdk/iam/2.20.146, Apache-2.0, approved, #9271 -maven/mavencentral/software.amazon.awssdk/identity-spi/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/identity-spi/2.21.5, Apache-2.0, approved, #11129 maven/mavencentral/software.amazon.awssdk/json-utils/2.20.146, Apache-2.0, approved, #8614 -maven/mavencentral/software.amazon.awssdk/json-utils/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/json-utils/2.21.5, Apache-2.0, approved, #11119 maven/mavencentral/software.amazon.awssdk/metrics-spi/2.20.146, Apache-2.0, approved, #8636 -maven/mavencentral/software.amazon.awssdk/metrics-spi/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/metrics-spi/2.21.5, Apache-2.0, approved, #11144 maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.20.146, Apache-2.0, approved, #8613 -maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.21.5, Apache-2.0, approved, #11140 maven/mavencentral/software.amazon.awssdk/profiles/2.20.146, Apache-2.0, approved, #8600 -maven/mavencentral/software.amazon.awssdk/profiles/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/profiles/2.21.5, Apache-2.0, approved, #11148 maven/mavencentral/software.amazon.awssdk/protocol-core/2.20.146, Apache-2.0, approved, #8635 -maven/mavencentral/software.amazon.awssdk/protocol-core/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/protocol-core/2.21.5, Apache-2.0, approved, #11141 maven/mavencentral/software.amazon.awssdk/regions/2.20.146, Apache-2.0, approved, #8632 -maven/mavencentral/software.amazon.awssdk/regions/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/regions/2.21.5, Apache-2.0, approved, #11142 maven/mavencentral/software.amazon.awssdk/s3-transfer-manager/2.21.5, , restricted, clearlydefined maven/mavencentral/software.amazon.awssdk/s3/2.20.146, Apache-2.0, approved, #8623 -maven/mavencentral/software.amazon.awssdk/s3/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/s3/2.21.5, Apache-2.0, approved, #11135 maven/mavencentral/software.amazon.awssdk/sdk-core/2.20.146, Apache-2.0, approved, #8611 -maven/mavencentral/software.amazon.awssdk/sdk-core/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/sdk-core/2.21.5, Apache-2.0, approved, #11121 maven/mavencentral/software.amazon.awssdk/sts/2.20.146, Apache-2.0, approved, #9269 maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.20.146, Apache-2.0, approved, #8622 -maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.21.5, Apache-2.0, approved, #11127 maven/mavencentral/software.amazon.awssdk/utils/2.20.146, Apache-2.0, approved, #8625 -maven/mavencentral/software.amazon.awssdk/utils/2.21.5, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/utils/2.21.5, Apache-2.0, approved, #11136 maven/mavencentral/software.amazon.eventstream/eventstream/1.0.1, Apache-2.0, approved, clearlydefined diff --git a/core/edr-cache-core/src/main/java/org/eclipse/tractusx/edc/edr/core/defaults/EdrCacheEntryPredicateConverter.java b/core/edr-cache-core/src/main/java/org/eclipse/tractusx/edc/edr/core/defaults/EdrCacheEntryPredicateConverter.java index 23845d991..ec725a6ee 100644 --- a/core/edr-cache-core/src/main/java/org/eclipse/tractusx/edc/edr/core/defaults/EdrCacheEntryPredicateConverter.java +++ b/core/edr-cache-core/src/main/java/org/eclipse/tractusx/edc/edr/core/defaults/EdrCacheEntryPredicateConverter.java @@ -32,6 +32,12 @@ */ public class EdrCacheEntryPredicateConverter implements CriterionToPredicateConverter { + public static final String ASSET_ID = "assetId"; + public static final String AGREEMENT_ID = "agreementId"; + public static final String PROVIDER_ID = "providerId"; + public static final String CONTRACT_NEGOTIATION_ID = "contractNegotiationId"; + public static final String STATE = "state"; + @Override public Predicate convert(Criterion criterion) { var operator = criterion.getOperator().toLowerCase(); @@ -40,10 +46,25 @@ public Predicate convert(Criterion criterion) { case "=" -> equalPredicate(criterion); case "in" -> inPredicate(criterion); case "like" -> likePredicate(criterion); - default -> throw new IllegalArgumentException(format("Operator [%s] is not supported by this converter!", criterion.getOperator())); + default -> + throw new IllegalArgumentException(format("Operator [%s] is not supported by this converter!", criterion.getOperator())); }; } + protected Object property(String key, Object object) { + if (object instanceof EndpointDataReferenceEntry entry) { + return switch (key) { + case ASSET_ID -> entry.getAssetId(); + case AGREEMENT_ID -> entry.getAgreementId(); + case PROVIDER_ID -> entry.getProviderId(); + case CONTRACT_NEGOTIATION_ID -> entry.getContractNegotiationId(); + case STATE -> entry.getState(); + default -> null; + }; + } + throw new IllegalArgumentException("Can only handle objects of type " + EndpointDataReferenceEntry.class.getSimpleName() + " but received an " + object.getClass().getSimpleName()); + } + @NotNull private Predicate equalPredicate(Criterion criterion) { return t -> { @@ -117,17 +138,4 @@ private Predicate likePredicate(Criterion criterion) { return false; }; } - - protected Object property(String key, Object object) { - if (object instanceof EndpointDataReferenceEntry entry) { - return switch (key) { - case "assetId" -> entry.getAssetId(); - case "agreementId" -> entry.getAgreementId(); - case "providerId" -> entry.getProviderId(); - case "state" -> entry.getState(); - default -> null; - }; - } - throw new IllegalArgumentException("Can only handle objects of type " + EndpointDataReferenceEntry.class.getSimpleName() + " but received an " + object.getClass().getSimpleName()); - } } diff --git a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrApi.java b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrApi.java index a09601b36..cfc92db32 100644 --- a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrApi.java +++ b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrApi.java @@ -49,7 +49,7 @@ public interface EdrApi { @ApiResponse(responseCode = "400", description = "Request was malformed", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) } ) - JsonArray queryEdrs(String assetId, String agreementId, String providerId); + JsonArray queryEdrs(String assetId, String agreementId, String contractNegotiationId, String providerId); @Operation(description = "Gets an EDR with the given transfer process ID", responses = { diff --git a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrController.java b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrController.java index 79abbdb5c..99bcbc02b 100644 --- a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrController.java +++ b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrController.java @@ -47,6 +47,7 @@ import static org.eclipse.tractusx.edc.api.edr.dto.NegotiateEdrRequestDto.EDR_REQUEST_DTO_TYPE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.AGREEMENT_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.ASSET_ID; +import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.CONTRACT_NEGOTIATION_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.PROVIDER_ID; @Consumes({ MediaType.APPLICATION_JSON }) @@ -89,11 +90,14 @@ public JsonObject initiateEdrNegotiation(JsonObject requestObject) { @GET @Override - public JsonArray queryEdrs(@QueryParam("assetId") String assetId, @QueryParam("agreementId") String agreementId, @QueryParam("providerId") String providerId) { - if (assetId == null && agreementId == null) { - throw new InvalidRequestException("At least one of this query parameter is required [assetId,agreementId]"); + public JsonArray queryEdrs(@QueryParam("assetId") String assetId, + @QueryParam("agreementId") String agreementId, + @QueryParam("contractNegotiationId") String contractNegotiationId, + @QueryParam("providerId") String providerId) { + if (assetId == null && agreementId == null && contractNegotiationId == null) { + throw new InvalidRequestException("At least one of this query parameter is required [assetId, agreementId, contractNegotiationId]"); } - return edrService.findBy(querySpec(assetId, agreementId, providerId)) + return edrService.findBy(querySpec(assetId, agreementId, contractNegotiationId, providerId)) .orElseThrow(exceptionMapper(EndpointDataReferenceEntry.class)) .stream() .map(edrCached -> transformerRegistry.transform(edrCached, JsonObject.class)) @@ -124,7 +128,7 @@ private void logIfError(Result result) { result.onFailure(f -> monitor.warning(f.getFailureDetail())); } - private QuerySpec querySpec(String assetId, String agreementId, String providerId) { + private QuerySpec querySpec(String assetId, String agreementId, String contractNegotiationId, String providerId) { var queryBuilder = QuerySpec.Builder.newInstance(); if (assetId != null) { queryBuilder.filter(fieldFilter(ASSET_ID, assetId)); @@ -132,6 +136,9 @@ private QuerySpec querySpec(String assetId, String agreementId, String providerI if (agreementId != null) { queryBuilder.filter(fieldFilter(AGREEMENT_ID, agreementId)); } + if (contractNegotiationId != null) { + queryBuilder.filter(fieldFilter(CONTRACT_NEGOTIATION_ID, contractNegotiationId)); + } if (providerId != null) { queryBuilder.filter(fieldFilter(PROVIDER_ID, providerId)); } diff --git a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java index ce0d1ef97..f0dd211cf 100644 --- a/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java +++ b/edc-extensions/edr/edr-api/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java @@ -25,6 +25,7 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_AGREEMENT_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_ASSET_ID; +import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_CONTRACT_NEGOTIATION_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_EXPIRATION_DATE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_PROVIDER_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_STATE; @@ -40,15 +41,24 @@ public JsonObjectFromEndpointDataReferenceEntryTransformer() { @Override public @Nullable JsonObject transform(@NotNull EndpointDataReferenceEntry dto, @NotNull TransformerContext context) { - return Json.createObjectBuilder() + + var builder = Json.createObjectBuilder() .add(TYPE, EDR_ENTRY_TYPE) .add(EDR_ENTRY_AGREEMENT_ID, dto.getAgreementId()) .add(EDR_ENTRY_TRANSFER_PROCESS_ID, dto.getTransferProcessId()) .add(EDR_ENTRY_ASSET_ID, dto.getAssetId()) - .add(EDR_ENTRY_PROVIDER_ID, dto.getProviderId()) .add(EDR_ENTRY_STATE, dto.getEdrState()) - .add(EDR_ENTRY_EXPIRATION_DATE, dto.getExpirationTimestamp()) - .build(); + .add(EDR_ENTRY_EXPIRATION_DATE, dto.getExpirationTimestamp()); + + if (dto.getProviderId() != null) { + builder.add(EDR_ENTRY_PROVIDER_ID, dto.getProviderId()); + } + + if (dto.getContractNegotiationId() != null) { + builder.add(EDR_ENTRY_CONTRACT_NEGOTIATION_ID, dto.getContractNegotiationId()); + } + + return builder.build(); } diff --git a/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrControllerTest.java b/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrControllerTest.java index 11e122553..81ae69845 100644 --- a/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrControllerTest.java +++ b/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrControllerTest.java @@ -58,8 +58,10 @@ import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.AGREEMENT_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.ASSET_ID; +import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.CONTRACT_NEGOTIATION_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_AGREEMENT_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_ASSET_ID; +import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_CONTRACT_NEGOTIATION_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_PROVIDER_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_STATE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_TRANSFER_PROCESS_ID; @@ -269,6 +271,53 @@ void queryEdrs_shouldReturnCachedEntries_whenAgreementIdIsProvided() { .body("[0].'edc:providerId'", is(entry.getProviderId())); } + @Test + void queryEdrs_shouldReturnCachedEntries_whenContractNegotiationIdIsProvided() { + var assetId = "assetId"; + var transferProcessId = "transferProcessId"; + var agreementId = "agreementId"; + var providerId = "providerId"; + var contractNegotiationId = "contractNegotiationId"; + + var entry = EndpointDataReferenceEntry.Builder.newInstance() + .transferProcessId(transferProcessId) + .agreementId(agreementId) + .assetId(assetId) + .providerId(providerId) + .contractNegotiationId(contractNegotiationId) + .build(); + + + var response = Json.createObjectBuilder() + .add(TYPE, EDR_ENTRY_TYPE) + .add(EDR_ENTRY_ASSET_ID, entry.getAssetId()) + .add(EDR_ENTRY_TRANSFER_PROCESS_ID, entry.getTransferProcessId()) + .add(EDR_ENTRY_AGREEMENT_ID, entry.getAgreementId()) + .add(EDR_ENTRY_CONTRACT_NEGOTIATION_ID, entry.getContractNegotiationId()) + .add(EDR_ENTRY_PROVIDER_ID, entry.getProviderId()) + .build(); + + var filter = QuerySpec.Builder.newInstance() + .filter(fieldFilter(CONTRACT_NEGOTIATION_ID, contractNegotiationId)) + .filter(fieldFilter(PROVIDER_ID, entry.getProviderId())) + .build(); + + when(edrService.findBy(eq(filter))).thenReturn(ServiceResult.success(List.of(entry))); + when(transformerRegistry.transform(any(EndpointDataReferenceEntry.class), eq(JsonObject.class))).thenReturn(Result.success(response)); + + baseRequest() + .contentType(MediaType.APPLICATION_JSON) + .get(EDR_PATH + format("?=contractNegotiationId=%s&providerId=%s", entry.getContractNegotiationId(), entry.getProviderId())) + .then() + .log().all(true) + .statusCode(200) + .body("[0].'edc:transferProcessId'", is(entry.getTransferProcessId())) + .body("[0].'edc:agreementId'", is(entry.getAgreementId())) + .body("[0].'edc:contractNegotiationId'", is(entry.getContractNegotiationId())) + .body("[0].'edc:assetId'", is(entry.getAssetId())) + .body("[0].'edc:providerId'", is(entry.getProviderId())); + } + @Test void deleteEdr() { var transferProcessId = "id"; diff --git a/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java b/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java index a038ee1e0..b500f29f4 100644 --- a/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java +++ b/edc-extensions/edr/edr-api/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_AGREEMENT_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_ASSET_ID; +import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_CONTRACT_NEGOTIATION_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_EXPIRATION_DATE; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_PROVIDER_ID; import static org.eclipse.tractusx.edc.edr.spi.types.EndpointDataReferenceEntry.EDR_ENTRY_STATE; @@ -49,6 +50,7 @@ void transform() { .transferProcessId("tpId") .agreementId("aId") .providerId("providerId") + .contractNegotiationId("contractNegotiationId") .state(EndpointDataReferenceEntryStates.NEGOTIATED.code()) .expirationTimestamp(Instant.now().toEpochMilli()) .build(); @@ -57,6 +59,7 @@ void transform() { assertThat(jsonObject).isNotNull(); assertThat(jsonObject.getJsonString(EDR_ENTRY_AGREEMENT_ID).getString()).isNotNull().isEqualTo(dto.getAgreementId()); + assertThat(jsonObject.getJsonString(EDR_ENTRY_CONTRACT_NEGOTIATION_ID).getString()).isNotNull().isEqualTo(dto.getContractNegotiationId()); assertThat(jsonObject.getJsonString(EDR_ENTRY_ASSET_ID).getString()).isNotNull().isEqualTo(dto.getAssetId()); assertThat(jsonObject.getJsonString(EDR_ENTRY_TRANSFER_PROCESS_ID).getString()).isNotNull().isEqualTo(dto.getTransferProcessId()); assertThat(jsonObject.getJsonString(EDR_ENTRY_PROVIDER_ID).getString()).isNotNull().isEqualTo(dto.getProviderId()); diff --git a/edc-extensions/edr/edr-cache-sql/docs/schema.sql b/edc-extensions/edr/edr-cache-sql/docs/schema.sql index 9e707af1b..24a94045f 100644 --- a/edc-extensions/edr/edr-cache-sql/docs/schema.sql +++ b/edc-extensions/edr/edr-cache-sql/docs/schema.sql @@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS edc_edr_cache agreement_id VARCHAR NOT NULL, asset_id VARCHAR NOT NULL, edr_id VARCHAR NOT NULL, + contract_negotiation_id VARCHAR, provider_id VARCHAR, expiration_timestamp BIGINT, state INTEGER DEFAULT 0 NOT NULL, diff --git a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/SqlEndpointDataReferenceCache.java b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/SqlEndpointDataReferenceCache.java index 8b22138cc..5da73c62f 100644 --- a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/SqlEndpointDataReferenceCache.java +++ b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/SqlEndpointDataReferenceCache.java @@ -135,6 +135,7 @@ public void save(EndpointDataReferenceEntry entry, EndpointDataReference edr) { entry.getAgreementId(), edr.getId(), entry.getProviderId(), + entry.getContractNegotiationId(), entry.getExpirationTimestamp(), entry.getState(), entry.getStateCount(), @@ -253,6 +254,7 @@ private EndpointDataReferenceEntry mapResultSet(ResultSet resultSet) throws SQLE .transferProcessId(resultSet.getString(statements.getTransferProcessIdColumn())) .assetId(resultSet.getString(statements.getAssetIdColumn())) .agreementId(resultSet.getString(statements.getAgreementIdColumn())) + .contractNegotiationId(resultSet.getString(statements.getContractNegotiationIdColumn())) .providerId(resultSet.getString(statements.getProviderIdColumn())) .state(resultSet.getInt(statements.getStateColumn())) .stateTimestamp(resultSet.getLong(statements.getStateTimestampColumn())) diff --git a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/BaseSqlEdrStatements.java b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/BaseSqlEdrStatements.java index ddd2d462d..3b22f8d41 100644 --- a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/BaseSqlEdrStatements.java +++ b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/BaseSqlEdrStatements.java @@ -34,13 +34,14 @@ public SqlQueryStatement createQuery(QuerySpec querySpec) { @Override public String getInsertTemplate() { - return format("INSERT INTO %s (%s, %s, %s, %s,%s, %s, %s, %s, %s, %s, %s, %s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + return format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", getEdrTable(), getTransferProcessIdColumn(), getAssetIdColumn(), getAgreementIdColumn(), getEdrId(), getProviderIdColumn(), + getContractNegotiationIdColumn(), getExpirationTimestampColumn(), getStateColumn(), getStateCountColumn(), diff --git a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrMapping.java b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrMapping.java index fa75652a3..2a99d2c35 100644 --- a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrMapping.java +++ b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrMapping.java @@ -26,6 +26,7 @@ public EdrMapping(EdrStatements statements) { add("assetId", statements.getAssetIdColumn()); add("agreementId", statements.getAgreementIdColumn()); add("providerId", statements.getProviderIdColumn()); + add("contractNegotiationId", statements.getContractNegotiationIdColumn()); add("state", statements.getStateColumn()); } } diff --git a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrStatements.java b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrStatements.java index 9414a3d1b..68a980050 100644 --- a/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrStatements.java +++ b/edc-extensions/edr/edr-cache-sql/src/main/java/org/eclipse/tractusx/edc/edr/store/sql/schema/EdrStatements.java @@ -39,6 +39,10 @@ default String getProviderIdColumn() { return "provider_id"; } + default String getContractNegotiationIdColumn() { + return "contract_negotiation_id"; + } + default String getAssetIdColumn() { return "asset_id"; } diff --git a/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/LocalCallbackExtension.java b/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/LocalCallbackExtension.java index 1eb68859e..bf2a76534 100644 --- a/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/LocalCallbackExtension.java +++ b/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/LocalCallbackExtension.java @@ -15,6 +15,7 @@ package org.eclipse.tractusx.edc.callback; import org.eclipse.edc.connector.spi.callback.CallbackProtocolResolverRegistry; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; import org.eclipse.edc.connector.transfer.spi.store.TransferProcessStore; import org.eclipse.edc.runtime.metamodel.annotation.Extension; @@ -62,6 +63,9 @@ public class LocalCallbackExtension implements ServiceExtension { @Inject private EndpointDataReferenceCache endpointDataReferenceCache; + @Inject + private ContractAgreementService agreementService; + @Inject private TypeTransformerRegistry transformerRegistry; @@ -74,7 +78,7 @@ public String name() { public void initialize(ServiceExtensionContext context) { callbackRegistry.registerHandler(new ContractNegotiationCallback(transferProcessService, monitor)); - callbackRegistry.registerHandler(new TransferProcessLocalCallback(edrCache, transferProcessStore, transformerRegistry, transactionContext, monitor)); + callbackRegistry.registerHandler(new TransferProcessLocalCallback(edrCache, transferProcessStore, agreementService, transformerRegistry, transactionContext, monitor)); resolverRegistry.registerResolver(this::resolveProtocol); registry.register(new InProcessCallbackMessageDispatcher(callbackRegistry)); diff --git a/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallback.java b/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallback.java index 50c1791a5..b05593f2e 100644 --- a/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallback.java +++ b/edc-extensions/edr/edr-callback/src/main/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallback.java @@ -16,6 +16,7 @@ import com.nimbusds.jwt.SignedJWT; import org.eclipse.edc.connector.spi.callback.CallbackEventRemoteMessage; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; import org.eclipse.edc.connector.transfer.spi.event.TransferProcessStarted; import org.eclipse.edc.connector.transfer.spi.store.TransferProcessStore; import org.eclipse.edc.spi.event.Event; @@ -41,14 +42,16 @@ public class TransferProcessLocalCallback implements InProcessCallback { private final EndpointDataReferenceCache edrCache; private final TransferProcessStore transferProcessStore; private final TypeTransformerRegistry transformerRegistry; - private final TransactionContext transactionContext; - private final Monitor monitor; + private final ContractAgreementService agreementService; - public TransferProcessLocalCallback(EndpointDataReferenceCache edrCache, TransferProcessStore transferProcessStore, TypeTransformerRegistry transformerRegistry, TransactionContext transactionContext, Monitor monitor) { + public TransferProcessLocalCallback(EndpointDataReferenceCache edrCache, TransferProcessStore transferProcessStore, + ContractAgreementService agreementService, TypeTransformerRegistry transformerRegistry, + TransactionContext transactionContext, Monitor monitor) { this.edrCache = edrCache; this.transferProcessStore = transferProcessStore; + this.agreementService = agreementService; this.transformerRegistry = transformerRegistry; this.transactionContext = transactionContext; this.monitor = monitor; @@ -69,7 +72,15 @@ public Result invoke(CallbackEventRemoteMessage messa private Result storeEdr(EndpointDataReference edr) { return transactionContext.execute(() -> { var transferProcess = transferProcessStore.findForCorrelationId(edr.getId()); + if (transferProcess != null) { + String contractNegotiationId = null; + var contractNegotiation = agreementService.findNegotiation(transferProcess.getContractId()); + if (contractNegotiation != null) { + contractNegotiationId = contractNegotiation.getId(); + } else { + monitor.warning(format("Contract negotiation for agreement with id: %s is missing.", transferProcess.getContractId())); + } var expirationTime = extractExpirationTime(edr); if (expirationTime.failed()) { @@ -82,6 +93,7 @@ private Result storeEdr(EndpointDataReference edr) { .providerId(transferProcess.getDataRequest().getConnectorId()) .state(EndpointDataReferenceEntryStates.NEGOTIATED.code()) .expirationTimestamp(expirationTime.getContent()) + .contractNegotiationId(contractNegotiationId) .build(); cleanOldEdr(transferProcess.getDataRequest().getAssetId(), transferProcess.getDataRequest().getContractId()); diff --git a/edc-extensions/edr/edr-callback/src/test/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallbackTest.java b/edc-extensions/edr/edr-callback/src/test/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallbackTest.java index 19c5d280e..b64b82e89 100644 --- a/edc-extensions/edr/edr-callback/src/test/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallbackTest.java +++ b/edc-extensions/edr/edr-callback/src/test/java/org/eclipse/tractusx/edc/callback/TransferProcessLocalCallbackTest.java @@ -14,6 +14,7 @@ package org.eclipse.tractusx.edc.callback; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; import org.eclipse.edc.connector.transfer.spi.event.TransferProcessCompleted; import org.eclipse.edc.connector.transfer.spi.event.TransferProcessDeprovisioned; import org.eclipse.edc.connector.transfer.spi.event.TransferProcessEvent; @@ -63,19 +64,21 @@ public class TransferProcessLocalCallbackTest { - TransferProcessStore transferProcessStore = mock(TransferProcessStore.class); - EndpointDataReferenceCache edrCache = mock(EndpointDataReferenceCache.class); + TransferProcessStore transferProcessStore = mock(); + EndpointDataReferenceCache edrCache = mock(); TransactionContext transactionContext = new NoopTransactionContext(); TransferProcessLocalCallback callback; + ContractAgreementService agreementService = mock(); + TypeTransformerRegistry transformerRegistry = mock(TypeTransformerRegistry.class); @BeforeEach void setup() { - callback = new TransferProcessLocalCallback(edrCache, transferProcessStore, transformerRegistry, transactionContext, mock(Monitor.class)); + callback = new TransferProcessLocalCallback(edrCache, transferProcessStore, agreementService, transformerRegistry, transactionContext, mock(Monitor.class)); } @Test @@ -122,7 +125,7 @@ void invoke_shouldStoreTheEdrInCache_whenDataAddressIsPresent() { verify(edrCache).save(cacheEntryCaptor.capture(), edrCaptor.capture()); verify(edrCache).update(argThat(entry -> entry.getState() == EndpointDataReferenceEntryStates.EXPIRED.code())); - + assertThat(edrCaptor.getValue()).usingRecursiveComparison().isEqualTo(edr); } diff --git a/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/edr/V0_0_4__Add_ContractNegotiationId_Column.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/edr/V0_0_4__Add_ContractNegotiationId_Column.sql new file mode 100644 index 000000000..291f325c3 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/edr/V0_0_4__Add_ContractNegotiationId_Column.sql @@ -0,0 +1,19 @@ +-- +-- Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +-- +-- 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 +-- +-- SPDX-License-Identifier: Apache-2.0 +-- +-- Contributors: +-- Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation +-- + +-- Statements are designed for and tested with Postgres only! + + +-- add column +ALTER TABLE edc_edr_cache ADD COLUMN contract_negotiation_id VARCHAR; + diff --git a/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/lifecycle/Participant.java b/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/lifecycle/Participant.java index da0c45b30..d807494fe 100644 --- a/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/lifecycle/Participant.java +++ b/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/lifecycle/Participant.java @@ -242,6 +242,17 @@ public JsonArray getEdrEntriesByAssetId(String assetId) { .as(JsonArray.class); } + public JsonArray getEdrEntriesByContractNegotiationId(String contractNegotiationId) { + return baseRequest() + .when() + .get("/edrs?contractNegotiationId={contractNegotiationId}", contractNegotiationId) + .then() + .statusCode(200) + .extract() + .body() + .as(JsonArray.class); + } + public JsonArray getEdrEntriesByAgreementId(String agreementId) { return baseRequest() .when() diff --git a/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/tests/edr/AbstractNegotiateEdrTest.java b/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/tests/edr/AbstractNegotiateEdrTest.java index 71a54ebc9..82aabe165 100644 --- a/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/tests/edr/AbstractNegotiateEdrTest.java +++ b/edc-tests/e2e-tests/src/test/java/org/eclipse/tractusx/edc/tests/edr/AbstractNegotiateEdrTest.java @@ -111,7 +111,7 @@ void negotiateEdr_shouldInvokeCallbacks() throws IOException { .add(createCallback(url.toString(), true, Set.of("contract.negotiation", "transfer.process"))) .build(); - SOKRATES.negotiateEdr(PLATO, assetId, callbacks); + var contractNegotiationId = SOKRATES.negotiateEdr(PLATO, assetId, callbacks); var events = expectedEvents.stream() .map(receivedEvent -> waitForEvent(server, receivedEvent)) @@ -131,7 +131,17 @@ void negotiateEdr_shouldInvokeCallbacks() throws IOException { assertThat(edrCaches).hasSize(1); + assertThat(SOKRATES.getEdrEntriesByContractNegotiationId(contractNegotiationId)).hasSize(1); + + assertThat(edrCaches).hasSize(1); + var transferProcessId = edrCaches.get(0).asJsonObject().getString("edc:transferProcessId"); + var cnId = edrCaches.get(0).asJsonObject().getString("edc:contractNegotiationId"); + var agreementId = edrCaches.get(0).asJsonObject().getString("edc:agreementId"); + + assertThat(cnId).isEqualTo(contractNegotiationId); + assertThat(SOKRATES.getEdrEntriesByAgreementId(agreementId)).hasSize(1); + var edr = SOKRATES.getEdr(transferProcessId); diff --git a/spi/edr-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/types/EndpointDataReferenceEntry.java b/spi/edr-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/types/EndpointDataReferenceEntry.java index 3e0b0a15f..a54026fe9 100644 --- a/spi/edr-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/types/EndpointDataReferenceEntry.java +++ b/spi/edr-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/types/EndpointDataReferenceEntry.java @@ -49,6 +49,9 @@ public class EndpointDataReferenceEntry extends StatefulEntity edrEntry("assetId" + i, "agreementId" + i, "tpId" + i, "contractNegotiationId" + i)) + .forEach(entry -> getStore().save(entry, edr(entry.getTransferProcessId()))); + + var entry = edrEntry("assetId", "agreementId", "tpId", "contractNegotiationId"); + getStore().save(entry, edr("edrId")); + + var filter = Criterion.Builder.newInstance() + .operandLeft("contractNegotiationId") + .operator("=") + .operandRight(entry.getContractNegotiationId()) + .build(); + + assertThat(getStore().queryForEntries(QuerySpec.Builder.newInstance().filter(filter).build())).containsOnly(entry); + } + @Test void queryEntries_providerIdQuerySpec() { IntStream.range(0, 10) diff --git a/spi/edr-spi/src/testFixtures/java/org/eclipse/tractusx/edc/edr/spi/TestFunctions.java b/spi/edr-spi/src/testFixtures/java/org/eclipse/tractusx/edc/edr/spi/TestFunctions.java index 69f07ecca..97d823275 100644 --- a/spi/edr-spi/src/testFixtures/java/org/eclipse/tractusx/edc/edr/spi/TestFunctions.java +++ b/spi/edr-spi/src/testFixtures/java/org/eclipse/tractusx/edc/edr/spi/TestFunctions.java @@ -37,12 +37,21 @@ public static EndpointDataReferenceEntry edrEntry(String assetId, String agreeme return edrEntry(assetId, agreementId, transferProcessId, NEGOTIATED); } + public static EndpointDataReferenceEntry edrEntry(String assetId, String agreementId, String transferProcessId, String contractNegotiationId) { + return edrEntry(assetId, agreementId, transferProcessId, NEGOTIATED, contractNegotiationId); + } + public static EndpointDataReferenceEntry edrEntry(String assetId, String agreementId, String transferProcessId, EndpointDataReferenceEntryStates state) { + return edrEntry(assetId, agreementId, transferProcessId, state, null); + } + + public static EndpointDataReferenceEntry edrEntry(String assetId, String agreementId, String transferProcessId, EndpointDataReferenceEntryStates state, String contractNegotiationId) { return EndpointDataReferenceEntry.Builder.newInstance() .assetId(assetId) .agreementId(agreementId) .transferProcessId(transferProcessId) .providerId(UUID.randomUUID().toString()) + .contractNegotiationId(contractNegotiationId) .state(state.code()) .build(); }