Skip to content

Commit 07592d1

Browse files
Add variable async option to REST API
1 parent 8f94c40 commit 07592d1

20 files changed

+1101
-122
lines changed

modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/CmmnRestUrls.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public final class CmmnRestUrls {
4040
public static final String SEGMENT_CASE_INSTANCE_RESOURCE = "case-instances";
4141
public static final String SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE = "plan-item-instances";
4242
public static final String SEGMENT_VARIABLES = "variables";
43+
public static final String SEGMENT_VARIABLES_ASYNC = "variables-async";
4344
public static final String SEGMENT_VARIABLE_INSTANCE_RESOURCE = "variable-instances";
4445
public static final String SEGMENT_EVENT_SUBSCRIPTIONS = "event-subscriptions";
4546
public static final String SEGMENT_SUBTASKS = "subtasks";
@@ -242,11 +243,21 @@ public final class CmmnRestUrls {
242243
* URL template for case instance variable collection: <i>cmmn-runtime/case-instances/{0:processInstanceId}/variables</i>
243244
*/
244245
public static final String[] URL_CASE_INSTANCE_VARIABLE_COLLECTION = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_CASE_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES };
246+
247+
/**
248+
* URL template for case instance variable collection: <i>cmmn-runtime/case-instances/{0:processInstanceId}/variables-async</i>
249+
*/
250+
public static final String[] URL_CASE_INSTANCE_VARIABLE_ASYNC_COLLECTION = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_CASE_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES_ASYNC };
245251

246252
/**
247253
* URL template for a single case instance variable: <i>cmmn-runtime/case-instances /{0:caseInstanceId}/variables/{1:variableName}</i>
248254
*/
249255
public static final String[] URL_CASE_INSTANCE_VARIABLE = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_CASE_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES, "{1}" };
256+
257+
/**
258+
* URL template for a single case instance variable: <i>cmmn-runtime/case-instances /{0:caseInstanceId}/variables-async/{1:variableName}</i>
259+
*/
260+
public static final String[] URL_CASE_INSTANCE_VARIABLE_ASYNC = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_CASE_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES_ASYNC, "{1}" };
250261

251262
/**
252263
* URL template for a single case instance variable data: <i>cmmn-runtime/case-instances/{0:processInstanceId}/variables/{1:variableName}/data</i>
@@ -289,17 +300,25 @@ public final class CmmnRestUrls {
289300
*/
290301
public static final String[] URL_PLAN_ITEM_INSTANCE = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}" };
291302

292-
293303
/**
294304
* URL template for plan item instance variables: <i>cmmn-runtime/plan-item-instances/{0:planItemInstanceId}/variables</i>
295305
*/
296-
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLES = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}",
297-
SEGMENT_VARIABLES };
306+
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLES = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES };
307+
308+
/**
309+
* URL template for plan item instance variables: <i>cmmn-runtime/plan-item-instances/{0:planItemInstanceId}/variables-async</i>
310+
*/
311+
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLES_ASYNC = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES_ASYNC };
312+
298313
/**
299314
* URL template for a single plan item instance variable: <i>cmmn-runtime/plan-item-instances/{0:planItemInstanceId}/variables/{1:variableName}</i>
300315
*/
301-
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLE = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES,
302-
"{1}" };
316+
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLE = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES, "{1}" };
317+
318+
/**
319+
* URL template for a single plan item instance variable: <i>cmmn-runtime/plan-item-instances/{0:planItemInstanceId}/variables-async/{1:variableName}</i>
320+
*/
321+
public static final String[] URL_PLAN_ITEM_INSTANCE_VARIABLE_ASYNC = { SEGMENT_RUNTIME_RESOURCES, SEGMENT_PLAN_ITEM_INSTANCE_RESOURCE, "{0}", SEGMENT_VARIABLES_ASYNC, "{1}" };
303322

304323
/**
305324
* URL template for a single case instance: <i>cmmn-runtime/plan-item-instances/{0:planItemInstanceId}/variables/{1:variableName}/data</i>

modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/BaseVariableResource.java

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
import java.util.List;
2525
import java.util.Map;
2626

27-
import jakarta.servlet.http.HttpServletRequest;
28-
import jakarta.servlet.http.HttpServletResponse;
29-
3027
import org.apache.commons.io.IOUtils;
3128
import org.flowable.cmmn.api.runtime.CaseInstance;
3229
import org.flowable.cmmn.api.runtime.PlanItemInstance;
@@ -48,6 +45,9 @@
4845

4946
import com.fasterxml.jackson.databind.ObjectMapper;
5047

48+
import jakarta.servlet.http.HttpServletRequest;
49+
import jakarta.servlet.http.HttpServletResponse;
50+
5151
/**
5252
* @author Tijs Rademakers
5353
*/
@@ -180,21 +180,22 @@ protected List<RestVariable> processCaseVariables(CaseInstance caseInstance) {
180180
return result;
181181
}
182182

183-
protected Object createVariable(CaseInstance caseInstance, HttpServletRequest request, HttpServletResponse response) {
184-
return createVariable(caseInstance.getId(), CmmnRestResponseFactory.VARIABLE_CASE, request, response, RestVariableScope.GLOBAL,
183+
protected Object createVariable(CaseInstance caseInstance, boolean async, HttpServletRequest request, HttpServletResponse response) {
184+
return createVariable(caseInstance.getId(), CmmnRestResponseFactory.VARIABLE_CASE, async, request, response, RestVariableScope.GLOBAL,
185185
createVariableInterceptor(caseInstance));
186186
}
187187

188-
protected Object createVariable(PlanItemInstance planItemInstance, HttpServletRequest request, HttpServletResponse response) {
189-
return createVariable(planItemInstance.getId(), CmmnRestResponseFactory.VARIABLE_PLAN_ITEM, request, response, RestVariableScope.LOCAL,
188+
protected Object createVariable(PlanItemInstance planItemInstance, boolean async, HttpServletRequest request, HttpServletResponse response) {
189+
return createVariable(planItemInstance.getId(), CmmnRestResponseFactory.VARIABLE_PLAN_ITEM, async, request, response, RestVariableScope.LOCAL,
190190
createVariableInterceptor(planItemInstance));
191191
}
192192

193-
protected Object createVariable(String instanceId, int variableType, HttpServletRequest request, HttpServletResponse response, RestVariableScope scope,
194-
VariableInterceptor variableInterceptor) {
193+
protected Object createVariable(String instanceId, int variableType, boolean async, HttpServletRequest request, HttpServletResponse response,
194+
RestVariableScope scope, VariableInterceptor variableInterceptor) {
195+
195196
Object result = null;
196197
if (request instanceof MultipartHttpServletRequest) {
197-
result = setBinaryVariable((MultipartHttpServletRequest) request, instanceId, variableType, true, scope, variableInterceptor);
198+
result = setBinaryVariable((MultipartHttpServletRequest) request, instanceId, variableType, true, async, scope, variableInterceptor);
198199
} else {
199200

200201
List<RestVariable> inputVariables = new ArrayList<>();
@@ -229,19 +230,32 @@ protected Object createVariable(String instanceId, int variableType, HttpServlet
229230

230231
if (!variablesToSet.isEmpty()) {
231232
variableInterceptor.createVariables(variablesToSet);
232-
Map<String, Object> setVariables;
233+
Map<String, Object> setVariables = null;
233234
if (variableType == CmmnRestResponseFactory.VARIABLE_PLAN_ITEM || scope == RestVariableScope.LOCAL) {
234-
runtimeService.setLocalVariables(instanceId, variablesToSet);
235-
setVariables = runtimeService.getLocalVariables(instanceId, variablesToSet.keySet());
235+
if (async) {
236+
runtimeService.setLocalVariablesAsync(instanceId, variablesToSet);
237+
238+
} else {
239+
runtimeService.setLocalVariables(instanceId, variablesToSet);
240+
setVariables = runtimeService.getLocalVariables(instanceId, variablesToSet.keySet());
241+
}
242+
236243
} else {
237-
runtimeService.setVariables(instanceId, variablesToSet);
238-
setVariables = runtimeService.getVariables(instanceId, variablesToSet.keySet());
244+
if (async) {
245+
runtimeService.setVariablesAsync(instanceId, variablesToSet);
246+
247+
} else {
248+
runtimeService.setVariables(instanceId, variablesToSet);
249+
setVariables = runtimeService.getVariables(instanceId, variablesToSet.keySet());
250+
}
239251
}
240252

241-
for (RestVariable inputVariable : inputVariables) {
242-
String variableName = inputVariable.getName();
243-
Object variableValue = setVariables.get(variableName);
244-
resultVariables.add(restResponseFactory.createRestVariable(variableName, variableValue, scope, instanceId, variableType, false));
253+
if (!async) {
254+
for (RestVariable inputVariable : inputVariables) {
255+
String variableName = inputVariable.getName();
256+
Object variableValue = setVariables.get(variableName);
257+
resultVariables.add(restResponseFactory.createRestVariable(variableName, variableValue, scope, instanceId, variableType, false));
258+
}
245259
}
246260
}
247261
}
@@ -265,23 +279,29 @@ public void deleteAllVariables(CaseInstance caseInstance) {
265279
runtimeService.removeVariables(caseInstance.getId(), currentVariables);
266280
}
267281

268-
protected RestVariable setSimpleVariable(RestVariable restVariable, String instanceId, boolean isNew, RestVariableScope scope, int variableType, VariableInterceptor variableInterceptor) {
282+
protected RestVariable setSimpleVariable(RestVariable restVariable, String instanceId, boolean isNew, boolean async, RestVariableScope scope, int variableType, VariableInterceptor variableInterceptor) {
269283
if (restVariable.getName() == null) {
270284
throw new FlowableIllegalArgumentException("Variable name is required");
271285
}
272286

273287
Object actualVariableValue = restResponseFactory.getVariableValue(restVariable);
274288

275-
setVariable(instanceId, restVariable.getName(), actualVariableValue, scope, isNew, variableInterceptor);
289+
setVariable(instanceId, restVariable.getName(), actualVariableValue, scope, isNew, async, variableInterceptor);
276290

277-
RestVariable variable = getVariableFromRequestWithoutAccessCheck(instanceId, restVariable.getName(), variableType, false);
278-
// We are setting the scope because the fetched variable does not have it
279-
variable.setVariableScope(scope);
291+
RestVariable variable = null;
292+
293+
if (!async) {
294+
variable = getVariableFromRequestWithoutAccessCheck(instanceId, restVariable.getName(), variableType, false);
295+
296+
// We are setting the scope because the fetched variable does not have it
297+
variable.setVariableScope(scope);
298+
}
299+
280300
return variable;
281301
}
282302

283303
protected RestVariable setBinaryVariable(MultipartHttpServletRequest request, String instanceId, int responseVariableType, boolean isNew,
284-
RestVariableScope scope, VariableInterceptor variableInterceptor) {
304+
boolean async, RestVariableScope scope, VariableInterceptor variableInterceptor) {
285305

286306
// Validate input and set defaults
287307
if (request.getFileMap().size() == 0) {
@@ -338,31 +358,39 @@ protected RestVariable setBinaryVariable(MultipartHttpServletRequest request, St
338358
if (variableType.equals(CmmnRestResponseFactory.BYTE_ARRAY_VARIABLE_TYPE)) {
339359
// Use raw bytes as variable value
340360
byte[] variableBytes = IOUtils.toByteArray(file.getInputStream());
341-
setVariable(instanceId, variableName, variableBytes, scope, isNew, variableInterceptor);
361+
setVariable(instanceId, variableName, variableBytes, scope, isNew, async, variableInterceptor);
342362

343363
} else if (isSerializableVariableAllowed) {
344364
// Try deserializing the object
345365
ObjectInputStream stream = new ObjectInputStream(file.getInputStream());
346366
Object value = stream.readObject();
347-
setVariable(instanceId, variableName, value, scope, isNew, variableInterceptor);
367+
setVariable(instanceId, variableName, value, scope, isNew, async, variableInterceptor);
348368
stream.close();
349369
} else {
350370
throw new FlowableContentNotSupportedException("Serialized objects are not allowed");
351371
}
352372

353-
RestVariable restVariable = getVariableFromRequestWithoutAccessCheck(instanceId, variableName, responseVariableType, false);
354-
// We are setting the scope because the fetched variable does not have it
355-
restVariable.setVariableScope(scope);
373+
RestVariable restVariable = null;
374+
375+
if (!async) {
376+
restVariable = getVariableFromRequestWithoutAccessCheck(instanceId, variableName, responseVariableType, false);
377+
378+
// We are setting the scope because the fetched variable does not have it
379+
restVariable.setVariableScope(scope);
380+
}
381+
356382
return restVariable;
383+
357384
} catch (IOException ioe) {
358385
throw new FlowableIllegalArgumentException("Could not process multipart content", ioe);
386+
359387
} catch (ClassNotFoundException ioe) {
360388
throw new FlowableContentNotSupportedException(
361389
"The provided body contains a serialized object for which the class was not found: " + ioe.getMessage());
362390
}
363391
}
364392

365-
protected void setVariable(String instanceId, String name, Object value, RestVariableScope scope, boolean isNew, VariableInterceptor variableInterceptor) {
393+
protected void setVariable(String instanceId, String name, Object value, RestVariableScope scope, boolean isNew, boolean async, VariableInterceptor variableInterceptor) {
366394
if (isNew) {
367395
variableInterceptor.createVariables(Collections.singletonMap(name, value));
368396
} else {
@@ -374,9 +402,19 @@ protected void setVariable(String instanceId, String name, Object value, RestVar
374402
if (isNew && runtimeService.hasLocalVariable(instanceId, name)) {
375403
throw new FlowableConflictException("Local variable '" + name + "' is already present on plan item instance '" + instanceId + "'.");
376404
}
377-
runtimeService.setLocalVariable(instanceId, name, value);
405+
406+
if (async) {
407+
runtimeService.setLocalVariableAsync(instanceId, name, value);
408+
} else {
409+
runtimeService.setLocalVariable(instanceId, name, value);
410+
}
411+
378412
} else {
379-
runtimeService.setVariable(instanceId, name, value);
413+
if (async) {
414+
runtimeService.setVariableAsync(instanceId, name, value);
415+
} else {
416+
runtimeService.setVariable(instanceId, name, value);
417+
}
380418
}
381419
}
382420

0 commit comments

Comments
 (0)