diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b384c19..dc5c740e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Added service to stop the execution of the workflow instance - nflow-rest: - Added service to stop the execution of the workflow instance + - Add support for user-provided action description when updating a workflow instance ## 1.2.0 (2014-12-23) diff --git a/ROADMAP.md b/ROADMAP.md index 46c27f145..de6f75774 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,37 +1,51 @@ -## 1.X.X +## Next release -* fixes and new features based on production needs -* more examples of nflow usage -* screencast of making example application - -## 2.0.0 (Vuohi) - -**target date 28.11.2014** - -* nFlow radiator - * pie chart for workflows in different states - * graphs for visualizing incoming/processed workflow instances -* nFlow management UI - * search workflow instances - * update workflow instance state - * visualization of workflow instances (incl. action history) -* workflow management - * high-level locks - only one workflow against lock running at a time - * subworkflow support - * internal nFlow metastate for workflows (created, started, finished)? -* archive tables -* performance testing -* quickstart maven archetype -* improved PostgreSQL support -* optional support for flyway +* Performance test framework +* Performance improvements +* Support for sub-workflows +* Status for workflows (created, in progress, finished etc.) +* Type for workflow actions (normal, manual, recovery etc.) +* Improvement for handling not permitted state changes +* Add checksum for workflow definitions in database to allow easy comparison +* Improvement for handling invalid states +* Training material +* Marketing material +* Fixes and new features based on production needs ## Future releases -* improved human workflow support - * e.g. send ticket (http-link containing token) through email for opening a form in which human task can be performed -* tools for generating workflow definition skeleton based on graph -* alarms (with configurable thresholds) -* additional data storage support - * Oracle - * MongoDB - * DB2 +* Quickstart maven archetype +* Optional support for database migration tool +* RequestData validation based on workflow definition when inserting new workflow instances +* Support for other databases +* High-level locks - only one workflow instance against lock running at a time +* Archive tables +* Improved human workflow support +* Tools for generating workflow definition skeletons +* Human-friendly mode for REST API +* Immediate execution of new workflow instance (if not busy) +* Increase test coverage +* Screencast of making an example application +* Support alarms +* Support alarm configuration in Explorer +* Support WAR and EAR packaging +* Option to skip writing workflow action when updating workflow instance to database +* Switch from JodaTime to Java 8 Date and Time API +* Java client for nFlow REST API +* nFlow Eclipse plugin +* Replace CXF with Jersey +* Add package-descriptions to javadocs +* Design and order nFlow stickers +* Support large amount of results in workflow instance search +* Provide more examples on using nFlow in different ways +* Support specifying next activation time as delta instead of absolute time in API +* Guice module that starts nFlow engine +* Define allowed state changes with annotations +* Support multiple executor groups in one Explorer +* Align Explorer page "buttons" to left +* Avoid throwing generic RuntimeExceptions +* Add missing javadocs for public API +* Configuration to disable Swagger and/or Explorer +* Fork/join support +* Collect metrics from REST API +* Remove need for transactions when using PostgreSQL to allow enabling auto-commit diff --git a/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResource.java b/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResource.java index 32ea797d9..eb28c53f1 100644 --- a/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResource.java +++ b/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResource.java @@ -7,6 +7,7 @@ import static javax.ws.rs.core.Response.status; import static javax.ws.rs.core.Response.Status.CONFLICT; import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.trimToEmpty; import static org.apache.commons.lang3.StringUtils.trimToNull; import static org.joda.time.DateTime.now; @@ -86,14 +87,18 @@ public Response createWorkflowInstance(@Valid CreateWorkflowInstanceRequest req) public Response updateWorkflowInstance(@ApiParam("Internal id for workflow instance") @PathParam("id") int id, UpdateWorkflowInstanceRequest req) { WorkflowInstance.Builder builder = new WorkflowInstance.Builder().setId(id); - String msg = ""; + String msg = defaultIfBlank(req.actionDescription, ""); if (!isEmpty(req.state)) { builder.setState(req.state); - msg = "API changed state to " + req.state + ". "; + if (isBlank(req.actionDescription)) { + msg = "API changed state to " + req.state + ". "; + } } if (req.nextActivationTime != null) { builder.setNextActivation(req.nextActivationTime); - msg += "API changed nextActivationTime to " + req.nextActivationTime + "."; + if (isBlank(req.actionDescription)) { + msg += "API changed nextActivationTime to " + req.nextActivationTime + "."; + } } if (msg.isEmpty()) { return noContent().build(); diff --git a/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/msg/UpdateWorkflowInstanceRequest.java b/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/msg/UpdateWorkflowInstanceRequest.java index ca73f6181..ede19094e 100644 --- a/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/msg/UpdateWorkflowInstanceRequest.java +++ b/nflow-rest-api/src/main/java/com/nitorcreations/nflow/rest/v1/msg/UpdateWorkflowInstanceRequest.java @@ -17,4 +17,6 @@ public class UpdateWorkflowInstanceRequest { @ApiModelProperty(value = "New next activation time for next workflow instance processing", required=false) public DateTime nextActivationTime; + @ApiModelProperty(value = "Description of the action", required = false) + public String actionDescription; } diff --git a/nflow-rest-api/src/test/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResourceTest.java b/nflow-rest-api/src/test/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResourceTest.java index b6c7fe74f..a045ffb73 100644 --- a/nflow-rest-api/src/test/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResourceTest.java +++ b/nflow-rest-api/src/test/java/com/nitorcreations/nflow/rest/v1/WorkflowInstanceResourceTest.java @@ -84,7 +84,18 @@ public void whenUpdatingStateUpdateWorkflowInstanceWorks() { req.state = "newState"; resource.updateWorkflowInstance(3, req); verify(workflowInstances).updateWorkflowInstance((WorkflowInstance) argThat(hasField("state", equalTo(req.state))), - (WorkflowInstanceAction)argThat(hasField("stateText", equalTo("API changed state to newState.")))); + (WorkflowInstanceAction) argThat(hasField("stateText", equalTo("API changed state to newState.")))); + } + + @Test + public void whenUpdatingStateWithDescriptionUpdateWorkflowInstanceWorks() { + when(workflowInstances.getWorkflowInstance(3)).thenReturn(i); + UpdateWorkflowInstanceRequest req = new UpdateWorkflowInstanceRequest(); + req.state = "newState"; + req.actionDescription = "description"; + resource.updateWorkflowInstance(3, req); + verify(workflowInstances).updateWorkflowInstance((WorkflowInstance) argThat(hasField("state", equalTo(req.state))), + (WorkflowInstanceAction) argThat(hasField("stateText", equalTo("description")))); } @Test @@ -93,8 +104,10 @@ public void whenUpdatingNextActivationTimeUpdateWorkflowInstanceWorks() { UpdateWorkflowInstanceRequest req = new UpdateWorkflowInstanceRequest(); req.nextActivationTime = new DateTime(2014,11,12,17,55,0); resource.updateWorkflowInstance(3, req); - verify(workflowInstances).updateWorkflowInstance((WorkflowInstance) argThat(hasField("state", equalTo(null))), - (WorkflowInstanceAction)argThat(hasField("stateText", equalTo("API changed nextActivationTime to " + req.nextActivationTime + ".")))); + verify(workflowInstances).updateWorkflowInstance( + (WorkflowInstance) argThat(hasField("state", equalTo(null))), + (WorkflowInstanceAction) argThat(hasField("stateText", equalTo("API changed nextActivationTime to " + + req.nextActivationTime + ".")))); } @Test @@ -111,6 +124,17 @@ public void stoppingWorkflowInstanceWithEmptyActionDescriptionWorks() { verify(workflowInstances).stopWorkflowInstance(3, "Workflow stopped via API"); } + @Test + public void whenUpdatingNextActivationTimeWithDescriptionUpdateWorkflowInstanceWorks() { + when(workflowInstances.getWorkflowInstance(3)).thenReturn(i); + UpdateWorkflowInstanceRequest req = new UpdateWorkflowInstanceRequest(); + req.nextActivationTime = new DateTime(2014, 11, 12, 17, 55, 0); + req.actionDescription = "description"; + resource.updateWorkflowInstance(3, req); + verify(workflowInstances).updateWorkflowInstance((WorkflowInstance) argThat(hasField("state", equalTo(null))), + (WorkflowInstanceAction) argThat(hasField("stateText", equalTo("description")))); + } + @SuppressWarnings("unchecked") @Test public void listWorkflowInstancesWorks() {