package betsy.bpmn.engines.jbpm; import java.nio.file.Path; import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import betsy.bpmn.engines.BPMNProcessStarter; import betsy.bpmn.engines.JsonHelper; import betsy.bpmn.model.Variables; import betsy.common.tasks.FileTasks; import betsy.common.tasks.WaitTasks; import betsy.common.timeouts.timeout.TimeoutRepository; import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import pebl.benchmark.test.steps.vars.Variable; public class JbpmProcessStarter implements BPMNProcessStarter { private static final Logger LOGGER = Logger.getLogger(JbpmProcessStarter.class); private static final Pattern LOG_FILE_EXTRACT_DEPLOYMENT_ID = Pattern.compile("DEPLOY job for \\[([^\\]]*)\\]"); private final String user; private final String password; private final String requestUrl; private final Path serverLog; public JbpmProcessStarter(Path serverLog) { this.serverLog = Objects.requireNonNull(serverLog); user = "admin"; password = "admin"; requestUrl = "http://localhost:8080/jbpm-console"; } @Override public void start(String processName, List<Variable> variables) throws RuntimeException { // determine deployment String deploymentID = getDeploymentID(requestUrl, user, password); if (Objects.equals(deploymentID, "")) { deploymentID = FileTasks.readAllLines(serverLog) .stream() .map(line -> { Matcher matcher = LOG_FILE_EXTRACT_DEPLOYMENT_ID.matcher(line); if (matcher.find()) { return matcher.group(1); } else { return null; } }) .filter(Objects::nonNull) .findFirst().orElse(""); } if (Objects.equals(deploymentID, "")) { LOGGER.error("Cannot start as the deployment ID cannot be determined for " + processName + " with " + variables); return; } String queryParameter = new Variables(variables).toQueryParameter(); String processStartRequestURL = requestUrl + "/rest/runtime/" + deploymentID + "/process/" + processName + "/start" + queryParameter; try { LOGGER.info("Trying to start process \"" + processName + "\"."); JsonHelper.postStringWithAuth(processStartRequestURL, new JSONObject(), 200, user, password); } catch (RuntimeException ex) { if (ex.getMessage() != null && ex.getMessage().contains("No runtime manager could be found")) { LOGGER.info("Instantiation failed as no runtime manager could be found. Retrying in " + TimeoutRepository.getTimeout("JbpmTester.runTest").getTimeoutInMs() + "ms."); //retry after delay WaitTasks.sleep(TimeoutRepository.getTimeout("JbpmTester.runTest").getTimeoutInMs()); try { JsonHelper.postStringWithAuth(processStartRequestURL, new JSONObject(), 200, user, password); } catch (RuntimeException innerEx) { LOGGER.info("Runtime error: Instantiation still not possible. Aborting test.", innerEx); throw new RuntimeException(innerEx); } } else { LOGGER.info("Runtime error: Instantiation of process failed. Reason:", ex); throw new RuntimeException(ex); } } } public static String getDeploymentID(String requestUrl, String user, String password) { JSONArray json = JsonHelper.getJSONWithAuthAsArray(requestUrl + "/rest/deployment/", 200, user, password); if (json.length() == 0) { return ""; } JSONObject jsonObject = json.optJSONObject(0); if (jsonObject.has("deploymentUnitList")) { JSONArray deploymentUnitList = jsonObject.optJSONArray("deploymentUnitList"); if (deploymentUnitList.length() == 0) { LOGGER.error("Could not retrieve deployment ID"); return ""; } JSONObject firstElement = null; try { firstElement = deploymentUnitList.getJSONObject(0); } catch (JSONException e) { throw new RuntimeException(e); } if (firstElement.has("deployment-unit")) { JSONObject deploymentUnit = firstElement.optJSONObject("deployment-unit"); return getDeploymentID(deploymentUnit); } else { return getDeploymentID(firstElement); } } else { return getDeploymentID(jsonObject); } } public static String getDeploymentID(JSONObject deploymentUnit) { return deploymentUnit.optString("groupId") + ":" + deploymentUnit.optString("artifactId") + ":" + deploymentUnit.optString("version"); } }