From 1e8c32129a8672c666ba4d321607a79bb1649646 Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Tue, 21 Nov 2023 15:53:15 +0100 Subject: [PATCH 1/5] refactor: separate DataPlaneClient and DataPlaneSelectorClient --- ... => EmbeddedDataPlaneSelectorService.java} | 6 - .../core/DataPlaneSelectorExtension.java | 1 - .../TransferDataPlaneCoreExtension.java | 11 +- ...roviderPushTransferDataFlowController.java | 21 ++- .../TransferDataPlaneCoreExtensionTest.java | 2 +- ...derPushTransferDataFlowControllerTest.java | 61 ++++--- ... => DataPlaneSelectorClientExtension.java} | 29 ++-- .../EmbeddedDataPlaneSelectorClient.java | 52 ------ .../client/RemoteDataPlaneSelectorClient.java | 156 ------------------ ...rg.eclipse.edc.spi.system.ServiceExtension | 2 +- ...DataPlaneSelectorClientExtensionTest.java} | 39 ++--- .../dataplane/selector/TestFunctions.java | 28 ---- .../EmbeddedDataPlaneSelectorClientTest.java | 63 ------- .../RemoteDataPlaneSelectorClientTest.java | 118 ------------- .../client/DataPlaneClientExtension.java | 17 +- .../client/EmbeddedDataPlaneClient.java | 2 +- .../client/RemoteDataPlaneClient.java | 43 ++--- .../client/DataPlaneClientExtensionTest.java | 9 +- .../client/EmbeddedDataPlaneClientTest.java | 2 +- .../client/RemoteDataPlaneClientTest.java | 35 +--- .../edc/spi/response/StatusResult.java | 20 +++ .../transfer/spi/flow/DataFlowManager.java | 16 -- .../data-plane-selector-spi/build.gradle.kts | 2 +- .../selector}/spi/client/DataPlaneClient.java | 6 +- .../spi/client/DataPlaneClientFactory.java | 30 ++++ .../spi/client/DataPlaneSelectorClient.java | 52 ------ 26 files changed, 167 insertions(+), 656 deletions(-) rename core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/{DataPlaneSelectorServiceImpl.java => EmbeddedDataPlaneSelectorService.java} (95%) rename extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/{DataPlaneInstanceClientExtension.java => DataPlaneSelectorClientExtension.java} (69%) delete mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClient.java delete mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClient.java rename extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/{DataPlaneInstanceClientExtensionTest.java => DataPlaneSelectorClientExtensionTest.java} (61%) delete mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/TestFunctions.java delete mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClientTest.java delete mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClientTest.java rename spi/{data-plane/data-plane-spi/src/main/java/org/eclipse/edc/connector/dataplane => data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector}/spi/client/DataPlaneClient.java (80%) create mode 100644 spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java delete mode 100644 spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneSelectorClient.java diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorServiceImpl.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java similarity index 95% rename from core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorServiceImpl.java rename to core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java index 19582a8589c..821f9d34ae7 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorServiceImpl.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java @@ -24,7 +24,6 @@ import org.eclipse.edc.spi.types.domain.DataAddress; import org.eclipse.edc.transaction.spi.TransactionContext; -import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -61,11 +60,6 @@ public DataPlaneInstance select(DataAddress source, DataAddress destination, Str return selector.select(source, destination, strategy); } - @Override - public Collection getAllStrategies() { - return selectionStrategyRegistry.getAll(); - } - @Override public ServiceResult addInstance(DataPlaneInstance instance) { return transactionContext.execute(() -> { diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java index 72b19dc737b..8a4ba04e851 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java @@ -38,7 +38,6 @@ public class DataPlaneSelectorExtension implements ServiceExtension { @Inject private TransactionContext transactionContext; - @Override public void initialize(ServiceExtensionContext context) { var selector = new DataPlaneSelectorImpl(instanceStore); diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java index caccfc03155..ca88b34b595 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java @@ -16,8 +16,8 @@ package org.eclipse.edc.connector.transfer.dataplane; import org.eclipse.edc.connector.api.control.configuration.ControlApiConfiguration; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; import org.eclipse.edc.connector.transfer.dataplane.api.ConsumerPullTransferTokenValidationApiController; import org.eclipse.edc.connector.transfer.dataplane.flow.ConsumerPullTransferDataFlowController; import org.eclipse.edc.connector.transfer.dataplane.flow.ProviderPushTransferDataFlowController; @@ -75,15 +75,15 @@ public class TransferDataPlaneCoreExtension implements ServiceExtension { @Inject private DataEncrypter dataEncrypter; - @Inject - private DataPlaneClient dataPlaneClient; - @Inject private ControlApiConfiguration controlApiConfiguration; @Inject private DataPlaneSelectorClient selectorClient; + @Inject + private DataPlaneClientFactory clientFactory; + @Inject private ConsumerPullTokenExpirationDateFunction tokenExpirationDateFunction; @@ -112,7 +112,7 @@ public void initialize(ServiceExtensionContext context) { var resolver = new ConsumerPullDataPlaneProxyResolver(dataEncrypter, typeManager, new TokenGenerationServiceImpl(keyPair.getPrivate()), tokenExpirationDateFunction); dataFlowManager.register(new ConsumerPullTransferDataFlowController(selectorClient, resolver)); - dataFlowManager.register(new ProviderPushTransferDataFlowController(callbackUrl, dataPlaneClient)); + dataFlowManager.register(new ProviderPushTransferDataFlowController(callbackUrl, selectorClient, clientFactory)); dataAddressValidatorRegistry.registerDestinationValidator("HttpProxy", dataAddress -> ValidationResult.success()); } @@ -135,4 +135,5 @@ private TokenValidationService tokenValidationService(PublicKey publicKey) { registry.addRule(new ExpirationDateValidationRule(clock)); return new TokenValidationServiceImpl(id -> publicKey, registry); } + } diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java index 7b21b06d491..4878c8b9814 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java @@ -14,7 +14,8 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.transfer.spi.callback.ControlApiUrl; import org.eclipse.edc.connector.transfer.spi.flow.DataFlowController; import org.eclipse.edc.connector.transfer.spi.types.DataFlowResponse; @@ -31,11 +32,13 @@ public class ProviderPushTransferDataFlowController implements DataFlowController { private final ControlApiUrl callbackUrl; - private final DataPlaneClient dataPlaneClient; + private final DataPlaneSelectorClient selectorClient; + private final DataPlaneClientFactory clientFactory; - public ProviderPushTransferDataFlowController(ControlApiUrl callbackUrl, DataPlaneClient dataPlaneClient) { + public ProviderPushTransferDataFlowController(ControlApiUrl callbackUrl, DataPlaneSelectorClient selectorClient, DataPlaneClientFactory clientFactory) { this.callbackUrl = callbackUrl; - this.dataPlaneClient = dataPlaneClient; + this.selectorClient = selectorClient; + this.clientFactory = clientFactory; } @Override @@ -54,12 +57,18 @@ public boolean canHandle(TransferProcess transferProcess) { .callbackAddress(callbackUrl != null ? callbackUrl.get() : null) .build(); - return dataPlaneClient.transfer(dataFlowRequest).map(it -> DataFlowResponse.Builder.newInstance().build()); + var dataPlaneInstance = selectorClient.find(transferProcess.getContentDataAddress(), transferProcess.getDataDestination()); + return clientFactory.createClient(dataPlaneInstance) + .transfer(dataFlowRequest) + .map(it -> DataFlowResponse.Builder.newInstance().build()); } @Override public StatusResult terminate(TransferProcess transferProcess) { - return dataPlaneClient.terminate(transferProcess.getId()); + return selectorClient.getAll().stream().map(clientFactory::createClient) + .map(client -> client.terminate(transferProcess.getId())) + .reduce(StatusResult::merge) + .orElse(StatusResult.success()); } } diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtensionTest.java b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtensionTest.java index 6608e044e0c..f2d02db008e 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtensionTest.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtensionTest.java @@ -19,7 +19,7 @@ import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; import org.eclipse.edc.connector.api.control.configuration.ControlApiConfiguration; import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; import org.eclipse.edc.connector.transfer.dataplane.api.ConsumerPullTransferTokenValidationApiController; import org.eclipse.edc.connector.transfer.dataplane.flow.ConsumerPullTransferDataFlowController; import org.eclipse.edc.connector.transfer.dataplane.flow.ProviderPushTransferDataFlowController; diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java index 651903b6035..a364159d0b2 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java @@ -14,7 +14,10 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.transfer.spi.types.DataRequest; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; import org.eclipse.edc.policy.model.Policy; @@ -26,6 +29,7 @@ import org.mockito.ArgumentCaptor; import java.net.URI; +import java.util.List; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -39,8 +43,10 @@ class ProviderPushTransferDataFlowControllerTest { private final DataPlaneClient dataPlaneClient = mock(); + private final DataPlaneClientFactory dataPlaneClientFactory = mock(); + private final DataPlaneSelectorClient dataPlaneSelectorClient = mock(); private final ProviderPushTransferDataFlowController flowController = - new ProviderPushTransferDataFlowController(() -> URI.create("http://localhost"), dataPlaneClient); + new ProviderPushTransferDataFlowController(() -> URI.create("http://localhost"), dataPlaneSelectorClient, dataPlaneClientFactory); @Test void canHandle() { @@ -48,24 +54,6 @@ void canHandle() { assertThat(flowController.canHandle(transferProcess("not-http-proxy"))).isTrue(); } - @Test - void initiateFlow_returnFailedResultIfTransferFails() { - var errorMsg = "error"; - var transferProcess = TransferProcess.Builder.newInstance() - .dataRequest(createDataRequest()) - .contentDataAddress(testDataAddress()) - .build(); - - when(dataPlaneClient.transfer(any())).thenReturn(StatusResult.failure(ResponseStatus.FATAL_ERROR, errorMsg)); - - var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); - - verify(dataPlaneClient).transfer(any()); - - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureMessages()).allSatisfy(s -> assertThat(s).contains(errorMsg)); - } - @Test void initiateFlow_transferSuccess() { var request = createDataRequest(); @@ -76,6 +64,9 @@ void initiateFlow_transferSuccess() { .build(); when(dataPlaneClient.transfer(any(DataFlowRequest.class))).thenReturn(StatusResult.success()); + var dataPlaneInstance = createDataPlaneInstance(); + when(dataPlaneSelectorClient.find(any(), any())).thenReturn(dataPlaneInstance); + when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); @@ -92,27 +83,24 @@ void initiateFlow_transferSuccess() { } @Test - void initiateFlow_transferSuccessWithAdditionalProperties() { - var request = createDataRequest("test"); - var source = testDataAddress(); + void initiateFlow_returnFailedResultIfTransferFails() { + var errorMsg = "error"; var transferProcess = TransferProcess.Builder.newInstance() .dataRequest(createDataRequest()) .contentDataAddress(testDataAddress()) .build(); - when(dataPlaneClient.transfer(any(DataFlowRequest.class))).thenReturn(StatusResult.success()); + when(dataPlaneClient.transfer(any())).thenReturn(StatusResult.failure(ResponseStatus.FATAL_ERROR, errorMsg)); + var dataPlaneInstance = createDataPlaneInstance(); + when(dataPlaneSelectorClient.find(any(), any())).thenReturn(dataPlaneInstance); + when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); - assertThat(result.succeeded()).isTrue(); - var captor = ArgumentCaptor.forClass(DataFlowRequest.class); - verify(dataPlaneClient).transfer(captor.capture()); - var captured = captor.getValue(); - assertThat(captured.isTrackable()).isTrue(); - assertThat(captured.getProcessId()).isEqualTo(transferProcess.getId()); - assertThat(captured.getSourceDataAddress()).usingRecursiveComparison().isEqualTo(source); - assertThat(captured.getDestinationDataAddress()).usingRecursiveComparison().isEqualTo(request.getDataDestination()); - assertThat(captured.getCallbackAddress()).isNotNull(); + verify(dataPlaneClient).transfer(any()); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureMessages()).allSatisfy(s -> assertThat(s).contains(errorMsg)); } @Test @@ -123,6 +111,9 @@ void terminate_shouldCallTerminate() { .contentDataAddress(testDataAddress()) .build(); when(dataPlaneClient.terminate(any())).thenReturn(StatusResult.success()); + var dataPlaneInstance = createDataPlaneInstance(); + when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); + when(dataPlaneSelectorClient.getAll()).thenReturn(List.of(dataPlaneInstance)); var result = flowController.terminate(transferProcess); @@ -130,6 +121,10 @@ void terminate_shouldCallTerminate() { verify(dataPlaneClient).terminate("transferProcessId"); } + private DataPlaneInstance createDataPlaneInstance() { + return DataPlaneInstance.Builder.newInstance().url("http://any").build(); + } + private DataAddress testDataAddress() { return DataAddress.Builder.newInstance().type("test-type").build(); } diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtension.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java similarity index 69% rename from extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtension.java rename to extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java index 21d70bbbd72..145e69f99f9 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtension.java +++ b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java @@ -20,7 +20,7 @@ import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.http.EdcHttpClient; import org.eclipse.edc.spi.system.ServiceExtension; @@ -33,12 +33,15 @@ import static java.lang.String.format; -@Provides(DataPlaneSelectorClient.class) -@Extension(value = "DataPlane instance client") -public class DataPlaneInstanceClientExtension implements ServiceExtension { +@Extension(value = "DataPlane Selector client") +public class DataPlaneSelectorClientExtension implements ServiceExtension { - @Setting - private static final String DPF_SELECTOR_URL_SETTING = "edc.dpf.selector.url"; + @Setting(value = "The DataPlane selector api URL") + static final String DPF_SELECTOR_URL_SETTING = "edc.dpf.selector.url"; + + private static final String DEFAULT_DATAPLANE_SELECTOR_STRATEGY = "random"; + @Setting(value = "Defines strategy for Data Plane instance selection in case Data Plane is not embedded in current runtime", defaultValue = DEFAULT_DATAPLANE_SELECTOR_STRATEGY) + private static final String DPF_SELECTOR_STRATEGY = "edc.dataplane.client.selector.strategy"; @Inject(required = false) private DataPlaneSelectorService selector; @@ -52,23 +55,23 @@ public class DataPlaneInstanceClientExtension implements ServiceExtension { @Inject private TypeTransformerRegistry typeTransformerRegistry; - @Override - public void initialize(ServiceExtensionContext context) { - + @Provider + public DataPlaneSelectorClient dataPlaneSelectorClient(ServiceExtensionContext context) { var url = context.getConfig().getString(DPF_SELECTOR_URL_SETTING, null); var monitor = context.getMonitor(); + var selectionStrategy = context.getSetting(DPF_SELECTOR_STRATEGY, DEFAULT_DATAPLANE_SELECTOR_STRATEGY); DataPlaneSelectorClient client; - if (StringUtils.isNullOrEmpty(url)) { + if (StringUtils.isNullOrBlank(url)) { Objects.requireNonNull(selector, format("If [%s] is not specified, a DataPlaneSelectorService instance must be provided", DPF_SELECTOR_URL_SETTING)); - client = new EmbeddedDataPlaneSelectorClient(selector); + client = new EmbeddedDataPlaneSelectorClient(selector, selectionStrategy); monitor.debug("Using embedded DPF selector"); } else { Objects.requireNonNull(httpClient, format("If [%s] is specified, an EdcHttpClient instance must be provided", DPF_SELECTOR_URL_SETTING)); - client = new RemoteDataPlaneSelectorClient(httpClient, url, typeManager.getMapper(), typeTransformerRegistry); + client = new RemoteDataPlaneSelectorClient(httpClient, url, typeManager.getMapper(), typeTransformerRegistry, selectionStrategy); monitor.debug("Using remote DPF selector"); } - context.registerService(DataPlaneSelectorClient.class, client); + return client; } } diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClient.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClient.java deleted file mode 100644 index 665d63c3e8a..00000000000 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClient.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.client; - -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.spi.types.domain.DataAddress; - -import java.util.List; - -/** - * Implementation of a {@link DataPlaneSelectorClient} that uses a local {@link DataPlaneSelector}, - * i.e. one that runs in the same JVM as the control plane. - */ -public class EmbeddedDataPlaneSelectorClient implements DataPlaneSelectorClient { - - - private final DataPlaneSelectorService selector; - - public EmbeddedDataPlaneSelectorClient(DataPlaneSelectorService selector) { - this.selector = selector; - } - - @Override - public List getAll() { - return selector.getAll(); - } - - @Override - public DataPlaneInstance find(DataAddress source, DataAddress destination) { - return selector.select(source, destination); - } - - @Override - public DataPlaneInstance find(DataAddress source, DataAddress destination, String selectionStrategyName) { - return selector.select(source, destination, selectionStrategyName); - } -} diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClient.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClient.java deleted file mode 100644 index 378002ad2dc..00000000000 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClient.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.client; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.json.Json; -import jakarta.json.JsonObject; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.http.EdcHttpClient; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.util.string.StringUtils; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import static jakarta.json.Json.createObjectBuilder; -import static java.lang.String.format; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; -import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; -import static org.eclipse.edc.spi.CoreConstants.EDC_PREFIX; - -/** - * Implementation of a {@link DataPlaneSelectorClient} that uses a remote {@link DataPlaneSelector}, that is - * accessible via REST API. - */ -public class RemoteDataPlaneSelectorClient implements DataPlaneSelectorClient { - public static final MediaType TYPE_JSON = MediaType.parse("application/json"); - private static final String SELECT_PATH = "/select"; - private final String baseUrl; - private final EdcHttpClient client; - private final ObjectMapper mapper; - private final TypeTransformerRegistry typeTransformerRegistry; - - public RemoteDataPlaneSelectorClient(EdcHttpClient client, String baseUrl, ObjectMapper mapper, TypeTransformerRegistry typeTransformerRegistry) { - this.baseUrl = baseUrl; - this.client = client; - this.mapper = mapper; - this.typeTransformerRegistry = typeTransformerRegistry; - } - - @Override - public List getAll() { - try { - var request = new Request.Builder().get().url(baseUrl).build(); - - try (var response = client.execute(request)) { - - var tr = new TypeReference>() { - }; - return handleResponse(response, tr, Collections.emptyList()).stream() - .map(j -> typeTransformerRegistry.transform(j, DataPlaneInstance.class)) - .filter(Result::succeeded) - .map(Result::getContent) - .toList(); - } - } catch (IOException e) { - throw new EdcException(e); - } - } - - @Override - public DataPlaneInstance find(DataAddress source, DataAddress destination) { - return selectDataPlane(source, destination, null); - } - - @Override - public DataPlaneInstance find(DataAddress source, DataAddress destination, String selectionStrategyName) { - return selectDataPlane(source, destination, selectionStrategyName); - } - - private DataPlaneInstance selectDataPlane(DataAddress source, DataAddress destination, String selectionStrategy) { - var srcAddress = typeTransformerRegistry.transform(source, JsonObject.class).orElseThrow(f -> new EdcException(f.getFailureDetail())); - var dstAddress = typeTransformerRegistry.transform(destination, JsonObject.class).orElseThrow(f -> new EdcException(f.getFailureDetail())); - var jsonObject = Json.createObjectBuilder() - .add(CONTEXT, createObjectBuilder().add(EDC_PREFIX, EDC_NAMESPACE)) - .add(TYPE, EDC_NAMESPACE + "SelectionRequest") - .add(EDC_NAMESPACE + "source", srcAddress) - .add(EDC_NAMESPACE + "destination", dstAddress); - if (selectionStrategy != null) { - jsonObject.add(EDC_NAMESPACE + "strategy", selectionStrategy); - } - RequestBody body = RequestBody.create(jsonObject.build().toString(), TYPE_JSON); - - var request = new Request.Builder().post(body).url(baseUrl + SELECT_PATH).build(); - - try { - try (var response = client.execute(request)) { - - var tr = new TypeReference() { - }; - var jo = handleResponse(response, tr, null); - return jo != null ? - typeTransformerRegistry.transform(jo, DataPlaneInstance.class) - .orElseThrow(f -> new EdcException(f.getFailureDetail())) : null; - } - } catch (IOException e) { - throw new EdcException(e); - } - } - - private R handleResponse(Response response, TypeReference tr, R defaultValue) { - if (response.isSuccessful()) { - R r = handleSuccess(response, tr); - return r == null ? defaultValue : r; - } else { - return handleError(response); - } - } - - private R handleSuccess(Response response, TypeReference tr) { - try { - var body = response.body().string(); - if (StringUtils.isNullOrEmpty(body)) { - return null; - } - - return mapper.readValue(body, tr); - } catch (IOException e) { - throw new EdcException(e); - } - } - - private R handleError(Response response) { - return switch (response.code()) { - case 400 -> throw new IllegalArgumentException("Remote API returned HTTP 400"); - case 404 -> null; - default -> - throw new IllegalArgumentException(format("An unknown error happened, HTTP Status = %d", response.code())); - }; - } - -} diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/data-plane-selector/data-plane-selector-client/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index eab309be07b..69196e0c1ab 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/extensions/data-plane-selector/data-plane-selector-client/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -12,4 +12,4 @@ # # -org.eclipse.edc.connector.dataplane.selector.DataPlaneInstanceClientExtension +org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorClientExtension diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtensionTest.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java similarity index 61% rename from extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtensionTest.java rename to extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java index c666248404b..eb7d6ce26c3 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneInstanceClientExtensionTest.java +++ b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java @@ -17,7 +17,6 @@ import org.eclipse.edc.connector.dataplane.selector.client.EmbeddedDataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.client.RemoteDataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.http.EdcHttpClient; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -31,15 +30,15 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorClientExtension.DPF_SELECTOR_URL_SETTING; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) -class DataPlaneInstanceClientExtensionTest { +class DataPlaneSelectorClientExtensionTest { - private static final String EDC_DPF_SELECTOR_URL_SETTING = "edc.dpf.selector.url"; - private DataPlaneInstanceClientExtension extension; + private DataPlaneSelectorClientExtension extension; private ServiceExtensionContext context; @BeforeEach @@ -50,53 +49,45 @@ void setUp(ServiceExtensionContext context) { @Test void initialize_noSetting_shouldUseEmbedded(ObjectFactory factory) { context.registerService(DataPlaneSelectorService.class, mock(DataPlaneSelectorService.class)); - extension = factory.constructInstance(DataPlaneInstanceClientExtension.class); + extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - extension.initialize(context); + var client = extension.dataPlaneSelectorClient(context); - var client = context.getService(DataPlaneSelectorClient.class); assertThat(client).isInstanceOf(EmbeddedDataPlaneSelectorClient.class); } @Test void initialize_noSetting_shouldUseEmbedded_serviceMissing(ObjectFactory factory) { context.registerService(DataPlaneSelectorService.class, null); - extension = factory.constructInstance(DataPlaneInstanceClientExtension.class); + extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - assertThatThrownBy(() -> extension.initialize(context)).isInstanceOf(NullPointerException.class) - .hasMessage("If [" + EDC_DPF_SELECTOR_URL_SETTING + "] is not specified, a DataPlaneSelectorService instance must be provided"); - - var client = context.getService(DataPlaneSelectorClient.class, true); - assertThat(client).isNull(); + assertThatThrownBy(() -> extension.dataPlaneSelectorClient(context)).isInstanceOf(NullPointerException.class) + .hasMessage("If [" + DPF_SELECTOR_URL_SETTING + "] is not specified, a DataPlaneSelectorService instance must be provided"); } @Test void initialize_withSetting(ObjectFactory factory) { - var config = ConfigFactory.fromMap(Map.of(EDC_DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); + var config = ConfigFactory.fromMap(Map.of(DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); when(context.getConfig()).thenReturn(config); context.registerService(EdcHttpClient.class, mock(EdcHttpClient.class)); - extension = factory.constructInstance(DataPlaneInstanceClientExtension.class); + extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - extension.initialize(context); + var client = extension.dataPlaneSelectorClient(context); - var client = context.getService(DataPlaneSelectorClient.class); assertThat(client).isInstanceOf(RemoteDataPlaneSelectorClient.class); } @Test void initialize_withSetting_httpClientMissing(ObjectFactory factory) { context.registerService(EdcHttpClient.class, null); - var config = ConfigFactory.fromMap(Map.of(EDC_DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); + var config = ConfigFactory.fromMap(Map.of(DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); when(context.getConfig()).thenReturn(config); - extension = factory.constructInstance(DataPlaneInstanceClientExtension.class); - - assertThatThrownBy(() -> extension.initialize(context)).isInstanceOf(NullPointerException.class) - .hasMessage("If [" + EDC_DPF_SELECTOR_URL_SETTING + "] is specified, an EdcHttpClient instance must be provided"); + extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - var client = context.getService(DataPlaneSelectorClient.class, true); - assertThat(client).isNull(); + assertThatThrownBy(() -> extension.dataPlaneSelectorClient(context)).isInstanceOf(NullPointerException.class) + .hasMessage("If [" + DPF_SELECTOR_URL_SETTING + "] is specified, an EdcHttpClient instance must be provided"); } } diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/TestFunctions.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/TestFunctions.java deleted file mode 100644 index e7e566da6de..00000000000 --- a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/TestFunctions.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector; - -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; - -public class TestFunctions { - - public static DataPlaneInstance createInstance(String id) { - return DataPlaneInstance.Builder.newInstance() - .id(id) - .url("http://somewhere.com:1234/api/v1") - .build(); - } - -} diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClientTest.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClientTest.java deleted file mode 100644 index 331c1184efd..00000000000 --- a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/EmbeddedDataPlaneSelectorClientTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.client; - -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -class EmbeddedDataPlaneSelectorClientTest { - - private EmbeddedDataPlaneSelectorClient client; - private DataPlaneSelectorService serviceMock; - - @BeforeEach - void setUp() { - serviceMock = mock(DataPlaneSelectorService.class); - client = new EmbeddedDataPlaneSelectorClient(serviceMock); - } - - @Test - void getAll() { - client.getAll(); - verify(serviceMock).getAll(); - verifyNoMoreInteractions(serviceMock); - } - - @Test - void find() { - var src = DataAddress.Builder.newInstance().type("test-type").build(); - var dest = DataAddress.Builder.newInstance().type("test-type").build(); - client.find(src, dest); - verify(serviceMock).select(eq(src), eq(dest)); - verifyNoMoreInteractions(serviceMock); - } - - @Test - void find_withStrategy() { - var src = DataAddress.Builder.newInstance().type("test-type").build(); - var dest = DataAddress.Builder.newInstance().type("test-type").build(); - client.find(src, dest, "test-strategy"); - verify(serviceMock).select(eq(src), eq(dest), eq("test-strategy")); - verifyNoMoreInteractions(serviceMock); - } - -} \ No newline at end of file diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClientTest.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClientTest.java deleted file mode 100644 index 2daea9ef259..00000000000 --- a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/client/RemoteDataPlaneSelectorClientTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.client; - -import jakarta.json.Json; -import org.eclipse.edc.connector.dataplane.selector.api.v2.DataplaneSelectorApiController; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectFromDataPlaneInstanceTransformer; -import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToDataPlaneInstanceTransformer; -import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToSelectionRequestTransformer; -import org.eclipse.edc.core.transform.TypeTransformerRegistryImpl; -import org.eclipse.edc.core.transform.transformer.from.JsonObjectFromDataAddressTransformer; -import org.eclipse.edc.core.transform.transformer.to.JsonObjectToDataAddressTransformer; -import org.eclipse.edc.core.transform.transformer.to.JsonValueToGenericTypeTransformer; -import org.eclipse.edc.jsonld.TitaniumJsonLd; -import org.eclipse.edc.jsonld.util.JacksonJsonLd; -import org.eclipse.edc.junit.annotations.ComponentTest; -import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; -import org.eclipse.edc.web.jersey.jsonld.JerseyJsonLdInterceptor; -import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.time.Clock; -import java.util.List; -import java.util.Map; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.TestFunctions.createInstance; -import static org.eclipse.edc.junit.testfixtures.TestUtils.testHttpClient; -import static org.eclipse.edc.spi.CoreConstants.JSON_LD; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ComponentTest -class RemoteDataPlaneSelectorClientTest extends RestControllerTestBase { - - private static final String BASE_URL = "http://localhost:%d/v2/dataplanes"; - private static final DataPlaneSelectorService SELECTOR_SERVICE_MOCK = mock(); - private static final TypeManager TYPE_MANAGER = new TypeManager(); - private final TypeTransformerRegistry typeTransformerRegistry = new TypeTransformerRegistryImpl(); - private final JsonObjectValidatorRegistry validator = mock(JsonObjectValidatorRegistry.class); - private RemoteDataPlaneSelectorClient client; - - @BeforeAll - public static void prepare() { - TYPE_MANAGER.registerTypes(DataPlaneInstance.class); - TYPE_MANAGER.registerContext(JSON_LD, JacksonJsonLd.createObjectMapper()); - } - - @BeforeEach - void setUp() { - var factory = Json.createBuilderFactory(Map.of()); - typeTransformerRegistry.register(new JsonObjectFromDataAddressTransformer(factory)); - typeTransformerRegistry.register(new JsonObjectToDataAddressTransformer()); - typeTransformerRegistry.register(new JsonObjectToSelectionRequestTransformer()); - typeTransformerRegistry.register(new JsonObjectFromDataPlaneInstanceTransformer(factory, JacksonJsonLd.createObjectMapper())); - typeTransformerRegistry.register(new JsonObjectToDataPlaneInstanceTransformer()); - typeTransformerRegistry.register(new JsonValueToGenericTypeTransformer(objectMapper)); - var url = format(BASE_URL, port); - client = new RemoteDataPlaneSelectorClient(testHttpClient(), url, JacksonJsonLd.createObjectMapper(), typeTransformerRegistry); - } - - @Test - void getAll() { - - when(SELECTOR_SERVICE_MOCK.getAll()).thenReturn(List.of(createInstance("test-inst1"), createInstance("test-inst2"))); - var result = client.getAll(); - assertThat(result).hasSize(2).extracting(DataPlaneInstance::getId).containsExactlyInAnyOrder("test-inst1", "test-inst2"); - } - - @Test - void find() { - var expected = createInstance("some-instance"); - when(SELECTOR_SERVICE_MOCK.select(any(), any())).thenReturn(expected); - var result = client.find(DataAddress.Builder.newInstance().type("test1").build(), DataAddress.Builder.newInstance().type("test2").build()); - assertThat(result).usingRecursiveComparison().isEqualTo(expected); - - } - - @Test - void find_withStrategy() { - var expected = createInstance("some-instance"); - when(SELECTOR_SERVICE_MOCK.select(any(), any(), eq("test-strategy"))).thenReturn(expected); - var result = client.find(DataAddress.Builder.newInstance().type("test1").build(), DataAddress.Builder.newInstance().type("test1").build(), "test-strategy"); - assertThat(result).usingRecursiveComparison().isEqualTo(expected); - } - - @Override - protected Object controller() { - return new DataplaneSelectorApiController(SELECTOR_SERVICE_MOCK, typeTransformerRegistry, validator, Clock.systemUTC()); - } - - @Override - protected Object additionalResource() { - return new JerseyJsonLdInterceptor(new TitaniumJsonLd(mock()), JacksonJsonLd.createObjectMapper(), "scope"); - } -} diff --git a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtension.java b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtension.java index 77bd2156793..4d994520b14 100644 --- a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtension.java +++ b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtension.java @@ -14,13 +14,11 @@ package org.eclipse.edc.connector.dataplane.client; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.http.EdcHttpClient; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -37,15 +35,9 @@ public class DataPlaneClientExtension implements ServiceExtension { public static final String NAME = "Data Plane Client"; - @Setting(value = "Defines strategy for Data Plane instance selection in case Data Plane is not embedded in current runtime") - private static final String DPF_SELECTOR_STRATEGY = "edc.dataplane.client.selector.strategy"; - @Inject(required = false) private DataPlaneManager dataPlaneManager; - @Inject(required = false) - private DataPlaneSelectorClient dataPlaneSelectorClient; - @Inject(required = false) private EdcHttpClient httpClient; @@ -58,17 +50,16 @@ public String name() { } @Provider - public DataPlaneClient dataPlaneClient(ServiceExtensionContext context) { + public DataPlaneClientFactory dataPlaneClientFactory(ServiceExtensionContext context) { if (dataPlaneManager != null) { // Data plane manager is embedded in the current runtime context.getMonitor().debug(() -> "Using embedded Data Plane client."); - return new EmbeddedDataPlaneClient(dataPlaneManager); + return instance -> new EmbeddedDataPlaneClient(dataPlaneManager); } context.getMonitor().debug(() -> "Using remote Data Plane client."); Objects.requireNonNull(httpClient, "To use remote Data Plane client, an EdcHttpClient instance must be registered"); - var selectionStrategy = context.getSetting(DPF_SELECTOR_STRATEGY, "random"); - return new RemoteDataPlaneClient(httpClient, dataPlaneSelectorClient, selectionStrategy, typeManager.getMapper()); + return instance -> new RemoteDataPlaneClient(httpClient, typeManager.getMapper(), instance); } } diff --git a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClient.java b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClient.java index 57cdace0f8d..787c44a53bd 100644 --- a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClient.java +++ b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClient.java @@ -15,7 +15,7 @@ package org.eclipse.edc.connector.dataplane.client; import io.opentelemetry.instrumentation.annotations.WithSpan; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.spi.response.ResponseStatus; import org.eclipse.edc.spi.response.StatusResult; diff --git a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClient.java b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClient.java index e672a7ffd8f..b8e3d1b8cc0 100644 --- a/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClient.java +++ b/extensions/data-plane/data-plane-client/src/main/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClient.java @@ -22,8 +22,8 @@ import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.connector.dataplane.spi.response.TransferErrorResponse; import org.eclipse.edc.spi.EdcException; @@ -32,7 +32,6 @@ import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; import java.io.IOException; -import java.util.Objects; import java.util.Optional; import static java.lang.String.format; @@ -43,35 +42,28 @@ */ public class RemoteDataPlaneClient implements DataPlaneClient { public static final MediaType TYPE_JSON = MediaType.parse("application/json"); - private final DataPlaneSelectorClient selectorClient; - private final String selectorStrategy; private final EdcHttpClient httpClient; private final ObjectMapper mapper; + private final DataPlaneInstance dataPlane; - public RemoteDataPlaneClient(EdcHttpClient httpClient, DataPlaneSelectorClient selectorClient, String selectorStrategy, ObjectMapper mapper) { - this.selectorClient = Objects.requireNonNull(selectorClient, "Data plane selector client"); - this.selectorStrategy = Objects.requireNonNull(selectorStrategy, "Selector strategy"); - this.httpClient = Objects.requireNonNull(httpClient, "Http client"); - this.mapper = Objects.requireNonNull(mapper, "Object mapper"); + public RemoteDataPlaneClient(EdcHttpClient httpClient, ObjectMapper mapper, DataPlaneInstance dataPlane) { + this.httpClient = httpClient; + this.mapper = mapper; + this.dataPlane = dataPlane; } @WithSpan @Override public StatusResult transfer(DataFlowRequest dataFlowRequest) { - var instance = selectorClient.find(dataFlowRequest.getSourceDataAddress(), dataFlowRequest.getDestinationDataAddress(), selectorStrategy); - if (instance == null) { - return StatusResult.failure(FATAL_ERROR, "Failed to find data plane instance supporting request: " + dataFlowRequest.getId()); - } - RequestBody body; try { body = RequestBody.create(mapper.writeValueAsString(dataFlowRequest), TYPE_JSON); } catch (JsonProcessingException e) { throw new EdcException(e); } - var rq = new Request.Builder().post(body).url(instance.getUrl()).build(); + var request = new Request.Builder().post(body).url(dataPlane.getUrl()).build(); - try (var response = httpClient.execute(rq)) { + try (var response = httpClient.execute(request)) { return handleResponse(response, dataFlowRequest.getId()); } catch (IOException e) { return StatusResult.failure(FATAL_ERROR, e.getMessage()); @@ -80,18 +72,13 @@ public StatusResult transfer(DataFlowRequest dataFlowRequest) { @Override public StatusResult terminate(String transferProcessId) { - return selectorClient.getAll().stream() - .map(dataPlane -> { - var request = new Request.Builder().delete().url(dataPlane.getUrl() + "/" + transferProcessId).build(); + var request = new Request.Builder().delete().url(dataPlane.getUrl() + "/" + transferProcessId).build(); - try (var response = httpClient.execute(request)) { // TODO: should retry when status is 409 (???) - return handleResponse(response, transferProcessId); - } catch (IOException e) { - return StatusResult.failure(FATAL_ERROR, e.getMessage()); - } - }) - .findAny() - .orElse(StatusResult.success()); + try (var response = httpClient.execute(request)) { + return handleResponse(response, transferProcessId); + } catch (IOException e) { + return StatusResult.failure(FATAL_ERROR, e.getMessage()); + } } private StatusResult handleResponse(Response response, String requestId) { diff --git a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java index 8ae7ec3aefc..0663275ae44 100644 --- a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java +++ b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java @@ -16,6 +16,7 @@ import dev.failsafe.RetryPolicy; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.http.EdcHttpClient; @@ -38,7 +39,7 @@ void verifyReturnEmbeddedClient(ServiceExtensionContext context, ObjectFactory f var extension = factory.constructInstance(DataPlaneClientExtension.class); - var client = extension.dataPlaneClient(context); + var client = extension.dataPlaneClientFactory(context).createClient(createDataPlaneInstance()); assertThat(client).isInstanceOf(EmbeddedDataPlaneClient.class); } @@ -53,8 +54,12 @@ void verifyReturnRemoteClient(ServiceExtensionContext context, ObjectFactory fac var extension = factory.constructInstance(DataPlaneClientExtension.class); - var client = extension.dataPlaneClient(context); + var client = extension.dataPlaneClientFactory(context).createClient(createDataPlaneInstance()); assertThat(client).isInstanceOf(RemoteDataPlaneClient.class); } + + private DataPlaneInstance createDataPlaneInstance() { + return DataPlaneInstance.Builder.newInstance().url("http://any").build(); + } } diff --git a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClientTest.java b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClientTest.java index 259c4b9418e..8fa1f47180f 100644 --- a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClientTest.java +++ b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/EmbeddedDataPlaneClientTest.java @@ -14,7 +14,7 @@ package org.eclipse.edc.connector.dataplane.client; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.spi.response.StatusResult; import org.eclipse.edc.spi.result.Result; diff --git a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java index 6f812ca069b..ee60803281a 100644 --- a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java +++ b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java @@ -16,9 +16,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.spi.client.DataPlaneClient; import org.eclipse.edc.connector.dataplane.spi.response.TransferErrorResponse; import org.eclipse.edc.spi.response.ResponseStatus; import org.eclipse.edc.spi.types.TypeManager; @@ -43,10 +43,7 @@ import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.edc.junit.testfixtures.TestUtils.getFreePort; import static org.eclipse.edc.junit.testfixtures.TestUtils.testHttpClient; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.mockserver.integration.ClientAndServer.startClientAndServer; import static org.mockserver.matchers.Times.once; import static org.mockserver.model.HttpResponse.response; @@ -63,7 +60,8 @@ class RemoteDataPlaneClientTest { private static final String DATA_PLANE_API_URI = "http://localhost:" + DATA_PLANE_API_PORT + DATA_PLANE_PATH; private static ClientAndServer dataPlane; private final DataPlaneSelectorClient selectorClient = mock(); - private final DataPlaneClient dataPlaneClient = new RemoteDataPlaneClient(testHttpClient(), selectorClient, "test", MAPPER); + private final DataPlaneInstance instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); + private final DataPlaneClient dataPlaneClient = new RemoteDataPlaneClient(testHttpClient(), MAPPER, instance); @BeforeAll public static void setUp() { @@ -80,26 +78,10 @@ public void resetMockServer() { dataPlane.reset(); } - @Test - void transfer_verifyReturnsFatalErrorIfNoDataPlaneInstanceFound() { - var flowRequest = createDataFlowRequest(); - when(selectorClient.find(any(), any(), any())).thenReturn(null); - - var result = dataPlaneClient.transfer(flowRequest); - - assertThat(result.failed()).isTrue(); - assertThat(result.getFailure().status()).isEqualTo(ResponseStatus.FATAL_ERROR); - assertThat(result.getFailureMessages()) - .anySatisfy(s -> assertThat(s).contains("Failed to find data plane instance supporting request: " + flowRequest.getId())); - } - @Test void transfer_verifyReturnFatalErrorIfReceiveResponseWithNullBody() throws JsonProcessingException { var flowRequest = createDataFlowRequest(); - var instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); - when(selectorClient.find(any(), any(), any())).thenReturn(instance); - var httpRequest = new HttpRequest().withPath(DATA_PLANE_PATH).withBody(MAPPER.writeValueAsString(flowRequest)); dataPlane.when(httpRequest, once()).respond(response().withStatusCode(HttpStatusCode.BAD_REQUEST_400.code())); @@ -119,9 +101,6 @@ void transfer_verifyReturnFatalErrorIfReceiveResponseWithNullBody() throws JsonP void transfer_verifyReturnFatalErrorIfReceiveErrorInResponse() throws JsonProcessingException { var flowRequest = createDataFlowRequest(); - var instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); - when(selectorClient.find(any(), any(), any())).thenReturn(instance); - var httpRequest = new HttpRequest().withPath(DATA_PLANE_PATH).withBody(MAPPER.writeValueAsString(flowRequest)); var errorMsg = UUID.randomUUID().toString(); dataPlane.when(httpRequest, once()).respond(withResponse(errorMsg)); @@ -142,9 +121,6 @@ void transfer_verifyReturnFatalErrorIfReceiveErrorInResponse() throws JsonProces void transfer_verifyTransferSuccess() throws JsonProcessingException { var flowRequest = createDataFlowRequest(); - var instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); - when(selectorClient.find(any(), any(), any())).thenReturn(instance); - var httpRequest = new HttpRequest().withPath(DATA_PLANE_PATH).withBody(MAPPER.writeValueAsString(flowRequest)); dataPlane.when(httpRequest, once()).respond(response().withStatusCode(HttpStatusCode.OK_200.code())); @@ -157,22 +133,17 @@ void transfer_verifyTransferSuccess() throws JsonProcessingException { @Test void terminate_shouldCallTerminateOnAllTheAvailableDataPlanes() { - var instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); - when(selectorClient.getAll()).thenReturn(List.of(instance)); var httpRequest = new HttpRequest().withMethod("DELETE").withPath(DATA_PLANE_PATH + "/processId"); dataPlane.when(httpRequest, once()).respond(response().withStatusCode(NO_CONTENT_204.code())); var result = dataPlaneClient.terminate("processId"); assertThat(result).isSucceeded(); - verify(selectorClient).getAll(); dataPlane.verify(httpRequest, VerificationTimes.once()); } @Test void terminate_shouldFail_whenConflictResponse() { - var instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); - when(selectorClient.getAll()).thenReturn(List.of(instance)); var httpRequest = new HttpRequest().withMethod("DELETE").withPath(DATA_PLANE_PATH + "/processId"); dataPlane.when(httpRequest, once()).respond(response().withStatusCode(CONFLICT_409.code())); diff --git a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/response/StatusResult.java b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/response/StatusResult.java index 72b79d279a9..931c3a1057b 100644 --- a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/response/StatusResult.java +++ b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/response/StatusResult.java @@ -15,13 +15,16 @@ package org.eclipse.edc.spi.response; import org.eclipse.edc.spi.result.AbstractResult; +import org.eclipse.edc.spi.result.Failure; import org.eclipse.edc.spi.result.StoreFailure; import org.eclipse.edc.spi.result.StoreResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import static org.eclipse.edc.spi.response.ResponseStatus.ERROR_RETRY; import static org.eclipse.edc.spi.response.ResponseStatus.FATAL_ERROR; @@ -60,6 +63,23 @@ protected , C1> R1 newInstanc return (R1) new StatusResult<>(content, failure); } + /** + * Merges this result with another one. If both Results are successful, a new one is created with no content. If + * either this result or {@code other} is a failure, the merged result will be a {@code failure()} and will contain + * all failure messages, no content. If both results are failures, the merged result will contain failure messages + * of {@code this} result, then the failure messages of {@code other}. + */ + public StatusResult merge(StatusResult other) { + if (succeeded() && other.succeeded()) { + return newInstance(null, null); + } else { + var messages = new ArrayList(); + messages.addAll(Optional.ofNullable(getFailure()).map(Failure::getMessages).orElse(Collections.emptyList())); + messages.addAll(Optional.ofNullable(other.getFailure()).map(Failure::getMessages).orElse(Collections.emptyList())); + return StatusResult.failure(ResponseStatus.FATAL_ERROR, String.join(",", messages)); + } + } + public static StatusResult from(StoreResult storeResult) { if (storeResult.succeeded()) { return success(storeResult.getContent()); diff --git a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/flow/DataFlowManager.java b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/flow/DataFlowManager.java index baf34749c37..deae9c487aa 100644 --- a/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/flow/DataFlowManager.java +++ b/spi/control-plane/transfer-spi/src/main/java/org/eclipse/edc/connector/transfer/spi/flow/DataFlowManager.java @@ -15,12 +15,10 @@ package org.eclipse.edc.connector.transfer.spi.flow; import org.eclipse.edc.connector.transfer.spi.types.DataFlowResponse; -import org.eclipse.edc.connector.transfer.spi.types.DataRequest; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.response.StatusResult; -import org.eclipse.edc.spi.types.domain.DataAddress; import org.jetbrains.annotations.NotNull; /** @@ -63,18 +61,4 @@ public interface DataFlowManager { @NotNull StatusResult terminate(TransferProcess transferProcess); - /** - * Initiates a data flow. - * - * @param dataRequest the data to transfer - * @param contentAddress the address to resolve the asset contents. This may be the original asset address or an address resolving to generated content. - * @param policy the contract agreement usage policy for the asset being transferred - * @deprecated please use {@link #initiate(TransferProcess, Policy)} - */ - @NotNull - @Deprecated(since = "0.2.1", forRemoval = true) - default StatusResult initiate(DataRequest dataRequest, DataAddress contentAddress, Policy policy) { - var transferProcess = TransferProcess.Builder.newInstance().dataRequest(dataRequest).contentDataAddress(contentAddress).build(); - return initiate(transferProcess, policy); - } } diff --git a/spi/data-plane-selector/data-plane-selector-spi/build.gradle.kts b/spi/data-plane-selector/data-plane-selector-spi/build.gradle.kts index 298a763c1cd..1537ad9680d 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/build.gradle.kts +++ b/spi/data-plane-selector/data-plane-selector-spi/build.gradle.kts @@ -19,9 +19,9 @@ plugins { dependencies { api(project(":spi:common:core-spi")) + api(project(":spi:data-plane:data-plane-spi")) implementation(project(":core:common:util")) - // needed by the abstract test spec located in testFixtures testFixturesImplementation(libs.bundles.jupiter) testFixturesImplementation(libs.mockito.core) diff --git a/spi/data-plane/data-plane-spi/src/main/java/org/eclipse/edc/connector/dataplane/spi/client/DataPlaneClient.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java similarity index 80% rename from spi/data-plane/data-plane-spi/src/main/java/org/eclipse/edc/connector/dataplane/spi/client/DataPlaneClient.java rename to spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java index 6f8838eb597..3ac6f9b7c6b 100644 --- a/spi/data-plane/data-plane-spi/src/main/java/org/eclipse/edc/connector/dataplane/spi/client/DataPlaneClient.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Amadeus + * 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 @@ -8,11 +8,11 @@ * SPDX-License-Identifier: Apache-2.0 * * Contributors: - * Amadeus - initial API and implementation + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation * */ -package org.eclipse.edc.connector.dataplane.spi.client; +package org.eclipse.edc.connector.dataplane.selector.spi.client; import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.response.StatusResult; diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java new file mode 100644 index 00000000000..fc7f532765c --- /dev/null +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java @@ -0,0 +1,30 @@ +/* + * 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.connector.dataplane.selector.spi.client; + +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; + +/** + * TODO: docs + */ +@FunctionalInterface +public interface DataPlaneClientFactory { + + /** + * TODO: docs + */ + DataPlaneClient createClient(DataPlaneInstance dataPlaneInstance); + +} diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneSelectorClient.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneSelectorClient.java deleted file mode 100644 index dec99d2274d..00000000000 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneSelectorClient.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.spi.client; - -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategy; -import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * Main interaction interface for an EDC runtime (=control plane) to communicate with the DPF selector. - */ -@ExtensionPoint -public interface DataPlaneSelectorClient { - - /** - * Returns all {@link DataPlaneInstance}s known in the system - */ - List getAll(); - - /** - * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the default - * {@link SelectionStrategy} which is "random" - */ - @Nullable - DataPlaneInstance find(DataAddress source, DataAddress destination); - - /** - * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the given - * {@link SelectionStrategy}. - * - * @throws IllegalArgumentException if the selection strategy was not found - */ - @Nullable - DataPlaneInstance find(DataAddress source, DataAddress destination, String selectionStrategyName); - -} From 6f7853c4792751b99df1e99a3799ffef705d7880 Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Wed, 22 Nov 2023 17:48:55 +0100 Subject: [PATCH 2/5] inline DataPlaneSelectorClient --- .../EmbeddedDataPlaneSelectorService.java | 4 +- .../core/DataPlaneSelectorExtension.java | 15 +- .../TransferDataPlaneCoreExtension.java | 8 +- ...onsumerPullTransferDataFlowController.java | 10 +- ...roviderPushTransferDataFlowController.java | 8 +- ...merPullTransferDataFlowControllerTest.java | 12 +- ...derPushTransferDataFlowControllerTest.java | 12 +- .../DataPlaneSelectorApiExtensionTest.java | 2 +- .../DataPlaneSelectorClientExtension.java | 30 +--- .../RemoteDataPlaneSelectorService.java | 157 ++++++++++++++++++ .../DataPlaneSelectorClientExtensionTest.java | 61 ++----- .../RemoteDataPlaneSelectorServiceTest.java | 118 +++++++++++++ .../client/DataPlaneClientExtensionTest.java | 2 - .../client/RemoteDataPlaneClientTest.java | 3 - launchers/dpf-selector/build.gradle.kts | 1 - .../spi/DataPlaneSelectorService.java | 21 ++- .../selector/spi/client/DataPlaneClient.java | 4 +- .../spi/client/DataPlaneClientFactory.java | 7 +- .../control-plane/build.gradle.kts | 1 - .../build.gradle.kts | 1 - .../telemetry-test-runtime/build.gradle.kts | 1 - 21 files changed, 351 insertions(+), 127 deletions(-) create mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java create mode 100644 extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorServiceTest.java diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java index 821f9d34ae7..5d0543956db 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java @@ -27,14 +27,14 @@ import java.util.List; import java.util.stream.Collectors; -public class DataPlaneSelectorServiceImpl implements DataPlaneSelectorService { +public class EmbeddedDataPlaneSelectorService implements DataPlaneSelectorService { private final DataPlaneSelector selector; private final DataPlaneInstanceStore store; private final SelectionStrategyRegistry selectionStrategyRegistry; private final TransactionContext transactionContext; - public DataPlaneSelectorServiceImpl(DataPlaneSelector selector, DataPlaneInstanceStore store, SelectionStrategyRegistry selectionStrategyRegistry, TransactionContext transactionContext) { + public EmbeddedDataPlaneSelectorService(DataPlaneSelector selector, DataPlaneInstanceStore store, SelectionStrategyRegistry selectionStrategyRegistry, TransactionContext transactionContext) { this.selector = selector; this.store = store; this.selectionStrategyRegistry = selectionStrategyRegistry; diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java index 8a4ba04e851..16a81f8675c 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java @@ -14,7 +14,7 @@ package org.eclipse.edc.connector.dataplane.selector.core; -import org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorServiceImpl; +import org.eclipse.edc.connector.dataplane.selector.EmbeddedDataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; @@ -23,12 +23,13 @@ import org.eclipse.edc.connector.dataplane.selector.strategy.DefaultSelectionStrategyRegistry; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Provides; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.transaction.spi.TransactionContext; -@Provides({ DataPlaneSelector.class, SelectionStrategyRegistry.class, DataPlaneSelectorService.class }) +@Provides({ DataPlaneSelector.class, SelectionStrategyRegistry.class }) @Extension(value = "DataPlane core selector") public class DataPlaneSelectorExtension implements ServiceExtension { @@ -38,6 +39,8 @@ public class DataPlaneSelectorExtension implements ServiceExtension { @Inject private TransactionContext transactionContext; + private DataPlaneSelectorService dataPlaneSelectorService; + @Override public void initialize(ServiceExtensionContext context) { var selector = new DataPlaneSelectorImpl(instanceStore); @@ -45,9 +48,15 @@ public void initialize(ServiceExtensionContext context) { var strategy = new DefaultSelectionStrategyRegistry(); strategy.add(new RandomSelectionStrategy()); + dataPlaneSelectorService = new EmbeddedDataPlaneSelectorService(selector, instanceStore, strategy, transactionContext); + context.registerService(DataPlaneSelector.class, selector); context.registerService(SelectionStrategyRegistry.class, strategy); - context.registerService(DataPlaneSelectorService.class, new DataPlaneSelectorServiceImpl(selector, instanceStore, strategy, transactionContext)); + } + + @Provider(isDefault = true) + public DataPlaneSelectorService dataPlaneSelectorService() { + return dataPlaneSelectorService; } } diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java index ca88b34b595..abca4b8935f 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/TransferDataPlaneCoreExtension.java @@ -16,8 +16,8 @@ package org.eclipse.edc.connector.transfer.dataplane; import org.eclipse.edc.connector.api.control.configuration.ControlApiConfiguration; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.transfer.dataplane.api.ConsumerPullTransferTokenValidationApiController; import org.eclipse.edc.connector.transfer.dataplane.flow.ConsumerPullTransferDataFlowController; import org.eclipse.edc.connector.transfer.dataplane.flow.ProviderPushTransferDataFlowController; @@ -79,7 +79,7 @@ public class TransferDataPlaneCoreExtension implements ServiceExtension { private ControlApiConfiguration controlApiConfiguration; @Inject - private DataPlaneSelectorClient selectorClient; + private DataPlaneSelectorService selectorService; @Inject private DataPlaneClientFactory clientFactory; @@ -111,8 +111,8 @@ public void initialize(ServiceExtensionContext context) { webService.registerResource(controlApiConfiguration.getContextAlias(), controller); var resolver = new ConsumerPullDataPlaneProxyResolver(dataEncrypter, typeManager, new TokenGenerationServiceImpl(keyPair.getPrivate()), tokenExpirationDateFunction); - dataFlowManager.register(new ConsumerPullTransferDataFlowController(selectorClient, resolver)); - dataFlowManager.register(new ProviderPushTransferDataFlowController(callbackUrl, selectorClient, clientFactory)); + dataFlowManager.register(new ConsumerPullTransferDataFlowController(selectorService, resolver)); + dataFlowManager.register(new ProviderPushTransferDataFlowController(callbackUrl, selectorService, clientFactory)); dataAddressValidatorRegistry.registerDestinationValidator("HttpProxy", dataAddress -> ValidationResult.success()); } diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowController.java b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowController.java index ccc5810621e..572d6efd387 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowController.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowController.java @@ -14,7 +14,7 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.transfer.dataplane.proxy.ConsumerPullDataPlaneProxyResolver; import org.eclipse.edc.connector.transfer.spi.flow.DataFlowController; import org.eclipse.edc.connector.transfer.spi.types.DataFlowResponse; @@ -33,11 +33,11 @@ public class ConsumerPullTransferDataFlowController implements DataFlowController { - private final DataPlaneSelectorClient selectorClient; + private final DataPlaneSelectorService selectorService; private final ConsumerPullDataPlaneProxyResolver resolver; - public ConsumerPullTransferDataFlowController(DataPlaneSelectorClient selectorClient, ConsumerPullDataPlaneProxyResolver resolver) { - this.selectorClient = selectorClient; + public ConsumerPullTransferDataFlowController(DataPlaneSelectorService selectorService, ConsumerPullDataPlaneProxyResolver resolver) { + this.selectorService = selectorService; this.resolver = resolver; } @@ -50,7 +50,7 @@ public boolean canHandle(TransferProcess transferProcess) { public @NotNull StatusResult initiateFlow(TransferProcess transferProcess, Policy policy) { var contentAddress = transferProcess.getContentDataAddress(); var dataRequest = transferProcess.getDataRequest(); - return Optional.ofNullable(selectorClient.find(contentAddress, dataRequest.getDataDestination())) + return Optional.ofNullable(selectorService.select(contentAddress, dataRequest.getDataDestination())) .map(instance -> resolver.toDataAddress(dataRequest, contentAddress, instance) .map(this::toResponse) .map(StatusResult::success) diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java index 4878c8b9814..a241c84e2f4 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/main/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowController.java @@ -14,8 +14,8 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.transfer.spi.callback.ControlApiUrl; import org.eclipse.edc.connector.transfer.spi.flow.DataFlowController; import org.eclipse.edc.connector.transfer.spi.types.DataFlowResponse; @@ -32,10 +32,10 @@ public class ProviderPushTransferDataFlowController implements DataFlowController { private final ControlApiUrl callbackUrl; - private final DataPlaneSelectorClient selectorClient; + private final DataPlaneSelectorService selectorClient; private final DataPlaneClientFactory clientFactory; - public ProviderPushTransferDataFlowController(ControlApiUrl callbackUrl, DataPlaneSelectorClient selectorClient, DataPlaneClientFactory clientFactory) { + public ProviderPushTransferDataFlowController(ControlApiUrl callbackUrl, DataPlaneSelectorService selectorClient, DataPlaneClientFactory clientFactory) { this.callbackUrl = callbackUrl; this.selectorClient = selectorClient; this.clientFactory = clientFactory; @@ -57,7 +57,7 @@ public boolean canHandle(TransferProcess transferProcess) { .callbackAddress(callbackUrl != null ? callbackUrl.get() : null) .build(); - var dataPlaneInstance = selectorClient.find(transferProcess.getContentDataAddress(), transferProcess.getDataDestination()); + var dataPlaneInstance = selectorClient.select(transferProcess.getContentDataAddress(), transferProcess.getDataDestination()); return clientFactory.createClient(dataPlaneInstance) .transfer(dataFlowRequest) .map(it -> DataFlowResponse.Builder.newInstance().build()); diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowControllerTest.java b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowControllerTest.java index 7fd28552ff0..351cb40e4e9 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowControllerTest.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ConsumerPullTransferDataFlowControllerTest.java @@ -14,7 +14,7 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.transfer.dataplane.proxy.ConsumerPullDataPlaneProxyResolver; import org.eclipse.edc.connector.transfer.spi.types.DataRequest; @@ -37,10 +37,10 @@ class ConsumerPullTransferDataFlowControllerTest { - private final DataPlaneSelectorClient selectorClient = mock(DataPlaneSelectorClient.class); - private final ConsumerPullDataPlaneProxyResolver resolver = mock(ConsumerPullDataPlaneProxyResolver.class); + private final DataPlaneSelectorService selectorService = mock(); + private final ConsumerPullDataPlaneProxyResolver resolver = mock(); - private final ConsumerPullTransferDataFlowController flowController = new ConsumerPullTransferDataFlowController(selectorClient, resolver); + private final ConsumerPullTransferDataFlowController flowController = new ConsumerPullTransferDataFlowController(selectorService, resolver); @Test void verifyCanHandle() { @@ -57,7 +57,7 @@ void initiateFlow_success() { .contentDataAddress(dataAddress()) .build(); - when(selectorClient.find(any(), argThat(destination -> destination.getType().equals(HTTP_PROXY)))).thenReturn(instance); + when(selectorService.select(any(), argThat(destination -> destination.getType().equals(HTTP_PROXY)))).thenReturn(instance); when(resolver.toDataAddress(any(), any(), any())).thenReturn(Result.success(proxyAddress)); var result = flowController.initiateFlow(transferProcess, null); @@ -90,7 +90,7 @@ void initiateFlow_returnsFailureIfAddressResolutionFails() { .contentDataAddress(dataAddress()) .build(); - when(selectorClient.find(any(), argThat(destination -> destination.getType().equals(HTTP_PROXY)))).thenReturn(instance); + when(selectorService.select(any(), argThat(destination -> destination.getType().equals(HTTP_PROXY)))).thenReturn(instance); when(resolver.toDataAddress(any(), any(), any())).thenReturn(Result.failure(errorMsg)); var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); diff --git a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java index a364159d0b2..3cba2c5bccc 100644 --- a/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java +++ b/extensions/control-plane/transfer/transfer-data-plane/src/test/java/org/eclipse/edc/connector/transfer/dataplane/flow/ProviderPushTransferDataFlowControllerTest.java @@ -14,9 +14,9 @@ package org.eclipse.edc.connector.transfer.dataplane.flow; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.transfer.spi.types.DataRequest; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; @@ -44,9 +44,9 @@ class ProviderPushTransferDataFlowControllerTest { private final DataPlaneClient dataPlaneClient = mock(); private final DataPlaneClientFactory dataPlaneClientFactory = mock(); - private final DataPlaneSelectorClient dataPlaneSelectorClient = mock(); + private final DataPlaneSelectorService selectorService = mock(); private final ProviderPushTransferDataFlowController flowController = - new ProviderPushTransferDataFlowController(() -> URI.create("http://localhost"), dataPlaneSelectorClient, dataPlaneClientFactory); + new ProviderPushTransferDataFlowController(() -> URI.create("http://localhost"), selectorService, dataPlaneClientFactory); @Test void canHandle() { @@ -65,7 +65,7 @@ void initiateFlow_transferSuccess() { when(dataPlaneClient.transfer(any(DataFlowRequest.class))).thenReturn(StatusResult.success()); var dataPlaneInstance = createDataPlaneInstance(); - when(dataPlaneSelectorClient.find(any(), any())).thenReturn(dataPlaneInstance); + when(selectorService.select(any(), any())).thenReturn(dataPlaneInstance); when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); @@ -92,7 +92,7 @@ void initiateFlow_returnFailedResultIfTransferFails() { when(dataPlaneClient.transfer(any())).thenReturn(StatusResult.failure(ResponseStatus.FATAL_ERROR, errorMsg)); var dataPlaneInstance = createDataPlaneInstance(); - when(dataPlaneSelectorClient.find(any(), any())).thenReturn(dataPlaneInstance); + when(selectorService.select(any(), any())).thenReturn(dataPlaneInstance); when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); var result = flowController.initiateFlow(transferProcess, Policy.Builder.newInstance().build()); @@ -113,7 +113,7 @@ void terminate_shouldCallTerminate() { when(dataPlaneClient.terminate(any())).thenReturn(StatusResult.success()); var dataPlaneInstance = createDataPlaneInstance(); when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient); - when(dataPlaneSelectorClient.getAll()).thenReturn(List.of(dataPlaneInstance)); + when(selectorService.getAll()).thenReturn(List.of(dataPlaneInstance)); var result = flowController.terminate(transferProcess); diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java index 17302e5a77a..6ea9fc6d7b8 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java @@ -62,7 +62,7 @@ void setUp(ServiceExtensionContext context, ObjectFactory factory) { context.registerService(TypeManager.class, new TypeManager()); context.registerService(WebService.class, webService); context.registerService(ManagementApiConfiguration.class, managementApiConfiguration); - context.registerService(DataPlaneSelectorService.class, new DataPlaneSelectorServiceImpl(mock(DataPlaneSelector.class), + context.registerService(DataPlaneSelectorService.class, new EmbeddedDataPlaneSelectorService(mock(DataPlaneSelector.class), mock(DataPlaneInstanceStore.class), mock(SelectionStrategyRegistry.class), new NoopTransactionContext())); context.registerService(ManagementApiTypeTransformerRegistry.class, transformerRegistry); diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java index 145e69f99f9..72700b19538 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java +++ b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtension.java @@ -14,10 +14,7 @@ package org.eclipse.edc.connector.dataplane.selector; -import org.eclipse.edc.connector.dataplane.selector.client.EmbeddedDataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.selector.client.RemoteDataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; @@ -27,11 +24,6 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.util.string.StringUtils; - -import java.util.Objects; - -import static java.lang.String.format; @Extension(value = "DataPlane Selector client") public class DataPlaneSelectorClientExtension implements ServiceExtension { @@ -43,9 +35,6 @@ public class DataPlaneSelectorClientExtension implements ServiceExtension { @Setting(value = "Defines strategy for Data Plane instance selection in case Data Plane is not embedded in current runtime", defaultValue = DEFAULT_DATAPLANE_SELECTOR_STRATEGY) private static final String DPF_SELECTOR_STRATEGY = "edc.dataplane.client.selector.strategy"; - @Inject(required = false) - private DataPlaneSelectorService selector; - @Inject(required = false) private EdcHttpClient httpClient; @@ -56,22 +45,9 @@ public class DataPlaneSelectorClientExtension implements ServiceExtension { private TypeTransformerRegistry typeTransformerRegistry; @Provider - public DataPlaneSelectorClient dataPlaneSelectorClient(ServiceExtensionContext context) { - var url = context.getConfig().getString(DPF_SELECTOR_URL_SETTING, null); - var monitor = context.getMonitor(); + public DataPlaneSelectorService dataPlaneSelectorService(ServiceExtensionContext context) { + var url = context.getConfig().getString(DPF_SELECTOR_URL_SETTING); var selectionStrategy = context.getSetting(DPF_SELECTOR_STRATEGY, DEFAULT_DATAPLANE_SELECTOR_STRATEGY); - - DataPlaneSelectorClient client; - if (StringUtils.isNullOrBlank(url)) { - Objects.requireNonNull(selector, format("If [%s] is not specified, a DataPlaneSelectorService instance must be provided", DPF_SELECTOR_URL_SETTING)); - client = new EmbeddedDataPlaneSelectorClient(selector, selectionStrategy); - monitor.debug("Using embedded DPF selector"); - } else { - Objects.requireNonNull(httpClient, format("If [%s] is specified, an EdcHttpClient instance must be provided", DPF_SELECTOR_URL_SETTING)); - client = new RemoteDataPlaneSelectorClient(httpClient, url, typeManager.getMapper(), typeTransformerRegistry, selectionStrategy); - monitor.debug("Using remote DPF selector"); - } - - return client; + return new RemoteDataPlaneSelectorService(httpClient, url, typeManager.getMapper(), typeTransformerRegistry, selectionStrategy); } } diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java new file mode 100644 index 00000000000..ec56c4a2359 --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java @@ -0,0 +1,157 @@ +/* + * 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.connector.dataplane.selector; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.http.EdcHttpClient; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.util.string.StringUtils; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import static jakarta.json.Json.createObjectBuilder; +import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.CoreConstants.EDC_PREFIX; + +public class RemoteDataPlaneSelectorService implements DataPlaneSelectorService { + + public static final MediaType TYPE_JSON = MediaType.parse("application/json"); + private static final String SELECT_PATH = "/select"; + private static final TypeReference JSON_OBJECT = new TypeReference<>() { + }; + private static final TypeReference> LIST_JSON_OBJECT = new TypeReference<>() { + }; + private final EdcHttpClient httpClient; + private final String url; + private final ObjectMapper mapper; + private final TypeTransformerRegistry typeTransformerRegistry; + private final String selectionStrategy; + + public RemoteDataPlaneSelectorService(EdcHttpClient httpClient, String url, ObjectMapper mapper, + TypeTransformerRegistry typeTransformerRegistry, String selectionStrategy) { + this.httpClient = httpClient; + this.url = url; + this.mapper = mapper; + this.typeTransformerRegistry = typeTransformerRegistry; + this.selectionStrategy = selectionStrategy; + } + + @Override + public List getAll() { + try { + var request = new Request.Builder().get().url(url).build(); + + try (var response = httpClient.execute(request)) { + + return handleResponse(response, LIST_JSON_OBJECT, Collections.emptyList()).stream() + .map(j -> typeTransformerRegistry.transform(j, DataPlaneInstance.class)) + .filter(Result::succeeded) + .map(Result::getContent) + .toList(); + } + } catch (IOException e) { + throw new EdcException(e); + } + } + + @Override + public DataPlaneInstance select(DataAddress source, DataAddress destination) { + return select(source, destination, selectionStrategy); + } + + @Override + public DataPlaneInstance select(DataAddress source, DataAddress destination, String selectionStrategy) { + var srcAddress = typeTransformerRegistry.transform(source, JsonObject.class).orElseThrow(f -> new EdcException(f.getFailureDetail())); + var dstAddress = typeTransformerRegistry.transform(destination, JsonObject.class).orElseThrow(f -> new EdcException(f.getFailureDetail())); + var jsonObject = Json.createObjectBuilder() + .add(CONTEXT, createObjectBuilder().add(EDC_PREFIX, EDC_NAMESPACE)) + .add(TYPE, EDC_NAMESPACE + "SelectionRequest") + .add(EDC_NAMESPACE + "source", srcAddress) + .add(EDC_NAMESPACE + "destination", dstAddress); + if (selectionStrategy != null) { + jsonObject.add(EDC_NAMESPACE + "strategy", selectionStrategy); + } + var body = RequestBody.create(jsonObject.build().toString(), TYPE_JSON); + + var request = new Request.Builder().post(body).url(url + SELECT_PATH).build(); + + try { + try (var response = httpClient.execute(request)) { + + var jo = handleResponse(response, JSON_OBJECT, null); + return jo != null ? + typeTransformerRegistry.transform(jo, DataPlaneInstance.class) + .orElseThrow(f -> new EdcException(f.getFailureDetail())) : null; + } + } catch (IOException e) { + throw new EdcException(e); + } + } + + @Override + public ServiceResult addInstance(DataPlaneInstance instance) { + throw new UnsupportedOperationException("not implemented"); + } + + + private R handleResponse(Response response, TypeReference tr, R defaultValue) { + if (response.isSuccessful()) { + R r = handleSuccess(response, tr); + return r == null ? defaultValue : r; + } else { + return handleError(response); + } + } + + private R handleSuccess(Response response, TypeReference tr) { + try { + var body = response.body().string(); + if (StringUtils.isNullOrEmpty(body)) { + return null; + } + + return mapper.readValue(body, tr); + } catch (IOException e) { + throw new EdcException(e); + } + } + + private R handleError(Response response) { + return switch (response.code()) { + case 400 -> throw new IllegalArgumentException("Remote API returned HTTP 400"); + case 404 -> null; + default -> + throw new IllegalArgumentException(format("An unknown error happened, HTTP Status = %d", response.code())); + }; + } +} diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java index eb7d6ce26c3..58fb207a088 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java +++ b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorClientExtensionTest.java @@ -14,80 +14,39 @@ package org.eclipse.edc.connector.dataplane.selector; -import org.eclipse.edc.connector.dataplane.selector.client.EmbeddedDataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.selector.client.RemoteDataPlaneSelectorClient; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.http.EdcHttpClient; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.eclipse.edc.spi.system.injection.ObjectFactory; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.util.Map; +import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorClientExtension.DPF_SELECTOR_URL_SETTING; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) class DataPlaneSelectorClientExtensionTest { - private DataPlaneSelectorClientExtension extension; - private ServiceExtensionContext context; - - @BeforeEach - void setUp(ServiceExtensionContext context) { - this.context = spy(context); - } - - @Test - void initialize_noSetting_shouldUseEmbedded(ObjectFactory factory) { - context.registerService(DataPlaneSelectorService.class, mock(DataPlaneSelectorService.class)); - extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - - var client = extension.dataPlaneSelectorClient(context); - - assertThat(client).isInstanceOf(EmbeddedDataPlaneSelectorClient.class); - } - @Test - void initialize_noSetting_shouldUseEmbedded_serviceMissing(ObjectFactory factory) { - context.registerService(DataPlaneSelectorService.class, null); - extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - - assertThatThrownBy(() -> extension.dataPlaneSelectorClient(context)).isInstanceOf(NullPointerException.class) - .hasMessage("If [" + DPF_SELECTOR_URL_SETTING + "] is not specified, a DataPlaneSelectorService instance must be provided"); - } + void dataPlaneSelectorService_shouldReturnRemoteService(DataPlaneSelectorClientExtension extension, ServiceExtensionContext context) { + when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of(DPF_SELECTOR_URL_SETTING, "http://any"))); - @Test - void initialize_withSetting(ObjectFactory factory) { - var config = ConfigFactory.fromMap(Map.of(DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); - when(context.getConfig()).thenReturn(config); + var client = extension.dataPlaneSelectorService(context); - context.registerService(EdcHttpClient.class, mock(EdcHttpClient.class)); - extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); - - var client = extension.dataPlaneSelectorClient(context); - - assertThat(client).isInstanceOf(RemoteDataPlaneSelectorClient.class); + assertThat(client).isInstanceOf(RemoteDataPlaneSelectorService.class); } @Test - void initialize_withSetting_httpClientMissing(ObjectFactory factory) { - context.registerService(EdcHttpClient.class, null); - var config = ConfigFactory.fromMap(Map.of(DPF_SELECTOR_URL_SETTING, "http://someurl.com:1234")); - when(context.getConfig()).thenReturn(config); - - extension = factory.constructInstance(DataPlaneSelectorClientExtension.class); + void dataPlaneSelectorService_shouldThrowException_whenUrlNotConfigured(DataPlaneSelectorClientExtension extension, ServiceExtensionContext context) { + when(context.getConfig()).thenReturn(ConfigFactory.fromMap(emptyMap())); - assertThatThrownBy(() -> extension.dataPlaneSelectorClient(context)).isInstanceOf(NullPointerException.class) - .hasMessage("If [" + DPF_SELECTOR_URL_SETTING + "] is specified, an EdcHttpClient instance must be provided"); + assertThatThrownBy(() -> extension.dataPlaneSelectorService(context)).isInstanceOf(EdcException.class) + .hasMessageContaining("No setting found"); } } diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorServiceTest.java b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorServiceTest.java new file mode 100644 index 00000000000..c51d54c8e9c --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-client/src/test/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorServiceTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020 - 2022 Microsoft Corporation + * + * 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: + * Microsoft Corporation - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector; + +import jakarta.json.Json; +import org.eclipse.edc.connector.dataplane.selector.api.v2.DataplaneSelectorApiController; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectFromDataPlaneInstanceTransformer; +import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToDataPlaneInstanceTransformer; +import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToSelectionRequestTransformer; +import org.eclipse.edc.core.transform.TypeTransformerRegistryImpl; +import org.eclipse.edc.core.transform.transformer.from.JsonObjectFromDataAddressTransformer; +import org.eclipse.edc.core.transform.transformer.to.JsonObjectToDataAddressTransformer; +import org.eclipse.edc.core.transform.transformer.to.JsonValueToGenericTypeTransformer; +import org.eclipse.edc.jsonld.TitaniumJsonLd; +import org.eclipse.edc.jsonld.util.JacksonJsonLd; +import org.eclipse.edc.junit.annotations.ComponentTest; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.jsonld.JerseyJsonLdInterceptor; +import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Clock; +import java.util.List; +import java.util.Map; + +import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.junit.testfixtures.TestUtils.testHttpClient; +import static org.eclipse.edc.spi.CoreConstants.JSON_LD; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@ComponentTest +class RemoteDataPlaneSelectorServiceTest extends RestControllerTestBase { + + private static final String BASE_URL = "http://localhost:%d/v2/dataplanes"; + private static final DataPlaneSelectorService SELECTOR_SERVICE_MOCK = mock(); + private static final TypeManager TYPE_MANAGER = new TypeManager(); + private final TypeTransformerRegistry typeTransformerRegistry = new TypeTransformerRegistryImpl(); + private final JsonObjectValidatorRegistry validator = mock(); + private RemoteDataPlaneSelectorService service; + + @BeforeAll + public static void prepare() { + TYPE_MANAGER.registerTypes(DataPlaneInstance.class); + TYPE_MANAGER.registerContext(JSON_LD, JacksonJsonLd.createObjectMapper()); + } + + @BeforeEach + void setUp() { + var factory = Json.createBuilderFactory(Map.of()); + typeTransformerRegistry.register(new JsonObjectFromDataAddressTransformer(factory)); + typeTransformerRegistry.register(new JsonObjectToDataAddressTransformer()); + typeTransformerRegistry.register(new JsonObjectToSelectionRequestTransformer()); + typeTransformerRegistry.register(new JsonObjectFromDataPlaneInstanceTransformer(factory, JacksonJsonLd.createObjectMapper())); + typeTransformerRegistry.register(new JsonObjectToDataPlaneInstanceTransformer()); + typeTransformerRegistry.register(new JsonValueToGenericTypeTransformer(objectMapper)); + var url = format(BASE_URL, port); + service = new RemoteDataPlaneSelectorService(testHttpClient(), url, JacksonJsonLd.createObjectMapper(), typeTransformerRegistry, "selectionStrategy"); + } + + @Test + void getAll() { + when(SELECTOR_SERVICE_MOCK.getAll()).thenReturn(List.of(createInstance("test-inst1"), createInstance("test-inst2"))); + + var result = service.getAll(); + + assertThat(result).hasSize(2).extracting(DataPlaneInstance::getId).containsExactlyInAnyOrder("test-inst1", "test-inst2"); + } + + @Test + void find() { + var expected = createInstance("some-instance"); + when(SELECTOR_SERVICE_MOCK.select(any(), any())).thenReturn(expected); + + var result = service.select(DataAddress.Builder.newInstance().type("test1").build(), DataAddress.Builder.newInstance().type("test2").build()); + + assertThat(result).usingRecursiveComparison().isEqualTo(expected); + + } + + @Override + protected Object controller() { + return new DataplaneSelectorApiController(SELECTOR_SERVICE_MOCK, typeTransformerRegistry, validator, Clock.systemUTC()); + } + + @Override + protected Object additionalResource() { + return new JerseyJsonLdInterceptor(new TitaniumJsonLd(mock()), JacksonJsonLd.createObjectMapper(), "scope"); + } + + private DataPlaneInstance createInstance(String id) { + return DataPlaneInstance.Builder.newInstance() + .id(id) + .url("http://somewhere.com:1234/api/v1") + .build(); + } +} diff --git a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java index 0663275ae44..bcfe5689b64 100644 --- a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java +++ b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneClientExtensionTest.java @@ -15,7 +15,6 @@ package org.eclipse.edc.connector.dataplane.client; import dev.failsafe.RetryPolicy; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.spi.manager.DataPlaneManager; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; @@ -49,7 +48,6 @@ void verifyReturnRemoteClient(ServiceExtensionContext context, ObjectFactory fac context.registerService(DataPlaneManager.class, null); context.registerService(EdcHttpClient.class, mock(EdcHttpClient.class)); context.registerService(RetryPolicy.class, mock(RetryPolicy.class)); - context.registerService(DataPlaneSelectorClient.class, mock(DataPlaneSelectorClient.class)); context.registerService(TypeManager.class, new TypeManager()); var extension = factory.constructInstance(DataPlaneClientExtension.class); diff --git a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java index ee60803281a..920e0b311f8 100644 --- a/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java +++ b/extensions/data-plane/data-plane-client/src/test/java/org/eclipse/edc/connector/dataplane/client/RemoteDataPlaneClientTest.java @@ -17,7 +17,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClient; -import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneSelectorClient; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.spi.response.TransferErrorResponse; import org.eclipse.edc.spi.response.ResponseStatus; @@ -43,7 +42,6 @@ import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.edc.junit.testfixtures.TestUtils.getFreePort; import static org.eclipse.edc.junit.testfixtures.TestUtils.testHttpClient; -import static org.mockito.Mockito.mock; import static org.mockserver.integration.ClientAndServer.startClientAndServer; import static org.mockserver.matchers.Times.once; import static org.mockserver.model.HttpResponse.response; @@ -59,7 +57,6 @@ class RemoteDataPlaneClientTest { private static final String DATA_PLANE_PATH = "/transfer"; private static final String DATA_PLANE_API_URI = "http://localhost:" + DATA_PLANE_API_PORT + DATA_PLANE_PATH; private static ClientAndServer dataPlane; - private final DataPlaneSelectorClient selectorClient = mock(); private final DataPlaneInstance instance = DataPlaneInstance.Builder.newInstance().url(DATA_PLANE_API_URI).build(); private final DataPlaneClient dataPlaneClient = new RemoteDataPlaneClient(testHttpClient(), MAPPER, instance); diff --git a/launchers/dpf-selector/build.gradle.kts b/launchers/dpf-selector/build.gradle.kts index a655948852c..53b6fc082aa 100644 --- a/launchers/dpf-selector/build.gradle.kts +++ b/launchers/dpf-selector/build.gradle.kts @@ -22,7 +22,6 @@ dependencies { implementation(project(":extensions:common:api:api-observability")) api(project(":core:data-plane-selector:data-plane-selector-core")) api(project(":extensions:data-plane-selector:data-plane-selector-api")) - api(project(":extensions:data-plane-selector:data-plane-selector-client")) } application { diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java index 48f3c155d0a..d610738d160 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java @@ -19,23 +19,34 @@ import org.eclipse.edc.spi.result.ServiceResult; import org.eclipse.edc.spi.types.domain.DataAddress; -import java.util.Collection; import java.util.List; /** - * Wrapper service to encapsulate all functionality required by DPF selector clients (e.g. API controllers), e.g. to - * get, add and find a particular {@link DataPlaneInstance} + * Main interaction interface for an EDC runtime (=control plane) to communicate with the DPF selector. */ @ExtensionPoint public interface DataPlaneSelectorService { + + /** + * Returns all {@link DataPlaneInstance}s known in the system + */ List getAll(); + /** + * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the configured + * strategy. + */ DataPlaneInstance select(DataAddress source, DataAddress destination); + /** + * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the passed + * strategy. + */ DataPlaneInstance select(DataAddress source, DataAddress destination, String selectionStrategy); - Collection getAllStrategies(); - + /** + * Add a data plane instance + */ ServiceResult addInstance(DataPlaneInstance instance); } diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java index 3ac6f9b7c6b..32338c3c176 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2022 Amadeus * * This program and the accompanying materials are made available under the * terms of the Apache License, Version 2.0 which is available at @@ -8,7 +8,7 @@ * SPDX-License-Identifier: Apache-2.0 * * Contributors: - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * Amadeus - initial API and implementation * */ diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java index fc7f532765c..00a64a7b406 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/client/DataPlaneClientFactory.java @@ -17,13 +17,16 @@ import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; /** - * TODO: docs + * Factory for {@link DataPlaneClient} instances. */ @FunctionalInterface public interface DataPlaneClientFactory { /** - * TODO: docs + * Create a {@link DataPlaneClient} that points to the {@link DataPlaneInstance} + * + * @param dataPlaneInstance the data plane instance. + * @return the data plane client. */ DataPlaneClient createClient(DataPlaneInstance dataPlaneInstance); diff --git a/system-tests/e2e-transfer-test/control-plane/build.gradle.kts b/system-tests/e2e-transfer-test/control-plane/build.gradle.kts index c0766ab185f..bf32786e813 100644 --- a/system-tests/e2e-transfer-test/control-plane/build.gradle.kts +++ b/system-tests/e2e-transfer-test/control-plane/build.gradle.kts @@ -30,7 +30,6 @@ dependencies { implementation(project(":core:data-plane-selector:data-plane-selector-core")) implementation(project(":extensions:data-plane-selector:data-plane-selector-api")) - implementation(project(":extensions:data-plane-selector:data-plane-selector-client")) implementation(project(":extensions:control-plane:provision:provision-http")) implementation(project(":extensions:control-plane:transfer:transfer-pull-http-receiver")) diff --git a/system-tests/management-api/management-api-test-runtime/build.gradle.kts b/system-tests/management-api/management-api-test-runtime/build.gradle.kts index 5090d1c5e2a..89b7407954a 100644 --- a/system-tests/management-api/management-api-test-runtime/build.gradle.kts +++ b/system-tests/management-api/management-api-test-runtime/build.gradle.kts @@ -28,7 +28,6 @@ dependencies { implementation(project(":extensions:data-plane:data-plane-client")) implementation(project(":core:data-plane-selector:data-plane-selector-core")) - implementation(project(":extensions:data-plane-selector:data-plane-selector-client")) } edcBuild { diff --git a/system-tests/telemetry/telemetry-test-runtime/build.gradle.kts b/system-tests/telemetry/telemetry-test-runtime/build.gradle.kts index 39c835d187f..114a1e16f8b 100644 --- a/system-tests/telemetry/telemetry-test-runtime/build.gradle.kts +++ b/system-tests/telemetry/telemetry-test-runtime/build.gradle.kts @@ -29,7 +29,6 @@ dependencies { implementation(project(":extensions:data-plane:data-plane-client")) implementation(project(":core:data-plane-selector:data-plane-selector-core")) - implementation(project(":extensions:data-plane-selector:data-plane-selector-client")) implementation(project(":extensions:common:metrics:micrometer-core")) implementation(project(":extensions:common:http:jersey-micrometer")) From c5208c84e4b47c5c0fe1caee77bc636c28ed8182 Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Thu, 23 Nov 2023 11:54:25 +0100 Subject: [PATCH 3/5] PR remarks --- ...PlaneSelectorDefaultServicesExtension.java | 10 +++++++ .../core/DataPlaneSelectorExtension.java | 27 ++++--------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java index 82dfb8b74aa..7c2c4caad22 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java @@ -15,7 +15,10 @@ package org.eclipse.edc.connector.dataplane.selector.core; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; +import org.eclipse.edc.connector.dataplane.selector.spi.strategy.RandomSelectionStrategy; +import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry; import org.eclipse.edc.connector.dataplane.selector.store.InMemoryDataPlaneInstanceStore; +import org.eclipse.edc.connector.dataplane.selector.strategy.DefaultSelectionStrategyRegistry; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.spi.system.ServiceExtension; @@ -37,4 +40,11 @@ public String name() { public DataPlaneInstanceStore instanceStore() { return new InMemoryDataPlaneInstanceStore(); } + + @Provider(isDefault = true) + public SelectionStrategyRegistry selectionStrategyRegistry() { + var strategy = new DefaultSelectionStrategyRegistry(); + strategy.add(new RandomSelectionStrategy()); + return strategy; + } } diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java index 16a81f8675c..68c3347dd6a 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java @@ -15,21 +15,15 @@ package org.eclipse.edc.connector.dataplane.selector.core; import org.eclipse.edc.connector.dataplane.selector.EmbeddedDataPlaneSelectorService; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; -import org.eclipse.edc.connector.dataplane.selector.spi.strategy.RandomSelectionStrategy; import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry; -import org.eclipse.edc.connector.dataplane.selector.strategy.DefaultSelectionStrategyRegistry; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.runtime.metamodel.annotation.Provides; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.transaction.spi.TransactionContext; -@Provides({ DataPlaneSelector.class, SelectionStrategyRegistry.class }) @Extension(value = "DataPlane core selector") public class DataPlaneSelectorExtension implements ServiceExtension { @@ -39,24 +33,13 @@ public class DataPlaneSelectorExtension implements ServiceExtension { @Inject private TransactionContext transactionContext; - private DataPlaneSelectorService dataPlaneSelectorService; - - @Override - public void initialize(ServiceExtensionContext context) { - var selector = new DataPlaneSelectorImpl(instanceStore); - - var strategy = new DefaultSelectionStrategyRegistry(); - strategy.add(new RandomSelectionStrategy()); - - dataPlaneSelectorService = new EmbeddedDataPlaneSelectorService(selector, instanceStore, strategy, transactionContext); - - context.registerService(DataPlaneSelector.class, selector); - context.registerService(SelectionStrategyRegistry.class, strategy); - } + @Inject + private SelectionStrategyRegistry selectionStrategyRegistry; - @Provider(isDefault = true) + @Provider public DataPlaneSelectorService dataPlaneSelectorService() { - return dataPlaneSelectorService; + var selector = new DataPlaneSelectorImpl(instanceStore); + return new EmbeddedDataPlaneSelectorService(selector, instanceStore, selectionStrategyRegistry, transactionContext); } } From cb81691e7ce2da8127bc46a823300cacb3cffd1d Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Thu, 23 Nov 2023 14:53:02 +0100 Subject: [PATCH 4/5] Inline DataPlaneSelector --- .../EmbeddedDataPlaneSelectorService.java | 13 +- .../core/DataPlaneSelectorExtension.java | 3 +- .../selector/core/DataPlaneSelectorImpl.java | 37 ------ .../EmbeddedDataPlaneSelectorServiceTest.java | 72 +++++++++++ .../core/DataPlaneSelectorImplTest.java | 116 ------------------ .../DataPlaneSelectorApiExtensionTest.java | 3 +- .../RemoteDataPlaneSelectorService.java | 9 +- .../selector/spi/DataPlaneSelector.java | 48 -------- .../spi/DataPlaneSelectorService.java | 4 +- .../spi/strategy/SelectionStrategy.java | 4 +- 10 files changed, 86 insertions(+), 223 deletions(-) delete mode 100644 core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImpl.java create mode 100644 core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java delete mode 100644 core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImplTest.java delete mode 100644 spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelector.java diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java index 5d0543956db..188204989aa 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java @@ -14,7 +14,6 @@ package org.eclipse.edc.connector.dataplane.selector; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; @@ -29,13 +28,11 @@ public class EmbeddedDataPlaneSelectorService implements DataPlaneSelectorService { - private final DataPlaneSelector selector; private final DataPlaneInstanceStore store; private final SelectionStrategyRegistry selectionStrategyRegistry; private final TransactionContext transactionContext; - public EmbeddedDataPlaneSelectorService(DataPlaneSelector selector, DataPlaneInstanceStore store, SelectionStrategyRegistry selectionStrategyRegistry, TransactionContext transactionContext) { - this.selector = selector; + public EmbeddedDataPlaneSelectorService(DataPlaneInstanceStore store, SelectionStrategyRegistry selectionStrategyRegistry, TransactionContext transactionContext) { this.store = store; this.selectionStrategyRegistry = selectionStrategyRegistry; this.transactionContext = transactionContext; @@ -46,18 +43,14 @@ public List getAll() { return store.getAll().collect(Collectors.toList()); } - @Override - public DataPlaneInstance select(DataAddress source, DataAddress destination) { - return selector.select(source, destination); - } - @Override public DataPlaneInstance select(DataAddress source, DataAddress destination, String selectionStrategy) { var strategy = selectionStrategyRegistry.find(selectionStrategy); if (strategy == null) { throw new IllegalArgumentException("Strategy " + selectionStrategy + " was not found"); } - return selector.select(source, destination, strategy); + var dataPlanes = store.getAll().filter(dataPlane -> dataPlane.canHandle(source, destination)).toList(); + return strategy.apply(dataPlanes); } @Override diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java index 68c3347dd6a..c0fffb4d3d0 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java @@ -38,8 +38,7 @@ public class DataPlaneSelectorExtension implements ServiceExtension { @Provider public DataPlaneSelectorService dataPlaneSelectorService() { - var selector = new DataPlaneSelectorImpl(instanceStore); - return new EmbeddedDataPlaneSelectorService(selector, instanceStore, selectionStrategyRegistry, transactionContext); + return new EmbeddedDataPlaneSelectorService(instanceStore, selectionStrategyRegistry, transactionContext); } } diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImpl.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImpl.java deleted file mode 100644 index 8a3af2f4edb..00000000000 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.core; - -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; -import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategy; -import org.eclipse.edc.spi.types.domain.DataAddress; - -import java.util.stream.Collectors; - -public class DataPlaneSelectorImpl implements DataPlaneSelector { - - private final DataPlaneInstanceStore instanceStore; - - public DataPlaneSelectorImpl(DataPlaneInstanceStore instanceStore) { - this.instanceStore = instanceStore; - } - - @Override - public DataPlaneInstance select(DataAddress sourceAddress, DataAddress destinationAddress, SelectionStrategy strategy) { - return strategy.apply(instanceStore.getAll().filter(di -> di.canHandle(sourceAddress, destinationAddress)).collect(Collectors.toList())); - } -} diff --git a/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java b/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java new file mode 100644 index 00000000000..6ecc2428a89 --- /dev/null +++ b/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java @@ -0,0 +1,72 @@ +/* + * 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.connector.dataplane.selector; + +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; +import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategy; +import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry; +import org.junit.jupiter.api.Test; + +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.eclipse.edc.connector.dataplane.selector.spi.testfixtures.TestFunctions.createAddress; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class EmbeddedDataPlaneSelectorServiceTest { + + private final DataPlaneInstanceStore store = mock(); + private final SelectionStrategyRegistry selectionStrategyRegistry = mock(); + private final DataPlaneSelectorService selector = new EmbeddedDataPlaneSelectorService(store, selectionStrategyRegistry, mock()); + + @Test + void select_shouldUseChosenSelector() { + var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, "srcTestType", "destTestType")).toList(); + when(store.getAll()).thenReturn(instances.stream()); + SelectionStrategy selectionStrategy = mock(); + when(selectionStrategy.apply(any())).thenAnswer(it -> instances.get(0)); + when(selectionStrategyRegistry.find(any())).thenReturn(selectionStrategy); + + var result = selector.select(createAddress("srcTestType"), createAddress("destTestType"), "strategy"); + + assertThat(result).isNotNull().extracting(DataPlaneInstance::getId).isEqualTo("instance0"); + verify(selectionStrategyRegistry).find("strategy"); + } + + @Test + void select_shouldThrowException_whenStrategyNotFound() { + var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, "srcTestType", "destTestType")).toList(); + when(store.getAll()).thenReturn(instances.stream()); + when(selectionStrategyRegistry.find(any())).thenReturn(null); + + assertThatThrownBy(() -> selector.select(createAddress("srcTestType"), createAddress("destTestType"), "strategy")) + .isInstanceOf(IllegalArgumentException.class); + } + + private DataPlaneInstance createInstanceMock(String id, String srcType, String destType) { + return DataPlaneInstance.Builder.newInstance() + .url("http://any") + .id(id) + .allowedSourceType(srcType) + .allowedDestType(destType) + .build(); + } +} diff --git a/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImplTest.java b/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImplTest.java deleted file mode 100644 index 72dff16e840..00000000000 --- a/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorImplTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.core; - -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; - -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.spi.testfixtures.TestFunctions.createAddress; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class DataPlaneSelectorImplTest { - - private DataPlaneSelectorImpl selector; - private DataPlaneInstanceStore storeMock; - - @BeforeEach - void setUp() { - storeMock = mock(DataPlaneInstanceStore.class); - selector = new DataPlaneSelectorImpl(storeMock); - } - - @Test - void select() { - var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, true)); - when(storeMock.getAll()).thenReturn(instances); - - var result = selector.select(createAddress("TestType"), createAddress("TestType")); - - assertThat(result).isNotNull(); - } - - @RepeatedTest(100) - void select_someCanHandle() { - var instances = Stream.of( - createInstanceMock("instance0", false), - createInstanceMock("instance1", true), - createInstanceMock("instance2", true), - createInstanceMock("instance3", false), - createInstanceMock("instance4", false) - ); - when(storeMock.getAll()).thenReturn(instances); - - var result = selector.select(createAddress("SomeType"), createAddress("FTP")); - - assertThat(result).isNotNull().extracting(DataPlaneInstance::getId).isIn("instance1", "instance2"); - } - - @Test - void select_noneCanHandle() { - var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, false)); - when(storeMock.getAll()).thenReturn(instances); - - var result = selector.select(createAddress("TestType"), createAddress("AmazonS3")); - - assertThat(result).isNull(); - } - - @Test - void select_withSelectionStrategy() { - var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, true)); - when(storeMock.getAll()).thenReturn(instances); - - var result = selector.select(createAddress("TestType"), createAddress("http"), instances1 -> instances1.get(0)); - - assertThat(result).isNotNull().extracting(DataPlaneInstance::getId).isEqualTo("instance0"); - } - - @Test - void select_withSelectionStrategy_someCanHandle() { - var instances = Stream.of( - createInstanceMock("instance0", false), - createInstanceMock("instance1", true), - createInstanceMock("instance2", true), - createInstanceMock("instance3", false), - createInstanceMock("instance4", false) - ); - when(storeMock.getAll()).thenReturn(instances); - - var result = selector.select(createAddress("AmazonS3"), createAddress("http"), instances1 -> instances1.get(0)); - - assertThat(result).isNotNull().extracting(DataPlaneInstance::getId).isEqualTo("instance1"); - } - - @Test - void select_verifyDefaultRandomSelection() { - - } - - private DataPlaneInstance createInstanceMock(String id, boolean canHandle) { - var mock = mock(DataPlaneInstance.class); - when(mock.getId()).thenReturn(id); - when(mock.canHandle(any(), any())).thenReturn(canHandle); - return mock; - } -} \ No newline at end of file diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java index 6ea9fc6d7b8..738ef675526 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java @@ -18,7 +18,6 @@ import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration; import org.eclipse.edc.connector.api.management.configuration.transform.ManagementApiTypeTransformerRegistry; import org.eclipse.edc.connector.dataplane.selector.api.v2.DataplaneSelectorApiController; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry; @@ -62,7 +61,7 @@ void setUp(ServiceExtensionContext context, ObjectFactory factory) { context.registerService(TypeManager.class, new TypeManager()); context.registerService(WebService.class, webService); context.registerService(ManagementApiConfiguration.class, managementApiConfiguration); - context.registerService(DataPlaneSelectorService.class, new EmbeddedDataPlaneSelectorService(mock(DataPlaneSelector.class), + context.registerService(DataPlaneSelectorService.class, new EmbeddedDataPlaneSelectorService( mock(DataPlaneInstanceStore.class), mock(SelectionStrategyRegistry.class), new NoopTransactionContext())); context.registerService(ManagementApiTypeTransformerRegistry.class, transformerRegistry); diff --git a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java index ec56c4a2359..3178600b8bc 100644 --- a/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java +++ b/extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java @@ -84,11 +84,6 @@ public List getAll() { } } - @Override - public DataPlaneInstance select(DataAddress source, DataAddress destination) { - return select(source, destination, selectionStrategy); - } - @Override public DataPlaneInstance select(DataAddress source, DataAddress destination, String selectionStrategy) { var srcAddress = typeTransformerRegistry.transform(source, JsonObject.class).orElseThrow(f -> new EdcException(f.getFailureDetail())); @@ -98,9 +93,13 @@ public DataPlaneInstance select(DataAddress source, DataAddress destination, Str .add(TYPE, EDC_NAMESPACE + "SelectionRequest") .add(EDC_NAMESPACE + "source", srcAddress) .add(EDC_NAMESPACE + "destination", dstAddress); + if (selectionStrategy != null) { jsonObject.add(EDC_NAMESPACE + "strategy", selectionStrategy); + } else { + jsonObject.add(EDC_NAMESPACE + "strategy", this.selectionStrategy); } + var body = RequestBody.create(jsonObject.build().toString(), TYPE_JSON); var request = new Request.Builder().post(body).url(url + SELECT_PATH).build(); diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelector.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelector.java deleted file mode 100644 index 04804ec07fc..00000000000 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelector.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.connector.dataplane.selector.spi; - -import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; -import org.eclipse.edc.connector.dataplane.selector.spi.strategy.RandomSelectionStrategy; -import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategy; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.jetbrains.annotations.Nullable; - -/** - * A {@link DataPlaneSelector} accepts a certain data request (rather: its source and destination address) and selects a - * {@link DataPlaneInstance} that can handle that request. - * It can be thought of as a "software load-balancer" that determines the best-fitting DPF for a particular request. - */ -@FunctionalInterface -public interface DataPlaneSelector { - /** - * Computes the best-fit DPF for a given DataRequest. If more than one {@link DataPlaneInstance} objects fit the requirements, - * one is selected at random. - * - * @return The best-fit {@link DataPlaneInstance}, or null if none was found. - */ - @Nullable - default DataPlaneInstance select(DataAddress sourceAddress, DataAddress destinationAddress) { - return select(sourceAddress, destinationAddress, new RandomSelectionStrategy()); - } - - /** - * Computes the best-fit DPF for a given DataRequest using the given {@link SelectionStrategy}. - * - * @return The best-fit {@link DataPlaneInstance}, or null if none was found. - */ - @Nullable - DataPlaneInstance select(DataAddress sourceAddress, DataAddress destinationAddress, SelectionStrategy strategy); -} diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java index d610738d160..2a2230f74be 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/DataPlaneSelectorService.java @@ -36,7 +36,9 @@ public interface DataPlaneSelectorService { * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the configured * strategy. */ - DataPlaneInstance select(DataAddress source, DataAddress destination); + default DataPlaneInstance select(DataAddress source, DataAddress destination) { + return select(source, destination, "random"); + } /** * Selects the {@link DataPlaneInstance} that can handle a source and destination {@link DataAddress} using the passed diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/strategy/SelectionStrategy.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/strategy/SelectionStrategy.java index a6e724a76fe..6caf28dfad6 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/strategy/SelectionStrategy.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/strategy/SelectionStrategy.java @@ -14,14 +14,14 @@ package org.eclipse.edc.connector.dataplane.selector.spi.strategy; -import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelector; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import java.util.List; import java.util.function.Function; /** - * Interface for different algorithms by which the {@link DataPlaneSelector} + * Interface for different algorithms by which the {@link DataPlaneSelectorService} * selects a particular {@link DataPlaneInstance} */ public interface SelectionStrategy extends Function, DataPlaneInstance> { From 6255da34943a8b52a2425a6780946e60f6a89ba5 Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Thu, 23 Nov 2023 14:55:13 +0100 Subject: [PATCH 5/5] Move classes --- .../DataPlaneSelectorDefaultServicesExtension.java | 6 +++--- .../selector/{core => }/DataPlaneSelectorExtension.java | 8 ++++---- .../{ => service}/EmbeddedDataPlaneSelectorService.java | 6 +++--- .../services/org.eclipse.edc.spi.system.ServiceExtension | 4 ++-- .../EmbeddedDataPlaneSelectorServiceTest.java | 2 +- .../selector/DataPlaneSelectorApiExtensionTest.java | 1 + 6 files changed, 14 insertions(+), 13 deletions(-) rename core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/{core => }/DataPlaneSelectorDefaultServicesExtension.java (92%) rename core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/{core => }/DataPlaneSelectorExtension.java (80%) rename core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/{ => service}/EmbeddedDataPlaneSelectorService.java (91%) rename core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/{ => service}/EmbeddedDataPlaneSelectorServiceTest.java (98%) diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorDefaultServicesExtension.java similarity index 92% rename from core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java rename to core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorDefaultServicesExtension.java index 7c2c4caad22..08903852dbb 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorDefaultServicesExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorDefaultServicesExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * 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 @@ -8,11 +8,11 @@ * SPDX-License-Identifier: Apache-2.0 * * Contributors: - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - Initial implementation + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation * */ -package org.eclipse.edc.connector.dataplane.selector.core; +package org.eclipse.edc.connector.dataplane.selector; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; import org.eclipse.edc.connector.dataplane.selector.spi.strategy.RandomSelectionStrategy; diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorExtension.java similarity index 80% rename from core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java rename to core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorExtension.java index c0fffb4d3d0..3f0cb798891 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/core/DataPlaneSelectorExtension.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2022 Microsoft Corporation + * 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 @@ -8,13 +8,13 @@ * SPDX-License-Identifier: Apache-2.0 * * Contributors: - * Microsoft Corporation - initial API and implementation + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation * */ -package org.eclipse.edc.connector.dataplane.selector.core; +package org.eclipse.edc.connector.dataplane.selector; -import org.eclipse.edc.connector.dataplane.selector.EmbeddedDataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.service.EmbeddedDataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry; diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorService.java similarity index 91% rename from core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java rename to core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorService.java index 188204989aa..b5591ee9586 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorService.java +++ b/core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2022 Microsoft Corporation + * 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 @@ -8,11 +8,11 @@ * SPDX-License-Identifier: Apache-2.0 * * Contributors: - * Microsoft Corporation - initial API and implementation + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation * */ -package org.eclipse.edc.connector.dataplane.selector; +package org.eclipse.edc.connector.dataplane.selector.service; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; diff --git a/core/data-plane-selector/data-plane-selector-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/core/data-plane-selector/data-plane-selector-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index 502f9df9b4a..40f6f7e63fb 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/core/data-plane-selector/data-plane-selector-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -12,5 +12,5 @@ # # -org.eclipse.edc.connector.dataplane.selector.core.DataPlaneSelectorExtension -org.eclipse.edc.connector.dataplane.selector.core.DataPlaneSelectorDefaultServicesExtension \ No newline at end of file +org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorExtension +org.eclipse.edc.connector.dataplane.selector.DataPlaneSelectorDefaultServicesExtension diff --git a/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java b/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorServiceTest.java similarity index 98% rename from core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java rename to core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorServiceTest.java index 6ecc2428a89..5d2b555358d 100644 --- a/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/EmbeddedDataPlaneSelectorServiceTest.java +++ b/core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorServiceTest.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.connector.dataplane.selector; +package org.eclipse.edc.connector.dataplane.selector.service; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java index 738ef675526..0fe9b9e222b 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtensionTest.java @@ -18,6 +18,7 @@ import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration; import org.eclipse.edc.connector.api.management.configuration.transform.ManagementApiTypeTransformerRegistry; import org.eclipse.edc.connector.dataplane.selector.api.v2.DataplaneSelectorApiController; +import org.eclipse.edc.connector.dataplane.selector.service.EmbeddedDataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; import org.eclipse.edc.connector.dataplane.selector.spi.strategy.SelectionStrategyRegistry;