2424import org .eclipse .dataplane .domain .dataflow .DataFlowResponseMessage ;
2525import org .eclipse .dataplane .domain .dataflow .DataFlowStartMessage ;
2626import org .eclipse .dataplane .domain .dataflow .DataFlowStartedNotificationMessage ;
27+ import org .eclipse .dataplane .domain .dataflow .DataFlowStatusResponseMessage ;
28+ import org .jspecify .annotations .NonNull ;
2729import org .junit .jupiter .api .AfterEach ;
2830import org .junit .jupiter .api .BeforeEach ;
2931import org .junit .jupiter .api .Test ;
4143import static org .awaitility .Awaitility .await ;
4244import static org .eclipse .dataplane .domain .dataflow .DataFlow .State .PREPARED ;
4345import static org .eclipse .dataplane .domain .dataflow .DataFlow .State .STARTED ;
46+ import static org .eclipse .dataplane .domain .dataflow .DataFlow .State .STARTING ;
4447
4548class ConsumerPullTest {
4649
@@ -69,18 +72,14 @@ void shouldPullDataFromProvider() {
6972 var transferType = "FileSystem-PULL" ;
7073 var processId = UUID .randomUUID ().toString ();
7174 var consumerProcessId = "consumer_" + processId ;
72- var prepareMessage = new DataFlowPrepareMessage ("theMessageId" , "theParticipantId" , "theCounterPartyId" ,
73- "theDataspaceContext" , consumerProcessId , "theAgreementId" , "theDatasetId" , controlPlane .consumerCallbackAddress (),
74- transferType , emptyList (), emptyMap ());
75+ var prepareMessage = createPrepareMessage (consumerProcessId , transferType );
7576
7677 var prepareResponse = controlPlane .consumerPrepare (prepareMessage ).statusCode (200 ).extract ().as (DataFlowResponseMessage .class );
7778 assertThat (prepareResponse .state ()).isEqualTo (PREPARED .name ());
7879 assertThat (prepareResponse .dataAddress ()).isNull ();
7980
8081 var providerProcessId = "provider_" + processId ;
81- var startMessage = new DataFlowStartMessage ("theMessageId" , "theParticipantId" , "theCounterPartyId" ,
82- "theDataspaceContext" , providerProcessId , "theAgreementId" , "theDatasetId" , controlPlane .providerCallbackAddress (),
83- transferType , null , emptyList (), emptyMap ());
82+ var startMessage = createStartMessage (providerProcessId , transferType );
8483 var startResponse = controlPlane .providerStart (startMessage ).statusCode (200 ).extract ().as (DataFlowResponseMessage .class );
8584 assertThat (startResponse .state ()).isEqualTo (STARTED .name ());
8685 assertThat (startResponse .dataAddress ()).isNotNull ();
@@ -92,6 +91,39 @@ void shouldPullDataFromProvider() {
9291 });
9392 }
9493
94+ @ Test
95+ void shouldPermitAsyncStartup () {
96+ var transferType = "FileSystemAsync-PULL" ;
97+ var processId = UUID .randomUUID ().toString ();
98+ var consumerProcessId = "consumer_" + processId ;
99+ var prepareMessage = createPrepareMessage (consumerProcessId , transferType );
100+ controlPlane .consumerPrepare (prepareMessage ).statusCode (200 ).extract ().as (DataFlowResponseMessage .class );
101+
102+ var providerProcessId = "provider_" + processId ;
103+ var startMessage = createStartMessage (providerProcessId , transferType );
104+ var startResponse = controlPlane .providerStart (startMessage ).statusCode (202 ).extract ().as (DataFlowResponseMessage .class );
105+ assertThat (startResponse .state ()).isEqualTo (STARTING .name ());
106+ assertThat (startResponse .dataAddress ()).isNull ();
107+
108+ providerDataPlane .completeStartup (providerProcessId );
109+
110+ assertThat (controlPlane .providerStatus (providerProcessId ).statusCode (200 ).extract ().as (DataFlowStatusResponseMessage .class ).state ())
111+ .isEqualTo (STARTED .name ());
112+ }
113+
114+ private @ NonNull DataFlowStartMessage createStartMessage (String providerProcessId , String transferType ) {
115+ return new DataFlowStartMessage ("theMessageId" , "theParticipantId" , "theCounterPartyId" ,
116+ "theDataspaceContext" , providerProcessId , "theAgreementId" , "theDatasetId" , controlPlane .providerCallbackAddress (),
117+ transferType , null , emptyList (), emptyMap ());
118+ }
119+
120+ private @ NonNull DataFlowPrepareMessage createPrepareMessage (String consumerProcessId , String transferType ) {
121+ return new DataFlowPrepareMessage ("theMessageId" , "theParticipantId" , "theCounterPartyId" ,
122+ "theDataspaceContext" , consumerProcessId , "theAgreementId" , "theDatasetId" , controlPlane .consumerCallbackAddress (),
123+ transferType , emptyList (), emptyMap ());
124+ }
125+
126+
95127 private class ConsumerDataPlane {
96128
97129 private final Path storage ;
@@ -144,7 +176,22 @@ public Object controller() {
144176 return sdk .controller ();
145177 }
146178
179+ public void completeStartup (String dataFlowId ) {
180+ sdk .getById (dataFlowId )
181+ .compose (dataFlow -> sdk .notifyStarted (dataFlowId , this ::prepareSourceDataAddress ))
182+ .orElseThrow (f -> new RuntimeException (f .getCause ()));
183+ }
184+
147185 private Result <DataFlow > onStart (DataFlow dataFlow ) {
186+ if (dataFlow .getTransferType ().equals ("FileSystemAsync-PULL" )) {
187+ dataFlow .transitionToStarting ();
188+ return Result .success (dataFlow );
189+ }
190+
191+ return prepareSourceDataAddress (dataFlow );
192+ }
193+
194+ private Result <DataFlow > prepareSourceDataAddress (DataFlow dataFlow ) {
148195 try {
149196 var destinationDirectory = Files .createTempDirectory (dataFlow .getId ());
150197 for (var i = 0 ; i < filesToBeCreated ; i ++) {
@@ -154,7 +201,6 @@ private Result<DataFlow> onStart(DataFlow dataFlow) {
154201
155202 var dataAddress = new DataAddress ("FileSystem" , "directory" , destinationDirectory .toString (), emptyList ());
156203 dataFlow .setDataAddress (dataAddress );
157-
158204 return Result .success (dataFlow );
159205 } catch (IOException e ) {
160206 return Result .failure (e );
0 commit comments