A Camel Demo for Amazon's Simple Worklfow Service
Join the DZone community and get the full member experience.
Join For FreeIn a previous post I explained why AWS SWF service is good and announced the new Camel SWF component. Now the component documentation is ready and here is a simple, fully working demo. It consist of three independent standalone Camel routes:
A workflow producer allows us to interact with a workflow. It can
start a new workflow execution, query its state, send signals to a
running workflow, or terminate and cancel it. In our demo, the
WorkflowProducer starts a route that schedules 10 workflow executions where the each execution receives as an argument a number.
package com.ofbizian.swf.demo; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.main.Main; public class WorkflowProducer { public static String COMMON_OPTIONS = "accessKey=XXX" + "&secretKey=XXX" + "&domainName=demo" + "&workflowList=demo-wlist" + "&activityList=demo-alist" + "&version=1.0" + "&clientConfiguration.endpoint=swf.eu-west-12.amazonaws.com"; public static void main(String[] args) throws Exception { Main main = new Main(); main.enableHangupSupport(); WorkflowProducerRoute route = new WorkflowProducerRoute(); main.addRouteBuilder(route); main.run(); } static class WorkflowProducerRoute extends RouteBuilder { @Override public void configure() throws Exception { from("timer://workflowProducer?repeatCount=10") .setBody(property("CamelTimerCounter")) .to("aws-swf://workflow?" + COMMON_OPTIONS + "&eventName=calculator") .log("SENT WORKFLOW TASK ${body}"); } } }
Once a workflow execution is scheduled, we need a process that will decide
what are the next steps for it. In Camel it is done using a Workflow
Consumer. A workflow consumer represents the workflow logic. When it is
started, it will start polling workflow decision tasks and process them.
In addition to processing decision tasks, a workflow consumer route,
will also receive signals (send from a workflow producer) or state
queries. The primary purpose of a workflow consumer is to schedule
activity tasks for execution using activity producers. Actually activity
tasks can be scheduled only from a thread started by a workflow
consumer.
package com.ofbizian.swf.demo; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.aws.swf.SWFConstants; import org.apache.camel.main.Main; public class WorkflowConsumer { public static void main(String[] args) throws Exception { Main main = new Main(); main.enableHangupSupport(); WorkflowConsumerRoute route = new WorkflowConsumerRoute(); main.addRouteBuilder(route); main.run(); } static class WorkflowConsumerRoute extends RouteBuilder { @Override public void configure() throws Exception { from("aws-swf://workflow?" + WorkflowProducer.COMMON_OPTIONS + "&eventName=calculator") .choice() .when(header(SWFConstants.ACTION).isEqualTo(SWFConstants.SIGNAL_RECEIVED_ACTION)) .log("Signal received ${body}") .when(header(SWFConstants.ACTION).isEqualTo(SWFConstants.GET_STATE_ACTION)) .log("State asked ${body}") .when(header(SWFConstants.ACTION).isEqualTo(SWFConstants.EXECUTE_ACTION)) .setBody(simple("${body[0]}")) .log("EXECUTION TASK RECEIVED ${body}") .filter(simple("${body} > 5")) .to("aws-swf://activity?" + WorkflowProducer.COMMON_OPTIONS + "&eventName=incrementor"); } } }
The logic in our demo decider is simple: if the incoming argument is
greater than 5, we schedule a task for execution. Otherwise the workflow
will complete as there are no other tasks to be executed. Notice that
it also has branches for handing signal and state query events.
The final peace of our distributed (since it consists of three
independent applications) workflow application is the ActivityConsumer
that actually performs some calculations. It has the simplest possible
implementation: increments the given argument and returns it.
package com.ofbizian.swf.demo; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.main.Main; public class ActivityConsumer { public static void main(String[] args) throws Exception { Main main = new Main(); main.enableHangupSupport(); ActivityConsumerRoute route = new ActivityConsumerRoute(); main.addRouteBuilder(route); main.run(); } static class ActivityConsumerRoute extends RouteBuilder { @Override public void configure() throws Exception { from("aws-swf://activity?" + WorkflowProducer.COMMON_OPTIONS + "&eventName=incrementor") .setBody(simple("${body[0]}")) .log("RECEIVED ACTIVITY TASK ${body}") .setBody(simple("${body}++")); } } }
All you need to do to run this demo is to create the appropriate workflow domain and add your key/secret to the route.
Published at DZone with permission of Bilgin Ibryam, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
4 Expert Tips for High Availability and Disaster Recovery of Your Cloud Deployment
-
Security Challenges for Microservice Applications in Multi-Cloud Environments
-
Web Development Checklist
-
Transactional Outbox Patterns Step by Step With Spring and Kotlin
Comments