Skip to content

Commit 60a48c0

Browse files
refactor: move federated catalog end-to-end tests to connector repo (#5543)
1 parent 990ffe6 commit 60a48c0

20 files changed

Lines changed: 1468 additions & 0 deletions

File tree

settings.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ include(":system-tests:telemetry:telemetry-test-runner")
316316
include(":system-tests:telemetry:telemetry-test-runtime")
317317
include(":system-tests:version-api:version-api-test-runner")
318318
include(":system-tests:version-api:version-api-test-runtime")
319+
include(":system-tests:e2e-federatedcatalog-tests:component-tests")
320+
include(":system-tests:e2e-federatedcatalog-tests:end2end-test:catalog-runtime")
321+
include(":system-tests:e2e-federatedcatalog-tests:end2end-test:connector-runtime")
322+
include(":system-tests:e2e-federatedcatalog-tests:end2end-test:e2e-junit-runner")
319323

320324
// BOM modules ----------------------------------------------------------------
321325
include(":dist:bom:controlplane-base-bom")

system-tests/bom-tests/src/test/java/org/eclipse/edc/test/bom/BomSmokeTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,33 @@ class ControlPlaneDcp extends SmokeTest {
7979
);
8080
}
8181

82+
@Nested
83+
@EndToEndTest
84+
class FederatedCatalogDcp extends SmokeTest {
85+
86+
@RegisterExtension
87+
protected RuntimeExtension runtime =
88+
new RuntimePerMethodExtension(new EmbeddedRuntime("fc-dcp-bom", ":dist:bom:federatedcatalog-dcp-bom")
89+
.configurationProvider(() -> ConfigFactory.fromMap(new HashMap<>() {
90+
{
91+
put("edc.iam.sts.oauth.token.url", "https://sts.com/token");
92+
put("edc.iam.sts.oauth.client.id", "test-clientid");
93+
put("edc.iam.sts.oauth.client.secret.alias", "test-alias");
94+
put("web.http.port", DEFAULT_PORT);
95+
put("web.http.path", DEFAULT_PATH);
96+
put("web.http.catalog.port", "8081");
97+
put("web.http.catalog.path", "/api/catalog");
98+
put("web.http.version.port", String.valueOf(getFreePort()));
99+
put("edc.catalog.cache.execution.period.seconds", "5");
100+
put("edc.iam.issuer.id", "did:web:testparticipant");
101+
put("edc.iam.sts.privatekey.alias", "private-alias");
102+
put("edc.iam.sts.publickey.id", "public-key-id");
103+
put("edc.catalog.cache.execution.delay.seconds", "0");
104+
}
105+
}))
106+
);
107+
}
108+
82109
@Nested
83110
@EndToEndTest
84111
public class DataPlaneBase extends SmokeTest {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2021 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Microsoft Corporation - initial API and implementation
12+
*
13+
*/
14+
15+
plugins {
16+
`java-library`
17+
}
18+
19+
dependencies {
20+
testImplementation(project(":core:federated-catalog-core-2025"))
21+
testImplementation(project(":extensions:federated-catalog:api:federated-catalog-api"))
22+
23+
testImplementation(project(":spi:common:json-ld-spi"))
24+
testImplementation(project(":spi:control-plane:catalog-spi"))
25+
testImplementation(project(":data-protocols:dsp"))
26+
testImplementation(project(":core:common:lib:json-ld-lib"))
27+
testImplementation(project(":extensions:common:http:jetty-core"))
28+
testImplementation(project(":core:common:junit"))
29+
testImplementation(project(":spi:data-plane-selector:data-plane-selector-spi"))
30+
31+
testImplementation(project(":data-protocols:dsp:dsp-http-spi"))
32+
testImplementation(project(":data-protocols:dsp:dsp-2025:dsp-spi-2025"))
33+
testImplementation(project(":spi:common:core-spi"))
34+
testImplementation(project(":spi:common:policy-model"))
35+
testImplementation(project(":spi:common:transform-spi"))
36+
testImplementation(project(":spi:crawler-spi"))
37+
testImplementation(project(":spi:federated-catalog-spi"))
38+
testImplementation(project(":spi:common:protocol-spi"))
39+
40+
testImplementation(libs.restAssured)
41+
testImplementation(libs.awaitility)
42+
43+
testRuntimeOnly(project(":extensions:common:iam:iam-mock"))
44+
}
45+
46+
edcBuild {
47+
publish.set(false)
48+
}

system-tests/e2e-federatedcatalog-tests/component-tests/src/test/java/org/eclipse/edc/catalog/CatalogRuntimeComponentTest.java

Lines changed: 379 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright (c) 2022 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Microsoft Corporation - initial API and implementation
12+
*
13+
*/
14+
15+
package org.eclipse.edc.catalog;
16+
17+
import com.fasterxml.jackson.core.JsonProcessingException;
18+
import com.fasterxml.jackson.core.type.TypeReference;
19+
import com.fasterxml.jackson.databind.DeserializationFeature;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import io.restassured.http.ContentType;
22+
import io.restassured.specification.RequestSpecification;
23+
import jakarta.json.Json;
24+
import jakarta.json.JsonObject;
25+
import org.eclipse.edc.connector.controlplane.catalog.spi.Catalog;
26+
import org.eclipse.edc.connector.controlplane.catalog.spi.DataService;
27+
import org.eclipse.edc.connector.controlplane.catalog.spi.Dataset;
28+
import org.eclipse.edc.connector.controlplane.catalog.spi.Distribution;
29+
import org.eclipse.edc.jsonld.spi.JsonLd;
30+
import org.eclipse.edc.policy.model.Policy;
31+
import org.eclipse.edc.spi.query.QuerySpec;
32+
import org.eclipse.edc.spi.response.StatusResult;
33+
import org.eclipse.edc.spi.result.Result;
34+
35+
import java.util.ArrayList;
36+
import java.util.HashMap;
37+
import java.util.List;
38+
import java.util.Map;
39+
import java.util.UUID;
40+
import java.util.concurrent.CompletableFuture;
41+
import java.util.function.Function;
42+
import java.util.stream.IntStream;
43+
44+
import static io.restassured.RestAssured.given;
45+
import static java.util.Arrays.asList;
46+
import static java.util.concurrent.CompletableFuture.completedFuture;
47+
import static java.util.stream.Collectors.toList;
48+
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
49+
import static org.eclipse.edc.util.io.Ports.getFreePort;
50+
51+
public class TestFunctions {
52+
public static final String CATALOG_QUERY_BASE_PATH = "/catalog";
53+
public static final int CATALOG_QUERY_PORT = getFreePort();
54+
private static final String PATH = "/v1alpha/catalog/query";
55+
private static final TypeReference<List<Map<String, Object>>> MAP_TYPE = new TypeReference<>() {
56+
};
57+
58+
private static RequestSpecification baseRequest() {
59+
return given()
60+
.baseUri("http://localhost:" + CATALOG_QUERY_PORT)
61+
.basePath(CATALOG_QUERY_BASE_PATH)
62+
.contentType(ContentType.JSON)
63+
.when();
64+
}
65+
66+
public static CompletableFuture<StatusResult<byte[]>> emptyCatalog(Function<Catalog, StatusResult<byte[]>> transformationFunction) {
67+
return completedFuture(transformationFunction.apply(catalogBuilder().build()));
68+
}
69+
70+
public static CompletableFuture<StatusResult<byte[]>> emptyCatalog(Function<Catalog, StatusResult<byte[]>> transformationFunction, String catalogId) {
71+
return completedFuture(transformationFunction.apply(catalogBuilder().id(catalogId).build()));
72+
}
73+
74+
public static Catalog.Builder catalogBuilder() {
75+
return Catalog.Builder.newInstance()
76+
.participantId("test-participant")
77+
.id(UUID.randomUUID().toString())
78+
.properties(new HashMap<>())
79+
.dataServices(new ArrayList<>())
80+
.datasets(new ArrayList<>());
81+
}
82+
83+
public static CompletableFuture<StatusResult<byte[]>> catalogOf(Function<Catalog, StatusResult<byte[]>> transformationFunction, String catId, Dataset... datasets) {
84+
return completedFuture(transformationFunction.apply(catalogBuilder().id(catId).datasets(asList(datasets)).build()));
85+
}
86+
87+
public static CompletableFuture<StatusResult<byte[]>> randomCatalog(Function<Catalog, StatusResult<byte[]>> transformationFunction, String id, int howManyDatasets) {
88+
return completedFuture(transformationFunction.apply(catalogBuilder()
89+
.id(id)
90+
.datasets(IntStream.range(0, howManyDatasets).mapToObj(i -> createDataset("DataSet_" + UUID.randomUUID())).collect(toList()))
91+
.build()));
92+
}
93+
94+
public static List<Catalog> queryCatalogApi(JsonLd jsonLd, Function<JsonObject, Catalog> transformerFunction) {
95+
var objectMapper = new ObjectMapper();
96+
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
97+
var body = baseRequest()
98+
.body(TestFunctions.createEmptyQuery())
99+
.post(PATH)
100+
.body();
101+
102+
try {
103+
var maps = objectMapper.readValue(body.asString(), MAP_TYPE);
104+
return maps.stream().map(map -> Json.createObjectBuilder(map).build())
105+
.map(jsonLd::expand)
106+
.map(Result::getContent)
107+
.map(transformerFunction)
108+
.toList();
109+
} catch (JsonProcessingException e) {
110+
throw new AssertionError(e);
111+
}
112+
}
113+
114+
public static JsonObject createEmptyQuery() {
115+
return Json.createObjectBuilder()
116+
.add(TYPE, QuerySpec.EDC_QUERY_SPEC_TYPE)
117+
.build();
118+
}
119+
120+
public static Dataset createDataset(String dataset1) {
121+
return Dataset.Builder.newInstance()
122+
.offer("test-offer", Policy.Builder.newInstance().build())
123+
.distribution(Distribution.Builder.newInstance().format("test-format").dataService(DataService.Builder.newInstance().build()).build())
124+
.id(dataset1)
125+
.build();
126+
}
127+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2022 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Microsoft Corporation - initial API and implementation
12+
*
13+
*/
14+
15+
package org.eclipse.edc.catalog.instrumentation;
16+
17+
import org.eclipse.edc.connector.dataplane.selector.spi.client.DataPlaneClientFactory;
18+
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
19+
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
20+
import org.eclipse.edc.spi.message.RemoteMessageDispatcher;
21+
import org.eclipse.edc.spi.message.RemoteMessageDispatcherRegistry;
22+
import org.eclipse.edc.spi.system.ServiceExtension;
23+
import org.eclipse.edc.spi.system.ServiceExtensionContext;
24+
25+
import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DATASPACE_PROTOCOL_HTTP_V_2025_1;
26+
import static org.mockito.Mockito.mock;
27+
28+
public class MockInjectionExtension implements ServiceExtension {
29+
30+
@Inject
31+
private RemoteMessageDispatcherRegistry registry;
32+
private RemoteMessageDispatcher dispatcher;
33+
34+
@Override
35+
public void initialize(ServiceExtensionContext context) {
36+
registry.register(DATASPACE_PROTOCOL_HTTP_V_2025_1, createDispatcher());
37+
}
38+
39+
@Provider
40+
public RemoteMessageDispatcher createDispatcher() {
41+
if (dispatcher == null) {
42+
dispatcher = mock(RemoteMessageDispatcher.class);
43+
}
44+
45+
return dispatcher;
46+
}
47+
48+
@Provider
49+
public DataPlaneClientFactory createDataPlaneClientFactory() {
50+
return mock();
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2022 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Microsoft Corporation - initial API and implementation
12+
*
13+
*/
14+
15+
package org.eclipse.edc.catalog.matchers;
16+
17+
import org.eclipse.edc.connector.controlplane.catalog.spi.CatalogRequestMessage;
18+
import org.mockito.ArgumentMatcher;
19+
20+
public abstract class CatalogRequestMatcher implements ArgumentMatcher<CatalogRequestMessage> {
21+
22+
public static CatalogRequestMatcher sentTo(String recipientId, String recipientUrl) {
23+
return new CatalogRequestMatcher() {
24+
@Override
25+
public boolean matches(CatalogRequestMessage argument) {
26+
return argument.getCounterPartyId().equals(recipientId) &&
27+
argument.getCounterPartyAddress().equals(recipientUrl);
28+
}
29+
};
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.eclipse.edc.catalog.instrumentation.MockInjectionExtension
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"@id": "sub-catalog-id",
3+
"@type": "dcat:Catalog",
4+
"dcat:dataset": [
5+
{
6+
"@id": "subcatalog-asset-a873f2be-295e-4d03-af1c-0e15c1363627",
7+
"@type": "dcat:Dataset",
8+
"odrl:hasPolicy": {
9+
"@id": "ODkzNGY3MzEtYzdmMy00N2NiLTlmM2UtNGU1ZDljOGNjNzU3:bm9ybWFsLWFzc2V0LWE4NzNmMmJlLTI5NWUtNGQwMy1hZjFjLTBlMTVjMTM2MzYyNw==:OGZhMzc3ODktOTZlYS00ZGQ1LWIyZjktNjYzNTQwOWZlNTUw",
10+
"@type": "odrl:Offer",
11+
"odrl:permission": [
12+
],
13+
"odrl:prohibition": [
14+
],
15+
"odrl:obligation": [
16+
]
17+
},
18+
"dcat:distribution": [
19+
],
20+
"id": "normal-asset-a873f2be-295e-4d03-af1c-0e15c1363627"
21+
}
22+
],
23+
"dcat:distribution": [
24+
],
25+
"dcat:service": {
26+
"@id": "5cc832e4-9b77-412b-a21e-7d5b49516f2c",
27+
"@type": "dcat:DataService",
28+
"dcat:endpointDescription": "dspace:connector",
29+
"dcat:endpointURL": "http://localhost:55229/protocol",
30+
"dct:terms": "dspace:connector",
31+
"dct:endpointUrl": "http://localhost:55229/protocol"
32+
},
33+
"dspace:participantId": "anonymous",
34+
"participantId": "anonymous",
35+
"@context": {
36+
"@vocab": "https://w3id.org/edc/v0.0.1/ns/",
37+
"edc": "https://w3id.org/edc/v0.0.1/ns/",
38+
"dcat": "http://www.w3.org/ns/dcat#",
39+
"dct": "http://purl.org/dc/terms/",
40+
"odrl": "http://www.w3.org/ns/odrl/2/",
41+
"dspace": "https://w3id.org/dspace/2025/1/"
42+
}
43+
}

0 commit comments

Comments
 (0)