Skip to content

Commit 4efd6ae

Browse files
authored
feat: add findById method on DataPlaneSelectorService (#4225)
feat: add findById method on data plane selector control api
1 parent d22b18e commit 4efd6ae

File tree

10 files changed

+220
-134
lines changed

10 files changed

+220
-134
lines changed

core/data-plane-selector/data-plane-selector-core/src/main/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorService.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ public ServiceResult<DataPlaneInstance> select(DataAddress source, String transf
6868
});
6969
}
7070

71-
7271
@Override
7372
public ServiceResult<Void> addInstance(DataPlaneInstance instance) {
7473
return transactionContext.execute(() -> {
@@ -86,4 +85,15 @@ public ServiceResult<Void> addInstance(DataPlaneInstance instance) {
8685
public ServiceResult<Void> delete(String instanceId) {
8786
return transactionContext.execute(() -> ServiceResult.from(store.deleteById(instanceId))).mapEmpty();
8887
}
88+
89+
@Override
90+
public ServiceResult<DataPlaneInstance> findById(String id) {
91+
return transactionContext.execute(() -> {
92+
var instance = store.findById(id);
93+
if (instance == null) {
94+
return ServiceResult.notFound("Data Plane instance with id %s not found".formatted(id));
95+
}
96+
return ServiceResult.success(instance);
97+
});
98+
}
8999
}

core/data-plane-selector/data-plane-selector-core/src/test/java/org/eclipse/edc/connector/dataplane/selector/service/EmbeddedDataPlaneSelectorServiceTest.java

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
import org.junit.jupiter.api.Test;
2828

2929
import java.util.UUID;
30-
import java.util.stream.IntStream;
3130
import java.util.stream.Stream;
3231

32+
import static java.util.stream.IntStream.range;
3333
import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat;
3434
import static org.eclipse.edc.spi.result.ServiceFailure.Reason.BAD_REQUEST;
3535
import static org.eclipse.edc.spi.result.ServiceFailure.Reason.NOT_FOUND;
@@ -44,39 +44,47 @@ public class EmbeddedDataPlaneSelectorServiceTest {
4444
private final SelectionStrategyRegistry selectionStrategyRegistry = mock();
4545
private final DataPlaneSelectorService service = new EmbeddedDataPlaneSelectorService(store, selectionStrategyRegistry, new NoopTransactionContext());
4646

47-
@Test
48-
void select_shouldUseChosenSelector() {
49-
var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, "srcTestType", "destTestType")).toList();
50-
when(store.getAll()).thenReturn(instances.stream());
51-
SelectionStrategy selectionStrategy = mock();
52-
when(selectionStrategy.apply(any())).thenAnswer(it -> instances.get(0));
53-
when(selectionStrategyRegistry.find(any())).thenReturn(selectionStrategy);
54-
55-
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
47+
@Nested
48+
class Select {
5649

57-
assertThat(result).isSucceeded().extracting(DataPlaneInstance::getId).isEqualTo("instance0");
58-
verify(selectionStrategyRegistry).find("strategy");
59-
}
50+
@Test
51+
void select_shouldUseChosenSelector() {
52+
var instances = range(0, 10)
53+
.mapToObj(i -> createInstanceBuilder("instance" + i).build())
54+
.toList();
55+
when(store.getAll()).thenReturn(instances.stream());
56+
SelectionStrategy selectionStrategy = mock();
57+
when(selectionStrategy.apply(any())).thenAnswer(it -> instances.get(0));
58+
when(selectionStrategyRegistry.find(any())).thenReturn(selectionStrategy);
59+
60+
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
61+
62+
assertThat(result).isSucceeded().extracting(DataPlaneInstance::getId).isEqualTo("instance0");
63+
verify(selectionStrategyRegistry).find("strategy");
64+
}
6065

61-
@Test
62-
void select_shouldReturnBadRequest_whenStrategyNotFound() {
63-
var instances = IntStream.range(0, 10).mapToObj(i -> createInstanceMock("instance" + i, "srcTestType", "destTestType")).toList();
64-
when(store.getAll()).thenReturn(instances.stream());
65-
when(selectionStrategyRegistry.find(any())).thenReturn(null);
66+
@Test
67+
void select_shouldReturnBadRequest_whenStrategyNotFound() {
68+
var instances = range(0, 10)
69+
.mapToObj(i -> createInstanceBuilder("instance" + i).build())
70+
.toList();
71+
when(store.getAll()).thenReturn(instances.stream());
72+
when(selectionStrategyRegistry.find(any())).thenReturn(null);
6673

67-
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
74+
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
6875

69-
assertThat(result).isFailed().extracting(ServiceFailure::getReason).isEqualTo(BAD_REQUEST);
70-
}
76+
assertThat(result).isFailed().extracting(ServiceFailure::getReason).isEqualTo(BAD_REQUEST);
77+
}
7178

72-
@Test
73-
void select_shouldReturnNotFound_whenInstanceNotFound() {
74-
when(store.getAll()).thenReturn(Stream.empty());
75-
when(selectionStrategyRegistry.find(any())).thenReturn(mock());
79+
@Test
80+
void select_shouldReturnNotFound_whenInstanceNotFound() {
81+
when(store.getAll()).thenReturn(Stream.empty());
82+
when(selectionStrategyRegistry.find(any())).thenReturn(mock());
7683

77-
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
84+
var result = service.select(createAddress("srcTestType"), "transferType", "strategy");
7885

79-
assertThat(result).isFailed().extracting(ServiceFailure::getReason).isEqualTo(NOT_FOUND);
86+
assertThat(result).isFailed().extracting(ServiceFailure::getReason).isEqualTo(NOT_FOUND);
87+
}
8088
}
8189

8290
@Nested
@@ -105,11 +113,27 @@ void shouldReturnNotFound_whenInstanceIsNotFound() {
105113

106114
}
107115

108-
private DataPlaneInstance createInstanceMock(String id, String srcType, String destType) {
109-
return createInstanceBuilder(id)
110-
.allowedSourceType(srcType)
111-
.allowedDestType(destType)
112-
.build();
116+
@Nested
117+
class FindById {
118+
119+
@Test
120+
void shouldReturnInstance() {
121+
var instance = createInstanceBuilder("instanceId").build();
122+
when(store.findById(any())).thenReturn(instance);
123+
124+
var result = service.findById("instanceId");
125+
126+
assertThat(result).isSucceeded().isSameAs(instance);
127+
}
128+
129+
@Test
130+
void shouldFail_whenInstanceDoesNotExist() {
131+
when(store.findById(any())).thenReturn(null);
132+
133+
var result = service.findById("any");
134+
135+
assertThat(result).isFailed().extracting(ServiceFailure::getReason).isEqualTo(NOT_FOUND);
136+
}
113137
}
114138

115139
private DataPlaneInstance.Builder createInstanceBuilder(String id) {

extensions/control-plane/transfer/transfer-data-plane-signaling/src/main/java/org/eclipse/edc/connector/controlplane/transfer/dataplane/flow/DataPlaneSignalingFlowController.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ public boolean canHandle(TransferProcess transferProcess) {
110110
.dataPlaneId(dataPlaneInstance.getId())
111111
.build()
112112
);
113-
114113
}
115114

116115
@Override
@@ -150,17 +149,10 @@ public Set<String> transferTypesFor(Asset asset) {
150149
}
151150

152151
private StatusResult<DataPlaneClient> getClientForDataplane(String id) {
153-
var result = selectorClient.getAll();
154-
if (result.failed()) {
155-
return StatusResult.failure(FATAL_ERROR, result.getFailureDetail());
156-
}
157-
158-
return result.getContent().stream()
159-
.filter(instance -> instance.getId().equals(id))
160-
.findFirst()
152+
return selectorClient.findById(id)
161153
.map(clientFactory::createClient)
162154
.map(StatusResult::success)
163-
.orElseGet(() -> StatusResult.failure(FATAL_ERROR, "No data-plane found with id %s".formatted(id)));
155+
.orElse(f -> StatusResult.failure(FATAL_ERROR, "No data-plane found with id %s. %s".formatted(id, f.getFailureDetail())));
164156
}
165157

166158
}

extensions/control-plane/transfer/transfer-data-plane-signaling/src/test/java/org/eclipse/edc/connector/controlplane/transfer/dataplane/flow/DataPlaneSignalingFlowControllerTest.java

Lines changed: 6 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,14 @@ class Terminate {
223223
@Test
224224
void shouldCallTerminateOnTheRightDataPlane() {
225225
var dataPlaneInstance = dataPlaneInstanceBuilder().id("dataPlaneId").build();
226-
var anotherDataPlane = dataPlaneInstanceBuilder().id("anotherId").build();
227226
var transferProcess = transferProcessBuilder()
228227
.id("transferProcessId")
229228
.contentDataAddress(testDataAddress())
230229
.dataPlaneId("dataPlaneId")
231230
.build();
232231
when(dataPlaneClient.terminate(any())).thenReturn(StatusResult.success());
233232
when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient);
234-
when(selectorService.getAll()).thenReturn(ServiceResult.success(List.of(dataPlaneInstance, anotherDataPlane)));
233+
when(selectorService.findById(any())).thenReturn(ServiceResult.success(dataPlaneInstance));
235234

236235
var result = flowController.terminate(transferProcess);
237236

@@ -241,35 +240,20 @@ void shouldCallTerminateOnTheRightDataPlane() {
241240
}
242241

243242
@Test
244-
void shouldFail_withInvalidDataPlaneId() {
245-
var dataPlaneInstance = createDataPlaneInstance();
243+
void shouldFail_whenDataPlaneNotFound() {
246244
var transferProcess = transferProcessBuilder()
247245
.id("transferProcessId")
248246
.contentDataAddress(testDataAddress())
249247
.dataPlaneId("invalid")
250248
.build();
251249
when(dataPlaneClient.terminate(any())).thenReturn(StatusResult.success());
252250
when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient);
253-
when(selectorService.getAll()).thenReturn(ServiceResult.success(List.of(dataPlaneInstance)));
251+
when(selectorService.findById(any())).thenReturn(ServiceResult.notFound("not found"));
254252

255253
var result = flowController.terminate(transferProcess);
256254

257255
assertThat(result).isFailed().detail().contains("Failed to select the data plane for terminating the transfer process");
258256
}
259-
260-
@Test
261-
void shouldFail_whenCannotGetDataplaneInstances() {
262-
var transferProcess = transferProcessBuilder()
263-
.id("transferProcessId")
264-
.contentDataAddress(testDataAddress())
265-
.dataPlaneId("invalid")
266-
.build();
267-
when(selectorService.getAll()).thenReturn(ServiceResult.unexpected("error"));
268-
269-
var result = flowController.terminate(transferProcess);
270-
271-
assertThat(result).isFailed();
272-
}
273257
}
274258

275259
@Nested
@@ -285,26 +269,7 @@ void shouldCallTerminate() {
285269
when(dataPlaneClient.suspend(any())).thenReturn(StatusResult.success());
286270
var dataPlaneInstance = dataPlaneInstanceBuilder().id("dataPlaneId").build();
287271
when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient);
288-
when(selectorService.getAll()).thenReturn(ServiceResult.success(List.of(dataPlaneInstance)));
289-
290-
var result = flowController.suspend(transferProcess);
291-
292-
assertThat(result).isSucceeded();
293-
verify(dataPlaneClient).suspend("transferProcessId");
294-
}
295-
296-
@Test
297-
void shouldCallSuspendOnTheRightDataPlane() {
298-
var dataPlaneInstance = dataPlaneInstanceBuilder().id("dataPlaneId").build();
299-
var anotherDataPlane = dataPlaneInstanceBuilder().id("anotherDataPlaneId").build();
300-
var transferProcess = TransferProcess.Builder.newInstance()
301-
.id("transferProcessId")
302-
.contentDataAddress(testDataAddress())
303-
.dataPlaneId(dataPlaneInstance.getId())
304-
.build();
305-
when(dataPlaneClient.suspend(any())).thenReturn(StatusResult.success());
306-
when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient);
307-
when(selectorService.getAll()).thenReturn(ServiceResult.success(List.of(dataPlaneInstance, anotherDataPlane)));
272+
when(selectorService.findById(any())).thenReturn(ServiceResult.success(dataPlaneInstance));
308273

309274
var result = flowController.suspend(transferProcess);
310275

@@ -314,35 +279,21 @@ void shouldCallSuspendOnTheRightDataPlane() {
314279
}
315280

316281
@Test
317-
void shouldFail_withInvalidDataPlaneId() {
318-
var dataPlaneInstance = createDataPlaneInstance();
282+
void shouldFail_whenDataPlaneDoesNotExist() {
319283
var transferProcess = TransferProcess.Builder.newInstance()
320284
.id("transferProcessId")
321285
.contentDataAddress(testDataAddress())
322286
.dataPlaneId("invalid")
323287
.build();
324288
when(dataPlaneClient.suspend(any())).thenReturn(StatusResult.success());
325289
when(dataPlaneClientFactory.createClient(any())).thenReturn(dataPlaneClient);
326-
when(selectorService.getAll()).thenReturn(ServiceResult.success(List.of(dataPlaneInstance)));
290+
when(selectorService.findById(any())).thenReturn(ServiceResult.notFound("not found"));
327291

328292
var result = flowController.suspend(transferProcess);
329293

330294
assertThat(result).isFailed().detail().contains("Failed to select the data plane for suspending the transfer process");
331295
}
332296

333-
@Test
334-
void shouldFail_whenCannotGetDataplaneInstances() {
335-
var transferProcess = transferProcessBuilder()
336-
.id("transferProcessId")
337-
.contentDataAddress(testDataAddress())
338-
.dataPlaneId("invalid")
339-
.build();
340-
when(selectorService.getAll()).thenReturn(ServiceResult.unexpected("error"));
341-
342-
var result = flowController.suspend(transferProcess);
343-
344-
assertThat(result).isFailed();
345-
}
346297
}
347298

348299
@Nested

extensions/data-plane-selector/data-plane-selector-client/src/main/java/org/eclipse/edc/connector/dataplane/selector/RemoteDataPlaneSelectorService.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ public RemoteDataPlaneSelectorService(EdcHttpClient httpClient, String url, Obje
6969

7070
@Override
7171
public ServiceResult<List<DataPlaneInstance>> getAll() {
72-
var builder = new Request.Builder().get().url(url);
73-
authenticationProvider.authenticationHeaders().forEach(builder::header);
72+
var requestBuilder = new Request.Builder().get().url(url);
7473

75-
return request(builder.build())
74+
return request(requestBuilder)
7675
.compose(this::toJsonArray)
7776
.map(it -> it.stream()
7877
.map(j -> typeTransformerRegistry.transform(j, DataPlaneInstance.class))
@@ -95,10 +94,9 @@ public ServiceResult<DataPlaneInstance> select(DataAddress source, String transf
9594

9695
var body = RequestBody.create(jsonObject.toString(), TYPE_JSON);
9796

98-
var builder = new Request.Builder().post(body).url(url + SELECT_PATH);
99-
authenticationProvider.authenticationHeaders().forEach(builder::header);
97+
var requestBuilder = new Request.Builder().post(body).url(url + SELECT_PATH);
10098

101-
return request(builder.build()).compose(this::toJsonObject)
99+
return request(requestBuilder).compose(this::toJsonObject)
102100
.map(it -> typeTransformerRegistry.transform(it, DataPlaneInstance.class))
103101
.compose(ServiceResult::from);
104102
}
@@ -115,22 +113,30 @@ public ServiceResult<Void> addInstance(DataPlaneInstance instance) {
115113
.build();
116114
var body = RequestBody.create(requestBody.toString(), TYPE_JSON);
117115

118-
var builder = new Request.Builder().post(body).url(url);
119-
authenticationProvider.authenticationHeaders().forEach(builder::header);
116+
var requestBuilder = new Request.Builder().post(body).url(url);
120117

121-
return request(builder.build()).mapEmpty();
118+
return request(requestBuilder).mapEmpty();
122119
}
123120

124121
@Override
125122
public ServiceResult<Void> delete(String instanceId) {
126-
var request = new Request.Builder().delete().url(url + "/" + instanceId).build();
123+
var requestBuilder = new Request.Builder().delete().url(url + "/" + instanceId);
127124

128-
return request(request).mapEmpty();
125+
return request(requestBuilder).mapEmpty();
129126
}
130127

131-
private <R> ServiceResult<String> request(Request request) {
128+
@Override
129+
public ServiceResult<DataPlaneInstance> findById(String id) {
130+
var requestBuilder = new Request.Builder().get().url(url + "/" + id);
131+
132+
return request(requestBuilder).compose(this::toJsonObject)
133+
.map(it -> typeTransformerRegistry.transform(it, DataPlaneInstance.class).getContent());
134+
}
135+
136+
private <R> ServiceResult<String> request(Request.Builder requestBuilder) {
137+
authenticationProvider.authenticationHeaders().forEach(requestBuilder::header);
132138
try (
133-
var response = httpClient.execute(request);
139+
var response = httpClient.execute(requestBuilder.build());
134140
var responseBody = response.body();
135141
) {
136142
var bodyAsString = responseBody == null ? null : responseBody.string();

0 commit comments

Comments
 (0)