From 08425b3654d4187e8149011592f17591a65817da Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Mon, 31 Jul 2023 14:49:21 +0200 Subject: [PATCH] extract RequestProvider --- .../DspCatalogHttpDispatcherExtension.java | 32 ++-- .../delegate/CatalogRequestHttpDelegate.java | 105 ------------ .../CatalogRequestHttpRawDelegate.java | 27 +--- .../DatasetRequestHttpRawDelegate.java | 33 +--- .../CatalogRequestHttpRawDelegateTest.java | 27 +--- ...CatalogRequestMessageHttpDelegateTest.java | 153 ------------------ .../DatasetRequestHttpRawDelegateTest.java | 19 +-- .../DspHttpRemoteMessageDispatcherImpl.java | 21 +-- .../dispatcher/GetDspHttpRequestFactory.java | 39 +++++ .../dispatcher/PostDspHttpRequestFactory.java | 51 ++++++ .../dsp/DspHttpCoreExtensionTest.java | 66 ++------ .../eclipse/edc/protocol/dsp/TestMessage.java | 29 ++++ ...spHttpRemoteMessageDispatcherImplTest.java | 42 +++-- .../GetDspHttpRequestFactoryTest.java | 41 +++++ .../PostDspHttpRequestFactoryTest.java | 55 +++++++ .../dispatcher/DspHttpDispatcherDelegate.java | 41 +---- .../DspHttpRemoteMessageDispatcher.java | 10 +- .../spi/dispatcher/DspHttpRequestFactory.java | 35 ++++ .../spi/dispatcher/RequestPathProvider.java | 34 ++++ .../DspHttpDispatcherDelegateTest.java | 12 +- .../DspHttpDispatcherDelegateTestBase.java | 35 ---- ...DspNegotiationHttpDispatcherExtension.java | 57 ++++++- .../ContractAgreementMessageHttpDelegate.java | 23 +-- ...eementVerificationMessageHttpDelegate.java | 25 +-- ...ctNegotiationEventMessageHttpDelegate.java | 24 +-- ...tiationTerminationMessageHttpDelegate.java | 24 +-- .../ContractOfferMessageHttpDelegate.java | 18 +-- .../ContractRequestMessageHttpDelegate.java | 28 +--- ...tractAgreementMessageHttpDelegateTest.java | 60 ------- ...ntVerificationMessageHttpDelegateTest.java | 32 ---- ...gotiationEventMessageHttpDelegateTest.java | 32 ---- ...ionTerminationMessageHttpDelegateTest.java | 32 ---- .../ContractOfferMessageHttpDelegateTest.java | 44 +---- ...ontractRequestMessageHttpDelegateTest.java | 75 --------- .../build.gradle.kts | 3 +- ...DspTransferProcessDispatcherExtension.java | 35 +++- .../delegate/TransferCompletionDelegate.java | 16 +- .../delegate/TransferRequestDelegate.java | 16 +- .../delegate/TransferStartDelegate.java | 16 +- .../delegate/TransferTerminationDelegate.java | 16 +- .../TransferCompletionDelegateTest.java | 30 ---- .../delegate/TransferRequestDelegateTest.java | 45 ------ .../delegate/TransferStartDelegateTest.java | 30 ---- .../TransferTerminationDelegateTest.java | 30 ---- .../catalog/CatalogApiExtension.java | 9 +- ...JsonObjectToCatalogRequestTransformer.java | 7 +- ...ObjectToCatalogRequestTransformerTest.java | 16 ++ .../edc/catalog/spi/CatalogRequest.java | 1 - .../edc/test/system/utils/Participant.java | 2 +- .../managementapi/CatalogApiEndToEndTest.java | 1 + 50 files changed, 482 insertions(+), 1172 deletions(-) delete mode 100644 data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpDelegate.java delete mode 100644 data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestMessageHttpDelegateTest.java create mode 100644 data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactory.java create mode 100644 data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactory.java create mode 100644 data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/TestMessage.java create mode 100644 data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactoryTest.java create mode 100644 data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactoryTest.java create mode 100644 data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRequestFactory.java create mode 100644 data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/RequestPathProvider.java diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/DspCatalogHttpDispatcherExtension.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/DspCatalogHttpDispatcherExtension.java index a20979baf8b..e0282861f53 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/DspCatalogHttpDispatcherExtension.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/DspCatalogHttpDispatcherExtension.java @@ -14,20 +14,22 @@ package org.eclipse.edc.protocol.dsp.catalog.dispatcher; -import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate.CatalogRequestHttpDelegate; +import org.eclipse.edc.catalog.spi.CatalogRequestMessage; +import org.eclipse.edc.catalog.spi.DatasetRequestMessage; import org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate.CatalogRequestHttpRawDelegate; import org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate.DatasetRequestHttpRawDelegate; +import org.eclipse.edc.protocol.dsp.dispatcher.GetDspHttpRequestFactory; +import org.eclipse.edc.protocol.dsp.dispatcher.PostDspHttpRequestFactory; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRemoteMessageDispatcher; import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import static org.eclipse.edc.spi.CoreConstants.JSON_LD; +import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.CATALOG_REQUEST; +import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.DATASET_REQUEST; /** * Creates and registers the HTTP dispatcher delegate for sending a catalog request as defined in @@ -42,12 +44,6 @@ public class DspCatalogHttpDispatcherExtension implements ServiceExtension { private DspHttpRemoteMessageDispatcher messageDispatcher; @Inject private JsonLdRemoteMessageSerializer remoteMessageSerializer; - @Inject - private TypeManager typeManager; - @Inject - private TypeTransformerRegistry transformerRegistry; - @Inject - private JsonLd jsonLdService; @Override public String name() { @@ -56,10 +52,16 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - var mapper = typeManager.getMapper(JSON_LD); - messageDispatcher.registerDelegate(new CatalogRequestHttpDelegate(remoteMessageSerializer, mapper, transformerRegistry, jsonLdService)); - messageDispatcher.registerDelegate(new CatalogRequestHttpRawDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new DatasetRequestHttpRawDelegate(remoteMessageSerializer)); + messageDispatcher.registerMessage( + CatalogRequestMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + CATALOG_REQUEST), + new CatalogRequestHttpRawDelegate() + ); + messageDispatcher.registerMessage( + DatasetRequestMessage.class, + new GetDspHttpRequestFactory<>(m -> BASE_PATH + DATASET_REQUEST + "/" + m.getDatasetId()), + new DatasetRequestHttpRawDelegate() + ); } } diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpDelegate.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpDelegate.java deleted file mode 100644 index ebd7aac3d13..00000000000 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpDelegate.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2023 Fraunhofer Institute for Software and Systems Engineering - * - * 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: - * Fraunhofer Institute for Software and Systems Engineering - initial API and implementation - * - */ - -package org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate; - -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.json.JsonObject; -import okhttp3.Request; -import okhttp3.Response; -import org.eclipse.edc.catalog.spi.Catalog; -import org.eclipse.edc.catalog.spi.CatalogRequestMessage; -import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; -import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; - -import java.io.IOException; -import java.util.function.Function; - -import static java.lang.String.format; -import static java.lang.String.join; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.CATALOG_REQUEST; - -/** - * Delegate for dispatching catalog requests as defined in the dataspace protocol specification. - */ -public class CatalogRequestHttpDelegate extends DspHttpDispatcherDelegate { - - private final ObjectMapper mapper; - private final TypeTransformerRegistry transformerRegistry; - private final JsonLd jsonLdService; - - public CatalogRequestHttpDelegate(JsonLdRemoteMessageSerializer serializer, ObjectMapper mapper, TypeTransformerRegistry transformerRegistry, JsonLd jsonLdService) { - super(serializer); - this.mapper = mapper; - this.transformerRegistry = transformerRegistry; - this.jsonLdService = jsonLdService; - } - - @Override - public Class getMessageType() { - return CatalogRequestMessage.class; - } - - /** - * Sends a catalog request. The request body is constructed as defined in the dataspace protocol - * implementation. The request is sent to the remote component using the path from the - * specification. - * - * @param message the message - * @return the built okhttp request - */ - @Override - public Request buildRequest(CatalogRequestMessage message) { - return buildPostRequest(message, BASE_PATH + CATALOG_REQUEST); - } - - /** - * Parses the response to a catalog request. The JSON-LD structure from the response body is - * expanded and then transformed to an EDC catalog. - * - * @return a function that transforms the response body to a catalog. - */ - @Override - public Function parseResponse() { - return response -> { - try { - var jsonObject = mapper.readValue(response.body().bytes(), JsonObject.class); - var expansion = jsonLdService.expand(jsonObject); - - if (expansion.succeeded()) { - var result = transformerRegistry.transform(expansion.getContent(), Catalog.class); - if (result.succeeded()) { - return result.getContent(); - } else { - throw new EdcException(format("Failed to read response body: %s", join(", ", result.getFailureMessages()))); - } - } else { - throw new EdcException(expansion.getFailureDetail()); - } - - } catch (NullPointerException e) { - throw new EdcException("Failed to read response body, as body was null."); - } catch (IndexOutOfBoundsException e) { - throw new EdcException("Failed to expand JSON-LD in response body.", e); - } catch (IOException e) { - throw new EdcException("Failed to read response body.", e); - } - }; - } - -} diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegate.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegate.java index 36dd63f342d..ab216918957 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegate.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegate.java @@ -15,45 +15,22 @@ package org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.catalog.spi.CatalogRequestMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; -import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; import org.eclipse.edc.spi.EdcException; import java.io.IOException; import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.CATALOG_REQUEST; - /** * Delegate for dispatching catalog requests as defined in the * dataspace protocol specification */ public class CatalogRequestHttpRawDelegate extends DspHttpDispatcherDelegate { - public CatalogRequestHttpRawDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return CatalogRequestMessage.class; - } - - /** - * Sends a catalog request. The request body is constructed as defined in the dataspace protocol - * implementation. The request is sent to the remote component using the path from the - * specification. - * - * @param message the message - * @return the built okhttp request - */ - @Override - public Request buildRequest(CatalogRequestMessage message) { - return buildPostRequest(message, BASE_PATH + CATALOG_REQUEST); + public CatalogRequestHttpRawDelegate() { + super(); } /** diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegate.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegate.java index 4b6c048dd5a..4da7c169964 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegate.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegate.java @@ -15,51 +15,22 @@ package org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.HttpUrl; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.catalog.spi.DatasetRequestMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; -import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; import org.eclipse.edc.spi.EdcException; import java.io.IOException; import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.DATASET_REQUEST; - /** * Delegate for dispatching catalog requests as defined in the * dataspace protocol specification */ public class DatasetRequestHttpRawDelegate extends DspHttpDispatcherDelegate { - public DatasetRequestHttpRawDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return DatasetRequestMessage.class; - } - - /** - * Sends a catalog request. The request body is constructed as defined in the dataspace protocol - * implementation. The request is sent to the remote component using the path from the - * specification. - * - * @param message the message - * @return the built okhttp request - */ - @Override - public Request buildRequest(DatasetRequestMessage message) { - var url = HttpUrl.get(message.getCounterPartyAddress() + BASE_PATH + DATASET_REQUEST + "/" + message.getDatasetId()); - - return new Request.Builder() - .url(url) - .get() - .build(); + public DatasetRequestHttpRawDelegate() { + super(); } /** diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegateTest.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegateTest.java index 568ecb0731f..f3fdfdf3522 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegateTest.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestHttpRawDelegateTest.java @@ -18,7 +18,6 @@ import org.eclipse.edc.catalog.spi.CatalogRequestMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; -import org.eclipse.edc.spi.query.QuerySpec; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,8 +25,6 @@ import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.CATALOG_REQUEST; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -37,22 +34,7 @@ class CatalogRequestHttpRawDelegateTest extends DspHttpDispatcherDelegateTestBas @BeforeEach void setUp() { - delegate = new CatalogRequestHttpRawDelegate(serializer); - } - - @Test - void getMessageType_returnCatalogRequest() { - assertThat(delegate.getMessageType()).isEqualTo(CatalogRequestMessage.class); - } - - @Test - void buildRequest_returnRequest() throws IOException { - testBuildRequest_shouldReturnRequest(message(), BASE_PATH + CATALOG_REQUEST); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); + delegate = new CatalogRequestHttpRawDelegate(); } @Test @@ -79,11 +61,4 @@ void parseResponse_responseBodyNull_throwException() { return delegate; } - private CatalogRequestMessage message() { - return CatalogRequestMessage.Builder.newInstance() - .counterPartyAddress("http://connector") - .protocol("protocol") - .querySpec(QuerySpec.max()) - .build(); - } } diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestMessageHttpDelegateTest.java deleted file mode 100644 index 59b2e883792..00000000000 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/CatalogRequestMessageHttpDelegateTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2023 Fraunhofer Institute for Software and Systems Engineering - * - * 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: - * Fraunhofer Institute for Software and Systems Engineering - initial API and implementation - * - */ - -package org.eclipse.edc.protocol.dsp.catalog.dispatcher.delegate; - -import jakarta.json.Json; -import jakarta.json.JsonObject; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.eclipse.edc.catalog.spi.Catalog; -import org.eclipse.edc.catalog.spi.CatalogRequestMessage; -import org.eclipse.edc.jsonld.TitaniumJsonLd; -import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; -import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.Result; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.CATALOG_REQUEST; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -class CatalogRequestMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { - - private final JsonLd jsonLdService = new TitaniumJsonLd(mock(Monitor.class)); - private CatalogRequestHttpDelegate delegate; - - @BeforeEach - void setUp() { - delegate = new CatalogRequestHttpDelegate(serializer, mapper, registry, jsonLdService); - } - - @Test - void getMessageType_returnCatalogRequest() { - assertThat(delegate.getMessageType()).isEqualTo(CatalogRequestMessage.class); - } - - @Test - void buildRequest_returnRequest() throws IOException { - testBuildRequest_shouldReturnRequest(message(), BASE_PATH + CATALOG_REQUEST); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - - @Test - void parseResponse_returnCatalog() throws IOException { - var jsonObject = getJsonObject(); - var catalog = Catalog.Builder.newInstance().build(); - var response = mock(Response.class); - var responseBody = mock(ResponseBody.class); - var bytes = "test".getBytes(); - - when(response.body()).thenReturn(responseBody); - when(responseBody.bytes()).thenReturn(bytes); - when(mapper.readValue(bytes, JsonObject.class)).thenReturn(jsonObject); - when(registry.transform(any(JsonObject.class), eq(Catalog.class))).thenReturn(Result.success(catalog)); - - var result = delegate.parseResponse().apply(response); - - assertThat(result).isEqualTo(catalog); - verify(mapper, times(1)).readValue(bytes, JsonObject.class); - verify(registry, times(1)).transform(isA(JsonObject.class), eq(Catalog.class)); - } - - @Test - void parseResponse_transformationFails_throwException() throws IOException { - var jsonObject = getJsonObject(); - var response = mock(Response.class); - var responseBody = mock(ResponseBody.class); - - when(response.body()).thenReturn(responseBody); - when(responseBody.bytes()).thenReturn("test".getBytes()); - when(mapper.readValue(any(byte[].class), eq(JsonObject.class))).thenReturn(jsonObject); - when(registry.transform(any(JsonObject.class), eq(Catalog.class))).thenReturn(Result.failure("error")); - - assertThatThrownBy(() -> delegate.parseResponse().apply(response)).isInstanceOf(EdcException.class); - } - - @Test - void parseResponse_readingResponseBodyFails_throwException() throws IOException { - testParseResponse_shouldThrowException_whenReadingResponseBodyFails(); - } - - @Test - void parseResponse_responseBodyNull_throwException() { - testParseResponse_shouldThrowException_whenResponseBodyNull(); - } - - @Test - void parseResponse_expandingJsonLdFails_throwException() throws IOException { - // JSON is missing @context -> expanding returns empty JsonArray - var jsonObject = Json.createObjectBuilder() - .add("key", "value") - .build(); - var response = mock(Response.class); - var responseBody = mock(ResponseBody.class); - - when(response.body()).thenReturn(responseBody); - when(responseBody.bytes()).thenReturn("test".getBytes()); - when(mapper.readValue(any(byte[].class), eq(JsonObject.class))).thenReturn(jsonObject); - - assertThatThrownBy(() -> delegate.parseResponse().apply(response)).isInstanceOf(EdcException.class); - } - - @Override - protected DspHttpDispatcherDelegate delegate() { - return delegate; - } - - private JsonObject getJsonObject() { - return Json.createObjectBuilder() - .add(CONTEXT, Json.createObjectBuilder().add("prefix", "http://schema").build()) - .add("prefix:key", "value") - .build(); - } - - private CatalogRequestMessage message() { - return CatalogRequestMessage.Builder.newInstance() - .counterPartyAddress("http://connector") - .protocol("protocol") - .querySpec(QuerySpec.max()) - .build(); - } -} diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegateTest.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegateTest.java index ff67e219f6f..dee5da6bff4 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegateTest.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/catalog/dispatcher/delegate/DatasetRequestHttpRawDelegateTest.java @@ -25,8 +25,6 @@ import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.catalog.dispatcher.CatalogApiPaths.DATASET_REQUEST; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,22 +34,7 @@ class DatasetRequestHttpRawDelegateTest extends DspHttpDispatcherDelegateTestBas @BeforeEach void setUp() { - delegate = new DatasetRequestHttpRawDelegate(serializer); - } - - @Test - void getMessageType_returnDatasetRequest() { - assertThat(delegate.getMessageType()).isEqualTo(DatasetRequestMessage.class); - } - - @Test - void buildRequest_returnRequest() { - var message = message(); - - var httpRequest = delegate().buildRequest(message); - - assertThat(httpRequest.method()).isEqualTo("GET"); - assertThat(httpRequest.url().url()).hasToString(message.getCounterPartyAddress() + BASE_PATH + DATASET_REQUEST + "/" + message.getDatasetId()); + delegate = new DatasetRequestHttpRawDelegate(); } @Test diff --git a/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImpl.java b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImpl.java index ed5fd5f8198..2f010a920cf 100644 --- a/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImpl.java +++ b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImpl.java @@ -19,6 +19,7 @@ import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRemoteMessageDispatcher; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRequestFactory; import org.eclipse.edc.protocol.dsp.spi.types.HttpMessageProtocol; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.http.EdcHttpClient; @@ -44,7 +45,7 @@ */ public class DspHttpRemoteMessageDispatcherImpl implements DspHttpRemoteMessageDispatcher { - private final Map, DspHttpDispatcherDelegate> delegates = new HashMap<>(); + private final Map, Handlers> handlers = new HashMap<>(); private final Map, PolicyScope> policyScopes = new HashMap<>(); private final EdcHttpClient httpClient; private final IdentityService identityService; @@ -90,12 +91,12 @@ public CompletableFuture send(Class responseT @Override public CompletableFuture> dispatch(Class responseType, M message) { - var delegate = (DspHttpDispatcherDelegate) delegates.get(message.getClass()); - if (delegate == null) { + var handlers = (Handlers) this.handlers.get(message.getClass()); + if (handlers == null) { return failedFuture(new EdcException(format("No DSP message dispatcher found for message type %s", message.getClass()))); } - var request = delegate.buildRequest(message); + var request = handlers.requestFactory.createRequest(message); var tokenParametersBuilder = tokenDecorator.decorate(TokenParameters.Builder.newInstance()); @@ -118,21 +119,23 @@ public CompletableFuture> dispatch( .header("Authorization", token.getToken()) .build(); - return httpClient.executeAsync(requestWithAuth, List.of(retryWhenStatusNot2xxOr4xx()), delegate.handleResponse()); + return httpClient.executeAsync(requestWithAuth, List.of(retryWhenStatusNot2xxOr4xx()), handlers.delegate.handleResponse()); }) .orElse(failure -> failedFuture(new EdcException(format("Unable to obtain credentials: %s", failure.getFailureDetail())))); } @Override - public void registerDelegate(DspHttpDispatcherDelegate delegate) { - delegates.put(delegate.getMessageType(), delegate); + public void registerPolicyScope(Class messageClass, String scope, Function policyProvider) { + policyScopes.put(messageClass, new PolicyScope<>(messageClass, scope, policyProvider)); } @Override - public void registerPolicyScope(Class messageClass, String scope, Function policyProvider) { - policyScopes.put(messageClass, new PolicyScope(messageClass, scope, policyProvider)); + public void registerMessage(Class clazz, DspHttpRequestFactory requestFactory, DspHttpDispatcherDelegate delegate) { + handlers.put(clazz, new Handlers<>(requestFactory, delegate)); } + private record Handlers(DspHttpRequestFactory requestFactory, DspHttpDispatcherDelegate delegate) { } + private record PolicyScope(Class messageClass, String scope, Function policyProvider) {} } diff --git a/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactory.java b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactory.java new file mode 100644 index 00000000000..fe9ca9f98f9 --- /dev/null +++ b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactory.java @@ -0,0 +1,39 @@ +/* + * 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.dispatcher; + +import okhttp3.HttpUrl; +import okhttp3.Request; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRequestFactory; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.RequestPathProvider; +import org.eclipse.edc.spi.types.domain.message.RemoteMessage; + +public class GetDspHttpRequestFactory implements DspHttpRequestFactory { + private final RequestPathProvider pathProvider; + + public GetDspHttpRequestFactory(RequestPathProvider pathProvider) { + this.pathProvider = pathProvider; + } + + @Override + public Request createRequest(M message) { + var url = HttpUrl.get(message.getCounterPartyAddress() + pathProvider.providePath(message)); + + return new Request.Builder() + .url(url) + .get() + .build(); + } +} diff --git a/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactory.java b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactory.java new file mode 100644 index 00000000000..eb8039718ec --- /dev/null +++ b/data-protocols/dsp/dsp-http-core/src/main/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactory.java @@ -0,0 +1,51 @@ +/* + * 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.dispatcher; + +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRequestFactory; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.RequestPathProvider; +import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; +import org.eclipse.edc.spi.types.domain.message.RemoteMessage; + +public class PostDspHttpRequestFactory implements DspHttpRequestFactory { + + public static final String APPLICATION_JSON = "application/json"; + private final RequestPathProvider pathProvider; + private final JsonLdRemoteMessageSerializer serializer; + + public PostDspHttpRequestFactory(JsonLdRemoteMessageSerializer serializer, RequestPathProvider pathProvider) { + this.serializer = serializer; + this.pathProvider = pathProvider; + } + + @Override + public Request createRequest(M message) { + var body = serializer.serialize(message); + var requestBody = RequestBody.create(body, MediaType.get(APPLICATION_JSON)); + + var url = HttpUrl.get(message.getCounterPartyAddress() + pathProvider.providePath(message)); + + return new Request.Builder() + .url(url) + .header("Content-Type", APPLICATION_JSON) + .post(requestBody) + .build(); + } + +} diff --git a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/DspHttpCoreExtensionTest.java b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/DspHttpCoreExtensionTest.java index 2e2efc292c6..174540c32cf 100644 --- a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/DspHttpCoreExtensionTest.java +++ b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/DspHttpCoreExtensionTest.java @@ -14,24 +14,17 @@ package org.eclipse.edc.protocol.dsp; -import okhttp3.Request; -import okhttp3.Response; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.spi.iam.IdentityService; import org.eclipse.edc.spi.iam.TokenDecorator; -import org.eclipse.edc.spi.message.RemoteMessageDispatcherRegistry; import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.injection.ObjectFactory; -import org.eclipse.edc.spi.types.domain.message.RemoteMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import java.util.function.Function; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; @@ -41,78 +34,39 @@ @ExtendWith(DependencyInjectionExtension.class) class DspHttpCoreExtensionTest { + private final IdentityService identityService = mock(); private DspHttpCoreExtension extension; @BeforeEach void setUp(ServiceExtensionContext context) { - context.registerService(RemoteMessageDispatcherRegistry.class, mock(RemoteMessageDispatcherRegistry.class)); - + context.registerService(IdentityService.class, identityService); } @Test @DisplayName("Assert usage of the default (noop) token decorator") void createDispatcher_noTokenDecorator_shouldUseNoop(ServiceExtensionContext context, ObjectFactory factory) { - var isMock = mock(IdentityService.class); - when(isMock.obtainClientCredentials(any())).thenReturn(Result.failure("not-important")); - context.registerService(IdentityService.class, isMock); + when(identityService.obtainClientCredentials(any())).thenReturn(Result.failure("not-important")); context.registerService(TokenDecorator.class, null); - extension = factory.constructInstance(DspHttpCoreExtension.class); var dispatcher = extension.dspHttpRemoteMessageDispatcher(context); - dispatcher.registerDelegate(new TestMessageDelegate()); - dispatcher.dispatch(String.class, new TestMessage()); + dispatcher.registerMessage(TestMessage.class, mock(), mock()); + dispatcher.dispatch(String.class, new TestMessage("protocol", "address")); - verify(isMock).obtainClientCredentials(argThat(tokenParams -> tokenParams.getScope() == null)); + verify(identityService).obtainClientCredentials(argThat(tokenParams -> tokenParams.getScope() == null)); } @Test @DisplayName("Assert usage of an injected TokenDecorator") void createDispatcher_withTokenDecorator_shouldUse(ServiceExtensionContext context, ObjectFactory factory) { - var isMock = mock(IdentityService.class); - when(isMock.obtainClientCredentials(any())).thenReturn(Result.failure("not-important")); - context.registerService(IdentityService.class, isMock); + when(identityService.obtainClientCredentials(any())).thenReturn(Result.failure("not-important")); context.registerService(TokenDecorator.class, (td) -> td.scope("test-scope")); - extension = factory.constructInstance(DspHttpCoreExtension.class); var dispatcher = extension.dspHttpRemoteMessageDispatcher(context); - dispatcher.registerDelegate(new TestMessageDelegate()); - dispatcher.dispatch(String.class, new TestMessage()); - - verify(isMock).obtainClientCredentials(argThat(tokenParams -> tokenParams.getScope().equals("test-scope"))); - } - - private static class TestMessage implements RemoteMessage { - @Override - public String getProtocol() { - return null; - } - - @Override - public String getCounterPartyAddress() { - return "http://connector"; - } - } - - private static class TestMessageDelegate extends DspHttpDispatcherDelegate { - protected TestMessageDelegate() { - super(null); - } - - @Override - public Class getMessageType() { - return TestMessage.class; - } - - @Override - public Request buildRequest(TestMessage message) { - return null; - } + dispatcher.registerMessage(TestMessage.class, mock(), mock()); + dispatcher.dispatch(String.class, new TestMessage("protocol", "address")); - @Override - public Function parseResponse() { - return null; - } + verify(identityService).obtainClientCredentials(argThat(tokenParams -> tokenParams.getScope().equals("test-scope"))); } } diff --git a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/TestMessage.java b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/TestMessage.java new file mode 100644 index 00000000000..c408511083b --- /dev/null +++ b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/TestMessage.java @@ -0,0 +1,29 @@ +/* + * 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; + +import org.eclipse.edc.spi.types.domain.message.RemoteMessage; + +public record TestMessage(String protocol, String counterPartyAddress) implements RemoteMessage { + @Override + public String getProtocol() { + return protocol; + } + + @Override + public String getCounterPartyAddress() { + return counterPartyAddress; + } +} diff --git a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImplTest.java b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImplTest.java index 6c7da4b4079..0873b7e025e 100644 --- a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImplTest.java +++ b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/DspHttpRemoteMessageDispatcherImplTest.java @@ -21,6 +21,7 @@ import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRemoteMessageDispatcher; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRequestFactory; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.http.EdcHttpClient; import org.eclipse.edc.spi.iam.IdentityService; @@ -54,21 +55,20 @@ class DspHttpRemoteMessageDispatcherImplTest { - private final EdcHttpClient httpClient = mock(EdcHttpClient.class); - private final IdentityService identityService = mock(IdentityService.class); + private final EdcHttpClient httpClient = mock(); + private final IdentityService identityService = mock(); + private final PolicyEngine policyEngine = mock(); + private final TokenDecorator tokenDecorator = mock(); + private final DspHttpRequestFactory requestFactory = mock(); private final DspHttpDispatcherDelegate delegate = mock(); - private final PolicyEngine policyEngine = mock(PolicyEngine.class); private final Duration timeout = Duration.of(5, SECONDS); private DspHttpRemoteMessageDispatcher dispatcher; - private TokenDecorator tokenDecoratorMock; @BeforeEach void setUp() { - tokenDecoratorMock = mock(TokenDecorator.class); - when(tokenDecoratorMock.decorate(any())).thenAnswer(a -> a.getArgument(0)); - dispatcher = new DspHttpRemoteMessageDispatcherImpl(httpClient, identityService, tokenDecoratorMock, policyEngine); - when(delegate.getMessageType()).thenReturn(TestMessage.class); + when(tokenDecorator.decorate(any())).thenAnswer(a -> a.getArgument(0)); + dispatcher = new DspHttpRemoteMessageDispatcherImpl(httpClient, identityService, tokenDecorator, policyEngine); } @Test @@ -82,20 +82,20 @@ void dispatch_sendRequestViaHttpClient() { Function> responseFunction = response -> StatusResult.success(responseBody); var authToken = "token"; - when(delegate.buildRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); + when(requestFactory.createRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); when(delegate.handleResponse()).thenReturn(responseFunction); when(httpClient.executeAsync(any(), any(), any())).thenReturn(completedFuture(responseBody)); when(identityService.obtainClientCredentials(any())) .thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token(authToken).build())); - dispatcher.registerDelegate(delegate); + dispatcher.registerMessage(TestMessage.class, requestFactory, delegate); var message = new TestMessage(); var result = dispatcher.dispatch(String.class, message); assertThat(result).succeedsWithin(timeout).isEqualTo(responseBody); - verify(delegate).buildRequest(message); + verify(requestFactory).createRequest(message); verify(identityService).obtainClientCredentials(argThat(tr -> tr.getAudience().equals(message.getCounterPartyAddress()))); verify(httpClient).executeAsync(argThat(r -> authToken.equals(r.headers().get("Authorization"))), any(), eq(responseFunction)); } @@ -108,14 +108,14 @@ void dispatch_ensureTokenDecoratorScope() { Map additional = Map.of("foo", "bar"); - when(tokenDecoratorMock.decorate(any())).thenAnswer(a -> a.getArgument(0, TokenParameters.Builder.class).scope("test-scope").additional(additional)); - when(delegate.buildRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); + when(tokenDecorator.decorate(any())).thenAnswer(a -> a.getArgument(0, TokenParameters.Builder.class).scope("test-scope").additional(additional)); + when(requestFactory.createRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); when(delegate.handleResponse()).thenReturn(responseFunction); when(httpClient.executeAsync(any(), any(), any())).thenReturn(completedFuture(responseBody)); when(identityService.obtainClientCredentials(any())) .thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token(authToken).build())); - dispatcher.registerDelegate(delegate); + dispatcher.registerMessage(TestMessage.class, requestFactory, delegate); var message = new TestMessage(); var result = dispatcher.dispatch(String.class, message); @@ -123,8 +123,6 @@ void dispatch_ensureTokenDecoratorScope() { assertThat(result).succeedsWithin(timeout); var captor = ArgumentCaptor.forClass(TokenParameters.class); - - verify(delegate).buildRequest(message); verify(identityService).obtainClientCredentials(captor.capture()); verify(httpClient).executeAsync(argThat(r -> authToken.equals(r.headers().get("Authorization"))), any(), eq(responseFunction)); @@ -146,8 +144,8 @@ void dispatch_noDelegateFound_throwException() { @Test void dispatch_failedToObtainToken_throwException() { - dispatcher.registerDelegate(delegate); - when(delegate.buildRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); + dispatcher.registerMessage(TestMessage.class, requestFactory, delegate); + when(requestFactory.createRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); when(identityService.obtainClientCredentials(any())).thenReturn(Result.failure("error")); assertThat(dispatcher.dispatch(String.class, new TestMessage())).failsWithin(timeout) @@ -158,12 +156,12 @@ void dispatch_failedToObtainToken_throwException() { @Test void dispatch_shouldNotEvaluatePolicy_whenItIsNotRegistered() { - when(delegate.buildRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); + when(requestFactory.createRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); when(delegate.handleResponse()).thenReturn(response -> null); when(httpClient.executeAsync(any(), any(), any())).thenReturn(completedFuture(null)); when(identityService.obtainClientCredentials(any())) .thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("any").build())); - dispatcher.registerDelegate(delegate); + dispatcher.registerMessage(TestMessage.class, requestFactory, delegate); var result = dispatcher.dispatch(String.class, new TestMessage()); @@ -173,12 +171,12 @@ void dispatch_shouldNotEvaluatePolicy_whenItIsNotRegistered() { @Test void dispatch_shouldEvaluatePolicy() { - when(delegate.buildRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); + when(requestFactory.createRequest(any())).thenReturn(new Request.Builder().url("http://url").build()); when(delegate.handleResponse()).thenReturn(response -> null); when(httpClient.executeAsync(any(), any(), any())).thenReturn(completedFuture(null)); when(identityService.obtainClientCredentials(any())) .thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("any").build())); - dispatcher.registerDelegate(delegate); + dispatcher.registerMessage(TestMessage.class, requestFactory, delegate); var policy = Policy.Builder.newInstance().build(); dispatcher.registerPolicyScope(TestMessage.class, "test.message", m -> policy); diff --git a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactoryTest.java b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactoryTest.java new file mode 100644 index 00000000000..03b00530d2c --- /dev/null +++ b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/GetDspHttpRequestFactoryTest.java @@ -0,0 +1,41 @@ +/* + * 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.dispatcher; + +import org.eclipse.edc.protocol.dsp.TestMessage; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.RequestPathProvider; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class GetDspHttpRequestFactoryTest { + + private final RequestPathProvider pathProvider = mock(); + private final GetDspHttpRequestFactory factory = new GetDspHttpRequestFactory<>(pathProvider); + + @Test + void shouldCreateProperHttpRequest() { + when(pathProvider.providePath(any())).thenReturn("/message/request/path"); + + var message = new TestMessage("protocol", "http://counter-party"); + var request = factory.createRequest(message); + + assertThat(request.url().url().toString()).isEqualTo("http://counter-party/message/request/path"); + assertThat(request.method()).isEqualTo("GET"); + } +} diff --git a/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactoryTest.java b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactoryTest.java new file mode 100644 index 00000000000..60903bda5b7 --- /dev/null +++ b/data-protocols/dsp/dsp-http-core/src/test/java/org/eclipse/edc/protocol/dsp/dispatcher/PostDspHttpRequestFactoryTest.java @@ -0,0 +1,55 @@ +/* + * 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.dispatcher; + +import okhttp3.MediaType; +import okio.Buffer; +import org.eclipse.edc.protocol.dsp.TestMessage; +import org.eclipse.edc.protocol.dsp.spi.dispatcher.RequestPathProvider; +import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class PostDspHttpRequestFactoryTest { + + private final RequestPathProvider pathProvider = mock(); + private final JsonLdRemoteMessageSerializer serializer = mock(); + private final PostDspHttpRequestFactory factory = new PostDspHttpRequestFactory<>(serializer, pathProvider); + + @Test + void shouldCreateProperHttpRequest() { + when(serializer.serialize(any())).thenReturn("serializedMessage"); + when(pathProvider.providePath(any())).thenReturn("/message/request/path"); + + var message = new TestMessage("protocol", "http://counter-party"); + var request = factory.createRequest(message); + + assertThat(request.url().url().toString()).isEqualTo("http://counter-party/message/request/path"); + assertThat(request.method()).isEqualTo("POST"); + assertThat(request.header("Content-Type")).isEqualTo("application/json"); + assertThat(request.body()).isNotNull().satisfies(body -> { + assertThat(body.contentType()).isNotNull().extracting(MediaType::toString).isEqualTo("application/json; charset=utf-8"); + try (var buffer = new Buffer()) { + body.writeTo(buffer); + assertThat(buffer.toString()).contains("serializedMessage"); + } + + }); + } +} diff --git a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegate.java b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegate.java index 32e7ae0f6ac..6f64c407ba0 100644 --- a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegate.java +++ b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegate.java @@ -14,13 +14,8 @@ package org.eclipse.edc.protocol.dsp.spi.dispatcher; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; -import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; import org.eclipse.edc.spi.response.StatusResult; import org.eclipse.edc.spi.types.domain.message.RemoteMessage; @@ -39,30 +34,9 @@ */ public abstract class DspHttpDispatcherDelegate { - private static final String APPLICATION_JSON = "application/json"; - - private final JsonLdRemoteMessageSerializer serializer; - - protected DspHttpDispatcherDelegate(JsonLdRemoteMessageSerializer serializer) { - this.serializer = serializer; + protected DspHttpDispatcherDelegate() { } - /** - * Returns the type of {@link RemoteMessage} this delegate can handle. - * - * @return the message type - */ - public abstract Class getMessageType(); - - /** - * Builds the HTTP request for the message including method, URL, body and headers. The - * Authorization header can be omitted as it is handled centrally. - * - * @param message the message - * @return the request builder - */ - public abstract Request buildRequest(M message); - /** * Handles the response and returns a {@link StatusResult} containing the response object * @@ -93,19 +67,6 @@ public Function> handleResponse() { */ protected abstract Function parseResponse(); - protected Request buildPostRequest(M message, String path) { - var body = serializer.serialize(message); - var requestBody = RequestBody.create(body, MediaType.get(APPLICATION_JSON)); - - var url = HttpUrl.get(message.getCounterPartyAddress() + path); - - return new Request.Builder() - .url(url) - .header("Content-Type", APPLICATION_JSON) - .post(requestBody) - .build(); - } - private String asString(ResponseBody it) { try { return it.string(); diff --git a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRemoteMessageDispatcher.java b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRemoteMessageDispatcher.java index 0d0dd8e644b..3f6e97040c8 100644 --- a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRemoteMessageDispatcher.java +++ b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRemoteMessageDispatcher.java @@ -24,15 +24,17 @@ * {@link RemoteMessageDispatcher} for sending dataspace protocol messages. */ public interface DspHttpRemoteMessageDispatcher extends RemoteMessageDispatcher { - + /** - * Registers a {@link DspHttpDispatcherDelegate} for supporting a specific type of remote message. + * Registers a message request factory and response parser * - * @param delegate the delegate + * @param clazz the message class. + * @param requestFactory the request factory. + * @param delegate the response parser delegate. * @param the type of message * @param the response type */ - void registerDelegate(DspHttpDispatcherDelegate delegate); + void registerMessage(Class clazz, DspHttpRequestFactory requestFactory, DspHttpDispatcherDelegate delegate); /** * Registers a {@link Policy} scope to be evaluated for certain types of messages diff --git a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRequestFactory.java b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRequestFactory.java new file mode 100644 index 00000000000..63603520ea8 --- /dev/null +++ b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpRequestFactory.java @@ -0,0 +1,35 @@ +/* + * 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.spi.dispatcher; + +import okhttp3.Request; +import org.eclipse.edc.spi.types.domain.message.RemoteMessage; + +/** + * Creates an HTTP request for the DSP HTTP Bindings given the message instance + * + * @param the message type. + */ +@FunctionalInterface +public interface DspHttpRequestFactory { + + /** + * Create the request given the message and a {@link RequestPathProvider} + * + * @param message the message. + * @return the request. + */ + Request createRequest(M message); +} diff --git a/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/RequestPathProvider.java b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/RequestPathProvider.java new file mode 100644 index 00000000000..77ad2cde990 --- /dev/null +++ b/data-protocols/dsp/dsp-http-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/RequestPathProvider.java @@ -0,0 +1,34 @@ +/* + * 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.spi.dispatcher; + + +import org.eclipse.edc.spi.types.domain.message.RemoteMessage; + +/** + * Provide http request path given the outgoing message. + * + * @param the message type + */ +@FunctionalInterface +public interface RequestPathProvider { + /** + * Return the path + * + * @param message the message. + * @return the path. + */ + String providePath(M message); +} diff --git a/data-protocols/dsp/dsp-http-spi/src/test/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegateTest.java b/data-protocols/dsp/dsp-http-spi/src/test/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegateTest.java index b8926795d90..48d9847596d 100644 --- a/data-protocols/dsp/dsp-http-spi/src/test/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegateTest.java +++ b/data-protocols/dsp/dsp-http-spi/src/test/java/org/eclipse/edc/protocol/dsp/spi/dispatcher/DspHttpDispatcherDelegateTest.java @@ -91,17 +91,7 @@ void handleResponse_shouldReturnRetryError_whenResponseIsServerError() { private class TestDspHttpDispatcherDelegate extends DspHttpDispatcherDelegate { TestDspHttpDispatcherDelegate() { - super(DspHttpDispatcherDelegateTest.this.serializer); - } - - @Override - public Class getMessageType() { - return null; - } - - @Override - public Request buildRequest(RemoteMessage message) { - return null; + super(); } @Override diff --git a/data-protocols/dsp/dsp-http-spi/src/testFixtures/java/org/eclipse/edc/protocol/dsp/spi/testfixtures/dispatcher/DspHttpDispatcherDelegateTestBase.java b/data-protocols/dsp/dsp-http-spi/src/testFixtures/java/org/eclipse/edc/protocol/dsp/spi/testfixtures/dispatcher/DspHttpDispatcherDelegateTestBase.java index b63a5d617a5..d5bfc6b9113 100644 --- a/data-protocols/dsp/dsp-http-spi/src/testFixtures/java/org/eclipse/edc/protocol/dsp/spi/testfixtures/dispatcher/DspHttpDispatcherDelegateTestBase.java +++ b/data-protocols/dsp/dsp-http-spi/src/testFixtures/java/org/eclipse/edc/protocol/dsp/spi/testfixtures/dispatcher/DspHttpDispatcherDelegateTestBase.java @@ -37,8 +37,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -59,39 +57,6 @@ public abstract class DspHttpDispatcherDelegateTestBase */ protected abstract DspHttpDispatcherDelegate delegate(); - /** - * Checks that a delegate, given a message, builds the expected HTTP request. The message should - * be serialized and added as the request body. Validates that the delegate sets the expected - * request path. Relevant for all delegates. - * - * @param message the message - * @param path the expected path - */ - protected void testBuildRequest_shouldReturnRequest(M message, String path) throws IOException { - var serializedBody = "serialized"; - - when(serializer.serialize(eq(message))).thenReturn(serializedBody); - - var httpRequest = delegate().buildRequest(message); - - assertThat(httpRequest.url().url()).hasToString(message.getCounterPartyAddress() + path); - assertThat(readRequestBody(httpRequest)).isEqualTo(serializedBody); - - verify(serializer, times(1)).serialize(eq(message)); - } - - /** - * Checks that a delegate throws an exception if serialization of the message to send fails. - * Relevant for all delegates. - * - * @param message the message - */ - protected void testBuildRequest_shouldThrowException_whenSerializationFails(M message) { - when(serializer.serialize(eq(message))).thenThrow(EdcException.class); - - assertThatThrownBy(() -> delegate().buildRequest(message)).isInstanceOf(EdcException.class); - } - /** * Checks that a delegate throws an exception when the response body is missing. Only relevant * for delegates that process the response body. diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/DspNegotiationHttpDispatcherExtension.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/DspNegotiationHttpDispatcherExtension.java index 8f9b08b18f3..938ee3ce220 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/DspNegotiationHttpDispatcherExtension.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/DspNegotiationHttpDispatcherExtension.java @@ -14,7 +14,14 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementMessage; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementVerificationMessage; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractNegotiationEventMessage; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiationTerminationMessage; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractOfferMessage; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractRequestMessage; import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.protocol.dsp.dispatcher.PostDspHttpRequestFactory; import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementMessageHttpDelegate; import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementVerificationMessageHttpDelegate; import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractNegotiationEventMessageHttpDelegate; @@ -29,6 +36,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.AGREEMENT; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_OFFER; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_REQUEST; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.EVENT; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.INITIAL_CONTRACT_REQUEST; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.TERMINATION; +import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.VERIFICATION; import static org.eclipse.edc.spi.CoreConstants.JSON_LD; @Extension(value = DspNegotiationHttpDispatcherExtension.NAME) @@ -52,11 +67,41 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - messageDispatcher.registerDelegate(new ContractAgreementMessageHttpDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new ContractAgreementVerificationMessageHttpDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new ContractNegotiationEventMessageHttpDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new ContractNegotiationTerminationMessageHttpDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new ContractRequestMessageHttpDelegate(remoteMessageSerializer, typeManager.getMapper(JSON_LD), jsonLdService)); - messageDispatcher.registerDelegate(new ContractOfferMessageHttpDelegate(remoteMessageSerializer)); + messageDispatcher.registerMessage( + ContractAgreementMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + AGREEMENT), + new ContractAgreementMessageHttpDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + ContractAgreementVerificationMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + AGREEMENT + VERIFICATION), + new ContractAgreementVerificationMessageHttpDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + ContractNegotiationEventMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + EVENT), + new ContractNegotiationEventMessageHttpDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + ContractNegotiationTerminationMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + TERMINATION), + new ContractNegotiationTerminationMessageHttpDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + ContractRequestMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> { + if (m.getType() == ContractRequestMessage.Type.INITIAL) { + return BASE_PATH + INITIAL_CONTRACT_REQUEST; + } else { + return BASE_PATH + m.getProcessId() + CONTRACT_REQUEST; + } + }), + new ContractRequestMessageHttpDelegate(remoteMessageSerializer, typeManager.getMapper(JSON_LD), jsonLdService) + ); + messageDispatcher.registerMessage( + ContractOfferMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + CONTRACT_OFFER), + new ContractOfferMessageHttpDelegate(remoteMessageSerializer) + ); } } diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegate.java index db553cb263a..32c9a8762d9 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegate.java @@ -14,7 +14,6 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -22,33 +21,13 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.AGREEMENT; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; - /** * Delegate for dispatching contract agreement message as defined in the dataspace protocol specification. */ public class ContractAgreementMessageHttpDelegate extends DspHttpDispatcherDelegate { public ContractAgreementMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return ContractAgreementMessage.class; - } - - /** - * Sends a contract agreement message. The request body is constructed as defined in the dataspace - * protocol. The request is sent to the remote component using the path from the http binding. - * - * @param message the message. - * @return the built okhttp request. - */ - @Override - public Request buildRequest(ContractAgreementMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + AGREEMENT); + super(); } /** diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegate.java index c82d816e0dc..c260b9a4f65 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegate.java @@ -14,7 +14,6 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementVerificationMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -22,35 +21,13 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.AGREEMENT; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.VERIFICATION; - /** * Delegate for dispatching contract agreement verification message as defined in the dataspace protocol specification. */ public class ContractAgreementVerificationMessageHttpDelegate extends DspHttpDispatcherDelegate { public ContractAgreementVerificationMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return ContractAgreementVerificationMessage.class; - } - - /** - * Sends a contract agreement verification message. The request body is constructed as defined in - * the dataspace protocol. The request is sent to the remote component using the path from the http - * binding. - * - * @param message the message. - * @return the built okhttp request. - */ - @Override - public Request buildRequest(ContractAgreementVerificationMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + AGREEMENT + VERIFICATION); + super(); } /** diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegate.java index a0e3c63853f..87195908a12 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegate.java @@ -14,7 +14,6 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractNegotiationEventMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -22,34 +21,13 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.EVENT; - /** * Delegate for dispatching contract negotiation event message as defined in the dataspace protocol specification. */ public class ContractNegotiationEventMessageHttpDelegate extends DspHttpDispatcherDelegate { public ContractNegotiationEventMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return ContractNegotiationEventMessage.class; - } - - /** - * Sends a contract negotiation event message. The request body is constructed as defined in the - * dataspace protocol. The request is sent to the remote component using the path from the http - * binding. - * - * @param message the message. - * @return the built okhttp request. - */ - @Override - public Request buildRequest(ContractNegotiationEventMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + EVENT); + super(); } /** diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegate.java index 148cd3c7a02..c80f7c12d02 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegate.java @@ -14,7 +14,6 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiationTerminationMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -22,34 +21,13 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.TERMINATION; - /** * Delegate for dispatching contract negotiation termination message as defined in the dataspace protocol specification. */ public class ContractNegotiationTerminationMessageHttpDelegate extends DspHttpDispatcherDelegate { public ContractNegotiationTerminationMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return ContractNegotiationTerminationMessage.class; - } - - /** - * Sends a contract negotiation termination message. The request body is constructed as defined - * in the dataspace protocol. The request is sent to the remote component using the path from the - * http binding. - * - * @param message the message. - * @return the built okhttp request. - */ - @Override - public Request buildRequest(ContractNegotiationTerminationMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + TERMINATION); + super(); } /** diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegate.java index ea88a0369ab..3d66c8b9c88 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegate.java @@ -14,7 +14,6 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractOfferMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -22,28 +21,15 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_OFFER; - /** * Delegate for dispatching contract offer message as defined in the dataspace protocol specification. */ public class ContractOfferMessageHttpDelegate extends DspHttpDispatcherDelegate { public ContractOfferMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); + super(); } - - @Override - public Class getMessageType() { - return ContractOfferMessage.class; - } - - @Override - public Request buildRequest(ContractOfferMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + CONTRACT_OFFER); - } - + @Override protected Function parseResponse() { return response -> null; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegate.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegate.java index 10e83018eee..dabbd8bac39 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegate.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegate.java @@ -16,7 +16,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractRequestMessage; import org.eclipse.edc.jsonld.spi.JsonLd; @@ -27,10 +26,6 @@ import java.io.IOException; import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_REQUEST; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.INITIAL_CONTRACT_REQUEST; - /** * Delegate for dispatching contract request message as defined in the dataspace protocol specification. */ @@ -41,32 +36,11 @@ public class ContractRequestMessageHttpDelegate extends DspHttpDispatcherDelegat public ContractRequestMessageHttpDelegate(JsonLdRemoteMessageSerializer serializer, ObjectMapper mapper, JsonLd jsonLdService) { - super(serializer); + super(); this.mapper = mapper; this.jsonLdService = jsonLdService; } - @Override - public Class getMessageType() { - return ContractRequestMessage.class; - } - - /** - * Sends a contract request message. The request body is constructed as defined in the dataspace - * protocol. The request is sent to the remote component using the path from the http binding. - * - * @param message the message. - * @return the built okhttp request. - */ - @Override - public Request buildRequest(ContractRequestMessage message) { - if (message.getType() == ContractRequestMessage.Type.INITIAL) { - return buildPostRequest(message, BASE_PATH + INITIAL_CONTRACT_REQUEST); - } else { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + CONTRACT_REQUEST); - } - } - @Override public Function parseResponse() { return response -> { diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegateTest.java index 2d20e37785c..e2631c31f63 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementMessageHttpDelegateTest.java @@ -14,25 +14,12 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; -import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementMessage; -import org.eclipse.edc.policy.model.Action; -import org.eclipse.edc.policy.model.Duty; -import org.eclipse.edc.policy.model.Permission; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.policy.model.Prohibition; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static java.util.UUID.randomUUID; -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.AGREEMENT; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; - class ContractAgreementMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private ContractAgreementMessageHttpDelegate delegate; @@ -42,58 +29,11 @@ void setUp() { delegate = new ContractAgreementMessageHttpDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractAgreementMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + AGREEMENT); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private ContractAgreementMessage message() { - var value = "example"; - return ContractAgreementMessage.Builder.newInstance() - .protocol(value) - .processId(value) - .counterPartyAddress("http://connector") - .contractAgreement(contractAgreement()) - .build(); - } - - private ContractAgreement contractAgreement() { - return ContractAgreement.Builder.newInstance() - .id(randomUUID().toString()) - .providerId("agentId") - .consumerId("agentId") - .assetId("assetId") - .policy(policy()).build(); - } - - private Policy policy() { - var action = Action.Builder.newInstance().type("USE").build(); - var permission = Permission.Builder.newInstance().action(action).build(); - var prohibition = Prohibition.Builder.newInstance().action(action).build(); - var duty = Duty.Builder.newInstance().action(action).build(); - return Policy.Builder.newInstance() - .permission(permission) - .prohibition(prohibition) - .duty(duty) - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegateTest.java index b809f655df2..5d7084ea138 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractAgreementVerificationMessageHttpDelegateTest.java @@ -20,13 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.AGREEMENT; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.VERIFICATION; - class ContractAgreementVerificationMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private ContractAgreementVerificationMessageHttpDelegate delegate; @@ -36,36 +29,11 @@ void setUp() { delegate = new ContractAgreementVerificationMessageHttpDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractAgreementVerificationMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + AGREEMENT + VERIFICATION); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private ContractAgreementVerificationMessage message() { - var value = "example"; - return ContractAgreementVerificationMessage.Builder.newInstance() - .protocol(value) - .processId(value) - .counterPartyAddress("http://connector") - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegateTest.java index 4e9c7273265..70d175b045a 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationEventMessageHttpDelegateTest.java @@ -20,12 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.EVENT; - class ContractNegotiationEventMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private ContractNegotiationEventMessageHttpDelegate delegate; @@ -35,37 +29,11 @@ void setUp() { delegate = new ContractNegotiationEventMessageHttpDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractNegotiationEventMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + EVENT); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private ContractNegotiationEventMessage message() { - var value = "example"; - return ContractNegotiationEventMessage.Builder.newInstance() - .protocol(value) - .processId(value) - .counterPartyAddress("http://connector") - .type(ContractNegotiationEventMessage.Type.FINALIZED) - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegateTest.java index 2a31ff64574..69e59dbb75d 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractNegotiationTerminationMessageHttpDelegateTest.java @@ -20,12 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.TERMINATION; - class ContractNegotiationTerminationMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private ContractNegotiationTerminationMessageHttpDelegate delegate; @@ -35,37 +29,11 @@ void setUp() { delegate = new ContractNegotiationTerminationMessageHttpDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractNegotiationTerminationMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + TERMINATION); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private ContractNegotiationTerminationMessage message() { - var value = "example"; - return ContractNegotiationTerminationMessage.Builder.newInstance() - .protocol(value) - .processId(value) - .counterPartyAddress("http://connector") - .rejectionReason(value) - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegateTest.java index c3652655180..a516df535f9 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractOfferMessageHttpDelegateTest.java @@ -15,20 +15,11 @@ package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractOfferMessage; -import org.eclipse.edc.connector.contract.spi.types.offer.ContractOffer; -import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static java.util.UUID.randomUUID; -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_OFFER; - class ContractOfferMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private ContractOfferMessageHttpDelegate delegate; @@ -37,23 +28,7 @@ class ContractOfferMessageHttpDelegateTest extends DspHttpDispatcherDelegateTest void setUp() { delegate = new ContractOfferMessageHttpDelegate(serializer); } - - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractOfferMessage.class); - } - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + CONTRACT_OFFER); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_shouldReturnNullFunction() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); @@ -63,22 +38,5 @@ void parseResponse_shouldReturnNullFunction() { protected DspHttpDispatcherDelegate delegate() { return delegate; } - - private ContractOfferMessage message() { - return ContractOfferMessage.Builder.newInstance() - .protocol("dsp") - .processId("processId") - .counterPartyAddress("http://connector") - .contractOffer(contractOffer()) - .callbackAddress("http://callback") - .build(); - } - - private ContractOffer contractOffer() { - return ContractOffer.Builder.newInstance() - .id(randomUUID().toString()) - .assetId("assetId") - .policy(Policy.Builder.newInstance().build()) - .build(); - } + } diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegateTest.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegateTest.java index 2582dd0b2d0..e71ba606864 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegateTest.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/dispatcher/delegate/ContractRequestMessageHttpDelegateTest.java @@ -19,14 +19,8 @@ import okhttp3.Response; import okhttp3.ResponseBody; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractRequestMessage; -import org.eclipse.edc.connector.contract.spi.types.offer.ContractOffer; import org.eclipse.edc.jsonld.TitaniumJsonLd; import org.eclipse.edc.jsonld.spi.JsonLdKeywords; -import org.eclipse.edc.policy.model.Action; -import org.eclipse.edc.policy.model.Duty; -import org.eclipse.edc.policy.model.Permission; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.policy.model.Prohibition; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; import org.eclipse.edc.spi.monitor.Monitor; @@ -35,11 +29,7 @@ import java.io.IOException; -import static java.util.UUID.randomUUID; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.CONTRACT_REQUEST; -import static org.eclipse.edc.protocol.dsp.negotiation.dispatcher.NegotiationApiPaths.INITIAL_CONTRACT_REQUEST; import static org.eclipse.edc.protocol.dsp.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION; import static org.eclipse.edc.protocol.dsp.type.DspNegotiationPropertyAndTypeNames.DSPACE_VALUE_NEGOTIATION_STATE_REQUESTED; import static org.eclipse.edc.protocol.dsp.type.DspPropertyAndTypeNames.DSPACE_PROPERTY_PROCESS_ID; @@ -51,8 +41,6 @@ class ContractRequestMessageHttpDelegateTest extends DspHttpDispatcherDelegateTestBase { private static final String PROCESS_ID = "processId"; - private static final String DATASET_ID = "datasetId"; - private static final String DSP = "DSP"; private ContractRequestMessageHttpDelegate delegate; private TitaniumJsonLd jsonLdService; @@ -63,27 +51,6 @@ void setUp() { delegate = new ContractRequestMessageHttpDelegate(serializer, mapper, jsonLdService); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(ContractRequestMessage.class); - } - - @Test - void buildRequest_initial() throws IOException { - testBuildRequest_shouldReturnRequest(message_initial(), BASE_PATH + INITIAL_CONTRACT_REQUEST); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + CONTRACT_REQUEST); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNegotiation() throws IOException { var response = mock(Response.class); @@ -117,48 +84,6 @@ void parseResponse_readingResponseBodyFails_throwException() throws IOException return delegate; } - private ContractRequestMessage message() { - return ContractRequestMessage.Builder.newInstance() - .protocol(DSP) - .processId(PROCESS_ID) - .counterPartyAddress("http://connector") - .dataSet(DATASET_ID) - .contractOffer(contractOffer()) - .type(ContractRequestMessage.Type.COUNTER_OFFER) - .build(); - } - - private ContractRequestMessage message_initial() { - var value = "example"; - return ContractRequestMessage.Builder.newInstance() - .protocol(value) - .processId(value) - .counterPartyAddress("http://connector") - .dataSet(value) - .contractOffer(contractOffer()) - .type(ContractRequestMessage.Type.INITIAL) - .build(); - } - - private ContractOffer contractOffer() { - return ContractOffer.Builder.newInstance() - .id(randomUUID().toString()) - .assetId("assetId") - .policy(policy()).build(); - } - - private Policy policy() { - var action = Action.Builder.newInstance().type("USE").build(); - var permission = Permission.Builder.newInstance().action(action).build(); - var prohibition = Prohibition.Builder.newInstance().action(action).build(); - var duty = Duty.Builder.newInstance().action(action).build(); - return Policy.Builder.newInstance() - .permission(permission) - .prohibition(prohibition) - .duty(duty) - .build(); - } - private JsonObject negotiation() { var builder = Json.createObjectBuilder(); builder.add(JsonLdKeywords.ID, "id1"); diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/build.gradle.kts b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/build.gradle.kts index fd474c54926..8a836d95807 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/build.gradle.kts +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/build.gradle.kts @@ -22,9 +22,10 @@ dependencies { api(project(":spi:control-plane:control-plane-spi")) api(project(":data-protocols:dsp:dsp-http-spi")) + implementation(project(":data-protocols:dsp:dsp-http-core")) implementation(project(":data-protocols:dsp:dsp-transfer-process:dsp-transfer-process-transform")) implementation(project(":extensions:common:json-ld")) testImplementation(testFixtures(project(":data-protocols:dsp:dsp-http-spi"))) -} \ No newline at end of file +} diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/DspTransferProcessDispatcherExtension.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/DspTransferProcessDispatcherExtension.java index 02db714d414..2008ba70b8e 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/DspTransferProcessDispatcherExtension.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/DspTransferProcessDispatcherExtension.java @@ -15,6 +15,11 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher; +import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferCompletionMessage; +import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferRequestMessage; +import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferStartMessage; +import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferTerminationMessage; +import org.eclipse.edc.protocol.dsp.dispatcher.PostDspHttpRequestFactory; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRemoteMessageDispatcher; import org.eclipse.edc.protocol.dsp.spi.serialization.JsonLdRemoteMessageSerializer; import org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate.TransferCompletionDelegate; @@ -26,6 +31,12 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_COMPLETION; +import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_INITIAL_REQUEST; +import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_START; +import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_TERMINATION; + /** * Provides HTTP dispatching for Dataspace Protocol transfer process messages via the {@link DspHttpRemoteMessageDispatcher}. @@ -47,9 +58,25 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - messageDispatcher.registerDelegate(new TransferRequestDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new TransferCompletionDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new TransferStartDelegate(remoteMessageSerializer)); - messageDispatcher.registerDelegate(new TransferTerminationDelegate(remoteMessageSerializer)); + messageDispatcher.registerMessage( + TransferRequestMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + TRANSFER_INITIAL_REQUEST), + new TransferRequestDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + TransferCompletionMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + TRANSFER_COMPLETION), + new TransferCompletionDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + TransferStartMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + TRANSFER_START), + new TransferStartDelegate(remoteMessageSerializer) + ); + messageDispatcher.registerMessage( + TransferTerminationMessage.class, + new PostDspHttpRequestFactory<>(remoteMessageSerializer, m -> BASE_PATH + m.getProcessId() + TRANSFER_TERMINATION), + new TransferTerminationDelegate(remoteMessageSerializer) + ); } } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegate.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegate.java index 09dcdfab3b8..49fbfa6ff6d 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegate.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegate.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferCompletionMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -23,23 +22,10 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_COMPLETION; - public class TransferCompletionDelegate extends DspHttpDispatcherDelegate { public TransferCompletionDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return TransferCompletionMessage.class; - } - - @Override - public Request buildRequest(TransferCompletionMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_COMPLETION); + super(); } @Override diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegate.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegate.java index 157e257cc28..486b3fe1d14 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegate.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegate.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferRequestMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -23,23 +22,10 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_INITIAL_REQUEST; - public class TransferRequestDelegate extends DspHttpDispatcherDelegate { public TransferRequestDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return TransferRequestMessage.class; - } - - @Override - public Request buildRequest(TransferRequestMessage message) { - return buildPostRequest(message, BASE_PATH + TRANSFER_INITIAL_REQUEST); + super(); } @Override diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegate.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegate.java index ab5a1320228..e47b28e2f08 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegate.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegate.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferStartMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -23,23 +22,10 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_START; - public class TransferStartDelegate extends DspHttpDispatcherDelegate { public TransferStartDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return TransferStartMessage.class; - } - - @Override - public Request buildRequest(TransferStartMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_START); + super(); } @Override diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegate.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegate.java index 14f69b197b8..6481a1dd492 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegate.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegate.java @@ -15,7 +15,6 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate; import jakarta.json.JsonObject; -import okhttp3.Request; import okhttp3.Response; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferTerminationMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; @@ -23,23 +22,10 @@ import java.util.function.Function; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_TERMINATION; - public class TransferTerminationDelegate extends DspHttpDispatcherDelegate { public TransferTerminationDelegate(JsonLdRemoteMessageSerializer serializer) { - super(serializer); - } - - @Override - public Class getMessageType() { - return TransferTerminationMessage.class; - } - - @Override - public Request buildRequest(TransferTerminationMessage message) { - return buildPostRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_TERMINATION); + super(); } @Override diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegateTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegateTest.java index e87a7a2dee3..faba2990943 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegateTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferCompletionDelegateTest.java @@ -20,12 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_COMPLETION; - class TransferCompletionDelegateTest extends DspHttpDispatcherDelegateTestBase { private TransferCompletionDelegate delegate; @@ -35,35 +29,11 @@ void setUp() { delegate = new TransferCompletionDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(TransferCompletionMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_COMPLETION); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private TransferCompletionMessage message() { - return TransferCompletionMessage.Builder.newInstance() - .processId("testId") - .protocol("dataspace-protocol") - .counterPartyAddress("http://test-connector-address") - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegateTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegateTest.java index a7371a3f760..48e0b6bf07b 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegateTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferRequestDelegateTest.java @@ -14,22 +14,12 @@ package org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.delegate; -import jakarta.json.Json; -import jakarta.json.JsonObject; import org.eclipse.edc.connector.transfer.spi.types.protocol.TransferRequestMessage; import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate; import org.eclipse.edc.protocol.dsp.spi.testfixtures.dispatcher.DspHttpDispatcherDelegateTestBase; -import org.eclipse.edc.spi.types.domain.DataAddress; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_INITIAL_REQUEST; - class TransferRequestDelegateTest extends DspHttpDispatcherDelegateTestBase { private TransferRequestDelegate delegate; @@ -39,22 +29,6 @@ void setUp() { delegate = new TransferRequestDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(TransferRequestMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + TRANSFER_INITIAL_REQUEST); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); @@ -65,23 +39,4 @@ void parseResponse_returnNull() { return delegate; } - private TransferRequestMessage message() { - return TransferRequestMessage.Builder.newInstance() - .processId("testId") - .protocol("dataspace-protocol") - .callbackAddress("http://test-connector-address") - .counterPartyAddress("http://test-connector-address") - .contractId("contractId") - .dataDestination(DataAddress.Builder.newInstance() - .type("type") - .build()) - .build(); - } - - private JsonObject getJsonObject() { - return Json.createObjectBuilder() - .add(CONTEXT, Json.createObjectBuilder().add("prefix", "http://schema").build()) - .add("prefix:key", "value") - .build(); - } } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegateTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegateTest.java index 086ac0c33c5..83ec4bda372 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegateTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferStartDelegateTest.java @@ -20,12 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_START; - class TransferStartDelegateTest extends DspHttpDispatcherDelegateTestBase { private TransferStartDelegate delegate; @@ -35,35 +29,11 @@ void setUp() { delegate = new TransferStartDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(TransferStartMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_START); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private TransferStartMessage message() { - return TransferStartMessage.Builder.newInstance() - .processId("testId") - .protocol("dataspace-protocol") - .counterPartyAddress("http://test-connector-address") - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegateTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegateTest.java index 17d35be11b7..6e44f1206e1 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegateTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-dispatcher/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/dispatcher/delegate/TransferTerminationDelegateTest.java @@ -20,12 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.BASE_PATH; -import static org.eclipse.edc.protocol.dsp.transferprocess.dispatcher.TransferProcessApiPaths.TRANSFER_TERMINATION; - class TransferTerminationDelegateTest extends DspHttpDispatcherDelegateTestBase { private TransferTerminationDelegate delegate; @@ -35,35 +29,11 @@ void setUp() { delegate = new TransferTerminationDelegate(serializer); } - @Test - void getMessageType() { - assertThat(delegate.getMessageType()).isEqualTo(TransferTerminationMessage.class); - } - - @Test - void buildRequest() throws IOException { - var message = message(); - testBuildRequest_shouldReturnRequest(message, BASE_PATH + message.getProcessId() + TRANSFER_TERMINATION); - } - - @Test - void buildRequest_serializationFails_throwException() { - testBuildRequest_shouldThrowException_whenSerializationFails(message()); - } - @Test void parseResponse_returnNull() { testParseResponse_shouldReturnNullFunction_whenResponseBodyNotProcessed(); } - private TransferTerminationMessage message() { - return TransferTerminationMessage.Builder.newInstance() - .processId("testId") - .protocol("dataspace-protocol") - .counterPartyAddress("http://test-connector-address") - .build(); - } - @Override protected DspHttpDispatcherDelegate delegate() { return delegate; diff --git a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/CatalogApiExtension.java b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/CatalogApiExtension.java index 9de57111b22..4b5078f1a02 100644 --- a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/CatalogApiExtension.java +++ b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/CatalogApiExtension.java @@ -14,8 +14,6 @@ package org.eclipse.edc.connector.api.management.catalog; -import org.eclipse.edc.catalog.spi.CatalogRequest; -import org.eclipse.edc.catalog.spi.DatasetRequest; import org.eclipse.edc.connector.api.management.catalog.transform.JsonObjectToCatalogRequestTransformer; import org.eclipse.edc.connector.api.management.catalog.transform.JsonObjectToDatasetRequestTransformer; import org.eclipse.edc.connector.api.management.catalog.validation.CatalogRequestValidator; @@ -30,6 +28,9 @@ import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; import org.eclipse.edc.web.spi.WebService; +import static org.eclipse.edc.catalog.spi.CatalogRequest.CATALOG_REQUEST_TYPE; +import static org.eclipse.edc.catalog.spi.DatasetRequest.DATASET_REQUEST_TYPE; + @Extension(value = CatalogApiExtension.NAME) public class CatalogApiExtension implements ServiceExtension { @@ -62,7 +63,7 @@ public void initialize(ServiceExtensionContext context) { webService.registerResource(config.getContextAlias(), new CatalogApiController(service, transformerRegistry, validatorRegistry)); - validatorRegistry.register(CatalogRequest.CATALOG_REQUEST_TYPE, CatalogRequestValidator.instance()); - validatorRegistry.register(DatasetRequest.DATASET_REQUEST_TYPE, DatasetRequestValidator.instance()); + validatorRegistry.register(CATALOG_REQUEST_TYPE, CatalogRequestValidator.instance()); + validatorRegistry.register(DATASET_REQUEST_TYPE, DatasetRequestValidator.instance()); } } diff --git a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformer.java b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformer.java index afe62f289c4..1da549348f4 100644 --- a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformer.java +++ b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformer.java @@ -51,10 +51,15 @@ public JsonObjectToCatalogRequestTransformer(Monitor monitor) { return object.get(CATALOG_REQUEST_PROVIDER_URL); }); + var querySpec = Optional.of(object) + .map(it -> it.get(CATALOG_REQUEST_QUERY_SPEC)) + .map(it -> transformObject(it, QuerySpec.class, context)) + .orElse(null); + return CatalogRequest.Builder.newInstance() .protocol(transformString(object.get(CATALOG_REQUEST_PROTOCOL), context)) - .querySpec(transformObject(object.get(CATALOG_REQUEST_QUERY_SPEC), QuerySpec.class, context)) .counterPartyAddress(transformString(counterPartyAddress, context)) + .querySpec(querySpec) .build(); } diff --git a/extensions/control-plane/api/management-api/catalog-api/src/test/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformerTest.java b/extensions/control-plane/api/management-api/catalog-api/src/test/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformerTest.java index 27664a67ee7..413895496ed 100644 --- a/extensions/control-plane/api/management-api/catalog-api/src/test/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformerTest.java +++ b/extensions/control-plane/api/management-api/catalog-api/src/test/java/org/eclipse/edc/connector/api/management/catalog/transform/JsonObjectToCatalogRequestTransformerTest.java @@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; class JsonObjectToCatalogRequestTransformerTest { @@ -91,4 +92,19 @@ void transform_shouldUseProviderId_whenCounterPartyAddressIsMissing() { verify(monitor).warning(anyString()); } + @Test + void transform_shouldHandleEmptyQuerySpec() { + var json = Json.createObjectBuilder() + .add(TYPE, CATALOG_REQUEST_TYPE) + .add(CATALOG_REQUEST_PROTOCOL, "protocol") + .add(CATALOG_REQUEST_COUNTER_PARTY_ADDRESS, "http://provider/url") + .build(); + + var result = transformer.transform(json, context); + + assertThat(result).isNotNull(); + assertThat(result.getQuerySpec()).isEqualTo(null); + verifyNoInteractions(context); + } + } diff --git a/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequest.java b/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequest.java index 963ca140527..96c0fb2e5b7 100644 --- a/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequest.java +++ b/spi/common/catalog-spi/src/main/java/org/eclipse/edc/catalog/spi/CatalogRequest.java @@ -18,7 +18,6 @@ import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import org.eclipse.edc.spi.query.QuerySpec; -import static java.util.Objects.requireNonNull; import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; public class CatalogRequest { diff --git a/system-tests/e2e-test-fixtures/src/testFixtures/java/org/eclipse/edc/test/system/utils/Participant.java b/system-tests/e2e-test-fixtures/src/testFixtures/java/org/eclipse/edc/test/system/utils/Participant.java index dd93ec5451b..e61868c06c8 100644 --- a/system-tests/e2e-test-fixtures/src/testFixtures/java/org/eclipse/edc/test/system/utils/Participant.java +++ b/system-tests/e2e-test-fixtures/src/testFixtures/java/org/eclipse/edc/test/system/utils/Participant.java @@ -217,7 +217,7 @@ public JsonObject getDatasetForAsset(Participant provider, String assetId) { .contentType(JSON) .when() .body(requestBody) - .post("/v2/catalog/request") + .post("/v2/catalog/dataset/request") .then() .log().all() .statusCode(200) diff --git a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java index 0676d3c91b5..712858e18a7 100644 --- a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java @@ -57,6 +57,7 @@ void requestCatalog_shouldReturnCatalog_withoutQuerySpec() { .body(requestBody) .post("/v2/catalog/request") .then() + .log().ifError() .statusCode(200) .contentType(JSON) .body(TYPE, is("dcat:Catalog"));