Skip to content

Commit

Permalink
Fix #958 - Allow async execution of flow from Rest API
Browse files Browse the repository at this point in the history
  • Loading branch information
gwilmer committed Feb 8, 2021
1 parent 4aa1ad8 commit a1671e9
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 21 deletions.
77 changes: 56 additions & 21 deletions metl-ui/src/main/java/org/jumpmind/metl/ui/api/ExecutionApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.HandlerMapping;
Expand Down Expand Up @@ -135,8 +136,12 @@ public class ExecutionApi {
@ResponseBody
public final ExecutionResults invoke(@ApiParam(value = "The name of the agent to use") @PathVariable("agentName") String agentName,
@ApiParam(value = "The name of the flow deployment to invoke") @PathVariable("deploymentName") String deploymentName,
@ApiParam(value = "Wether to start the flow asynchronously and poll for status") @RequestParam(required = false) Boolean async,
HttpServletRequest req) {
return callFlow(agentName, deploymentName, null, req);
if (async == null) {
async=false;
}
return callFlow(agentName, deploymentName, null, req, async);
}

@ApiOperation(
Expand All @@ -147,10 +152,25 @@ public final ExecutionResults invoke(@ApiParam(value = "The name of the agent to
public final ExecutionResults invoke(@ApiParam(value = "The name of the agent to use") @PathVariable("agentName") String agentName,
@ApiParam(value = "The name of the flow deployment to invoke") @PathVariable("deploymentName") String deploymentName,
@ApiParam(value = "The version of the deployed flow to invoke") @PathVariable("versionName") String versionName,
HttpServletRequest req) {
return callFlow(agentName, deploymentName, versionName, req);
@ApiParam(value = "Wether to start the flow asynchronously and poll for status") @RequestParam(required = false) Boolean async,
HttpServletRequest req) {
if (async == null) {
async=false;
}
return callFlow(agentName, deploymentName, versionName, req, async);
}

@ApiOperation(
value = "Check the status of a flow that has been invoked. This is the way a non-webservice enabled flow that has been invoked asynchronously can have status checked")
@RequestMapping(value = "/executions/{executionId}/status", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public final ExecutionResults status(@ApiParam(value = "The execution Id of the flow on which to check status") @PathVariable("executionId") String executionId,
HttpServletRequest req) {
return checkStatus(executionId);
}


@ApiIgnore
@RequestMapping(value = WS + "/**", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
Expand Down Expand Up @@ -438,7 +458,7 @@ private String whoAreYou(HttpServletRequest req) {
return userId;
}

protected final ExecutionResults callFlow(String agentName, String deploymentName, String versionName, HttpServletRequest req) {
protected final ExecutionResults callFlow(String agentName, String deploymentName, String versionName, HttpServletRequest req, Boolean async) {
agentName = decode(agentName);
deploymentName = decode(deploymentName);
Set<Agent> agents = agentManager.getAvailableAgents();
Expand Down Expand Up @@ -470,7 +490,7 @@ protected final ExecutionResults callFlow(String agentName, String deploymentNam
if (!done) {
AppUtils.sleep(50);
}
} while (!done);
} while (!done && !async);
break;
}
}
Expand All @@ -479,8 +499,33 @@ protected final ExecutionResults callFlow(String agentName, String deploymentNam
}

if (execution != null) {
ExecutionResults result = new ExecutionResults(execution.getId(), execution.getStatus(), execution.getStartTime(),
execution.getEndTime());
ExecutionResults result = checkStatus(execution.getId());
if (execution.getExecutionStatus() == ExecutionStatus.ERROR) {
//keep this the way it was for backwards compatibility
//although i don't like an http error in this circumstance
//because the flow was successfully kicked off, but failed
throw new FailureException(result);
} else {
return result;
}
} else {
String msg = "Unexpected error";
if (!foundAgent) {
msg = String.format("Could not find an agent named '%s'", agentName);
} else if (!foundDeployment) {
msg = String.format("Could not find a deployment name '%s'", deploymentName);
} else {
msg = String.format("Found deployment '%s', but it was not enabled", deploymentName);
}
throw new CouldNotFindDeploymentException(msg);
}
}

protected ExecutionResults checkStatus(String executionId) {
Execution execution = executionService.findExecution(executionId);
if (execution != null) {
ExecutionResults result = new ExecutionResults(execution.getId(), execution.getStatus(), execution.getStartTime(),
execution.getEndTime());
if (execution.getExecutionStatus() == ExecutionStatus.ERROR) {
List<ExecutionStep> steps = executionService.findExecutionSteps(execution.getId());
for (ExecutionStep executionStep : steps) {
Expand All @@ -494,23 +539,13 @@ protected final ExecutionResults callFlow(String agentName, String deploymentNam
}
}
}

throw new FailureException(result);
}
return result;
}
return result;
} else {
String msg = "Unexpected error";
if (!foundAgent) {
msg = String.format("Could not find an agent named '%s'", agentName);
} else if (!foundDeployment) {
msg = String.format("Could not find a deployment name '%s'", deploymentName);
} else {
msg = String.format("Found deployment '%s', but it was not enabled", deploymentName);
}
throw new CouldNotFindDeploymentException(msg);
throw new ExecutionNotFoundException(String.format("An execution with id %s was not found", executionId));
}
}

protected String decode(String value) {
try {
return URLDecoder.decode(value, "UTF-8");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Licensed to JumpMind Inc under one or more contributor
* license agreements. See the NOTICE file distributed
* with this work for additional information regarding
* copyright ownership. JumpMind Inc licenses this file
* to you under the GNU General Public License, version 3.0 (GPLv3)
* (the "License"); you may not use this file except in compliance
* with the License.
*
* You should have received a copy of the GNU General Public License,
* version 3.0 (GPLv3) along with this library; if not, see
* <http://www.gnu.org/licenses/>.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jumpmind.metl.ui.api;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value=HttpStatus.NOT_FOUND)
public class ExecutionNotFoundException extends RuntimeException {

private static final long serialVersionUID = 1L;

public ExecutionNotFoundException(String msg) {
super(msg);
}
}

0 comments on commit a1671e9

Please sign in to comment.