From a7b21bbe6b33f035f90a6f42d310cd60d578718c Mon Sep 17 00:00:00 2001 From: Jim Marino Date: Sun, 14 May 2023 16:15:15 +0200 Subject: [PATCH] feat: Move protocol setting from transformers to controllers (#2996) * Pull up protocol setting; align and simplify controllers * Move up protocol and align controllers * Checkstyle fixes --- .../catalog/api/DspCatalogApiExtension.java | 4 +- ...ller.java => DspCatalogApiController.java} | 19 +- ...pCatalogApiControllerIntegrationTest.java} | 2 +- ....java => DspCatalogApiControllerTest.java} | 10 +- ...ectToCatalogRequestMessageTransformer.java | 14 +- .../dsp-negotiation-api/build.gradle.kts | 5 +- .../api/DspNegotiationApiExtension.java | 4 +- ....java => DspNegotiationApiController.java} | 238 ++++++++++-------- .../api/controller/MessageSpec.java | 120 +++++++++ ...a => DspNegotiationApiControllerTest.java} | 16 +- ...ToContractAgreementMessageTransformer.java | 2 - ...reementVerificationMessageTransformer.java | 2 - ...actNegotiationEventMessageTransformer.java | 2 - ...otiationTerminationMessageTransformer.java | 2 - ...ctToContractRequestMessageTransformer.java | 3 +- .../dsp-transfer-process-api/build.gradle.kts | 5 +- .../DspTransferProcessApiController.java | 114 +++++---- .../api/controller/MessageSpec.java | 120 +++++++++ .../DspTransferProcessApiControllerTest.java | 5 + ...oTransferCompletionMessageTransformer.java | 3 - ...ctToTransferRequestMessageTransformer.java | 3 - ...jectToTransferStartMessageTransformer.java | 3 - ...TransferTerminationMessageTransformer.java | 3 - ...nsferCompletionMessageTransformerTest.java | 2 - ...ToTransferStartMessageTransformerTest.java | 4 - ...sferTerminationMessageTransformerTest.java | 2 - .../catalog/spi/CatalogRequestMessage.java | 59 ++--- .../domain/message/ProcessRemoteMessage.java | 2 + .../org/eclipse/edc/jsonld/spi}/TypeUtil.java | 2 +- .../eclipse/edc/jsonld/spi}/TypeUtilTest.java | 4 +- .../agreement/ContractAgreementMessage.java | 9 +- .../ContractAgreementVerificationMessage.java | 9 +- .../ContractNegotiationEventMessage.java | 9 +- ...ContractNegotiationTerminationMessage.java | 9 +- .../negotiation/ContractRequestMessage.java | 11 +- .../protocol/TransferCompletionMessage.java | 8 +- .../protocol/TransferRequestMessage.java | 9 +- .../types/protocol/TransferStartMessage.java | 9 +- .../protocol/TransferTerminationMessage.java | 9 +- 39 files changed, 600 insertions(+), 256 deletions(-) rename data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/{CatalogController.java => DspCatalogApiController.java} (87%) rename data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/{CatalogControllerIntegrationTest.java => DspCatalogApiControllerIntegrationTest.java} (99%) rename data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/{CatalogControllerTest.java => DspCatalogApiControllerTest.java} (93%) rename data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/{DspNegotiationController.java => DspNegotiationApiController.java} (54%) create mode 100644 data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/MessageSpec.java rename data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/{DspNegotiationControllerTest.java => DspNegotiationApiControllerTest.java} (97%) create mode 100644 data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/MessageSpec.java rename {data-protocols/dsp/dsp-transform/src/main/java/org/eclipse/edc/protocol/dsp/transform/util => spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi}/TypeUtil.java (97%) rename {data-protocols/dsp/dsp-transform/src/test/java/org/eclipse/edc/protocol/dsp/transform/util => spi/common/json-ld-spi/src/test/java/org/eclipse/edc/jsonld/spi}/TypeUtilTest.java (98%) diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/DspCatalogApiExtension.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/DspCatalogApiExtension.java index 624ea6d5fe1..b195ce53f81 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/DspCatalogApiExtension.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/DspCatalogApiExtension.java @@ -19,7 +19,7 @@ import org.eclipse.edc.connector.spi.catalog.CatalogProtocolService; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.protocol.dsp.api.configuration.DspApiConfiguration; -import org.eclipse.edc.protocol.dsp.catalog.api.controller.CatalogController; +import org.eclipse.edc.protocol.dsp.catalog.api.controller.DspCatalogApiController; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.iam.IdentityService; @@ -66,7 +66,7 @@ public String name() { public void initialize(ServiceExtensionContext context) { var mapper = typeManager.getMapper(JSON_LD); var dspCallbackAddress = apiConfiguration.getDspCallbackAddress(); - var catalogController = new CatalogController(context.getMonitor(), mapper, identityService, transformerRegistry, dspCallbackAddress, service, jsonLdService); + var catalogController = new DspCatalogApiController(context.getMonitor(), mapper, identityService, transformerRegistry, dspCallbackAddress, service, jsonLdService); webService.registerResource(apiConfiguration.getContextAlias(), catalogController); dataServiceRegistry.register(DataService.Builder.newInstance() diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogController.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiController.java similarity index 87% rename from data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogController.java rename to data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiController.java index 65704ad084b..ffefabec3c3 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogController.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiController.java @@ -38,10 +38,11 @@ import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.TypeUtil.isOfExpectedType; import static org.eclipse.edc.protocol.dsp.catalog.api.CatalogApiPaths.BASE_PATH; import static org.eclipse.edc.protocol.dsp.catalog.api.CatalogApiPaths.CATALOG_REQUEST; import static org.eclipse.edc.protocol.dsp.catalog.transform.DspCatalogPropertyAndTypeNames.DSPACE_CATALOG_REQUEST_TYPE; -import static org.eclipse.edc.protocol.dsp.transform.util.TypeUtil.isOfExpectedType; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; /** @@ -50,8 +51,8 @@ @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @Path(BASE_PATH) -public class CatalogController { - +public class DspCatalogApiController { + private final Monitor monitor; private final ObjectMapper mapper; private final IdentityService identityService; @@ -60,9 +61,9 @@ public class CatalogController { private final CatalogProtocolService service; private final JsonLd jsonLdService; - public CatalogController(Monitor monitor, ObjectMapper mapper, IdentityService identityService, - TypeTransformerRegistry transformerRegistry, String dspCallbackAddress, - CatalogProtocolService service, JsonLd jsonLdService) { + public DspCatalogApiController(Monitor monitor, ObjectMapper mapper, IdentityService identityService, + TypeTransformerRegistry transformerRegistry, String dspCallbackAddress, + CatalogProtocolService service, JsonLd jsonLdService) { this.monitor = monitor; this.mapper = mapper; this.identityService = identityService; @@ -76,7 +77,7 @@ public CatalogController(Monitor monitor, ObjectMapper mapper, IdentityService i @Path(CATALOG_REQUEST) public Map getCatalog(JsonObject jsonObject, @HeaderParam(AUTHORIZATION) String token) { monitor.debug(() -> "DSP: Incoming catalog request."); - + var tokenRepresentation = TokenRepresentation.Builder.newInstance() .token(token) .build(); @@ -96,6 +97,9 @@ public Map getCatalog(JsonObject jsonObject, @HeaderParam(AUTHOR var message = transformerRegistry.transform(expandedJson, CatalogRequestMessage.class) .orElseThrow(failure -> new InvalidRequestException(format("Request body was malformed: %s", failure.getFailureDetail()))); + // set protocol + message.setProtocol(DATASPACE_PROTOCOL_HTTP); + var catalog = service.getCatalog(message, claimToken) .orElseThrow(exceptionMapper(Catalog.class)); @@ -106,6 +110,7 @@ public Map getCatalog(JsonObject jsonObject, @HeaderParam(AUTHOR if (compacted.failed()) { throw new InvalidRequestException(compacted.getFailureDetail()); } + //noinspection unchecked return mapper.convertValue(compacted.getContent(), Map.class); } diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerIntegrationTest.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerIntegrationTest.java similarity index 99% rename from data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerIntegrationTest.java rename to data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerIntegrationTest.java index 3b80ab259ee..18150694b7b 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerIntegrationTest.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerIntegrationTest.java @@ -53,7 +53,7 @@ @ApiTest @ExtendWith(EdcExtension.class) -class CatalogControllerIntegrationTest { +class DspCatalogApiControllerIntegrationTest { private final int dspApiPort = getFreePort(); private final String dspApiPath = "/api/v1/dsp"; diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerTest.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerTest.java similarity index 93% rename from data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerTest.java rename to data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerTest.java index 383abcb9f0a..e06c965b8a9 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/CatalogControllerTest.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-api/src/test/java/org/eclipse/edc/protocol/dsp/catalog/api/controller/DspCatalogApiControllerTest.java @@ -49,6 +49,7 @@ import static org.eclipse.edc.jsonld.spi.Namespaces.ODRL_PREFIX; import static org.eclipse.edc.jsonld.spi.Namespaces.ODRL_SCHEMA; import static org.eclipse.edc.protocol.dsp.catalog.transform.DspCatalogPropertyAndTypeNames.DSPACE_CATALOG_REQUEST_TYPE; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.service.spi.result.ServiceResult.badRequest; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -57,7 +58,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class CatalogControllerTest { +class DspCatalogApiControllerTest { private final Monitor monitor = mock(Monitor.class); private final ObjectMapper mapper = mock(ObjectMapper.class); @@ -69,7 +70,7 @@ class CatalogControllerTest { private final JsonLd jsonLdService = new TitaniumJsonLd(mock(Monitor.class)); private JsonObject request; private CatalogRequestMessage requestMessage; - private CatalogController controller; + private DspCatalogApiController controller; private static ClaimToken createToken() { return ClaimToken.Builder.newInstance().build(); @@ -81,7 +82,7 @@ void setUp() { jsonLdService.registerNamespace(DCT_PREFIX, DCT_SCHEMA); jsonLdService.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA); jsonLdService.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA); - controller = new CatalogController(monitor, mapper, identityService, transformerRegistry, callbackAddress, service, jsonLdService); + controller = new DspCatalogApiController(monitor, mapper, identityService, transformerRegistry, callbackAddress, service, jsonLdService); request = Json.createObjectBuilder() .add(TYPE, DSPACE_CATALOG_REQUEST_TYPE) @@ -107,6 +108,9 @@ void getCatalog_returnCatalog() { assertThat(response).isEqualTo(responseMap); verify(service).getCatalog(requestMessage, token); + + // verify that the message protocol was set to the DSP protocol by the controller + assertThat(requestMessage.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); } @Test diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-transform/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/to/JsonObjectToCatalogRequestMessageTransformer.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-transform/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/to/JsonObjectToCatalogRequestMessageTransformer.java index 2d0d47d23d2..a495b5ab1a7 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-transform/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/to/JsonObjectToCatalogRequestMessageTransformer.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-transform/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/to/JsonObjectToCatalogRequestMessageTransformer.java @@ -27,32 +27,30 @@ import static java.lang.String.format; import static org.eclipse.edc.protocol.dsp.catalog.transform.DspCatalogPropertyAndTypeNames.DSPACE_FILTER_PROPERTY; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Transforms a {@link JsonObject} in JSON-LD expanded form to a {@link CatalogRequestMessage}. */ public class JsonObjectToCatalogRequestMessageTransformer extends AbstractJsonLdTransformer { - + private final ObjectMapper mapper; - + public JsonObjectToCatalogRequestMessageTransformer(ObjectMapper mapper) { super(JsonObject.class, CatalogRequestMessage.class); this.mapper = mapper; } - + @Override public @Nullable CatalogRequestMessage transform(@NotNull JsonObject object, @NotNull TransformerContext context) { var builder = CatalogRequestMessage.Builder.newInstance(); - builder.protocol(DATASPACE_PROTOCOL_HTTP); - + if (object.get(DSPACE_FILTER_PROPERTY) != null) { builder.querySpec(transformQuerySpec(object.get(DSPACE_FILTER_PROPERTY), context)); } - + return builder.build(); } - + private QuerySpec transformQuerySpec(JsonValue value, TransformerContext context) { if (value instanceof JsonObject) { return mapper.convertValue(value, QuerySpec.class); diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/build.gradle.kts b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/build.gradle.kts index c24a0be587c..dc484dc06c1 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/build.gradle.kts @@ -19,8 +19,9 @@ plugins { dependencies { api(project(":data-protocols:dsp:dsp-api-configuration")) + + // TODO remove this dependency by moving type constants to another module api(project(":data-protocols:dsp:dsp-negotiation:dsp-negotiation-transform")) - api(project(":data-protocols:dsp:dsp-transform")) api(project(":spi:common:core-spi")) api(project(":spi:control-plane:control-plane-spi")) @@ -32,4 +33,4 @@ dependencies { testImplementation(project(":core:common:junit")) testImplementation(testFixtures(project(":extensions:common:http:jersey-core"))) testImplementation(libs.restAssured) -} \ No newline at end of file +} diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/DspNegotiationApiExtension.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/DspNegotiationApiExtension.java index d7120c6e3ee..cfb9defeaa4 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/DspNegotiationApiExtension.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/DspNegotiationApiExtension.java @@ -17,7 +17,7 @@ import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationProtocolService; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.protocol.dsp.api.configuration.DspApiConfiguration; -import org.eclipse.edc.protocol.dsp.negotiation.api.controller.DspNegotiationController; +import org.eclipse.edc.protocol.dsp.negotiation.api.controller.DspNegotiationApiController; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.iam.IdentityService; @@ -71,7 +71,7 @@ public void initialize(ServiceExtensionContext context) { var callbackAddress = apiConfiguration.getDspCallbackAddress(); var objectMapper = typeManager.getMapper(JSON_LD); - var controller = new DspNegotiationController(callbackAddress, identityService, transformerRegistry, protocolService, jsonLdService, objectMapper, monitor); + var controller = new DspNegotiationApiController(callbackAddress, identityService, transformerRegistry, protocolService, jsonLdService, objectMapper, monitor); webService.registerResource(apiConfiguration.getContextAlias(), controller); } diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationController.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiController.java similarity index 54% rename from data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationController.java rename to data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiController.java index 36da5e6bb24..d2a5c3ccda4 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationController.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiController.java @@ -44,13 +44,13 @@ import org.eclipse.edc.web.spi.exception.AuthenticationFailedException; import org.eclipse.edc.web.spi.exception.InvalidRequestException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; -import java.util.Optional; -import java.util.function.BiFunction; import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.TypeUtil.isOfExpectedType; import static org.eclipse.edc.protocol.dsp.negotiation.api.NegotiationApiPaths.AGREEMENT; import static org.eclipse.edc.protocol.dsp.negotiation.api.NegotiationApiPaths.BASE_PATH; import static org.eclipse.edc.protocol.dsp.negotiation.api.NegotiationApiPaths.CONTRACT_OFFER; @@ -66,7 +66,7 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_EVENT_MESSAGE; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_CALLBACK_ADDRESS; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_TERMINATION_MESSAGE; -import static org.eclipse.edc.protocol.dsp.transform.util.TypeUtil.isOfExpectedType; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; /** @@ -76,7 +76,7 @@ @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) @Path(BASE_PATH) -public class DspNegotiationController { +public class DspNegotiationApiController { private final IdentityService identityService; private final TypeTransformerRegistry transformerRegistry; @@ -86,13 +86,13 @@ public class DspNegotiationController { private final ObjectMapper mapper; private final JsonLd jsonLdService; - public DspNegotiationController(String callbackAddress, - IdentityService identityService, - TypeTransformerRegistry transformerRegistry, - ContractNegotiationProtocolService protocolService, - JsonLd jsonLdService, - ObjectMapper mapper, - Monitor monitor) { + public DspNegotiationApiController(String callbackAddress, + IdentityService identityService, + TypeTransformerRegistry transformerRegistry, + ContractNegotiationProtocolService protocolService, + JsonLd jsonLdService, + ObjectMapper mapper, + Monitor monitor) { this.callbackAddress = callbackAddress; this.identityService = identityService; this.monitor = monitor; @@ -111,114 +111,129 @@ public DspNegotiationController(String callbackAddress, @GET @Path("{id}") public Map getNegotiation(@PathParam("id") String id, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming request for contract negotiation with id %s", id)); - checkAndReturnAuthToken(token); - throw new UnsupportedOperationException("Currently not supported."); } /** * Provider-specific endpoint. * - * @param body dspace:ContractRequestMessage sent by a consumer. - * @param token identity token. + * @param jsonObject dspace:ContractRequestMessage sent by a consumer. + * @param token identity token. */ @POST @Path(INITIAL_CONTRACT_REQUEST) - public Map initiateNegotiation(@RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> "DSP: Incoming ContractRequestMessage for initiating a contract negotiation."); + public Map initiateNegotiation(@RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { - var negotiation = processMessage(token, - Optional.empty(), - body, - DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, - ContractRequestMessage.class, - this::validateAndProcessRequest); + var negotiation = handleMessage(MessageSpec.Builder.newInstance(ContractRequestMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE) + .message(jsonObject) + .token(token) + .serviceCall(this::validateAndProcessRequest) + .build()); - var result = transformerRegistry.transform(negotiation, JsonObject.class).orElseThrow(failure -> new EdcException(format("Failed to build response: %s", failure.getFailureDetail()))); + var result = transformerRegistry.transform(negotiation, JsonObject.class) + .orElseThrow(failure -> new EdcException(format("Failed to build response: %s", failure.getFailureDetail()))); var compactResult = jsonLdService.compact(result); + //noinspection unchecked return compactResult.map(jo -> mapper.convertValue(jo, Map.class)).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); } /** * Provider-specific endpoint. * - * @param id of contract negotiation. - * @param body dspace:ContractRequestMessage sent by a consumer. - * @param token identity token. + * @param id of contract negotiation. + * @param jsonObject dspace:ContractRequestMessage sent by a consumer. + * @param token identity token. */ @POST @Path("{id}" + CONTRACT_REQUEST) - public void consumerOffer(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming ContractRequestMessage for process %s", id)); - - processMessage(token, Optional.of(id), body, DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, ContractRequestMessage.class, protocolService::notifyRequested); + public void consumerOffer(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { + + handleMessage(MessageSpec.Builder.newInstance(ContractRequestMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE) + .processId(id) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyRequested) + .build()); } /** * Endpoint on provider and consumer side. * - * @param id of contract negotiation. - * @param body dspace:ContractNegotiationEventMessage sent by consumer or provider. - * @param token identity token. + * @param id of contract negotiation. + * @param jsonObject dspace:ContractNegotiationEventMessage sent by consumer or provider. + * @param token identity token. */ @POST @Path("{id}" + EVENT) - public void createEvent(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_EVENT_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming ContractNegotiationEventMessage for process %s", id)); - - var claimToken = checkAndReturnAuthToken(token); - var expandedResult = jsonLdService.expand(body); - var expanded = expandedResult.map(ej -> ej).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - - var message = transformerRegistry.transform(hasValidType(expanded, DSPACE_NEGOTIATION_EVENT_MESSAGE), ContractNegotiationEventMessage.class) - .orElseThrow(failure -> new InvalidRequestException(format("Request body was malformed: %s", failure.getFailureDetail()))); - - validateProcessId(message.getProcessId(), id); + public void createEvent(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_EVENT_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { + + handleMessage(MessageSpec.Builder.newInstance(ContractNegotiationEventMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_EVENT_MESSAGE) + .processId(id) + .message(jsonObject) + .token(token) + .serviceCall(this::dispatchEventMessage) + .build()); - switch (message.getType()) { - case FINALIZED: - protocolService.notifyFinalized(message, claimToken).orElseThrow(exceptionMapper(ContractNegotiation.class)); - break; - case ACCEPTED: - protocolService.notifyAccepted(message, claimToken).orElseThrow(exceptionMapper(ContractNegotiation.class)); - break; - default: - throw new InvalidRequestException(String.format("Cannot process dspace:ContractNegotiationEventMessage with unexpected type %s.", message.getType())); - } } /** * Provider-specific endpoint. * - * @param id of contract negotiation. - * @param body dspace:ContractAgreementVerificationMessage sent by a consumer. - * @param token identity token. + * @param id of contract negotiation. + * @param jsonObject dspace:ContractAgreementVerificationMessage sent by a consumer. + * @param token identity token. */ @POST @Path("{id}" + AGREEMENT + VERIFICATION) - public void verifyAgreement(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_AGREEMENT_VERIFICATION_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming ContractAgreementVerificationMessage for process %s", id)); - - processMessage(token, Optional.of(id), body, DSPACE_NEGOTIATION_AGREEMENT_VERIFICATION_MESSAGE, ContractAgreementVerificationMessage.class, protocolService::notifyVerified); + public void verifyAgreement(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_AGREEMENT_VERIFICATION_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { + + handleMessage(MessageSpec.Builder.newInstance(ContractAgreementVerificationMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_AGREEMENT_VERIFICATION_MESSAGE) + .processId(id) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyVerified) + .build()); } /** * Endpoint on provider and consumer side. * - * @param id of contract negotiation. - * @param body dspace:ContractNegotiationTerminationMessage sent by consumer or provider. - * @param token identity token. + * @param id of contract negotiation. + * @param jsonObject dspace:ContractNegotiationTerminationMessage sent by consumer or provider. + * @param token identity token. */ @POST @Path("{id}" + TERMINATION) - public void terminateNegotiation(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_TERMINATION_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming ContractNegotiationTerminationMessage for process %s", id)); - - processMessage(token, Optional.of(id), body, DSPACE_NEGOTIATION_TERMINATION_MESSAGE, ContractNegotiationTerminationMessage.class, protocolService::notifyTerminated); + public void terminateNegotiation(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_TERMINATION_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { + + handleMessage(MessageSpec.Builder.newInstance(ContractNegotiationTerminationMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_TERMINATION_MESSAGE) + .processId(id) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyTerminated) + .build()); } /** @@ -230,8 +245,10 @@ public void terminateNegotiation(@PathParam("id") String id, @RequestBody(descri */ @POST @Path("{id}" + CONTRACT_OFFER) - - public void providerOffer(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_OFFER_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { + public void providerOffer(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_CONTRACT_OFFER_MESSAGE, required = true) + JsonObject body, + @HeaderParam(AUTHORIZATION) String token) { monitor.debug(() -> format("DSP: Incoming ContractOfferMessage for process %s", id)); checkAndReturnAuthToken(token); @@ -242,34 +259,46 @@ public void providerOffer(@PathParam("id") String id, @RequestBody(description = /** * Consumer-specific endpoint. * - * @param id of contract negotiation. - * @param body dspace:ContractAgreementMessage sent by a provider. - * @param token identity token. + * @param id of contract negotiation. + * @param jsonObject dspace:ContractAgreementMessage sent by a provider. + * @param token identity token. */ @POST @Path("{id}" + AGREEMENT) - public void createAgreement(@PathParam("id") String id, @RequestBody(description = DSPACE_NEGOTIATION_AGREEMENT_MESSAGE, required = true) JsonObject body, @HeaderParam(AUTHORIZATION) String token) { - monitor.debug(() -> format("DSP: Incoming ContractAgreementMessage for process %s", id)); - - processMessage(token, Optional.of(id), body, DSPACE_NEGOTIATION_AGREEMENT_MESSAGE, ContractAgreementMessage.class, protocolService::notifyAgreed); + public void createAgreement(@PathParam("id") String id, + @RequestBody(description = DSPACE_NEGOTIATION_AGREEMENT_MESSAGE, required = true) + JsonObject jsonObject, + @HeaderParam(AUTHORIZATION) String token) { + + handleMessage(MessageSpec.Builder.newInstance(ContractAgreementMessage.class) + .expectedMessageType(DSPACE_NEGOTIATION_AGREEMENT_MESSAGE) + .processId(id) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyAgreed) + .build()); } - private ContractNegotiation processMessage(String token, - Optional processId, - JsonObject body, - String expectedType, - Class messageClass, - BiFunction> serviceCall) { - var claimToken = checkAndReturnAuthToken(token); - var expanded = jsonLdService.expand(body).map(ej -> ej).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); + private ContractNegotiation handleMessage(MessageSpec messageSpec) { + monitor.debug(() -> format("DSP: Incoming %s for contract negotiation process%s", + messageSpec.getMessageClass().getSimpleName(), messageSpec.getProcessId() != null ? ": " + messageSpec.getProcessId() : "")); + + var claimToken = checkAndReturnAuthToken(messageSpec.getToken()); + var expanded = jsonLdService.expand(messageSpec.getMessage()) + .map(ej -> ej).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - var message = transformerRegistry.transform(hasValidType(expanded, expectedType), messageClass) + validateType(expanded, messageSpec.getExpectedMessageType()); + + var message = transformerRegistry.transform(expanded, messageSpec.getMessageClass()) .orElseThrow(failure -> new InvalidRequestException(format("Request body was malformed: %s", failure.getFailureDetail()))); - processId.ifPresent(id -> validateProcessId(message.getProcessId(), id)); + // set the remote protocol used + message.setProtocol(DATASPACE_PROTOCOL_HTTP); + + validateProcessId(messageSpec.getProcessId(), message.getProcessId()); // invokes negotiation protocol service method - return serviceCall.apply(message, claimToken).orElseThrow(exceptionMapper(ContractNegotiation.class)); + return messageSpec.getServiceCall().apply(message, claimToken).orElseThrow(exceptionMapper(ContractNegotiation.class)); } @NotNull @@ -280,24 +309,37 @@ private ServiceResult validateAndProcessRequest(ContractReq return protocolService.notifyRequested(message, claimToken); } + @NotNull + private ServiceResult dispatchEventMessage(ContractNegotiationEventMessage message, ClaimToken claimToken) { + switch (message.getType()) { + case FINALIZED: + return protocolService.notifyFinalized(message, claimToken); + case ACCEPTED: + return protocolService.notifyAccepted(message, claimToken); + default: + throw new InvalidRequestException(String.format("Cannot process dspace:ContractNegotiationEventMessage with unexpected type %s.", message.getType())); + } + } + private ClaimToken checkAndReturnAuthToken(String token) { var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build(); return identityService.verifyJwtToken(tokenRepresentation, callbackAddress).orElseThrow(failure -> new AuthenticationFailedException(format("Authentication failed: %s", failure.getFailureDetail()))); } - private void validateProcessId(String actual, String expected) { - if (!expected.equals(actual)) { - throw new InvalidRequestException(format("Invalid process ID. Expected: %s, actual: %s", expected, actual)); - } - } - - private JsonObject hasValidType(JsonObject object, String expected) { + private void validateType(JsonObject object, String expected) { if (!isOfExpectedType(object, expected)) { throw new InvalidRequestException(format("Request body was not of expected type: %s", expected)); } + } - return object; + private void validateProcessId(@Nullable String expected, String actual) { + if (expected == null) { + return; + } + if (!expected.equals(actual)) { + throw new InvalidRequestException(format("Invalid process ID. Expected: %s, actual: %s", expected, actual)); + } } } diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/MessageSpec.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/MessageSpec.java new file mode 100644 index 00000000000..6c3efcaa8fd --- /dev/null +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/MessageSpec.java @@ -0,0 +1,120 @@ +/* + * 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 + * + */ + +package org.eclipse.edc.protocol.dsp.negotiation.api.controller; + +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.protocol.ContractRemoteMessage; +import org.eclipse.edc.service.spi.result.ServiceResult; +import org.eclipse.edc.spi.iam.ClaimToken; + +import java.util.function.BiFunction; + +/** + * Defines an incoming DSP message as a remote message type. + */ +class MessageSpec { + private JsonObject message; + private String processId; + private String token; + private String expectedMessageType; + private Class messageClass; + private BiFunction> serviceCall; + + public JsonObject getMessage() { + return message; + } + + public String getProcessId() { + return processId; + } + + public String getToken() { + return token; + } + + public String getExpectedMessageType() { + return expectedMessageType; + } + + public Class getMessageClass() { + return messageClass; + } + + public BiFunction> getServiceCall() { + return serviceCall; + } + + private MessageSpec(Class messageClass) { + this.messageClass = messageClass; + } + + public static class Builder { + private MessageSpec spec; + + /** + * Creates a new message spec for the given remote message type. + */ + public static Builder newInstance(Class messageClass) { + return new Builder<>(messageClass); + } + + /** + * Json-Ld message. + */ + public Builder message(JsonObject message) { + spec.message = message; + return this; + } + + /** + * Process id. + */ + public Builder processId(String processId) { + spec.processId = processId; + return this; + } + + /** + * Security token. + */ + public Builder token(String token) { + spec.token = token; + return this; + } + + /** + * Expected Json-Ld message @type. + */ + public Builder expectedMessageType(String expectedMessageType) { + spec.expectedMessageType = expectedMessageType; + return this; + } + + public Builder serviceCall(BiFunction> serviceCall) { + spec.serviceCall = serviceCall; + return this; + } + + public MessageSpec build() { + return spec; + } + + private Builder(Class messageClass) { + spec = new MessageSpec<>(messageClass); + } + + } +} diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationControllerTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiControllerTest.java similarity index 97% rename from data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationControllerTest.java rename to data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiControllerTest.java index 2171dee74e6..d54ead8ab2a 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationControllerTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-api/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/api/controller/DspNegotiationApiControllerTest.java @@ -76,6 +76,7 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_CONTRACT_REQUEST_MESSAGE; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_EVENT_MESSAGE; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_TERMINATION_MESSAGE; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -85,7 +86,7 @@ import static org.mockito.Mockito.when; @ApiTest -public class DspNegotiationControllerTest extends RestControllerTestBase { +public class DspNegotiationApiControllerTest extends RestControllerTestBase { private final ObjectMapper mapper = mock(ObjectMapper.class); private final IdentityService identityService = mock(IdentityService.class); @@ -355,6 +356,10 @@ void callEndpoint_shouldCallService_whenValidRequest(String path, ContractRemote var verify = verify(protocolService, times(1)); serviceMethod.invoke(verify, message, token); + + // verify that the message protocol was set to the DSP protocol by the controller + assertThat(message.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); + } /** @@ -390,6 +395,10 @@ void callEndpoint_shouldReturnConflict_whenServiceResultConflict(String path, Co var verify = verify(protocolService, times(1)); serviceMethod.invoke(verify, message, token); + + // verify that the message protocol was set to the DSP protocol by the controller + assertThat(message.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); + } /** @@ -414,11 +423,14 @@ void callEndpoint_shouldReturnBadRequest_whenValidationFails(String path, Contra .post(path) .then() .statusCode(400); + + // verify that the message protocol was set to the DSP protocol by the controller + assertThat(message.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); } @Override protected Object controller() { - return new DspNegotiationController(callbackAddress, identityService, registry, protocolService, jsonLdService, mapper, mock(Monitor.class)); + return new DspNegotiationApiController(callbackAddress, identityService, registry, protocolService, jsonLdService, mapper, mock(Monitor.class)); } private RequestSpecification baseRequest() { diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementMessageTransformer.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementMessageTransformer.java index cbfb280ba95..3902c7dabcb 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementMessageTransformer.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementMessageTransformer.java @@ -34,7 +34,6 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROVIDER_ID; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_TIMESTAMP; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Creates a {@link ContractAgreementMessage} from a {@link JsonObject}. @@ -50,7 +49,6 @@ public JsonObjectToContractAgreementMessageTransformer() { @Override public @Nullable ContractAgreementMessage transform(@NotNull JsonObject object, @NotNull TransformerContext context) { var messageBuilder = ContractAgreementMessage.Builder.newInstance(); - messageBuilder.protocol(DATASPACE_PROTOCOL_HTTP); if (!transformMandatoryString(object.get(DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID), messageBuilder::processId, context)) { context.reportProblem(format("No '%s' specified on ContractAgreementMessage", DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID)); return null; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementVerificationMessageTransformer.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementVerificationMessageTransformer.java index f6259b0259a..43816d1c3ad 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementVerificationMessageTransformer.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractAgreementVerificationMessageTransformer.java @@ -23,7 +23,6 @@ import static java.lang.String.format; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Creates a {@link ContractAgreementVerificationMessage} from a {@link JsonObject}. @@ -37,7 +36,6 @@ public JsonObjectToContractAgreementVerificationMessageTransformer() { @Override public @Nullable ContractAgreementVerificationMessage transform(@NotNull JsonObject object, @NotNull TransformerContext context) { var builder = ContractAgreementVerificationMessage.Builder.newInstance(); - builder.protocol(DATASPACE_PROTOCOL_HTTP); if (!transformMandatoryString(object.get(DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID), builder::processId, context)) { context.reportProblem(format("ContractAgreementVerificationMessage is missing the '%s' property", DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID)); return null; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationEventMessageTransformer.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationEventMessageTransformer.java index 313b3be2e3e..e915d5b4909 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationEventMessageTransformer.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationEventMessageTransformer.java @@ -28,7 +28,6 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_EVENT_TYPE_ACCEPTED; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_EVENT_TYPE_FINALIZED; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Creates a {@link ContractNegotiationEventMessage} from a {@link JsonObject}. @@ -43,7 +42,6 @@ public JsonObjectToContractNegotiationEventMessageTransformer() { public @Nullable ContractNegotiationEventMessage transform(@NotNull JsonObject object, @NotNull TransformerContext context) { var builder = ContractNegotiationEventMessage.Builder.newInstance(); - builder.protocol(DATASPACE_PROTOCOL_HTTP); if (!transformMandatoryString(object.get(DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID), builder::processId, context)) { context.reportProblem(format("ContractNegotiationEventMessage is missing the %s property", DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID)); diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationTerminationMessageTransformer.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationTerminationMessageTransformer.java index d30cdee0646..89f798decdc 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationTerminationMessageTransformer.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractNegotiationTerminationMessageTransformer.java @@ -25,7 +25,6 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_CODE; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_REASON; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Creates a {@link ContractNegotiationTerminationMessage} from a {@link JsonObject}. @@ -39,7 +38,6 @@ public JsonObjectToContractNegotiationTerminationMessageTransformer() { @Override public @Nullable ContractNegotiationTerminationMessage transform(@NotNull JsonObject object, @NotNull TransformerContext context) { var builder = ContractNegotiationTerminationMessage.Builder.newInstance(); - builder.protocol(DATASPACE_PROTOCOL_HTTP); transformString(object.get(DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID), builder::processId, context); diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractRequestMessageTransformer.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractRequestMessageTransformer.java index 1daf7314762..4c6b894d65f 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractRequestMessageTransformer.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-transform/src/main/java/org.eclipse.edc.protocol.dsp.negotiation.transform/to/JsonObjectToContractRequestMessageTransformer.java @@ -29,7 +29,6 @@ import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_OFFER; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_OFFER_ID; import static org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationPropertyAndTypeNames.DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; /** * Creates a {@link ContractRequestMessage} from a {@link JsonObject}. @@ -42,7 +41,7 @@ public JsonObjectToContractRequestMessageTransformer() { @Override public @Nullable ContractRequestMessage transform(@NotNull JsonObject requestObject, @NotNull TransformerContext context) { - var builder = ContractRequestMessage.Builder.newInstance().protocol(DATASPACE_PROTOCOL_HTTP); + var builder = ContractRequestMessage.Builder.newInstance(); if (!transformMandatoryString(requestObject.get(DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID), builder::processId, context)) { context.reportProblem(format("No '%s' specified on ContractRequestMessage", DSPACE_NEGOTIATION_PROPERTY_PROCESS_ID)); return null; diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/build.gradle.kts b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/build.gradle.kts index fca2639a0e3..28dc40385ee 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/build.gradle.kts @@ -22,8 +22,9 @@ dependencies { api(project(":extensions:common:http")) api(project(":data-protocols:dsp:dsp-api-configuration")) - implementation(project(":extensions:common:json-ld")) - implementation(project(":data-protocols:dsp:dsp-transform")) + implementation(project(":spi:common:json-ld-spi")) + + // TODO remove this dependency by moving type constants to another module implementation(project(":data-protocols:dsp:dsp-transfer-process:dsp-transfer-process-transform")) implementation(libs.jakarta.rsApi) diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiController.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiController.java index 11da6eaa943..72d05a6ec64 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiController.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiController.java @@ -23,7 +23,6 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MediaType; import org.eclipse.edc.connector.spi.transferprocess.TransferProcessProtocolService; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; @@ -33,7 +32,6 @@ import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferStartMessage; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferTerminationMessage; import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.service.spi.result.ServiceResult; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.iam.ClaimToken; import org.eclipse.edc.spi.iam.IdentityService; @@ -44,10 +42,11 @@ import org.eclipse.edc.web.spi.exception.InvalidRequestException; import java.util.Map; -import java.util.Optional; -import java.util.function.BiFunction; +import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.TypeUtil.isOfExpectedType; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.BASE_PATH; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.TRANSFER_COMPLETION; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.TRANSFER_INITIAL_REQUEST; @@ -58,7 +57,6 @@ import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_TRANSFER_PROCESS_REQUEST_TYPE; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_TRANSFER_START_TYPE; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_TRANSFER_TERMINATION_TYPE; -import static org.eclipse.edc.protocol.dsp.transform.util.TypeUtil.isOfExpectedType; import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; /** @@ -78,8 +76,13 @@ public class DspTransferProcessApiController { private final String dspCallbackAddress; private final JsonLd jsonLdService; - public DspTransferProcessApiController(Monitor monitor, ObjectMapper mapper, TypeTransformerRegistry registry, - TransferProcessProtocolService protocolService, IdentityService identityService, String dspCallbackAddress, JsonLd jsonLdService) { + public DspTransferProcessApiController(Monitor monitor, + ObjectMapper mapper, + TypeTransformerRegistry registry, + TransferProcessProtocolService protocolService, + IdentityService identityService, + String dspCallbackAddress, + JsonLd jsonLdService) { this.monitor = monitor; this.protocolService = protocolService; this.registry = registry; @@ -112,16 +115,21 @@ public JsonObject getTransferProcess(@PathParam("id") String id) { */ @POST @Path(TRANSFER_INITIAL_REQUEST) - public Map initiateTransferProcess(JsonObject jsonObject, @HeaderParam(HttpHeaders.AUTHORIZATION) String token) { - var transferProcess = handleMessage(jsonObject, Optional.empty(), token, DSPACE_TRANSFER_PROCESS_REQUEST_TYPE, TransferRequestMessage.class, protocolService::notifyRequested); + public Map initiateTransferProcess(JsonObject jsonObject, @HeaderParam(AUTHORIZATION) String token) { + var transferProcessResponse = handleMessage(MessageSpec.Builder.newInstance(TransferRequestMessage.class) + .expectedMessageType(DSPACE_TRANSFER_PROCESS_REQUEST_TYPE) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyRequested) + .build()); - var transferProcessJson = registry.transform(transferProcess, JsonObject.class) + var transferProcessJson = registry.transform(transferProcessResponse, JsonObject.class) .orElseThrow(failure -> new EdcException(format("Response could not be created: %s", failure.getFailureDetail()))); var compacted = jsonLdService.compact(transferProcessJson); - return compacted.map(jo -> mapper.convertValue(jo, Map.class)) - .orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); + //noinspection unchecked + return compacted.map(jo -> mapper.convertValue(jo, Map.class)).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); } /** @@ -133,8 +141,14 @@ public Map initiateTransferProcess(JsonObject jsonObject, @Heade */ @POST @Path("{id}" + TRANSFER_START) - public void transferProcessStart(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(HttpHeaders.AUTHORIZATION) String token) { - handleMessage(jsonObject, Optional.of(id), token, DSPACE_TRANSFER_START_TYPE, TransferStartMessage.class, protocolService::notifyStarted); + public void transferProcessStart(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(AUTHORIZATION) String token) { + handleMessage(MessageSpec.Builder.newInstance(TransferStartMessage.class) + .processId(id) + .expectedMessageType(DSPACE_TRANSFER_START_TYPE) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyStarted) + .build()); } /** @@ -146,8 +160,14 @@ public void transferProcessStart(@PathParam("id") String id, JsonObject jsonObje */ @POST @Path("{id}" + TRANSFER_COMPLETION) - public void transferProcessCompletion(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(HttpHeaders.AUTHORIZATION) String token) { - handleMessage(jsonObject, Optional.of(id), token, DSPACE_TRANSFER_COMPLETION_TYPE, TransferCompletionMessage.class, protocolService::notifyCompleted); + public void transferProcessCompletion(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(AUTHORIZATION) String token) { + handleMessage(MessageSpec.Builder.newInstance(TransferCompletionMessage.class) + .processId(id) + .expectedMessageType(DSPACE_TRANSFER_COMPLETION_TYPE) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyCompleted) + .build()); } /** @@ -159,8 +179,14 @@ public void transferProcessCompletion(@PathParam("id") String id, JsonObject jso */ @POST @Path("{id}" + TRANSFER_TERMINATION) - public void transferProcessTermination(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(HttpHeaders.AUTHORIZATION) String token) { - handleMessage(jsonObject, Optional.of(id), token, DSPACE_TRANSFER_TERMINATION_TYPE, TransferTerminationMessage.class, protocolService::notifyTerminated); + public void transferProcessTermination(@PathParam("id") String id, JsonObject jsonObject, @HeaderParam(AUTHORIZATION) String token) { + handleMessage(MessageSpec.Builder.newInstance(TransferTerminationMessage.class) + .processId(id) + .expectedMessageType(DSPACE_TRANSFER_TERMINATION_TYPE) + .message(jsonObject) + .token(token) + .serviceCall(protocolService::notifyTerminated) + .build()); } /** @@ -184,39 +210,34 @@ public void transferProcessSuspension(@PathParam("id") String id) { * the one from the path. Then calls the service method with message and claim token. Will throw * an exception if any of the operations fail. * - * @param request the incoming request body - * @param processId the process ID path parameter, if the ID is part of the request path - * @param token the token from the authorization header - * @param expectedType the expected @type property of the message - * @param messageClass the message class to transform the request to - * @param serviceCall the service call to execute + * @param messageSpec the message spec * @return the transfer process returned by the service call */ - private TransferProcess handleMessage(JsonObject request, Optional processId, String token, String expectedType, - Class messageClass, BiFunction> serviceCall) { - processId.ifPresentOrElse(id -> monitor.debug(() -> format("DSP: Incoming %s for transfer process %s", messageClass.getSimpleName(), id)), - () -> monitor.debug(() -> format("DSP: Incoming %s for initiating a transfer process", messageClass.getSimpleName()))); + private TransferProcess handleMessage(MessageSpec messageSpec) { + monitor.debug(() -> format("DSP: Incoming %s for transfer process%s", + messageSpec.getMessageClass().getSimpleName(), messageSpec.getProcessId() != null ? ": " + messageSpec.getProcessId() : "")); + + var claimToken = checkAuthToken(messageSpec.getToken()); - var claimToken = checkAuthToken(token); + var expanded = jsonLdService.expand(messageSpec.getMessage()) + .map(ej -> ej).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - var expandedJson = jsonLdService.expand(request); - var expanded = expandedJson.map(ej -> ej).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - if (!isOfExpectedType(expanded, expectedType)) { - throw new InvalidRequestException(format("Request body was not of expected type: %s", expectedType)); + if (!isOfExpectedType(expanded, messageSpec.getExpectedMessageType())) { + throw new InvalidRequestException(format("Request body was not of expected type: %s", messageSpec.getExpectedMessageType())); } - var message = registry.transform(expanded, messageClass) + var message = registry.transform(expanded, messageSpec.getMessageClass()) .orElseThrow(failure -> new InvalidRequestException(format("Failed to read request body: %s", failure.getFailureDetail()))); - processId.ifPresent(id -> validateProcessId(message.getProcessId(), id)); + // set the remote protocol used + message.setProtocol(DATASPACE_PROTOCOL_HTTP); - return serviceCall.apply(message, claimToken) - .orElseThrow(exceptionMapper(TransferProcess.class)); + validateProcessId(messageSpec, message); + + return messageSpec.getServiceCall().apply(message, claimToken).orElseThrow(exceptionMapper(TransferProcess.class)); } private ClaimToken checkAuthToken(String token) { - var tokenRepresentation = TokenRepresentation.Builder.newInstance() - .token(token) - .build(); + var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build(); var result = identityService.verifyJwtToken(tokenRepresentation, dspCallbackAddress); if (result.failed()) { @@ -226,9 +247,16 @@ private ClaimToken checkAuthToken(String token) { return result.getContent(); } - private void validateProcessId(String actual, String expected) { - if (!expected.equals(actual)) { - throw new InvalidRequestException(format("Invalid process ID. Expected: %s, actual: %s", expected, actual)); + /** + * Ensures that a process id specified in an endpoint url matches the process id in the incoming DSP Json-Ld message. + */ + private void validateProcessId(MessageSpec messageSpec, TransferRemoteMessage message) { + var expected = messageSpec.getProcessId(); + if (expected != null) { + var actual = message.getProcessId(); + if (!expected.equals(actual)) { + throw new InvalidRequestException(format("Invalid process ID. Expected: %s, actual: %s", expected, actual)); + } } } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/MessageSpec.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/MessageSpec.java new file mode 100644 index 00000000000..a511c9d0fb5 --- /dev/null +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/MessageSpec.java @@ -0,0 +1,120 @@ +/* + * 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 + * + */ + +package org.eclipse.edc.protocol.dsp.transferprocess.api.controller; + +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; +import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferRemoteMessage; +import org.eclipse.edc.service.spi.result.ServiceResult; +import org.eclipse.edc.spi.iam.ClaimToken; + +import java.util.function.BiFunction; + +/** + * Defines an incoming DSP message as a remote message type. + */ +class MessageSpec { + private JsonObject message; + private String processId; + private String token; + private String expectedMessageType; + private Class messageClass; + private BiFunction> serviceCall; + + public JsonObject getMessage() { + return message; + } + + public String getProcessId() { + return processId; + } + + public String getToken() { + return token; + } + + public String getExpectedMessageType() { + return expectedMessageType; + } + + public Class getMessageClass() { + return messageClass; + } + + public BiFunction> getServiceCall() { + return serviceCall; + } + + private MessageSpec(Class messageClass) { + this.messageClass = messageClass; + } + + public static class Builder { + private MessageSpec spec; + + /** + * Creates a new message spec for the given remote message type. + */ + public static Builder newInstance(Class messageClass) { + return new Builder<>(messageClass); + } + + /** + * Json-Ld message. + */ + public Builder message(JsonObject message) { + spec.message = message; + return this; + } + + /** + * Process id. + */ + public Builder processId(String processId) { + spec.processId = processId; + return this; + } + + /** + * Security token. + */ + public Builder token(String token) { + spec.token = token; + return this; + } + + /** + * Expected Json-Ld message @type. + */ + public Builder expectedMessageType(String expectedMessageType) { + spec.expectedMessageType = expectedMessageType; + return this; + } + + public Builder serviceCall(BiFunction> serviceCall) { + spec.serviceCall = serviceCall; + return this; + } + + public MessageSpec build() { + return spec; + } + + private Builder(Class messageClass) { + spec = new MessageSpec<>(messageClass); + } + + } +} diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiControllerTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiControllerTest.java index e2586831e03..96c81f8cfc7 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiControllerTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-api/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/api/controller/DspTransferProcessApiControllerTest.java @@ -50,7 +50,9 @@ import java.util.stream.Stream; import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.BASE_PATH; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.TRANSFER_COMPLETION; import static org.eclipse.edc.protocol.dsp.transferprocess.api.TransferProcessApiPaths.TRANSFER_INITIAL_REQUEST; @@ -336,6 +338,9 @@ void callEndpoint_shouldCallService_whenValidRequest(String path, JsonObject req .then() .statusCode(204); + // verify that the message protocol was set to the DSP protocol by the controller + assertThat(message.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); + var verify = verify(protocolService, times(1)); serviceMethod.invoke(verify, message, token); } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferCompletionMessageTransformer.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferCompletionMessageTransformer.java index a3054641168..73e838c2a37 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferCompletionMessageTransformer.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferCompletionMessageTransformer.java @@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_PROCESS_ID; public class JsonObjectToTransferCompletionMessageTransformer extends AbstractJsonLdTransformer { @@ -34,8 +33,6 @@ public JsonObjectToTransferCompletionMessageTransformer() { public @Nullable TransferCompletionMessage transform(@NotNull JsonObject messageObject, @NotNull TransformerContext context) { var transferCompletionMessageBuilder = TransferCompletionMessage.Builder.newInstance(); - transferCompletionMessageBuilder.protocol(DATASPACE_PROTOCOL_HTTP); - transformString(messageObject.get(DSPACE_PROCESS_ID), transferCompletionMessageBuilder::processId, context); return transferCompletionMessageBuilder.build(); diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferRequestMessageTransformer.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferRequestMessageTransformer.java index 8f3a21bc73b..b34ecf66790 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferRequestMessageTransformer.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferRequestMessageTransformer.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCT_FORMAT_ATTRIBUTE; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_CALLBACK_ADDRESS; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_CONTRACT_AGREEMENT_ID; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_DATA_ADDRESS; @@ -39,8 +38,6 @@ public JsonObjectToTransferRequestMessageTransformer() { public @Nullable TransferRequestMessage transform(@NotNull JsonObject messageObject, @NotNull TransformerContext context) { var transferRequestMessageBuilder = TransferRequestMessage.Builder.newInstance(); - transferRequestMessageBuilder.protocol(DATASPACE_PROTOCOL_HTTP); - visitProperties(messageObject, k -> { switch (k) { case DSPACE_PROCESS_ID: return v -> transferRequestMessageBuilder.processId(transformString(v, context)); diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferStartMessageTransformer.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferStartMessageTransformer.java index d9c08567fb5..1647b15e6ac 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferStartMessageTransformer.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferStartMessageTransformer.java @@ -17,7 +17,6 @@ import jakarta.json.JsonObject; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferStartMessage; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; -import org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol; import org.eclipse.edc.spi.types.domain.DataAddress; import org.eclipse.edc.transform.spi.TransformerContext; import org.jetbrains.annotations.NotNull; @@ -36,8 +35,6 @@ public JsonObjectToTransferStartMessageTransformer() { public @Nullable TransferStartMessage transform(@NotNull JsonObject messageObject, @NotNull TransformerContext context) { var transferStartMessageBuilder = TransferStartMessage.Builder.newInstance(); - transferStartMessageBuilder.protocol(HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP); - transformString(messageObject.get(DSPACE_PROCESS_ID), transferStartMessageBuilder::processId, context); var dataAddressObject = returnJsonObject(messageObject.get(DSPACE_DATA_ADDRESS), context, DSPACE_DATA_ADDRESS, false); diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferTerminationMessageTransformer.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferTerminationMessageTransformer.java index 1994c6b64c2..02cc0996d42 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferTerminationMessageTransformer.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/to/JsonObjectToTransferTerminationMessageTransformer.java @@ -17,7 +17,6 @@ import jakarta.json.JsonObject; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferTerminationMessage; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; -import org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol; import org.eclipse.edc.transform.spi.TransformerContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,8 +36,6 @@ public JsonObjectToTransferTerminationMessageTransformer() { public @Nullable TransferTerminationMessage transform(@NotNull JsonObject messageObject, @NotNull TransformerContext context) { var transferTerminationMessageBuilder = TransferTerminationMessage.Builder.newInstance(); - transferTerminationMessageBuilder.protocol(HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP); - transformString(messageObject.get(DSPACE_PROCESS_ID), transferTerminationMessageBuilder::processId, context); if (messageObject.containsKey(DSPACE_CODE)) { diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferCompletionMessageTransformerTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferCompletionMessageTransformerTest.java index 63de12ae989..153911a00df 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferCompletionMessageTransformerTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferCompletionMessageTransformerTest.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.transformer.to; import jakarta.json.Json; -import org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol; import org.eclipse.edc.protocol.dsp.transferprocess.transformer.type.to.JsonObjectToTransferCompletionMessageTransformer; import org.eclipse.edc.transform.spi.TransformerContext; import org.junit.jupiter.api.BeforeEach; @@ -57,7 +56,6 @@ void jsonObjectToTransferCompletionMessage() { assertThat(result).isNotNull(); assertThat(result.getProcessId()).isEqualTo(processId); - assertThat(result.getProtocol()).isEqualTo(HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP); verify(context, never()).reportProblem(anyString()); } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferStartMessageTransformerTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferStartMessageTransformerTest.java index c59bc5fec92..8763fd549c8 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferStartMessageTransformerTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferStartMessageTransformerTest.java @@ -24,7 +24,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; -import static org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_DATA_ADDRESS; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_PROCESS_ID; import static org.eclipse.edc.protocol.dsp.transferprocess.transformer.DspTransferProcessPropertyAndTypeNames.DSPACE_TRANSFER_START_TYPE; @@ -63,7 +62,6 @@ void jsonObjectToTransferStartMessage() { assertThat(result).isNotNull(); assertThat(result.getProcessId()).isEqualTo(processId); - assertThat(result.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); verify(context, never()).reportProblem(anyString()); } @@ -86,7 +84,6 @@ void jsonObjectToTransferStartMessageWithDataAddress() { assertThat(result).isNotNull(); assertThat(result.getProcessId()).isEqualTo(processId); - assertThat(result.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); assertThat(result.getDataAddress()).isSameAs(dataAddress); verify(context, never()).reportProblem(anyString()); @@ -105,7 +102,6 @@ void jsonObjectToTransferStartMessageWithEmptyDataAddress() { assertThat(result).isNotNull(); assertThat(result.getProcessId()).isEqualTo(processId); - assertThat(result.getProtocol()).isEqualTo(DATASPACE_PROTOCOL_HTTP); assertThat(result.getDataAddress()).isNull(); verify(context, never()).reportProblem(anyString()); diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferTerminationMessageTransformerTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferTerminationMessageTransformerTest.java index c9c427c6da4..a9f71291922 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferTerminationMessageTransformerTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/to/JsonObjectToTransferTerminationMessageTransformerTest.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.transformer.to; import jakarta.json.Json; -import org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol; import org.eclipse.edc.protocol.dsp.transferprocess.transformer.type.to.JsonObjectToTransferTerminationMessageTransformer; import org.eclipse.edc.transform.spi.TransformerContext; import org.junit.jupiter.api.BeforeEach; @@ -69,7 +68,6 @@ void jsonObjectToTransferTerminationMessage() { assertThat(result).isNotNull(); assertThat(result.getProcessId()).isEqualTo("TestProcessId"); - assertThat(result.getProtocol()).isEqualTo(HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP); assertThat(result.getReason()).isEqualTo(format("[{\"%sfoo\":[{\"@value\":\"bar\"}]}]", DSPACE_SCHEMA)); assertThat(result.getCode()).isEqualTo("testCode"); diff --git a/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequestMessage.java b/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequestMessage.java index b7f214e395f..735066bc519 100644 --- a/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequestMessage.java +++ b/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequestMessage.java @@ -19,7 +19,6 @@ import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.types.domain.message.RemoteMessage; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Objects; @@ -29,19 +28,11 @@ @JsonDeserialize(builder = CatalogRequestMessage.Builder.class) public class CatalogRequestMessage implements RemoteMessage { - private final String protocol; + private String protocol = "unknown"; @Deprecated(forRemoval = true) - private final String connectorId; - private final String counterPartyAddress; - private final QuerySpec querySpec; - - private CatalogRequestMessage(@NotNull String protocol, @NotNull String connectorId, @NotNull String counterPartyAddress, - @Nullable QuerySpec querySpec) { - this.protocol = protocol; - this.connectorId = connectorId; - this.counterPartyAddress = counterPartyAddress; - this.querySpec = querySpec; - } + private String connectorId; + private String counterPartyAddress; + private QuerySpec querySpec; @NotNull @Override @@ -49,6 +40,10 @@ public String getProtocol() { return protocol; } + public void setProtocol(String protocol) { + this.protocol = protocol; + } + @NotNull @Override public String getCounterPartyAddress() { @@ -65,24 +60,11 @@ public QuerySpec getQuerySpec() { return querySpec; } - public Builder toBuilder() { - return new Builder(protocol, connectorId, counterPartyAddress, querySpec); + private CatalogRequestMessage() { } public static class Builder { - private String protocol; - private String connectorId; - private String counterPartyAddress; - private QuerySpec querySpec; - - private Builder() {} - - private Builder(String protocol, String connectorId, String counterPartyAddress, QuerySpec querySpec) { - this.protocol = protocol; - this.connectorId = connectorId; - this.counterPartyAddress = counterPartyAddress; - this.querySpec = querySpec; - } + private CatalogRequestMessage message; @JsonCreator public static CatalogRequestMessage.Builder newInstance() { @@ -90,34 +72,39 @@ public static CatalogRequestMessage.Builder newInstance() { } public CatalogRequestMessage.Builder protocol(String protocol) { - this.protocol = protocol; + this.message.protocol = protocol; return this; } @Deprecated public CatalogRequestMessage.Builder connectorId(String connectorId) { - this.connectorId = connectorId; + this.message.connectorId = connectorId; return this; } public CatalogRequestMessage.Builder counterPartyAddress(String callbackAddress) { - this.counterPartyAddress = callbackAddress; + this.message.counterPartyAddress = callbackAddress; return this; } public CatalogRequestMessage.Builder querySpec(QuerySpec querySpec) { - this.querySpec = querySpec; + this.message.querySpec = querySpec; return this; } public CatalogRequestMessage build() { - Objects.requireNonNull(protocol, "protocol"); + Objects.requireNonNull(message.protocol, "protocol"); - if (querySpec == null) { - querySpec = QuerySpec.none(); + if (message.querySpec == null) { + message.querySpec = QuerySpec.none(); } - return new CatalogRequestMessage(protocol, connectorId, counterPartyAddress, querySpec); + return message; } + + private Builder() { + message = new CatalogRequestMessage(); + } + } } diff --git a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/message/ProcessRemoteMessage.java b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/message/ProcessRemoteMessage.java index c53afadb138..172a7933975 100644 --- a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/message/ProcessRemoteMessage.java +++ b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/message/ProcessRemoteMessage.java @@ -36,4 +36,6 @@ public interface ProcessRemoteMessage extends RemoteMessage { */ @NotNull String getProcessId(); + + void setProtocol(String protocol); } diff --git a/data-protocols/dsp/dsp-transform/src/main/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtil.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/TypeUtil.java similarity index 97% rename from data-protocols/dsp/dsp-transform/src/main/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtil.java rename to spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/TypeUtil.java index d3ec2259a1e..dbc33f5be86 100644 --- a/data-protocols/dsp/dsp-transform/src/main/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtil.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/TypeUtil.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.protocol.dsp.transform.util; +package org.eclipse.edc.jsonld.spi; import jakarta.json.JsonArray; import jakarta.json.JsonObject; diff --git a/data-protocols/dsp/dsp-transform/src/test/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtilTest.java b/spi/common/json-ld-spi/src/test/java/org/eclipse/edc/jsonld/spi/TypeUtilTest.java similarity index 98% rename from data-protocols/dsp/dsp-transform/src/test/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtilTest.java rename to spi/common/json-ld-spi/src/test/java/org/eclipse/edc/jsonld/spi/TypeUtilTest.java index 1196de7ce3b..c3d93ef8318 100644 --- a/data-protocols/dsp/dsp-transform/src/test/java/org/eclipse/edc/protocol/dsp/transform/util/TypeUtilTest.java +++ b/spi/common/json-ld-spi/src/test/java/org/eclipse/edc/jsonld/spi/TypeUtilTest.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.protocol.dsp.transform.util; +package org.eclipse.edc.jsonld.spi; import jakarta.json.Json; import org.junit.jupiter.api.Assertions; @@ -104,4 +104,4 @@ public void isOfExpectedType_true() { Assertions.assertTrue(actual); } -} \ No newline at end of file +} diff --git a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementMessage.java b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementMessage.java index 5a702fdd32f..96f2075047f 100644 --- a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementMessage.java +++ b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementMessage.java @@ -24,7 +24,7 @@ public class ContractAgreementMessage implements ContractRemoteMessage { private String id; - private String protocol; + private String protocol = "unknown"; @Deprecated(forRemoval = true) private String connectorId; private String counterPartyAddress; @@ -44,6 +44,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -120,7 +126,6 @@ public ContractAgreementMessage build() { if (contractAgreementMessage.id == null) { contractAgreementMessage.id = randomUUID().toString(); } - Objects.requireNonNull(contractAgreementMessage.protocol, "protocol"); Objects.requireNonNull(contractAgreementMessage.contractAgreement, "contractAgreement"); Objects.requireNonNull(contractAgreementMessage.processId, "processId"); return contractAgreementMessage; diff --git a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementVerificationMessage.java b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementVerificationMessage.java index 5b7c3ba400b..4be8ecf8abe 100644 --- a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementVerificationMessage.java +++ b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractAgreementVerificationMessage.java @@ -24,7 +24,7 @@ public class ContractAgreementVerificationMessage implements ContractRemoteMessage { private String id; - private String protocol; + private String protocol = "unknown"; private String counterPartyAddress; private String processId; @@ -39,6 +39,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -86,7 +92,6 @@ public ContractAgreementVerificationMessage build() { message.id = randomUUID().toString(); } - Objects.requireNonNull(message.protocol, "protocol"); Objects.requireNonNull(message.processId, "processId"); return message; } diff --git a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractNegotiationEventMessage.java b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractNegotiationEventMessage.java index 8ff22a6e831..22cbba7fc66 100644 --- a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractNegotiationEventMessage.java +++ b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/agreement/ContractNegotiationEventMessage.java @@ -23,7 +23,7 @@ public class ContractNegotiationEventMessage implements ContractRemoteMessage { private String id; - private String protocol; + private String protocol = "unknown"; private String counterPartyAddress; private String processId; private Type type; @@ -39,6 +39,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -95,7 +101,6 @@ public ContractNegotiationEventMessage build() { if (message.id == null) { message.id = randomUUID().toString(); } - Objects.requireNonNull(message.protocol, "protocol"); Objects.requireNonNull(message.processId, "processId"); Objects.requireNonNull(message.type, "type"); return message; diff --git a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractNegotiationTerminationMessage.java b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractNegotiationTerminationMessage.java index 3be87d6af22..1137f114149 100644 --- a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractNegotiationTerminationMessage.java +++ b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractNegotiationTerminationMessage.java @@ -25,7 +25,7 @@ public class ContractNegotiationTerminationMessage implements ContractRemoteMessage { private String id; - private String protocol; + private String protocol = "unknown"; @Deprecated(forRemoval = true) private String connectorId; private String counterPartyAddress; @@ -44,6 +44,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -122,7 +128,6 @@ public ContractNegotiationTerminationMessage build() { contractNegotiationTerminationMessage.id = randomUUID().toString(); } - Objects.requireNonNull(contractNegotiationTerminationMessage.protocol, "protocol"); Objects.requireNonNull(contractNegotiationTerminationMessage.processId, "processId"); return contractNegotiationTerminationMessage; } diff --git a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractRequestMessage.java b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractRequestMessage.java index 84993f5e8b8..50a2f017443 100644 --- a/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractRequestMessage.java +++ b/spi/control-plane/contract-spi/src/main/java/org/eclipse/edc/connector/contract/spi/types/negotiation/ContractRequestMessage.java @@ -19,6 +19,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + import static java.util.Objects.requireNonNull; import static java.util.UUID.randomUUID; @@ -29,7 +31,7 @@ public class ContractRequestMessage implements ContractRemoteMessage { private String id; private Type type = Type.COUNTER_OFFER; - private String protocol; + private String protocol = "unknown"; @Deprecated(forRemoval = true) private String connectorId; private String counterPartyAddress; @@ -50,6 +52,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -159,7 +167,6 @@ public ContractRequestMessage build() { if (contractRequestMessage.id == null) { contractRequestMessage.id = randomUUID().toString(); } - requireNonNull(contractRequestMessage.protocol, "protocol"); requireNonNull(contractRequestMessage.processId, "processId"); if (contractRequestMessage.contractOfferId == null) { requireNonNull(contractRequestMessage.contractOffer, "contractOffer"); diff --git a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferCompletionMessage.java b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferCompletionMessage.java index fa487dcf120..48eda4ea53a 100644 --- a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferCompletionMessage.java +++ b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferCompletionMessage.java @@ -30,7 +30,7 @@ public class TransferCompletionMessage implements TransferRemoteMessage { private String id; private String counterPartyAddress; - private String protocol; + private String protocol = "unknown"; private String processId; @NotNull @@ -44,6 +44,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; diff --git a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferRequestMessage.java b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferRequestMessage.java index 5f6ddcbcbfa..0597b16451c 100644 --- a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferRequestMessage.java +++ b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferRequestMessage.java @@ -32,7 +32,7 @@ public class TransferRequestMessage implements TransferRemoteMessage { private String id; private String counterPartyAddress; - private String protocol; + private String protocol = "unknown"; private String processId; private String contractId; @Deprecated(forRemoval = true) @@ -54,6 +54,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -161,7 +167,6 @@ public TransferRequestMessage build() { message.id = randomUUID().toString(); } - Objects.requireNonNull(message.protocol, "The protocol must be specified"); Objects.requireNonNull(message.callbackAddress, "The callbackAddress must be specified"); return message; } diff --git a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferStartMessage.java b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferStartMessage.java index 35e81c34d8a..b6838a7250f 100644 --- a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferStartMessage.java +++ b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferStartMessage.java @@ -30,7 +30,7 @@ public class TransferStartMessage implements TransferRemoteMessage { private String id; private String counterPartyAddress; - private String protocol; + private String protocol = "unknown"; private String processId; private DataAddress dataAddress; @@ -46,6 +46,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -104,7 +110,6 @@ public TransferStartMessage build() { message.id = randomUUID().toString(); } - Objects.requireNonNull(message.protocol, "The protocol must be specified"); Objects.requireNonNull(message.processId, "The processId must be specified"); return message; } diff --git a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferTerminationMessage.java b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferTerminationMessage.java index 8648cf41866..a17c93ef14c 100644 --- a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferTerminationMessage.java +++ b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/types/protocol/TransferTerminationMessage.java @@ -31,7 +31,7 @@ public class TransferTerminationMessage implements TransferRemoteMessage { private String id; private String counterPartyAddress; - private String protocol; + private String protocol = "unknown"; private String processId; private String code; @@ -49,6 +49,12 @@ public String getProtocol() { return protocol; } + @Override + public void setProtocol(String protocol) { + Objects.requireNonNull(protocol); + this.protocol = protocol; + } + @Override public String getCounterPartyAddress() { return counterPartyAddress; @@ -116,7 +122,6 @@ public TransferTerminationMessage build() { message.id = randomUUID().toString(); } - Objects.requireNonNull(message.protocol, "The protocol must be specified"); Objects.requireNonNull(message.processId, "The processId must be specified"); //TODO add Nullcheck for message.code Issue https://github.com/eclipse-edc/Connector/issues/2810 return message;