diff --git a/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformer.java b/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformer.java index 7642802cb03..27dc78aa8ef 100644 --- a/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformer.java +++ b/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformer.java @@ -26,14 +26,12 @@ import java.util.Optional; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE_TIMESTAMP; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.LAST_ACTIVE; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.PROPERTIES; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.TURN_COUNT; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; @@ -54,10 +52,8 @@ public JsonObjectFromDataPlaneInstanceTransformer(JsonBuilderFactory jsonFactory .add(ID, dataPlaneInstance.getId()) .add(TYPE, DataPlaneInstance.DATAPLANE_INSTANCE_TYPE) .add(URL, dataPlaneInstance.getUrl().toString()) - .add(LAST_ACTIVE, dataPlaneInstance.getLastActive()) - .add(TURN_COUNT, dataPlaneInstance.getTurnCount()); + .add(LAST_ACTIVE, dataPlaneInstance.getLastActive()); - //properties if (dataPlaneInstance.getProperties() != null && !dataPlaneInstance.getProperties().isEmpty()) { var propBuilder = jsonFactory.createObjectBuilder(); transformProperties(dataPlaneInstance.getProperties(), propBuilder, mapper, context); @@ -67,9 +63,6 @@ public JsonObjectFromDataPlaneInstanceTransformer(JsonBuilderFactory jsonFactory var srcBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedSourceTypes()); builder.add(ALLOWED_SOURCE_TYPES, srcBldr); - var dstBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedDestTypes()); - builder.add(ALLOWED_DEST_TYPES, dstBldr); - var transferTypesBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedTransferTypes()); builder.add(ALLOWED_TRANSFER_TYPES, transferTypesBldr); diff --git a/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3Transformer.java b/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3Transformer.java new file mode 100644 index 00000000000..57decebe80b --- /dev/null +++ b/core/common/lib/transform-lib/src/main/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3Transformer.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.transform.transformer.edc.from; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstanceStates; +import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; +import org.eclipse.edc.transform.spi.TransformerContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE_TIMESTAMP; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.LAST_ACTIVE; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.PROPERTIES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.TURN_COUNT; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; + +public class JsonObjectFromDataPlaneInstanceV3Transformer extends AbstractJsonLdTransformer { + private final JsonBuilderFactory jsonFactory; + private final ObjectMapper mapper; + + public JsonObjectFromDataPlaneInstanceV3Transformer(JsonBuilderFactory jsonFactory, ObjectMapper mapper) { + super(DataPlaneInstance.class, JsonObject.class); + this.jsonFactory = jsonFactory; + this.mapper = mapper; + } + + @Override + public @Nullable JsonObject transform(@NotNull DataPlaneInstance dataPlaneInstance, @NotNull TransformerContext context) { + var builder = jsonFactory.createObjectBuilder() + .add(ID, dataPlaneInstance.getId()) + .add(TYPE, DataPlaneInstance.DATAPLANE_INSTANCE_TYPE) + .add(URL, dataPlaneInstance.getUrl().toString()) + .add(LAST_ACTIVE, dataPlaneInstance.getLastActive()) + .add(TURN_COUNT, dataPlaneInstance.getTurnCount()); + + if (dataPlaneInstance.getProperties() != null && !dataPlaneInstance.getProperties().isEmpty()) { + var propBuilder = jsonFactory.createObjectBuilder(); + transformProperties(dataPlaneInstance.getProperties(), propBuilder, mapper, context); + builder.add(PROPERTIES, propBuilder); + } + + var srcBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedSourceTypes()); + builder.add(ALLOWED_SOURCE_TYPES, srcBldr); + + var dstBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedDestTypes()); + builder.add(ALLOWED_DEST_TYPES, dstBldr); + + var transferTypesBldr = jsonFactory.createArrayBuilder(dataPlaneInstance.getAllowedTransferTypes()); + builder.add(ALLOWED_TRANSFER_TYPES, transferTypesBldr); + + var state = Optional.ofNullable(DataPlaneInstanceStates.from(dataPlaneInstance.getState())) + .map(Enum::name) + .orElse(null); + + addIfNotNull(state, DATAPLANE_INSTANCE_STATE, builder); + + builder.add(DATAPLANE_INSTANCE_STATE_TIMESTAMP, dataPlaneInstance.getStateTimestamp()); + + return builder.build(); + } +} diff --git a/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformerTest.java b/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformerTest.java index 4926563ab1d..024df40d781 100644 --- a/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformerTest.java +++ b/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceTransformerTest.java @@ -24,14 +24,12 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE_TIMESTAMP; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.LAST_ACTIVE; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.PROPERTIES; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.TURN_COUNT; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstanceStates.AVAILABLE; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; @@ -54,10 +52,8 @@ void transform() { .id("test-id") .url("http://foo.bar") .allowedSourceType("test-source-type") - .allowedDestType("test-dest-type") .allowedTransferType("test-transfer-type") .lastActive(15) - .turnCount(42) .property("foo", "bar") .build(); @@ -67,10 +63,8 @@ void transform() { assertThat(jsonObject.getString(ID)).isEqualTo("test-id"); assertThat(jsonObject.getString(URL)).isEqualTo("http://foo.bar"); assertThat(jsonObject.getJsonArray(ALLOWED_SOURCE_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-source-type")); - assertThat(jsonObject.getJsonArray(ALLOWED_DEST_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-dest-type")); assertThat(jsonObject.getJsonArray(ALLOWED_TRANSFER_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-transfer-type")); assertThat(jsonObject.getJsonNumber(LAST_ACTIVE).intValue()).isEqualTo(15); - assertThat(jsonObject.getJsonNumber(TURN_COUNT).intValue()).isEqualTo(42); assertThat(jsonObject.getJsonObject(PROPERTIES).getJsonString("foo").getString()).isEqualTo("bar"); } @@ -81,10 +75,8 @@ void transform_withState() { .id("test-id") .url("http://foo.bar") .allowedSourceType("test-source-type") - .allowedDestType("test-dest-type") .allowedTransferType("test-transfer-type") .lastActive(15) - .turnCount(42) .state(AVAILABLE.code()) .property("foo", "bar") .build(); @@ -95,10 +87,8 @@ void transform_withState() { assertThat(jsonObject.getString(ID)).isEqualTo("test-id"); assertThat(jsonObject.getString(URL)).isEqualTo("http://foo.bar"); assertThat(jsonObject.getJsonArray(ALLOWED_SOURCE_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-source-type")); - assertThat(jsonObject.getJsonArray(ALLOWED_DEST_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-dest-type")); assertThat(jsonObject.getJsonArray(ALLOWED_TRANSFER_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-transfer-type")); assertThat(jsonObject.getJsonNumber(LAST_ACTIVE).intValue()).isEqualTo(15); - assertThat(jsonObject.getJsonNumber(TURN_COUNT).intValue()).isEqualTo(42); assertThat(jsonObject.getString(DATAPLANE_INSTANCE_STATE)).isEqualTo(AVAILABLE.name()); assertThat(jsonObject.getJsonNumber(DATAPLANE_INSTANCE_STATE_TIMESTAMP).longValue()).isEqualTo(dpi.getStateTimestamp()); assertThat(jsonObject.getJsonObject(PROPERTIES).getJsonString("foo").getString()).isEqualTo("bar"); diff --git a/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3TransformerTest.java b/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3TransformerTest.java new file mode 100644 index 00000000000..12cf9327921 --- /dev/null +++ b/core/common/lib/transform-lib/src/test/java/org/eclipse/edc/transform/transformer/edc/from/JsonObjectFromDataPlaneInstanceV3TransformerTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.transform.transformer.edc.from; + +import jakarta.json.Json; +import jakarta.json.JsonString; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.transform.spi.TransformerContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_STATE_TIMESTAMP; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.LAST_ACTIVE; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.PROPERTIES; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.TURN_COUNT; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstanceStates.AVAILABLE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.util.JacksonJsonLd.createObjectMapper; +import static org.mockito.Mockito.mock; + +class JsonObjectFromDataPlaneInstanceV3TransformerTest { + + private final TransformerContext context = mock(); + private JsonObjectFromDataPlaneInstanceV3Transformer transformer; + + @BeforeEach + void setUp() { + transformer = new JsonObjectFromDataPlaneInstanceV3Transformer(Json.createBuilderFactory(Map.of()), createObjectMapper()); + } + + @Test + void transform() { + var dpi = DataPlaneInstance.Builder.newInstance() + .id("test-id") + .url("http://foo.bar") + .allowedSourceType("test-source-type") + .allowedDestType("test-dest-type") + .allowedTransferType("test-transfer-type") + .lastActive(15) + .turnCount(42) + .property("foo", "bar") + .build(); + + var jsonObject = transformer.transform(dpi, context); + + assertThat(jsonObject).isNotNull(); + assertThat(jsonObject.getString(ID)).isEqualTo("test-id"); + assertThat(jsonObject.getString(URL)).isEqualTo("http://foo.bar"); + assertThat(jsonObject.getJsonArray(ALLOWED_SOURCE_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-source-type")); + assertThat(jsonObject.getJsonArray(ALLOWED_DEST_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-dest-type")); + assertThat(jsonObject.getJsonArray(ALLOWED_TRANSFER_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-transfer-type")); + assertThat(jsonObject.getJsonNumber(LAST_ACTIVE).intValue()).isEqualTo(15); + assertThat(jsonObject.getJsonNumber(TURN_COUNT).intValue()).isEqualTo(42); + assertThat(jsonObject.getJsonObject(PROPERTIES).getJsonString("foo").getString()).isEqualTo("bar"); + + } + + @Test + void transform_withState() { + var dpi = DataPlaneInstance.Builder.newInstance() + .id("test-id") + .url("http://foo.bar") + .allowedSourceType("test-source-type") + .allowedDestType("test-dest-type") + .allowedTransferType("test-transfer-type") + .lastActive(15) + .turnCount(42) + .state(AVAILABLE.code()) + .property("foo", "bar") + .build(); + + var jsonObject = transformer.transform(dpi, context); + + assertThat(jsonObject).isNotNull(); + assertThat(jsonObject.getString(ID)).isEqualTo("test-id"); + assertThat(jsonObject.getString(URL)).isEqualTo("http://foo.bar"); + assertThat(jsonObject.getJsonArray(ALLOWED_SOURCE_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-source-type")); + assertThat(jsonObject.getJsonArray(ALLOWED_DEST_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-dest-type")); + assertThat(jsonObject.getJsonArray(ALLOWED_TRANSFER_TYPES)).hasSize(1).allMatch(v -> ((JsonString) v).getString().equals("test-transfer-type")); + assertThat(jsonObject.getJsonNumber(LAST_ACTIVE).intValue()).isEqualTo(15); + assertThat(jsonObject.getJsonNumber(TURN_COUNT).intValue()).isEqualTo(42); + assertThat(jsonObject.getString(DATAPLANE_INSTANCE_STATE)).isEqualTo(AVAILABLE.name()); + assertThat(jsonObject.getJsonNumber(DATAPLANE_INSTANCE_STATE_TIMESTAMP).longValue()).isEqualTo(dpi.getStateTimestamp()); + assertThat(jsonObject.getJsonObject(PROPERTIES).getJsonString("foo").getString()).isEqualTo("bar"); + + } +} diff --git a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json index 1389c995fd1..7a8bf93746d 100644 --- a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json +++ b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json @@ -1,8 +1,8 @@ [ { - "version": "3.0.4", + "version": "3.0.5", "urlPath": "/v3", - "lastUpdated": "2024-12-19T10:14:00Z", + "lastUpdated": "2025-01-08T14:26:00Z", "maturity": "stable" }, { @@ -14,7 +14,7 @@ { "version": "4.0.0-alpha", "urlPath": "/v4alpha", - "lastUpdated": "2024-12-04T14:24:00Z", + "lastUpdated": "2025-01-08T14:26:00Z", "maturity": "alpha" } ] diff --git a/extensions/common/iam/oauth2/oauth2-service/README.md b/extensions/common/iam/oauth2/oauth2-service/README.md index 413d830858c..73a8f81c424 100644 --- a/extensions/common/iam/oauth2/oauth2-service/README.md +++ b/extensions/common/iam/oauth2/oauth2-service/README.md @@ -4,4 +4,4 @@ This BOM provides a ready-to-use version of the [Oauth2 IdentityService](../oaut provided by the EDC. > **_NOTE:_** Unless you are sure of what you are doing, you do not want to implement your own Oauth2 Client in most cases. -> This BOM should thus be considered as the standard and recommended approach of embedding the Oauth2 Identity Service into your runtime. \ No newline at end of file +> This BOM should thus be considered as the standard and recommended approach of embedding the Oauth2 Identity Service into your runtime. diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtension.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtension.java index 310925f8b6b..665cd35393d 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtension.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/DataPlaneSelectorApiExtension.java @@ -16,9 +16,9 @@ import org.eclipse.edc.connector.dataplane.selector.api.v2.DataplaneSelectorApiV2Controller; import org.eclipse.edc.connector.dataplane.selector.api.v3.DataplaneSelectorApiV3Controller; +import org.eclipse.edc.connector.dataplane.selector.api.v4.DataplaneSelectorApiV4Controller; import org.eclipse.edc.connector.dataplane.selector.api.validation.DataPlaneInstanceValidator; 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.JsonObjectToSelectionRequestTransformer; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.transform.transformer.edc.from.JsonObjectFromDataPlaneInstanceTransformer; +import org.eclipse.edc.transform.transformer.edc.from.JsonObjectFromDataPlaneInstanceV3Transformer; import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToDataPlaneInstanceTransformer; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; import org.eclipse.edc.web.spi.WebService; @@ -62,15 +63,23 @@ public class DataPlaneSelectorApiExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - typeManager.registerTypes(DataPlaneInstance.class); var managementApiTransformerRegistry = transformerRegistry.forContext("management-api"); - validatorRegistry.register(DATAPLANE_INSTANCE_TYPE, DataPlaneInstanceValidator.instance()); - managementApiTransformerRegistry.register(new JsonObjectToSelectionRequestTransformer()); - managementApiTransformerRegistry.register(new JsonObjectToDataPlaneInstanceTransformer()); + // V4 managementApiTransformerRegistry.register(new JsonObjectFromDataPlaneInstanceTransformer(createBuilderFactory(Map.of()), typeManager.getMapper(JSON_LD))); + webservice.registerResource(ApiContext.MANAGEMENT, new DataplaneSelectorApiV4Controller(selectionService, managementApiTransformerRegistry)); + + // V3 + var managementApiTransformerRegistryV3 = managementApiTransformerRegistry.forContext("v3"); + managementApiTransformerRegistryV3.register(new JsonObjectFromDataPlaneInstanceV3Transformer(createBuilderFactory(Map.of()), typeManager.getMapper(JSON_LD))); + webservice.registerResource(ApiContext.MANAGEMENT, new DataplaneSelectorApiV3Controller(selectionService, managementApiTransformerRegistryV3)); - webservice.registerResource(ApiContext.MANAGEMENT, new DataplaneSelectorApiV2Controller(selectionService, managementApiTransformerRegistry, validatorRegistry, clock)); - webservice.registerResource(ApiContext.MANAGEMENT, new DataplaneSelectorApiV3Controller(selectionService, managementApiTransformerRegistry)); + // V2 + validatorRegistry.register(DATAPLANE_INSTANCE_TYPE, DataPlaneInstanceValidator.instance()); + var managementApiTransformerRegistryV2 = managementApiTransformerRegistry.forContext("v2"); + managementApiTransformerRegistryV2.register(new JsonObjectToSelectionRequestTransformer()); + managementApiTransformerRegistryV2.register(new JsonObjectToDataPlaneInstanceTransformer()); + managementApiTransformerRegistryV2.register(new JsonObjectFromDataPlaneInstanceV3Transformer(createBuilderFactory(Map.of()), typeManager.getMapper(JSON_LD))); + webservice.registerResource(ApiContext.MANAGEMENT, new DataplaneSelectorApiV2Controller(selectionService, managementApiTransformerRegistryV2, validatorRegistry, clock, context.getMonitor())); } } diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/DataPlaneInstanceSchema.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataPlaneInstanceSchemaV2.java similarity index 92% rename from extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/DataPlaneInstanceSchema.java rename to extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataPlaneInstanceSchemaV2.java index e18dfc2f9a7..e378d86d0ae 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/DataPlaneInstanceSchema.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataPlaneInstanceSchemaV2.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.connector.dataplane.selector.api.schemas; +package org.eclipse.edc.connector.dataplane.selector.api.v2; import io.swagger.v3.oas.annotations.media.Schema; @@ -25,8 +25,8 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; -@Schema(example = DataPlaneInstanceSchema.DATAPLANE_INSTANCE_EXAMPLE) -public record DataPlaneInstanceSchema( +@Schema(example = DataPlaneInstanceSchemaV2.DATAPLANE_INSTANCE_EXAMPLE) +public record DataPlaneInstanceSchemaV2( @Schema(name = CONTEXT, requiredMode = REQUIRED) Object context, @Schema(name = TYPE, example = DATAPLANE_INSTANCE_TYPE) diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2.java index d38a696d946..405eb269b56 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2.java @@ -28,8 +28,6 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import org.eclipse.edc.api.model.ApiCoreSchema; -import org.eclipse.edc.connector.dataplane.selector.api.schemas.DataPlaneInstanceSchema; -import org.eclipse.edc.connector.dataplane.selector.api.schemas.SelectionRequestSchema; @OpenAPIDefinition(info = @Info(version = "v2")) @Tag(name = "Dataplane Selector V2") @@ -41,7 +39,7 @@ public interface DataplaneSelectorApiV2 { requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = SelectionRequestSchema.class))), responses = { @ApiResponse(responseCode = "200", description = "The DataPlane instance that fits best for the given selection request", - content = @Content(schema = @Schema(implementation = DataPlaneInstanceSchema.class))), + content = @Content(schema = @Schema(implementation = DataPlaneInstanceSchemaV2.class))), @ApiResponse(responseCode = "204", description = "No suitable DataPlane instance was found"), @ApiResponse(responseCode = "400", description = "Request body was malformed", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) @@ -52,7 +50,7 @@ public interface DataplaneSelectorApiV2 { @Operation(method = "POST", description = "Adds one dataplane instance to the internal database of the selector. DEPRECATED: dataplanes should register themselves through control-api", - requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = DataPlaneInstanceSchema.class))), + requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = DataPlaneInstanceSchemaV2.class))), responses = { @ApiResponse(responseCode = "200", description = "Entry was added successfully to the database", content = @Content(schema = @Schema(implementation = ApiCoreSchema.IdResponseSchema.class))), @ApiResponse(responseCode = "400", description = "Request body was malformed", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) @@ -66,7 +64,7 @@ public interface DataplaneSelectorApiV2 { description = "Returns a list of all currently registered data plane instances", responses = { @ApiResponse(responseCode = "200", description = "A (potentially empty) list of currently registered data plane instances", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataPlaneInstanceSchema.class)))) + content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataPlaneInstanceSchemaV2.class)))) }, deprecated = true ) diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2Controller.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2Controller.java index 4afcb0a6d62..418f9d6f844 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2Controller.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/DataplaneSelectorApiV2Controller.java @@ -27,6 +27,7 @@ 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.monitor.Monitor; import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; @@ -36,6 +37,7 @@ import java.time.Clock; import static jakarta.json.stream.JsonCollectors.toJsonArray; +import static org.eclipse.edc.api.ApiWarnings.deprecationWarning; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_TYPE; import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; @@ -50,18 +52,22 @@ public class DataplaneSelectorApiV2Controller implements DataplaneSelectorApiV2 private final JsonObjectValidatorRegistry validatorRegistry; private final Clock clock; + private final Monitor monitor; - public DataplaneSelectorApiV2Controller(DataPlaneSelectorService selectionService, TypeTransformerRegistry transformerRegistry, JsonObjectValidatorRegistry validatorRegistry, Clock clock) { + public DataplaneSelectorApiV2Controller(DataPlaneSelectorService selectionService, TypeTransformerRegistry transformerRegistry, + JsonObjectValidatorRegistry validatorRegistry, Clock clock, Monitor monitor) { this.selectionService = selectionService; this.transformerRegistry = transformerRegistry; this.validatorRegistry = validatorRegistry; this.clock = clock; + this.monitor = monitor; } @Override @POST @Path("select") public JsonObject selectDataPlaneInstanceV2(JsonObject requestObject) { + monitor.warning(deprecationWarning("/v2", "/v3")); var request = transformerRegistry.transform(requestObject, SelectionRequest.class) .orElseThrow(InvalidRequestException::new); @@ -77,6 +83,7 @@ public JsonObject selectDataPlaneInstanceV2(JsonObject requestObject) { @Override @POST public JsonObject addDataPlaneInstanceV2(JsonObject jsonObject) { + monitor.warning(deprecationWarning("/v2", "/v3")); validatorRegistry.validate(DATAPLANE_INSTANCE_TYPE, jsonObject).orElseThrow(ValidationFailureException::new); var instance = transformerRegistry.transform(jsonObject, DataPlaneInstance.class) @@ -97,6 +104,7 @@ public JsonObject addDataPlaneInstanceV2(JsonObject jsonObject) { @Override @GET public JsonArray getAllDataPlaneInstancesV2() { + monitor.warning(deprecationWarning("/v2", "/v3")); var instances = selectionService.getAll().orElseThrow(exceptionMapper(DataPlaneInstance.class)); return instances.stream() .map(i -> transformerRegistry.transform(i, JsonObject.class)) diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/SelectionRequestSchema.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/SelectionRequestSchema.java similarity index 96% rename from extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/SelectionRequestSchema.java rename to extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/SelectionRequestSchema.java index 67a56b5a5be..e6b113af82c 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/schemas/SelectionRequestSchema.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v2/SelectionRequestSchema.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.connector.dataplane.selector.api.schemas; +package org.eclipse.edc.connector.dataplane.selector.api.v2; import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.edc.api.model.ApiCoreSchema; diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneInstanceSchemaV3.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneInstanceSchemaV3.java new file mode 100644 index 00000000000..e56311708c6 --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneInstanceSchemaV3.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v3; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.net.URL; +import java.util.Set; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; + +@Schema(example = DataPlaneInstanceSchemaV3.DATAPLANE_INSTANCE_EXAMPLE) +public record DataPlaneInstanceSchemaV3( + @Schema(name = CONTEXT, requiredMode = REQUIRED) + Object context, + @Schema(name = TYPE, example = DATAPLANE_INSTANCE_TYPE) + String type, + @Schema(name = ID) + String id, + @Schema(requiredMode = REQUIRED) + URL url, + @Schema(requiredMode = REQUIRED) + Set allowedSourceTypes, + @Schema(requiredMode = REQUIRED, deprecated = true) + Set allowedDestTypes, + @Schema(deprecated = true) + Integer turnCount, + Long lastActive, + String state, + Long stateTimestamp) { + public static final String DATAPLANE_INSTANCE_EXAMPLE = """ + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "your-dataplane-id", + "url": "http://somewhere.com:1234/api/v1", + "allowedSourceTypes": [ + "source-type1", + "source-type2" + ], + "allowedDestTypes": ["your-dest-type"], + "allowedTransferTypes": ["transfer-type"], + "state": "AVAILABLE", + "stateTimestamp": 1688465655 + } + """; +} diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataplaneSelectorApiV3.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataplaneSelectorApiV3.java index 1ad8e9f5cc5..e79a0036a84 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataplaneSelectorApiV3.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataplaneSelectorApiV3.java @@ -24,7 +24,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.json.JsonArray; import jakarta.ws.rs.GET; -import org.eclipse.edc.connector.dataplane.selector.api.schemas.DataPlaneInstanceSchema; @OpenAPIDefinition(info = @Info(version = "v3")) @Tag(name = "Dataplane Selector V3") @@ -34,7 +33,7 @@ public interface DataplaneSelectorApiV3 { description = "Returns a list of all currently registered data plane instances", responses = { @ApiResponse(responseCode = "200", description = "A (potentially empty) list of currently registered data plane instances", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataPlaneInstanceSchema.class)))) + content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataPlaneInstanceSchemaV3.class)))) } ) @GET diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneInstanceSchemaV4.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneInstanceSchemaV4.java new file mode 100644 index 00000000000..bfb0307ffa0 --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneInstanceSchemaV4.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v4; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.net.URL; +import java.util.Set; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; +import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.DATAPLANE_INSTANCE_TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; + +@Schema(example = DataPlaneInstanceSchemaV4.DATAPLANE_INSTANCE_EXAMPLE) +public record DataPlaneInstanceSchemaV4( + @Schema(name = CONTEXT, requiredMode = REQUIRED) + Object context, + @Schema(name = TYPE, example = DATAPLANE_INSTANCE_TYPE) + String type, + @Schema(name = ID) + String id, + @Schema(requiredMode = REQUIRED) + URL url, + @Schema(requiredMode = REQUIRED) + Set allowedSourceTypes, + Long lastActive, + String state, + Long stateTimestamp) { + public static final String DATAPLANE_INSTANCE_EXAMPLE = """ + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "your-dataplane-id", + "url": "http://somewhere.com:1234/api/v1", + "allowedSourceTypes": [ + "source-type1", + "source-type2" + ], + "allowedTransferTypes": ["transfer-type"], + "state": "AVAILABLE", + "stateTimestamp": 1688465655 + } + """; +} diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4.java new file mode 100644 index 00000000000..851ef1241e7 --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v4; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.json.JsonArray; +import jakarta.ws.rs.GET; + +@OpenAPIDefinition(info = @Info(version = "v4")) +@Tag(name = "Dataplane Selector V4") +public interface DataplaneSelectorApiV4 { + + @Operation(method = "GET", + description = "Returns a list of all currently registered data plane instances", + responses = { + @ApiResponse(responseCode = "200", description = "A (potentially empty) list of currently registered data plane instances", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = DataPlaneInstanceSchemaV4.class)))) + } + ) + @GET + JsonArray getAllDataPlaneInstancesV4(); + +} diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4Controller.java b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4Controller.java new file mode 100644 index 00000000000..341de15550a --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataplaneSelectorApiV4Controller.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v4; + +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; + +import static jakarta.json.stream.JsonCollectors.toJsonArray; +import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; + +@Consumes({ MediaType.APPLICATION_JSON }) +@Produces({ MediaType.APPLICATION_JSON }) +@Path("/v4alpha/dataplanes") +public class DataplaneSelectorApiV4Controller implements DataplaneSelectorApiV4 { + + private final DataPlaneSelectorService selectionService; + private final TypeTransformerRegistry transformerRegistry; + + public DataplaneSelectorApiV4Controller(DataPlaneSelectorService selectionService, TypeTransformerRegistry transformerRegistry) { + this.selectionService = selectionService; + this.transformerRegistry = transformerRegistry; + } + + @Override + @GET + public JsonArray getAllDataPlaneInstancesV4() { + var instances = selectionService.getAll().orElseThrow(exceptionMapper(DataPlaneInstance.class)); + return instances.stream() + .map(i -> transformerRegistry.transform(i, JsonObject.class)) + .filter(Result::succeeded) + .map(Result::getContent) + .collect(toJsonArray()); + } + +} 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 9f066a48bb4..65ff480f565 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 @@ -20,9 +20,6 @@ import org.eclipse.edc.connector.dataplane.selector.api.v3.DataplaneSelectorApiV3Controller; 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; -import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToSelectionRequestTransformer; import org.eclipse.edc.json.JacksonTypeManager; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.monitor.Monitor; @@ -33,7 +30,6 @@ import org.eclipse.edc.transaction.spi.NoopTransactionContext; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.transform.transformer.edc.from.JsonObjectFromDataPlaneInstanceTransformer; -import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToDataPlaneInstanceTransformer; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; import org.jetbrains.annotations.NotNull; @@ -43,6 +39,7 @@ import java.util.Collections; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.mock; @@ -52,20 +49,21 @@ @ExtendWith(DependencyInjectionExtension.class) class DataPlaneSelectorApiExtensionTest { - private final WebService webService = mock(WebService.class); - private final Monitor monitor = mock(Monitor.class); - private final TypeTransformerRegistry transformerRegistry = mock(); + private final WebService webService = mock(); + private final Monitor monitor = mock(); + private final TypeTransformerRegistry managementApiTransformerRegistry = mock(); private DataPlaneSelectorApiExtension extension; @BeforeEach void setUp(ServiceExtensionContext context, ObjectFactory factory) { context.registerService(TypeManager.class, new JacksonTypeManager()); context.registerService(WebService.class, webService); - context.registerService(DataPlaneSelectorService.class, new EmbeddedDataPlaneSelectorService( - mock(DataPlaneInstanceStore.class), mock(SelectionStrategyRegistry.class), new NoopTransactionContext())); + context.registerService(DataPlaneSelectorService.class, new EmbeddedDataPlaneSelectorService(mock(), mock(), + new NoopTransactionContext())); TypeTransformerRegistry parentTransformerRegistry = mock(); - when(parentTransformerRegistry.forContext("management-api")).thenReturn(transformerRegistry); + when(parentTransformerRegistry.forContext("management-api")).thenReturn(managementApiTransformerRegistry); + when(managementApiTransformerRegistry.forContext(any())).thenReturn(mock()); context.registerService(TypeTransformerRegistry.class, parentTransformerRegistry); extension = factory.constructInstance(DataPlaneSelectorApiExtension.class); } @@ -75,10 +73,9 @@ void shouldRegisterManagementContext() { var config = ConfigFactory.fromMap(Collections.emptyMap()); extension.initialize(contextWithConfig(config)); + verify(webService).registerResource(eq(ApiContext.MANAGEMENT), isA(DataplaneSelectorApiV2Controller.class)); - verify(transformerRegistry).register(isA(JsonObjectFromDataPlaneInstanceTransformer.class)); - verify(transformerRegistry).register(isA(JsonObjectToDataPlaneInstanceTransformer.class)); - verify(transformerRegistry).register(isA(JsonObjectToSelectionRequestTransformer.class)); + verify(managementApiTransformerRegistry).register(isA(JsonObjectFromDataPlaneInstanceTransformer.class)); } @Test diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/DataPlaneApiSelectorTest.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneApiSelectorV3Test.java similarity index 71% rename from extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/DataPlaneApiSelectorTest.java rename to extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneApiSelectorV3Test.java index 1614d846cae..1500c793af2 100644 --- a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/DataPlaneApiSelectorTest.java +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v3/DataPlaneApiSelectorV3Test.java @@ -12,12 +12,11 @@ * */ -package org.eclipse.edc.connector.dataplane.selector.api; +package org.eclipse.edc.connector.dataplane.selector.api.v3; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.JsonObject; -import org.eclipse.edc.connector.dataplane.selector.api.model.SelectionRequest; import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToSelectionRequestTransformer; import org.eclipse.edc.jsonld.TitaniumJsonLd; @@ -33,11 +32,10 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.api.schemas.DataPlaneInstanceSchema.DATAPLANE_INSTANCE_EXAMPLE; -import static org.eclipse.edc.connector.dataplane.selector.api.schemas.SelectionRequestSchema.SELECTION_REQUEST_INPUT_EXAMPLE; +import static org.eclipse.edc.connector.dataplane.selector.api.v3.DataPlaneInstanceSchemaV3.DATAPLANE_INSTANCE_EXAMPLE; import static org.mockito.Mockito.mock; -public class DataPlaneApiSelectorTest { +public class DataPlaneApiSelectorV3Test { private final ObjectMapper objectMapper = JacksonJsonLd.createObjectMapper(); private final JsonLd jsonLd = new TitaniumJsonLd(mock()); @@ -70,22 +68,4 @@ void dataPlaneInstanceInputExample() throws JsonProcessingException { }); } - @Test - void selectionRequestInputExample() throws JsonProcessingException { - - var jsonObject = objectMapper.readValue(SELECTION_REQUEST_INPUT_EXAMPLE, JsonObject.class); - assertThat(jsonObject).isNotNull(); - - var expanded = jsonLd.expand(jsonObject); - AbstractResultAssert.assertThat(expanded).isSucceeded() - .extracting(e -> transformer.transform(e, SelectionRequest.class).getContent()) - .isNotNull() - .satisfies(transformed -> { - assertThat(transformed.getStrategy()).isNotBlank(); - assertThat(transformed.getDestination()).isNotNull(); - assertThat(transformed.getSource()).isNotNull(); - assertThat(transformed.getTransferType()).isNotNull(); - }); - } - } diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneApiSelectorV4Test.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneApiSelectorV4Test.java new file mode 100644 index 00000000000..2914906f7d3 --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneApiSelectorV4Test.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v4; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.connector.dataplane.selector.transformer.JsonObjectToSelectionRequestTransformer; +import org.eclipse.edc.jsonld.TitaniumJsonLd; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.jsonld.util.JacksonJsonLd; +import org.eclipse.edc.junit.assertions.AbstractResultAssert; +import org.eclipse.edc.transform.TypeTransformerRegistryImpl; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToDataAddressTransformer; +import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToDataPlaneInstanceTransformer; +import org.eclipse.edc.transform.transformer.edc.to.JsonValueToGenericTypeTransformer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.connector.dataplane.selector.api.v4.DataPlaneInstanceSchemaV4.DATAPLANE_INSTANCE_EXAMPLE; +import static org.mockito.Mockito.mock; + +public class DataPlaneApiSelectorV4Test { + + private final ObjectMapper objectMapper = JacksonJsonLd.createObjectMapper(); + private final JsonLd jsonLd = new TitaniumJsonLd(mock()); + private final TypeTransformerRegistry transformer = new TypeTransformerRegistryImpl(); + + @BeforeEach + void setUp() { + transformer.register(new JsonObjectToDataPlaneInstanceTransformer()); + transformer.register(new JsonObjectToSelectionRequestTransformer()); + transformer.register(new JsonObjectToDataAddressTransformer()); + transformer.register(new JsonValueToGenericTypeTransformer(objectMapper)); + } + + @Test + void dataPlaneInstanceInputExample() throws JsonProcessingException { + + var jsonObject = objectMapper.readValue(DATAPLANE_INSTANCE_EXAMPLE, JsonObject.class); + assertThat(jsonObject).isNotNull(); + + var expanded = jsonLd.expand(jsonObject); + AbstractResultAssert.assertThat(expanded).isSucceeded() + .extracting(e -> transformer.transform(e, DataPlaneInstance.class).getContent()) + .isNotNull() + .satisfies(transformed -> { + assertThat(transformed.getId()).isNotBlank(); + assertThat(transformed.getUrl().toString()).isEqualTo("http://somewhere.com:1234/api/v1"); + assertThat(transformed.getAllowedSourceTypes()).containsExactlyInAnyOrder("source-type1", "source-type2"); + assertThat(transformed.getAllowedTransferTypes()).containsExactlyInAnyOrder("transfer-type"); + }); + } + + +} diff --git a/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneSelectorApiV4ControllerTest.java b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneSelectorApiV4ControllerTest.java new file mode 100644 index 00000000000..4cb2b39957d --- /dev/null +++ b/extensions/data-plane-selector/data-plane-selector-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/api/v4/DataPlaneSelectorApiV4ControllerTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.connector.dataplane.selector.api.v4; + +import io.restassured.specification.RequestSpecification; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.junit.annotations.ApiTest; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static io.restassured.RestAssured.given; +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.connector.dataplane.selector.TestFunctions.createInstance; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@ApiTest +public class DataPlaneSelectorApiV4ControllerTest extends RestControllerTestBase { + + private final DataPlaneSelectorService selectionService = mock(); + private final TypeTransformerRegistry transformerRegistry = mock(); + + @Test + void getAll() { + var list = List.of(createInstance("test-id1"), createInstance("test-id2"), createInstance("test-id3")); + when(selectionService.getAll()).thenReturn(ServiceResult.success(list)); + when(transformerRegistry.transform(isA(DataPlaneInstance.class), eq(JsonObject.class))) + .thenAnswer(i -> Result.success(jsonInstance(i.getArgument(0, DataPlaneInstance.class).getId()))); + + var array = baseRequest() + .get() + .then() + .log().ifValidationFails() + .statusCode(200) + .extract().body().as(JsonArray.class); + + assertThat(array).hasSize(3) + .allSatisfy(jo -> assertThat(jo.asJsonObject().getString(ID)) + .isIn("test-id1", "test-id2", "test-id3")); + } + + @Test + void getAll_noneExist() { + when(selectionService.getAll()).thenReturn(ServiceResult.success(emptyList())); + + var array = baseRequest() + .get() + .then() + .log().ifValidationFails() + .statusCode(200) + .extract().body().as(JsonArray.class); + + assertThat(array).isNotNull().isEmpty(); + } + + protected RequestSpecification baseRequest() { + return given() + .port(port) + .basePath("/v4alpha/dataplanes") + .when(); + } + + private JsonObject jsonInstance(String id) { + return Json.createObjectBuilder().add(ID, id).build(); + } + + @Override + protected Object controller() { + return new DataplaneSelectorApiV4Controller(selectionService, transformerRegistry); + } +} diff --git a/extensions/data-plane-selector/data-plane-selector-control-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidator.java b/extensions/data-plane-selector/data-plane-selector-control-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidator.java index 70f21c4b129..81a7a9a1d80 100644 --- a/extensions/data-plane-selector/data-plane-selector-control-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidator.java +++ b/extensions/data-plane-selector/data-plane-selector-control-api/src/main/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidator.java @@ -21,7 +21,6 @@ import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; import org.eclipse.edc.validator.spi.Validator; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; @@ -36,7 +35,6 @@ public static Validator instance() { .verifyId(MandatoryIdNotBlank::new) .verify(URL, MandatoryValue::new) .verify(ALLOWED_SOURCE_TYPES, MandatoryArray.min(1)) - .verify(ALLOWED_DEST_TYPES, MandatoryArray.min(1)) .verify(ALLOWED_TRANSFER_TYPES, MandatoryArray.min(1)) .build(); } diff --git a/extensions/data-plane-selector/data-plane-selector-control-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidatorTest.java b/extensions/data-plane-selector/data-plane-selector-control-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidatorTest.java index 43175a499fd..eb1ca1fdf7d 100644 --- a/extensions/data-plane-selector/data-plane-selector-control-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidatorTest.java +++ b/extensions/data-plane-selector/data-plane-selector-control-api/src/test/java/org/eclipse/edc/connector/dataplane/selector/control/api/DataPlaneInstanceValidatorTest.java @@ -25,7 +25,6 @@ import static jakarta.json.Json.createArrayBuilder; import static jakarta.json.Json.createObjectBuilder; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_DEST_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_SOURCE_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.ALLOWED_TRANSFER_TYPES; import static org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance.URL; @@ -43,7 +42,6 @@ void shouldPass_whenJsonIsValid() { .add(ID, "id") .add(URL, value("url")) .add(ALLOWED_SOURCE_TYPES, createArrayBuilder().add(value("src"))) - .add(ALLOWED_DEST_TYPES, createArrayBuilder().add(value("dest"))) .add(ALLOWED_TRANSFER_TYPES, createArrayBuilder().add(value("transfer"))) .build(); @@ -63,7 +61,6 @@ void shouldFail_whenMandatoryFieldsAreNotSet() { .anySatisfy(v -> assertThat(v.path()).isEqualTo(ID)) .anySatisfy(v -> assertThat(v.path()).isEqualTo(URL)) .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_SOURCE_TYPES)) - .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_DEST_TYPES)) .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_TRANSFER_TYPES)); } @@ -71,7 +68,6 @@ void shouldFail_whenMandatoryFieldsAreNotSet() { void shouldFail_whenAllowedTypesAreEmpty() { var json = createObjectBuilder() .add(ALLOWED_SOURCE_TYPES, createArrayBuilder()) - .add(ALLOWED_DEST_TYPES, createArrayBuilder()) .add(ALLOWED_TRANSFER_TYPES, createArrayBuilder()) .build(); @@ -80,7 +76,6 @@ void shouldFail_whenAllowedTypesAreEmpty() { assertThat(result).isFailed().extracting(ValidationFailure::getViolations, InstanceOfAssertFactories.list(Violation.class)) .isNotEmpty() .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_SOURCE_TYPES)) - .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_DEST_TYPES)) .anySatisfy(v -> assertThat(v.path()).isEqualTo(ALLOWED_TRANSFER_TYPES)); } diff --git a/extensions/data-plane/data-plane-self-registration/src/main/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtension.java b/extensions/data-plane/data-plane-self-registration/src/main/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtension.java index 300465fb841..8e291a81ea4 100644 --- a/extensions/data-plane/data-plane-self-registration/src/main/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtension.java +++ b/extensions/data-plane/data-plane-self-registration/src/main/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtension.java @@ -87,7 +87,6 @@ public void start() { .id(context.getComponentId()) .url(controlApiUrl.get().toString() + "/v1/dataflows") .allowedSourceTypes(pipelineService.supportedSourceTypes()) - .allowedDestTypes(pipelineService.supportedSinkTypes()) .allowedTransferType(transferTypes.collect(toSet())) .build(); @@ -118,7 +117,7 @@ public void shutdown() { } private @NotNull Stream toTransferTypes(FlowType pull, Set types, Set responseTypes) { - Stream transferTypes = types.stream().map(it -> "%s-%s".formatted(it, pull)); + var transferTypes = types.stream().map(it -> "%s-%s".formatted(it, pull)); return Stream.concat(transferTypes, responseTypes.stream().flatMap(responseType -> types.stream().map(it -> "%s-%s/%s".formatted(it, pull, responseType)))); } diff --git a/extensions/data-plane/data-plane-self-registration/src/test/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtensionTest.java b/extensions/data-plane/data-plane-self-registration/src/test/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtensionTest.java index a00b25888df..f4f4e662044 100644 --- a/extensions/data-plane/data-plane-self-registration/src/test/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtensionTest.java +++ b/extensions/data-plane/data-plane-self-registration/src/test/java/org/eclipse/edc/connector/dataplane/registration/DataplaneSelfRegistrationExtensionTest.java @@ -86,7 +86,6 @@ void shouldRegisterInstanceAtStartup(DataplaneSelfRegistrationExtension extensio assertThat(dataPlaneInstance.getId()).isEqualTo("componentId"); assertThat(dataPlaneInstance.getUrl()).isEqualTo(new URL("http://control/api/url/v1/dataflows")); assertThat(dataPlaneInstance.getAllowedSourceTypes()).containsExactlyInAnyOrder("sourceType", "anotherSourceType"); - assertThat(dataPlaneInstance.getAllowedDestTypes()).containsExactlyInAnyOrder("sinkType", "anotherSinkType"); assertThat(dataPlaneInstance.getAllowedTransferTypes()) .containsExactlyInAnyOrder("pullDestType-PULL", "anotherPullDestType-PULL", "sinkType-PUSH", "anotherSinkType-PUSH"); diff --git a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/instance/DataPlaneInstance.java b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/instance/DataPlaneInstance.java index 79d94dd6ee1..c74897c8fae 100644 --- a/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/instance/DataPlaneInstance.java +++ b/spi/data-plane-selector/data-plane-selector-spi/src/main/java/org/eclipse/edc/connector/dataplane/selector/spi/instance/DataPlaneInstance.java @@ -179,6 +179,7 @@ public Builder allowedSourceType(String type) { return this; } + @Deprecated(since = "0.7.0") public Builder allowedDestType(String type) { entity.allowedDestTypes.add(type); return this; @@ -208,6 +209,7 @@ public Builder property(String key, Object value) { return this; } + @Deprecated(since = "0.7.0") public Builder allowedDestTypes(Set types) { entity.allowedDestTypes = types; return this; diff --git a/system-tests/management-api/management-api-test-runner/build.gradle.kts b/system-tests/management-api/management-api-test-runner/build.gradle.kts index 9ac353d78c8..2545ad85e70 100644 --- a/system-tests/management-api/management-api-test-runner/build.gradle.kts +++ b/system-tests/management-api/management-api-test-runner/build.gradle.kts @@ -50,6 +50,7 @@ dependencies { testImplementation(project(":extensions:control-plane:api:management-api:transfer-process-api")) testImplementation(project(":extensions:control-plane:api:management-api:secrets-api")) testImplementation(project(":extensions:control-plane:api:management-api:edr-cache-api")) + testImplementation(project(":extensions:data-plane-selector:data-plane-selector-api")) } edcBuild { diff --git a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/DataPlaneSelectorApiEndToEndTest.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/DataPlaneSelectorApiEndToEndTest.java new file mode 100644 index 00000000000..ff8dac297c6 --- /dev/null +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/DataPlaneSelectorApiEndToEndTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 Cofinity-X + * + * 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: + * Cofinity-X - initial API and implementation + * + */ + +package org.eclipse.edc.test.e2e.managementapi; + +import io.restassured.http.ContentType; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.connector.dataplane.selector.spi.store.DataPlaneInstanceStore; +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.annotations.PostgresqlIntegrationTest; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; + +public class DataPlaneSelectorApiEndToEndTest { + + @Nested + @EndToEndTest + @ExtendWith(ManagementEndToEndExtension.InMemory.class) + class InMemory extends Tests { + } + + @Nested + @PostgresqlIntegrationTest + @ExtendWith(ManagementEndToEndExtension.Postgres.class) + class Postgres extends Tests { + } + + private abstract static class Tests { + + @Test + void getAllDataPlaneInstancesV4(ManagementEndToEndTestContext context, DataPlaneInstanceStore store) { + var instance = DataPlaneInstance.Builder.newInstance().url("http://any").build(); + store.save(instance); + + context.baseRequest() + .get("/v4alpha/dataplanes") + .then() + .log().ifValidationFails() + .statusCode(200) + .contentType(ContentType.JSON) + .body("[0].url", equalTo(instance.getUrl().toString())) + .body("[0].allowedDestTypes", nullValue()) + .body("[0].turnCount", nullValue()); + } + + @Test + void getAllDataPlaneInstancesV3(ManagementEndToEndTestContext context, DataPlaneInstanceStore store) { + var instance = DataPlaneInstance.Builder.newInstance().url("http://any").build(); + store.save(instance); + + context.baseRequest() + .get("/v3/dataplanes") + .then() + .log().ifValidationFails() + .statusCode(200) + .contentType(ContentType.JSON) + .body("[0].url", equalTo(instance.getUrl().toString())) + .body("[0].allowedDestTypes", notNullValue()) + .body("[0].turnCount", notNullValue()); + } + } +}