-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add capability to register an embedded dataplane
- Loading branch information
Marco Primo
authored and
Marco Primo
committed
Feb 21, 2024
1 parent
34c3285
commit 05f5b59
Showing
6 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
39 changes: 39 additions & 0 deletions
39
extensions/data-plane/embedded-data-plane-registration/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright (c) 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 | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements | ||
* Mercedes-Benz Tech Innovation GmbH - publish public api context into dedicated swagger hub page | ||
* | ||
*/ | ||
|
||
|
||
plugins { | ||
`java-library` | ||
} | ||
|
||
dependencies { | ||
api(project(":spi:data-plane:data-plane-spi")) | ||
implementation(project(":core:common:util")) | ||
implementation(project(":spi:data-plane-selector:data-plane-selector-spi")) | ||
implementation(project(":core:data-plane:data-plane-util")) | ||
|
||
testImplementation(project(":core:common:junit")) | ||
testImplementation(project(":spi:data-plane:data-plane-spi")) | ||
|
||
|
||
|
||
implementation(libs.jakarta.rsApi) | ||
|
||
|
||
} | ||
|
||
|
||
|
10 changes: 10 additions & 0 deletions
10
...rg/eclipse/edc/connector/dataplane/embedded/autoregistration/EmbeddedDataPlaneConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.eclipse.edc.connector.dataplane.embedded.autoregistration; | ||
|
||
public class EmbeddedDataPlaneConfig { | ||
public static final String CONFIG_PREFIX = "edc.embedded.dataplane"; | ||
public static final String URL_SUFFIX = "url"; | ||
public static final String DESTINATION_TYPES_SUFFIX = "destinationtypes"; | ||
public static final String SOURCE_TYPES_SUFFIX = "sourcetypes"; | ||
public static final String PROPERTIES_SUFFIX = "properties"; | ||
public static final String PUBLIC_API_URL_PROPERTY = "publicApiUrl"; | ||
} |
137 changes: 137 additions & 0 deletions
137
...ipse/edc/connector/dataplane/embedded/autoregistration/EmbeddedDataPlaneRegistration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* Copyright (c) 2021 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 implementation | ||
* | ||
*/ | ||
package org.eclipse.edc.connector.dataplane.embedded.autoregistration; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
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.spi.manager.DataPlaneManager; | ||
import org.eclipse.edc.runtime.metamodel.annotation.Inject; | ||
import org.eclipse.edc.spi.EdcException; | ||
import org.eclipse.edc.spi.monitor.Monitor; | ||
import org.eclipse.edc.spi.system.ServiceExtension; | ||
import org.eclipse.edc.spi.system.ServiceExtensionContext; | ||
import org.eclipse.edc.spi.system.configuration.Config; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Predicate; | ||
import java.util.stream.Collectors; | ||
|
||
import static java.util.Objects.nonNull; | ||
|
||
public class EmbeddedDataPlaneRegistration implements ServiceExtension { | ||
|
||
private static final String NAME = "Embedded DataPlane Auto Registration"; | ||
private static final String COMMA = ","; | ||
private static final String LOG_MISSING_CONFIGURATION = NAME + ": Missing configuration for " + EmbeddedDataPlaneConfig.CONFIG_PREFIX + ".%s.%s"; | ||
private static final String LOG_SKIP_BC_MISSING_CONFIGURATION = NAME + ": Configuration issues. Skip registering of Data Plane Instance '%s'"; | ||
private static final String LOG_REGISTERED = NAME + ": Registered Data Plane Instance. (id=%s, url=%s, sourceTypes=%s, destinationTypes=%s, properties=<omitted>)"; | ||
private Monitor monitor; | ||
@Inject | ||
private DataPlaneSelectorService selectorService; | ||
@Override | ||
public String name() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public void initialize(ServiceExtensionContext context) { | ||
this.monitor = context.getMonitor(); | ||
final Config config = context.getConfig(EmbeddedDataPlaneConfig.CONFIG_PREFIX); | ||
context.getService(DataPlaneManager.class); | ||
configureDataPlaneInstance(config); | ||
} | ||
|
||
public DataPlaneInstance createDataPlane(final Config config){ | ||
|
||
DataPlaneInstance dataPlaneInstance = null; | ||
final String id = config.currentNode(); | ||
final String url = config.getString(EmbeddedDataPlaneConfig.URL_SUFFIX, ""); | ||
final List<String> sourceTypes = | ||
Arrays.stream(config.getString(EmbeddedDataPlaneConfig.SOURCE_TYPES_SUFFIX, "").split(COMMA)) | ||
.map(String::trim) | ||
.filter(Predicate.not(String::isEmpty)) | ||
.distinct() | ||
.collect(Collectors.toList()); | ||
final List<String> destinationTypes = | ||
Arrays.stream(config.getString(EmbeddedDataPlaneConfig.DESTINATION_TYPES_SUFFIX, "").split(COMMA)) | ||
.map(String::trim) | ||
.filter(Predicate.not(String::isEmpty)) | ||
.distinct() | ||
.collect(Collectors.toList()); | ||
final String propertiesJson = config.getString(EmbeddedDataPlaneConfig.PROPERTIES_SUFFIX, "{}"); | ||
|
||
if (url.isEmpty()) { | ||
monitor.warning(String.format(LOG_MISSING_CONFIGURATION, id, EmbeddedDataPlaneConfig.URL_SUFFIX)); | ||
} | ||
|
||
if (sourceTypes.isEmpty()) { | ||
monitor.warning(String.format(LOG_MISSING_CONFIGURATION, id, EmbeddedDataPlaneConfig.SOURCE_TYPES_SUFFIX)); | ||
} | ||
|
||
if (destinationTypes.isEmpty()) { | ||
monitor.warning(String.format(LOG_MISSING_CONFIGURATION, id, EmbeddedDataPlaneConfig.DESTINATION_TYPES_SUFFIX)); | ||
} | ||
|
||
final Map<String, String> properties; | ||
try { | ||
ObjectMapper mapper = new ObjectMapper(); | ||
properties = mapper.readValue(propertiesJson, new TypeReference<Map<String, String>>() { | ||
}); | ||
} catch (JsonProcessingException e) { | ||
throw new EdcException(e); | ||
} | ||
|
||
final boolean missingPublicApiProperty = !properties.containsKey(EmbeddedDataPlaneConfig.PUBLIC_API_URL_PROPERTY); | ||
if (missingPublicApiProperty) { | ||
monitor.warning(String.format(LOG_MISSING_CONFIGURATION, id, EmbeddedDataPlaneConfig.PROPERTIES_SUFFIX) + "." + EmbeddedDataPlaneConfig.PUBLIC_API_URL_PROPERTY); | ||
} | ||
|
||
final boolean invalidConfiguration = | ||
url.isEmpty() || sourceTypes.isEmpty() || destinationTypes.isEmpty(); | ||
if (invalidConfiguration || missingPublicApiProperty) { | ||
monitor.warning(String.format(LOG_SKIP_BC_MISSING_CONFIGURATION, id)); | ||
return null; | ||
} | ||
final DataPlaneInstance.Builder builder = | ||
DataPlaneInstance.Builder.newInstance().id(id).url(url); | ||
|
||
sourceTypes.forEach(builder::allowedSourceType); | ||
destinationTypes.forEach(builder::allowedDestType); | ||
properties.forEach(builder::property); | ||
|
||
dataPlaneInstance = builder.build(); | ||
|
||
monitor.debug( | ||
String.format( | ||
LOG_REGISTERED, | ||
id, | ||
url, | ||
String.join(", ", sourceTypes), | ||
String.join(", ", destinationTypes))); | ||
return dataPlaneInstance; | ||
} | ||
private void configureDataPlaneInstance(final Config config) { | ||
var dataPlaneInstance = createDataPlane(config); | ||
if(nonNull(dataPlaneInstance)){ | ||
selectorService.addInstance(dataPlaneInstance); | ||
} | ||
|
||
|
||
} | ||
} |
1 change: 1 addition & 0 deletions
1
...stration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.eclipse.edc.connector.dataplane.embedded.autoregistration.EmbeddedDataPlaneRegistration |
82 changes: 82 additions & 0 deletions
82
.../edc/connector/dataplane/embedded/autoregistration/EmbeddedDataPlaneRegistrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
|
||
|
||
/* | ||
* Copyright (c) 2024 Zub4t (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: | ||
* Zub4t (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.connector.dataplane.embedded.autoregistration; | ||
|
||
|
||
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.system.ServiceExtensionContext; | ||
import org.eclipse.edc.spi.system.configuration.ConfigFactory; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.IntStream; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import static org.mockito.Mockito.mock; | ||
|
||
@ExtendWith(DependencyInjectionExtension.class) | ||
public class EmbeddedDataPlaneRegistrationTest { | ||
|
||
@Test | ||
void testName(EmbeddedDataPlaneRegistration extension) { | ||
Assertions.assertNotNull(extension.name()); | ||
Assertions.assertEquals("Embedded DataPlane Auto Registration", extension.name()); | ||
} | ||
@Test | ||
void embeddedDataPlaneRegistration_shouldThrowEdcException(EmbeddedDataPlaneRegistration extension, ServiceExtensionContext context) { | ||
assertThrows(org.eclipse.edc.spi.EdcException.class, () -> { | ||
extension.initialize(context); | ||
var dataPlaneInstance = extension.createDataPlane(ConfigFactory.fromMap(Collections.emptyMap())); | ||
|
||
}); | ||
} | ||
@Test | ||
void embeddedDataPlaneRegistration_shouldNotAddDataPlane(EmbeddedDataPlaneRegistration extension, ServiceExtensionContext context) { | ||
var dataPlaneManager = mock(DataPlaneManager.class); | ||
context.registerService(DataPlaneManager.class,dataPlaneManager); | ||
extension.initialize(context); | ||
var dataPlaneInstance = extension.createDataPlane(ConfigFactory.fromMap(Collections.emptyMap())); | ||
assertThat(dataPlaneInstance).isNull(); | ||
} | ||
@Test | ||
void embeddedDataPlaneRegistration_shouldAddDataPlane(EmbeddedDataPlaneRegistration extension, ServiceExtensionContext context) { | ||
var dataPlaneManager = mock(DataPlaneManager.class); | ||
context.registerService(DataPlaneManager.class,dataPlaneManager); | ||
|
||
List<String> keys = List.of( | ||
EmbeddedDataPlaneConfig.DESTINATION_TYPES_SUFFIX, | ||
EmbeddedDataPlaneConfig.SOURCE_TYPES_SUFFIX, | ||
EmbeddedDataPlaneConfig.URL_SUFFIX, | ||
EmbeddedDataPlaneConfig.PROPERTIES_SUFFIX); | ||
|
||
List<String> values = List.of("HttpProxy,HttpData","HttpData","http://localhost:19192/control/transfer","{\"publicApiUrl\": \"http://localhost:19291/public/\"}"); | ||
Map<String, String> map = IntStream.range(0, keys.size()) | ||
.boxed() | ||
.collect(HashMap::new, (m, i) -> m.put(keys.get(i), values.get(i)), Map::putAll); | ||
|
||
extension.initialize(context); | ||
var dataPlaneInstance = extension.createDataPlane(ConfigFactory.fromMap(map)); | ||
assertThat(dataPlaneInstance).isInstanceOf(DataPlaneInstance.class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters