Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 32 additions & 55 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,45 @@ plugins {
group = "org.eclipse.dataplane-core"
version = "0.0.11-SNAPSHOT"

repositories {
mavenCentral()
}

dependencies {
implementation("com.fasterxml.jackson.core:jackson-databind:2.21.3")
implementation("com.nimbusds:nimbus-jose-jwt:10.9")
implementation("jakarta.ws.rs:jakarta.ws.rs-api:4.0.0")

testImplementation(platform("org.junit:junit-bom:6.1.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("io.rest-assured:rest-assured:6.0.0")
testImplementation("org.assertj:assertj-core:3.27.7")
testImplementation("org.awaitility:awaitility:4.3.0")
testImplementation("org.eclipse.jetty.ee10:jetty-ee10-servlet:12.1.9")
testImplementation("org.eclipse.jetty:jetty-server:12.1.9")
val jerseyVersion = "4.0.2"
testImplementation("org.glassfish.jersey.containers:jersey-container-servlet:${jerseyVersion}")
testImplementation("org.glassfish.jersey.inject:jersey-hk2:${jerseyVersion}")
testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson:${jerseyVersion}")
testImplementation("org.mockito:mockito-core:5.23.0")
testImplementation("org.slf4j:slf4j-simple:2.0.18")
testImplementation("org.wiremock:wiremock-jetty12:3.13.2")
testImplementation("org.testcontainers:testcontainers-junit-jupiter:2.0.5")
testImplementation("org.testcontainers:testcontainers-postgresql:2.0.5")
testImplementation("org.postgresql:postgresql:42.7.11")
}
subprojects {
apply(plugin = "signing")
apply(plugin = "maven-publish")
apply(plugin = "com.vanniktech.maven.publish")

tasks.test {
useJUnitPlatform()
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}

signing {
useGpgCmd()
sign(publishing.publications)
}
signing {
useGpgCmd()
sign(publishing.publications)
}

mavenPublishing {
publishToMavenCentral(true)
mavenPublishing {
publishToMavenCentral(true)

signAllPublications()
signAllPublications()

pom {
name.set(project.name)
description.set("Dataplane Signaling SDK library")
url.set("https://github.com/eclipse-dataplane-core/dataplane-sdk-java")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
pom {
name.set(project.name)
description.set("Dataplane Signaling SDK library")
url.set("https://github.com/eclipse-dataplane-core/dataplane-sdk-java")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
}
developers {
developer {
name = "Dataplane Core Dev"
email = "dataplane-core-dev@eclipse.org"
developers {
developer {
name = "Dataplane Core Dev"
email = "dataplane-core-dev@eclipse.org"
}
}
scm {
url.set("https://github.com/eclipse-dataplane-core/dataplane-sdk-java")
connection.set("scm:git:git@github.com:eclipse-dataplane-core/dataplane-sdk-java.git")
}
}
scm {
url.set("https://github.com/eclipse-dataplane-core/dataplane-sdk-java")
connection.set("scm:git:git@github.com:eclipse-dataplane-core/dataplane-sdk-java.git")
}
}
}
38 changes: 38 additions & 0 deletions dataplane-sdk-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as for now, this package will be published with this groupId/artifactId:
org.eclipse.dataplane-core:core, maybe it would be better to call it sdk or dataplane-sdk to make it org.eclipse.dataplane-core:dataplane-sdk, as there could be something more in the future (see in the "rust" world there are also "facet" and "siglet")

we could keep a convention like:

  • org.eclipse.dataplane-core:dataplane-sdk
  • org.eclipse.dataplane-core:dataplane-sdk-jakarta-ee

and so on

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! I'm so used to it from EDC that I completely missed that 😄 adjusted it. I opted for dataplane-sdk-core instead of just dataplane-sdk, as with just the core module it would be missing the controllers and dataplane-sdk could sound like it's complete

* Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - initial API and implementation
*
*/

plugins {
`java-library`
}

dependencies {
implementation(libs.jackson.databind)
implementation(libs.nimbus.jwt)

compileOnly(libs.jakarta.rsApi)

testImplementation(platform(libs.junit.bom))
testImplementation(libs.junit.jupiter)
testRuntimeOnly(libs.junit.launcher)
testImplementation(libs.restAssured)
testImplementation(libs.assertJ)
testImplementation(libs.awaitility)

testImplementation(libs.mockito.core)
testImplementation(libs.slf4j.simple)

testImplementation(libs.testcontainers.junit.jupiter)
testImplementation(libs.testcontainers.postgresql)
testImplementation(libs.postgresql)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@
import org.eclipse.dataplane.logic.OnStarted;
import org.eclipse.dataplane.logic.OnSuspend;
import org.eclipse.dataplane.logic.OnTerminate;
import org.eclipse.dataplane.port.DataPlaneRegistrationApiController;
import org.eclipse.dataplane.port.DataPlaneSignalingApiController;
import org.eclipse.dataplane.port.exception.AuthorizationNotSupported;
import org.eclipse.dataplane.port.exception.ControlPlaneNotRegistered;
import org.eclipse.dataplane.port.exception.DataFlowNotifyControlPlaneFailed;
import org.eclipse.dataplane.port.exception.DataplaneNotRegistered;
import org.eclipse.dataplane.port.exception.ResourceNotFoundException;
import org.eclipse.dataplane.port.exception.UnauthorizedException;
import org.eclipse.dataplane.port.store.ControlPlaneStore;
import org.eclipse.dataplane.port.store.DataFlowStore;
import org.eclipse.dataplane.port.store.InMemoryControlPlaneStore;
Expand Down Expand Up @@ -92,14 +91,6 @@ public static Builder newInstance() {
return new Builder();
}

public DataPlaneSignalingApiController controller() {
return new DataPlaneSignalingApiController(this, authorizations);
}

public DataPlaneRegistrationApiController registrationController() {
return new DataPlaneRegistrationApiController(this);
}

public Result<DataFlow> getById(String dataFlowId) {
return dataFlowStore.findById(dataFlowId);
}
Expand Down Expand Up @@ -323,6 +314,13 @@ public Result<Void> completed(String flowId) {
});
}

public Result<String> extractControlplaneId(String authorizationHeader) {
return authorizations.values().stream()
.map(authorization -> authorization.extractCallerId(authorizationHeader))
.filter(Result::succeeded).findFirst()
.orElseGet(() -> Result.failure(new UnauthorizedException("Authorization method not recognized")));
}

public Result<Void> registerOn(String controlPlaneEndpoint) {

var message = new DataPlaneRegistrationMessage(id, endpoint, transferTypes, labels);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - initial API and implementation
*
*/

package org.eclipse.dataplane.port.exception;

public class UnauthorizedException extends RuntimeException {

public UnauthorizedException(String message) {
super(message);
}

}
23 changes: 23 additions & 0 deletions dataplane-sdk-jakarta-ee/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - initial API and implementation
*
*/

plugins {
`java-library`
}

dependencies {
implementation(project(":dataplane-sdk-core"))

implementation(libs.jakarta.rsApi)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@
import org.eclipse.dataplane.domain.dataflow.DataFlowStatusResponseMessage;
import org.eclipse.dataplane.domain.dataflow.DataFlowSuspendMessage;
import org.eclipse.dataplane.domain.dataflow.DataFlowTerminateMessage;
import org.eclipse.dataplane.domain.registration.Authorization;

import java.util.Map;

import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static jakarta.ws.rs.core.MediaType.WILDCARD;

Expand All @@ -48,11 +46,9 @@
public class DataPlaneSignalingApiController {

private final Dataplane dataplane;
private final Map<String, Authorization> authorizations;

public DataPlaneSignalingApiController(Dataplane dataplane, Map<String, Authorization> authorizations) {
public DataPlaneSignalingApiController(Dataplane dataplane) {
this.dataplane = dataplane;
this.authorizations = authorizations;
}

@POST
Expand Down Expand Up @@ -125,14 +121,11 @@ public DataFlowStatusResponseMessage status(@PathParam("flowId") String flowId)
}

private Result<String> extractControlplaneId(ContainerRequestContext requestContext) {
var authorizationHeader = requestContext.getHeaderString("Authorization");
var authorizationHeader = requestContext.getHeaderString(AUTHORIZATION);
if (authorizationHeader == null) {
return Result.failure(new NotAuthorizedException("Authorization header missing"));
}
return authorizations.values().stream()
.map(authorization -> authorization.extractCallerId(authorizationHeader))
.filter(Result::succeeded).findFirst()
.orElseGet(() -> Result.failure(new NotAuthorizedException("Authorization method not recognized")));
}

return dataplane.extractControlplaneId(authorizationHeader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* Contributors:
* Think-it GmbH - initial API and implementation
* Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - move Jakarta to separate module
*
*/

Expand All @@ -21,6 +22,7 @@
import org.eclipse.dataplane.port.exception.AuthorizationNotSupported;
import org.eclipse.dataplane.port.exception.ControlPlaneNotRegistered;
import org.eclipse.dataplane.port.exception.ResourceNotFoundException;
import org.eclipse.dataplane.port.exception.UnauthorizedException;

import java.util.function.Function;

Expand All @@ -43,6 +45,10 @@ public interface ExceptionMapper {
return new BadRequestException(exception);
}

if (exception instanceof UnauthorizedException unauthorized) {
return new NotAuthorizedException(unauthorized);
}

return new WebApplicationException("unexpected internal server error");
};

Expand Down
47 changes: 47 additions & 0 deletions e2e-tests/build.gradle.kts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this module should be excluded from the publication

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - initial API and implementation
*
*/

plugins {
`java-library`
}

dependencies {
testImplementation(project(":dataplane-sdk-core"))
testImplementation(project(":dataplane-sdk-jakarta-ee"))

testImplementation(libs.nimbus.jwt)

testImplementation(platform(libs.junit.bom))
testImplementation(libs.junit.jupiter)
testRuntimeOnly(libs.junit.launcher)
testImplementation(libs.restAssured)
testImplementation(libs.assertJ)
testImplementation(libs.awaitility)

testImplementation(libs.jakarta.rsApi)
testImplementation(libs.jersey.servlet)
testImplementation(libs.jersey.hk2)
testImplementation(libs.jersey.jackson)
testImplementation(libs.jetty.ee10.servlet)
testImplementation(libs.jetty.server)
testImplementation(libs.wiremock.jetty12)
}

tasks.withType<PublishToMavenRepository>().configureEach {
enabled = false
}

tasks.withType<PublishToMavenLocal>().configureEach {
enabled = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.dataplane.authorization.TestAuthorization;
import org.eclipse.dataplane.domain.registration.AuthorizationProfile;
import org.eclipse.dataplane.domain.registration.ControlPlaneRegistrationMessage;
import org.eclipse.dataplane.port.DataPlaneRegistrationApiController;
import org.eclipse.dataplane.port.exception.ResourceNotFoundException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -45,7 +46,7 @@ class ControlPlaneRegistrationApiTest {
void setUp() {
httpServer.start();

httpServer.deploy("/runtime/data-plane", sdk.registrationController());
httpServer.deploy("/runtime/data-plane", new DataPlaneRegistrationApiController(sdk));
}

@AfterEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.dataplane.domain.registration.AuthorizationProfile;
import org.eclipse.dataplane.domain.registration.ControlPlaneRegistrationMessage;
import org.eclipse.dataplane.domain.registration.Oauth2ClientCredentialsAuthorization;
import org.eclipse.dataplane.port.DataPlaneSignalingApiController;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -76,7 +77,7 @@ void setUp() {

controlPlane.initialize(httpServer, "/data-plane", "/data-plane");

httpServer.deploy("/data-plane", dataPlane.controller());
httpServer.deploy("/data-plane", new DataPlaneSignalingApiController(dataPlane));
httpServer.deploy("/oauth2", new Oauth2TokenController(clientId, clientSecret));
}

Expand Down
Loading