Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature#3335: Retry failed process step impl #3459

Merged
merged 4 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.eclipse.dirigible.components.engine.bpm.flowable.dto;

public class ActionData {

private String action;

public String getAction() {
return action;
}

public enum Action {
RETRY("RETRY");

private final String actionName;

Action(String actionName) {
this.actionName = actionName;
}

public String getActionName() {
return actionName;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package org.eclipse.dirigible.components.engine.bpm.flowable.endpoint;

import static java.text.MessageFormat.format;
import static org.eclipse.dirigible.components.engine.bpm.flowable.dto.ActionData.Action.*;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -19,6 +20,7 @@
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.eclipse.dirigible.components.base.endpoint.BaseEndpoint;
import org.eclipse.dirigible.components.engine.bpm.flowable.dto.ActionData;
import org.eclipse.dirigible.components.engine.bpm.flowable.dto.ProcessDefinitionData;
import org.eclipse.dirigible.components.engine.bpm.flowable.dto.ProcessInstanceData;
import org.eclipse.dirigible.components.engine.bpm.flowable.dto.VariableData;
Expand All @@ -33,6 +35,7 @@
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.job.api.Job;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -266,6 +269,11 @@ public ResponseEntity<List<VariableInstance>> getProcessInstanceVariables(@PathV
return ResponseEntity.ok(variables);
}

/**
* Add or update active process instance variable
*
* @param id the process instance id
*/
@PostMapping(value = "/bpm-processes/instance/{id}/variables")
public ResponseEntity<Void> addProcessInstanceVariables(@PathVariable("id") String id, @RequestBody VariableData variableData) {

Expand All @@ -279,6 +287,63 @@ public ResponseEntity<Void> addProcessInstanceVariables(@PathVariable("id") Stri
.build();
}

/**
* Execute action on active process instance variable
*
* @param id the process instance id
* @param actionData the action to be executed, possible values: RETRY
*/
@PostMapping(value = "/bpm-processes/instance/{id}")
public ResponseEntity<String> executeProcessInstanceAction(@PathVariable("id") String id, @RequestBody ActionData actionData) {

if (RETRY.getActionName()
.equals(actionData.getAction())) {
BpmService bpmService = getBpmService();
List<Job> jobs = bpmService.getBpmProviderFlowable()
.getProcessEngine()
.getManagementService()
.createDeadLetterJobQuery()
.processInstanceId(id)
.list();
if (jobs.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("No dead letter jobs found for process instance id [" + id + "]");
Dismissed Show dismissed Hide dismissed
}

bpmService.getBpmProviderFlowable()
.getProcessEngine()
.getManagementService()
.moveDeadLetterJobToExecutableJob(jobs.get(0)
.getId(),
1);
return ResponseEntity.ok()
.build();
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("Invalid action id provided [" + actionData.getAction() + "]");
Dismissed Show dismissed Hide dismissed
}
}

/**
* List dead-letter jobs for an active process instance variables.
*
* @param id the process instance id
* @return list of dead-letter jobs
*/
@GetMapping(value = "/bpm-processes/instance/{id}/jobs")
public ResponseEntity<List<Job>> getDeadLetterJobs(@PathVariable("id") String id) {

BpmService bpmService = getBpmService();
List<Job> jobs = bpmService.getBpmProviderFlowable()
.getProcessEngine()
.getManagementService()
.createDeadLetterJobQuery()
.processInstanceId(id)
.list();

return ResponseEntity.ok(jobs);
}

/**
* Gets the process image.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ public ProcessEngine getProcessEngine() {
cfg.setDatabaseSchemaUpdate(updateSchema ? ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE
: ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);

cfg.setAsyncExecutorActivate(true);
processEngine = cfg.buildProcessEngine();
if (logger.isInfoEnabled()) {
logger.info("Done initializng the Flowable Process Engine.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"id" : "asynchronousdefinition",
"type" : "Boolean",
"title" : "Asynchronous",
"value" : "false",
"value" : "true",
"description" : "Define the activity as asynchronous.",
"popular" : true
} ]
Expand All @@ -129,7 +129,7 @@
"id" : "exclusivedefinition",
"type" : "Boolean",
"title" : "Exclusive",
"value" : "false",
"value" : "true",
"description" : "Define the activity as exclusive.",
"popular" : true
} ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
glyph="sap-icon--search" title="Toggle search" aria-label="Toggle search"
ng-click="instances.toggleSearch()">
</fd-button>
<fd-toolbar-separator></fd-toolbar-separator>
<fd-button compact="true" state="{{ instances.selectedProcessInstanceId !== null ? '' : 'disabled' }}" glyph="sap-icon--restart"
title="Retry" aria-label="Retry" ng-click="instances.retry()">
</fd-button>
</fd-toolbar>
<fd-toolbar ng-show="instances.displaySearch">
<fd-input type="search" placeholder="Search" ng-keyup="instances.inputSearchKeyUp($event)"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE HTML>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" ng-app="ide-bpm-process-jobs"
ng-controller="IDEBpmProcessJobsViewController">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" sizes="any" href="data:;base64,iVBORw0KGgo=">
<title dg-view-title></title>
<script type="text/javascript" src="services/bpm-process-jobs-view.js"></script>
<script type="text/javascript" src="/services/js/resources-core/services/loader.js?id=ide-view-js"></script>
<theme></theme>
<script type="text/javascript" src="/webjars/jstree/jstree.min.js"></script>
<script type="text/javascript" src="/services/web/resources-core/ui/widgets/indicator.plugin.js"></script>
<link type="text/css" rel="stylesheet" href="/services/web/resources/styles/jstree.css" />
<link type="text/css" rel="stylesheet" href="/services/js/resources-core/services/loader.js?id=ide-view-css" />
<script type="text/javascript" src="js/bpm-process-jobs.js"></script>
</head>

<body class="dg-vbox">
<fd-scrollbar class="dg-fill-parent">
<table fd-table outer-borders="none" display-mode="compact" class="dg-list-border-bottom">
<thead fd-table-header sticky="true">
<tr fd-table-row>
<th fd-table-header-cell>Id</th>
<th fd-table-header-cell>Process Instance Id</th>
<th fd-table-header-cell>Execution Id</th>
<th fd-table-header-cell>Exception message</th>
<th fd-table-header-cell>Stacktrace</th>
</tr>
</thead>
<tbody fd-table-body>
<tr fd-table-row ng-repeat="next in jobsList track by next.id" hoverable="false" activable="false">
<td fd-table-cell>{{next.id}}</td>
<td fd-table-cell>{{next.processInstanceId}}</td>
<td fd-table-cell>{{next.executionId}}</td>
<td fd-table-cell>{{next.exceptionMessage}}</td>
<td fd-table-cell>{{next.exceptionStacktrace}}</td>
</tr>
<tr ng-if="jobsList.length === 0" fd-table-row>
<td fd-table-cell no-data="true">{{getNoDataMessage()}}</td>
</tr>
</tbody>
</table>
</fd-scrollbar>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"module": "ide-bpm-workspace/services/bpm-process-jobs-view.js",
"extensionPoint": "ide-view",
"description": "Business Process Jobs"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ IDEBPMWorkspacePerspective.config(["messageHubProvider", function (messageHubPro

IDEBPMWorkspacePerspective.controller("BpmWorkspaceViewController", ["$scope", function ($scope) {
$scope.layoutModel = {
views: ["bpm-process-definitions-view", "bpm-process-instances-view", "bpm-process-context-view", "bpm-image-viewer", "bpm-user-tasks"],
views: ["bpm-process-definitions-view", "bpm-process-instances-view", "bpm-process-context-view", "bpm-process-jobs-view", "bpm-image-viewer", "bpm-user-tasks"],
viewSettings: {
"bpm-process-definitions-view": { expanded: true },
"bpm-process-instances-view": { expanded: true },
"bpm-process-context-view": { expanded: true },
"bpm-process-jobs-view": { expanded: true },
"bpm-image-viewer": { closable: false },
},
layoutSettings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ideBpmProcessInstancesView.controller('IDEBpmProcessInstancesViewController', ['
this.instancesList = [];
this.pageSize = 10;
this.currentPage = 1;
this.selectedProcessInstanceId = null;

this.currentFetchDataInstance = null;

Expand Down Expand Up @@ -63,6 +64,27 @@ ideBpmProcessInstancesView.controller('IDEBpmProcessInstancesViewController', ['
this.displaySearch = !this.displaySearch;
}

this.retry = function() {
const apiUrl = '/services/ide/bpm/bpm-processes/instance/' + this.selectedProcessInstanceId;
const requestBody = { 'action': 'RETRY'};

$http({
method: 'POST',
url: apiUrl,
data: requestBody,
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
console.log('Successfully retried process instance with id [' + this.processInstanceId + ']');
$scope.reload();
})
.catch((error) => {
console.error('Error making POST request:', error);
});
}

this.selectAllChanged = function () {
for (let instance of this.instancesList) {
instance.selected = this.selectAll;
Expand All @@ -74,6 +96,7 @@ ideBpmProcessInstancesView.controller('IDEBpmProcessInstancesViewController', ['
messageHub.postMessage('diagram.instance', { instance: instance.id });
messageHub.postMessage('instance.selected', { instance: instance.id });
instance.selected = true;
this.selectedProcessInstanceId = instance.id;

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
* SPDX-License-Identifier: EPL-2.0
*/
let ideBpmProcessJobsView = angular.module('ide-bpm-process-jobs', ['ideUI', 'ideView']);

ideBpmProcessJobsView.config(["messageHubProvider", function (messageHubProvider) {
messageHubProvider.eventIdPrefix = 'bpm';
}]);

ideBpmProcessJobsView.controller('IDEBpmProcessJobsViewController', ['$scope', '$http', '$timeout', 'messageHub', function ($scope, $http, $timeout,messageHub,) {

$scope.jobsList = [];

$scope.reload = function () {
console.log("Reloading data for current process instance id: " + $scope.currentProcessInstanceId)
$scope.fetchData($scope.currentProcessInstanceId);
};

$scope.fetchData = function(processInstanceId) {
$http.get('/services/ide/bpm/bpm-processes/instance/' + processInstanceId + '/jobs', { params: { 'limit': 100 } })
.then((response) => {
$scope.jobsList = response.data;
});
}

$scope.getNoDataMessage = function () {
return 'No jobs have been found.';
}

messageHub.onDidReceiveMessage('instance.selected', function (msg) {
const processInstanceId = msg.data.instance;
$scope.fetchData(processInstanceId);
});

}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
* SPDX-License-Identifier: EPL-2.0
*/
const viewData = {
id: "bpm-process-jobs-view",
label: "Dead-Letter Jobs",
factory: "frame",
region: "bottom",
link: "../ide-bpm-workspace/bpm-process-jobs.html",
};
if (typeof exports !== 'undefined') {
exports.getView = function () {
return viewData;
}
}
Loading