tag:blogger.com,1999:blog-49178053071261051282024-03-20T02:35:41.983-07:00Accelerate your businessMaciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comBlogger138125tag:blogger.com,1999:blog-4917805307126105128.post-26727463496409375382022-07-03T23:28:00.004-07:002022-07-03T23:28:57.328-07:00An alternative look at workflows in cloud era<p><span style="caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px;">Workflows have been around software development for many decades. With its peak popularity around the SOA (service oriented architecture) times. Although it was always positioned as something on top, something superior. In fact, it led to smaller adoption as it became quite complex to build solutions on centralized workflow platforms. </span></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Currently workflows are starting to be more and more popular again, though their main use case is around service orchestration. In my opinion, this is the biggest misconception around workflows - they are actually way more than just service orchestration. </p><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">What are workflows good at then?</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Workflows serve very well in following use cases</p><ul style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin-bottom: 10px; margin-top: 0px; text-size-adjust: auto;"><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">business entity life cycle</strong><span class="Apple-converted-space"> </span>- a common use case in various enterprises or domains is to build systems that are responsible for an end to end life cycle of the business entity, e.g. parts in the automotive industry. Parts have well defined life cycle that goes through number of phases</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">event streams</strong><span class="Apple-converted-space"> </span>- execute business logic on top of the event stream. More and more common are IoT based use cases where workflows can run very close to the sensors without the need to push data to some cloud offerings for processing</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">batch processing</strong><span class="Apple-converted-space"> </span>- workflows are perfect fit for defining batch processors that are usually triggered by time events (run every night at 10pm) or by incoming message</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">human centric systems</strong><span class="Apple-converted-space"> </span>- workflows come with out of the box features that allow to model and implement advanced interactions with human actors such as reassignment, notifications, escalations and more</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">Kubernetes operators</strong><span class="Apple-converted-space"> </span>- operator pattern in Kubernetes is an excellent example where workflows have a natural place, operator logic is a constantly repeating the set of steps to reach the desired state of the resource, workflows can easily define the steps and then repeat consistently for each resource deployed to Kubernetes cluster</p></li></ul><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">The other aspect of a bit misleading approach to workflows is that they are usually outside of the service or system. While this makes sense for service orchestration use cases, it does not bring much value when it comes to above mentioned scenarios. Instead, workflows could play an essential role in the service or system being built. Let’s explore what this could look like and how it corresponds to the cloud.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">With that, let’s introduce three new concepts around workflows</p><ul style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin-bottom: 10px; margin-top: 0px; text-size-adjust: auto;"><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;">workflow as a service</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;">workflow as a function</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;">workflow as a function flow</p></li></ul><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">Workflow as a service</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Workflow as a service aims at using workflows to be the base for creating service on top of it. This means that developers use workflows as a sort of programming language, yet another one in their tool box to avoid the need of developing the boilerplate code. Let’s break this down a little bit </p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><img class="fr-fic fr-draggable fr-dib" data-creationdate="1656833453988" data-creationdateformatted="07/03/2022 07:30 AM" data-id="16017290" data-image="true" data-mimetype="image/png" data-modificationdate="null" data-name="1656833452926.png" data-new="false" data-size="86188" data-sizeformatted="86.2 kB" data-type="temp" data-url="https://dz2cdn1.dzone.com/storage/temp/16017290-1656833452926.png" src="https://dz2cdn1.dzone.com/storage/temp/16017290-1656833452926.png" style="border: 0px; box-sizing: border-box; cursor: pointer; display: block; float: none !important; height: auto; margin: auto; max-width: 100%; position: relative; text-align: center; vertical-align: top; width: 800px;" /></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">In the above workflow definition we can find few important aspects</p><ul style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin-bottom: 10px; margin-top: 0px; text-size-adjust: auto;"><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">set of activities</strong><span class="Apple-converted-space"> </span>that tells what will actually happen</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">data model</strong><span class="Apple-converted-space"> </span>(partNumber, info, status and valid) that represents a complete set of information associated with given resource</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">metadata</strong><span class="Apple-converted-space"> </span>of the workflow like id, name, version, etc</p></li></ul><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">All of that is considered source information to build up a service from it. Essentially, workflow definition represents CRUD (create, read, update, delete) service interface. The data model represents the resource behind the service interface - it’s the entity that the CRUD operations are managing. Set of activities extends the CRUD service interface with additional capabilities to allow consumers of the service a richer interaction model. </p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Workflow as a service concept aims at using workflow definition as input and transforming it to a fully functional service interface with complete business logic implementation instead of just having a set of stubs generated. Main idea behind it is to allow developers to focus on what is important - the business logic that is specific to the domain they work in rather than developing things that can be easily derived from the business model - CRUD service interface.</p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><img class="fr-fic fr-draggable fr-dib" data-creationdate="1656834110525" data-creationdateformatted="07/03/2022 07:41 AM" data-id="16017292" data-image="true" data-mimetype="image/png" data-modificationdate="null" data-name="1656834109223.png" data-new="false" data-size="167634" data-sizeformatted="167.6 kB" data-type="temp" data-url="https://dz2cdn1.dzone.com/storage/temp/16017292-1656834109223.png" src="https://dz2cdn1.dzone.com/storage/temp/16017292-1656834109223.png" style="border: 0px; box-sizing: border-box; cursor: pointer; display: block; float: none !important; height: auto; margin: auto; max-width: 100%; position: relative; text-align: center; vertical-align: top; width: 800px;" /></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">Workflow as a function</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Workflow as a function aims at taking more advantage of the various cloud offerings to offload developers from taking care of infrastructure. Cloud functions become quite popular where the most famous is AWS Lambda, but certainly it is not the only one. Other ones that are popular are Azure Functions and Google Cloud Functions but there are others that are starting to pop out as well. </p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Workflows can be used to model a business logic that will be then deployed as a function to one of the cloud offerings. What is important is that the workflow acts like an abstraction layer that again allows one to focus on the business needs rather than the plumbing code to know what it takes to run it as AWS Lambda or Azure Function.</p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><img class="fr-fic fr-dib fr-draggable" data-creationdate="1656832966319" data-creationdateformatted="07/03/2022 07:22 AM" data-id="16017285" data-image="true" data-mimetype="image/png" data-modificationdate="null" data-name="1656832965287.png" data-new="false" data-size="285833" data-sizeformatted="285.8 kB" data-type="temp" data-url="https://dz2cdn1.dzone.com/storage/temp/16017285-1656832965287.png" height="294px;" src="https://dz2cdn1.dzone.com/storage/temp/16017285-1656832965287.png" style="border: 0px; box-sizing: border-box; cursor: pointer; display: block; float: none !important; height: auto; margin: auto; max-width: 100%; position: relative; text-align: center; vertical-align: top;" width="928px;" /></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Above workflow, that is a user registration use case, clearly defines what is the business logic behind it and it is specific to a given domain. Workflow as a function means that it will be considered as a function, with well defined input and output. Deployment to the cloud function environment becomes the secondary aspect that is taken care of automatically.</p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">Workflow as a function flow</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Last but not least is the workflow as a function flow. It expands on the idea of workflow as a function where the main principle is to model business use case as complete as possible but break it down to number of functions that are </p><ul style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin-bottom: 10px; margin-top: 0px; text-size-adjust: auto;"><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">self contained</strong><span class="Apple-converted-space"> </span>- represent given piece of business logic</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">independent</strong><span class="Apple-converted-space"> </span>- are not aware of any other function</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">invokable at any time</strong><span class="Apple-converted-space"> </span>- can be triggered at any point in time regardless of the other functions</p></li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;"><p dir="ltr" style="box-sizing: border-box; margin: 5px 0px 15px;"><strong style="box-sizing: border-box;">scalable</strong><span class="Apple-converted-space"> </span>- functions can be easily scaled to accommodate the traffic needs</p></li></ul><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><img class="fr-fic fr-draggable fr-dib" data-creationdate="1656833024417" data-creationdateformatted="07/03/2022 07:23 AM" data-id="16017286" data-image="true" data-mimetype="image/png" data-modificationdate="null" data-name="1656833022881.png" data-new="false" data-size="336859" data-sizeformatted="336.9 kB" data-type="temp" data-url="https://dz2cdn1.dzone.com/storage/temp/16017286-1656833022881.png" height="294px;" src="https://dz2cdn1.dzone.com/storage/temp/16017286-1656833022881.png" style="border: 0px; box-sizing: border-box; cursor: pointer; display: block; float: none !important; height: auto; margin: auto; max-width: 100%; position: relative; text-align: center; vertical-align: top;" width="928px;" /></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Business logic is then represented at runtime as individual functions that are triggered by events. Each function has input (an event) and can produce zero or many outputs (events). In turn, produced events can trigger other functions. What is important to mention is that functions do not trigger (or call) other functions explicitly, they simply produce events that other functions can consume.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">This approach opens the doors for greater scalability as events can be efficiently distributed across many replicas of the functions.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Regardless of the concept used, workflows come with many features that make them useful to build core business logic. Something that is usually overlooked is the isolation characteristic that workflows bring by design. Workflows are built as a definition, sort of a blueprint and then this blueprint is instantiated to represent individual instances. Each instance exists in complete isolation, including its data, state, etc. Other features that are important are:</p><ul style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin-bottom: 10px; margin-top: 0px; text-size-adjust: auto;"><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;">reliable persistence, </li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;">distributed timer/job scheduling and execution, </li><li dir="ltr" style="box-sizing: border-box; padding: 0px 0px 8px;">messaging integration and many more.</li></ul><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">Enough theory, can this actually run?</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Being introduced to the concepts, an obvious question is - can it actually run? Is there anything that implements those concepts? </p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">The short answer is<span class="Apple-converted-space"> </span><strong style="box-sizing: border-box;">YES</strong>!</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">This leads us to an open source framework called<span class="Apple-converted-space"> </span><a href="https://automatiko.io/" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Automatiko</a><span class="Apple-converted-space"> </span>that aims at building services and functions based on workflows. It implements all three concepts in a unique way. Let’s explore a little bit about the framework itself.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Automatiko is built with Java, it’s fully open source under Apache 2 license and can be freely used for any type of use cases. It is built on top of<span class="Apple-converted-space"> </span><a href="https://quarkus.io/" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Quarkus</a>, a cloud native Java toolkit for building services of any kind. Automatiko seamlessly integrates with Quarkus to allow developers to be effective and to have the best developer experience.</p><h4 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.2; margin-bottom: 5px; margin-top: 20px; text-size-adjust: auto;">So how does Automatiko deliver workflow as a service, function and function flow?</h4><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">First and foremost, it follow Quarkus philosophy to perform as many things at build time. So it does all the heavy lifting at build time. The main parts of this hard work is to transform the workflows into service, function or function flow. Let’s dive into each of the concepts' implementation to understand it better.</p><h4 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.2; margin-bottom: 5px; margin-top: 20px; text-size-adjust: auto;">Workflow as a service in Automatiko </h4><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Automatiko at build time will look at workflow definitions and transform them to service interface - REST service interface with a complete definition based on OpenAPI. It can also create a GraphQL service interface that will open up for more advanced use cases to take advantage of applying principles of under and over fetching that GraphQL comes with. </p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">As mentioned before, it integrates with Quarkus and allows users to use any feature of Quarkus to pair it with the need of workflows. Taking it even further Automatiko discovers what is available and binds to it without much of a hassle. An example of it is integration with data stores or messaging brokers that can be easily used from workflows.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><a href="https://github.com/automatiko-io/automatiko-examples/tree/main/event-streams-sensors" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">A complete and ready to run example</a></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><h4 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.2; margin-bottom: 5px; margin-top: 20px; text-size-adjust: auto;">Workflow as a function in Automatiko</h4><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">To implement workflow as a function, Automatiko relies on<span class="Apple-converted-space"> </span><a href="https://quarkus.io/guides/funqy" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Funqy</a>, a Quarkus approach to building portable java functions. Similar to how it is done for workflow as a service, Automatiko at build time examines workflows and creates functions from them. As the aim for workflow as function is to be completely agnostic from the deployment platform, there is no need to change any line of code to make the function runnable on AWS Lambda, Azure Functions or Google Cloud Functions. It only requires project configuration (like dependencies) which Automatiko provides as configuration profiles.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><a href="https://github.com/automatiko-io/automatiko-examples/tree/main/user-registration-function" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">A complete and ready to run example</a></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><br style="box-sizing: border-box;" /></p><h4 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.2; margin-bottom: 5px; margin-top: 20px; text-size-adjust: auto;">Workflow as a function flow in Automatiko</h4><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Lastly, workflow as a function flow in Automatiko is also based on Funqy, but this time it leverages<span class="Apple-converted-space"> </span><a href="https://knative.dev/" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Knative</a><span class="Apple-converted-space"> </span>project to build function chaining based on events (<a href="https://cloudevents.io/" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Cloud Events</a>). Knative is a kubernetes based platform to deploy and manage modern serverless workloads. In particular, Knative eventing comes with universal subscription, delivery and management of events that allows to build modern applications by attaching business logic on top of the data stream - the events.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Again, at build time Automatiko breaks down the workflows into a set of functions and creates all the Knative manifest files required to deploy it. It comes with a trigger setup that binds all the pieces together (Knative eventing and the functions) so developers can easily move this from development to production.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgSHNnYElAw60Mig5sCFXCQr0mff-0gORSrgGtCcyTB7f-j2ByVnJK2swh-0ymeQj17B_w0Aar-HDLZQxKdQOIk20UWCgZyUvaYN9IeMA6WRQ3sklHS-9dLduVyCfqIo4ehCp9kytkYvdfMU9MzWdqMclAky0qzXO5IX8Z9uPsIDtyWzPGNr0iRZoxd" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="493" data-original-width="654" height="483" src="https://blogger.googleusercontent.com/img/a/AVvXsEgSHNnYElAw60Mig5sCFXCQr0mff-0gORSrgGtCcyTB7f-j2ByVnJK2swh-0ymeQj17B_w0Aar-HDLZQxKdQOIk20UWCgZyUvaYN9IeMA6WRQ3sklHS-9dLduVyCfqIo4ehCp9kytkYvdfMU9MzWdqMclAky0qzXO5IX8Z9uPsIDtyWzPGNr0iRZoxd=w640-h483" width="640" /></a></div><br style="box-sizing: border-box;" /><p></p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">Note that Knative is a container based serverless platform. With that, Automatiko follows this approach and packages all functions into a single container image that can be scaled without problems. Knowing the characteristic of the functions - self-contained and invokable at any time, this container can be scaled to any number of replicas to provide maximum throughput as each replica has same runtime responsibility and can take execution based on incoming events.</p><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;"><a href="https://github.com/automatiko-io/automatiko-examples/tree/main/user-registration" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">A complete and ready to run example</a></p><p style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">A more complete article on workflow as a function flow is also available in<span class="Apple-converted-space"> </span><a href="https://knative.dev/blog/articles/workflow-as-function-flow/" rel="noopener noreferrer" style="box-sizing: border-box; color: #29a8ff; text-decoration-line: none; user-select: auto;" target="_blank">Knative blog</a>.</p><h2 dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); clear: both; color: #222635; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 30px; letter-spacing: -0.5px; line-height: 1.2; margin: 20px 0px 5px; text-size-adjust: auto;">Wrapping up</h2><p dir="ltr" style="box-sizing: border-box; caret-color: rgb(34, 38, 53); color: #222635; font-family: Cambria, serif; font-size: 19px; margin: 5px 0px 15px; text-size-adjust: auto;">This article was intended to put a slightly different light at workflows, especially in relation to the cloud. Main takeaway is to give readers a bit of food for thought that workflows are much more than service orchestration and that using them as part of the core business logic has a lot to offer. Concepts introduced and the implementation of them should be a good proof that workflows used to represent business logic is not just possible but as well efficient from development and maintenance stand point.</p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-67080058065462433432022-06-01T01:36:00.001-07:002022-06-01T01:36:12.162-07:00Serverless Workflow vs BPMN - comparison<div style="text-align: left;"><br /></div><div><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">Workflows are becoming (again) more popular and pretty much all cloud providers have something to offer in that area. This article is not to cover all possible workflows but two in particular I have worked with</p><ul style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; margin-bottom: 1rem; margin-top: 0px;"><li style="box-sizing: border-box;">Serverless Workflow</li><li style="box-sizing: border-box;">BPMN - Business Process Model and Notation</li></ul><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;"></p><h3 class="section-heading" style="background-color: white; box-sizing: border-box; color: #212529; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 1.2; margin-bottom: 0.5rem; margin-top: 60px;"><span style="font-size: medium;">Serverless Workflow</span></h3><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;"><a href="https://serverlessworkflow.io/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">Serverless workflow</a> is a standards-based DSL (workflow definition language) and open-source developer tools and runtimes. What is worth to mention it is a vendor neutral workflow language that aims at providing portable workflow definition language and tools including runtimes.</p><h2 style="background-color: white; box-sizing: border-box; color: #212529; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 1.2; margin-bottom: 0.5rem; margin-top: 60px; text-align: left;"><span style="font-size: medium;">BPMN</span></h2><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;"><a href="https://www.bpmn.org/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">BPMN</a> is both graphical notation (it actually originated from it) and interchange format (xml based) to describe workflows or to put it more in context of BPMN a business process. It serves as documentation of the business logic but also is often used to execute these processes as part of automation platforms.</p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">So at first sight you can already notice first difference - one is positioned from technology perspective - serverless while the other is more business oriented. The other important difference is the target audience. Serverless Workflow definition uses DSL that can be either <code style="box-sizing: border-box; color: #e83e8c; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 17.5px; overflow-wrap: break-word;">JSON</code> or <code style="box-sizing: border-box; color: #e83e8c; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 17.5px; overflow-wrap: break-word;">YAML</code> which makes it a better fit for technical users. BPMN has started from being a documentation tool to be able to graphically model business logic and it then it was equipped with execution aspects.</p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">So then which one is for what and for whom? <a href="https://blog.automatiko.io/2022/05/15/serverless-vs-bpmn.html">Find out by reading full article</a>.</p></div>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-26801676063601853562022-03-09T00:25:00.002-08:002022-03-09T00:25:46.693-08:00Secure access to approval tasks with OAuth Proxy<p> <span style="color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">In</span><span style="color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;"> </span><a href="https://blog.automatiko.io/2022/02/12/tekton-approvals.html" style="box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; transition: all 0.2s ease 0s;">previous article</a><span style="color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">, Approval Tasks for Tekton has been introduced. Though that version lacked support for authentication to first of all secure the application and second to simplify usage for approvers - no need to manually enter user id or email to verify they are eligible to work on given approval task.</span></p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">This article will explain on high level what to do to secure Automatiko Approval Tasks for Tekton by using <a href="https://oauth2-proxy.github.io/oauth2-proxy/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">OAuth Proxy</a> as a side car container. </p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">Read on at <a href="https://blog.automatiko.io/2022/03/06/tekton-approvals-secuired.html">automatiko blog</a></p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-34083067908898624982022-02-16T06:12:00.003-08:002022-02-16T06:12:24.598-08:00Approvals - "the missing" part of Tekton<p><a href="https://tekton.dev/" style="box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; transition: all 0.2s ease 0s;">Tekton</a><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;"> </span><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">is a fantastic project that allows to build pipelines for your CI/CD needs. It works really great as it takes advantage of dynamic nature of Kubernetes cluster and uses resources only when it actually executes a task.</span></p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">Tasks that are executed can be pretty much anything that starts a container (pod) and executes. There is a huge collection of tasks available in <a href="https://hub.tekton.dev/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">Tekton Hub</a> that can be easily used within your own pipelines. Have a further read about Tekton if you're not familiar with it <a href="https://tekton.dev/docs/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">here</a>.</p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">There is just one tiny issue - tasks in Tetkon are mainly about executing things and not waiting for things. And here comes Automatiko that plugs into the Tekton ecosystem via <a href="https://tekton.dev/docs/pipelines/runs/" style="background-color: transparent; box-sizing: border-box; color: #212529; transition: all 0.2s ease 0s;">Custom Tasks</a>. Custom tasks (realized in Tekton as <code style="box-sizing: border-box; color: #e83e8c; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 17.5px; overflow-wrap: break-word;">Run</code>s) allow to provide additional capabilities that are not meant to execute things - like starting a container/pod. Read complete article at <a href="https://blog.automatiko.io/2022/02/12/tekton-approvals.html">automatiko blog</a></p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-86831018563455532021-12-22T08:20:00.001-08:002021-12-22T08:20:20.798-08:00Workflows with JMS messaging<p> <span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">Last several years there is a lot of buzz about Apache Kafka, Apache Pulsar and in general about event streams. But looking into lots of organizations they are in many case still relying on "old good traditional messaging". To give one example of that, IBM MQ is very popular within small, medium and big enterprises to realize messaging between systems.</span></p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">While event streams are starting to play bigger role in integration, there are still big opportunities to build systems and services based on traditional messaging. In Java world, JMS is an excellent solution to that. Majority (if not all) Java frameworks for building services have support for JMS such as Spring, Quarkus, Jakarta EE application servers and many more.</p><p style="background-color: white; box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; line-height: 1.5; margin: 30px 0px;">Have a read of full article <a href="https://blog.automatiko.io/2021/12/21/jms-messaging.html" target="_blank">here</a>.</p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-78566354147090750602021-11-30T00:51:00.000-08:002021-11-30T00:51:18.732-08:00Apache Kafka event stream with workflows<h2 class="section-heading" style="background-color: white; box-sizing: border-box; color: #212529; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 36px; line-height: 1.2; margin-bottom: 0.5rem; margin-top: 60px;">Apache Kafka event streams consumed by workflows</h2><p><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">An inspiration for this blog post is another blog post by Piotr Minkowski that perfectly introduced</span><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;"> </span><a href="https://piotrminkowski.com/2021/11/24/kafka-streams-with-quarkus/" style="box-sizing: border-box; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px; transition: all 0.2s ease 0s;">Kafka Streams with Quarkus</a><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;">. This triggered a thought - can workflows be used as an alternative to Kafka Streams to process multiple event streams (merge them and process various events streams with some correlation logic)?</span></p><p><span style="background-color: white; color: #212529; font-family: Lora, "Times New Roman", serif; font-size: 20px;"><br />A complete blog article can be found at <a href="https://blog.automatiko.io/2021/11/29/kafka-stream.html">Apache Kafka event stream with workflows</a></span> </p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-84560388968027018742021-04-29T00:59:00.003-07:002021-04-29T00:59:41.707-07:00User task forms and email notifications in Automatiko<p> <a href="https://blog.automatiko.io/2021/04/28/release-0.4.0.html" target="_blank">Automatiko 0.4.0 has just been released</a>. I comes with quite some new features among them are </p><p></p><ul style="text-align: left;"><li>user task forms that is provided by user task management addon</li><li>user task notifications that is provided by user task email addon</li></ul><div>These two combined provide an excellent support for human actors participating in workflow automation. This article is about to provide some hints behind these two features of Automatiko, so let's dive into them directly.</div><div><br /></div><h2 style="text-align: left;">User task forms</h2><div>Forms that represent user task (a task assigned to human actors) are a common requirement in the process/workflow automation scenarios. In many cases it is expected that forms will be auto generated by the workflow engine (and some offerings on the market actually do that). But the main problem with that approach is that is is very limited. In many cases it can only support basic forms and what is even more important they are not providing proper business context behind the task. They are usually very generic and expose internal parts of the workflow engine that runs them. </div><div><br /></div><div>To give an example - let's assume we have a simple vacation request approval task assigned to a manager. The auto generated forms are usually going to present it with a checkbox for approval decision and a button to complete the task. The reason for that is the generation of the task form is based on data types of its outputs which will be approved of type boolean and boolean is usually represented as check box. While this will work it does not show the form in expected format - meaning it would show the details of the request and then have two buttons one to approve and another to reject. Taking it even further if the reject button is used the form could ask for additional comment why it was rejected. This can't be done with auto generated forms.</div><div><br /></div><div>The approach in Automatiko is bit different, it can still show very simple generic form but that is considered as fallback option as sometimes there is just a matter of providing kind of "For your information" type of tasks where the only thing to be done is to acknowledge it. Though for anything that requires input from end user the form should be designed and provided as part of the service.</div><div><br /></div><div>This is realised with templates for user tasks. Each template is a fully featured HTML page that can use any kind of framework or styles. You can build a really dynamic forms with the use of JavaScript frameworks e.g. JQuery, you can style it with Bootstrap and so on. You own the entire space on how to build your forms, how to layout the forms, if you need to load data from other service to populate fields you can do that without a hassle.</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgWAIMVJSgc6H1C67fUiUQkqEaLSdt4UkinnQgOkZPcy9QglosCEgjAM5Y0H0BoT6_XEbtMVemREqX3naLu2NqsoB-IGJ0xdeXwxaQQpVQ8yi2Ba9hmEbYAslhBR5l3eTObSPyosnkOk4/s1278/examples-vacation-request-form-approval.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="702" data-original-width="1278" height="352" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgWAIMVJSgc6H1C67fUiUQkqEaLSdt4UkinnQgOkZPcy9QglosCEgjAM5Y0H0BoT6_XEbtMVemREqX3naLu2NqsoB-IGJ0xdeXwxaQQpVQ8yi2Ba9hmEbYAslhBR5l3eTObSPyosnkOk4/w640-h352/examples-vacation-request-form-approval.png" width="640" /></a></div><div>Templates in Automatiko relies on <a href="https://quarkus.io/guides/qute" target="_blank">Qute</a>, a server side templating engine from Quarkus. It gives you all the power of the templating and is very well tuned for performance and fast delivery to your clients. Automatiko will give you all the details you need for given task so you can render it and make it very contextual to your users so they will directly know what is expected from them. Plus you can make it to look and feel as any other application in your organisation.</div><div><br /></div><div>You can read up on the details on how to build your user tasks forms in <a href="https://docs.automatiko.io/main/0.4.0/components/user-tasks.html" target="_blank">Automatiko documentation</a> and you can also take a look at <a href="https://docs.automatiko.io/main/0.4.0/examples/vacations.html" target="_blank">vacation request example</a> what makes use of it.</div><div><br /></div><h2 style="text-align: left;">Email notifications</h2><div>Another important aspect of the user tasks in workflow automation is to notify when a task is assigned. This is very common and almost any user of workflow automation expects this to be out of the box. Automatiko comes with this by a means of addon that will equip your service with this feature.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9gjYb5tDl0LvoHnyPQEDt4fwIy2og4wxaPx7_M6EBkZ7Z7_Ne1yQrxEvHr2bqDB9XrH48UYyThh_hQRGCJ1bWyc__nH1zdOVauc7DNWpFp43ISo9eAzv1Ip5FcR3-Fs4-puUkMH4pE8k/s703/examples-vacation-request-form-email.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="703" data-original-width="623" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9gjYb5tDl0LvoHnyPQEDt4fwIy2og4wxaPx7_M6EBkZ7Z7_Ne1yQrxEvHr2bqDB9XrH48UYyThh_hQRGCJ1bWyc__nH1zdOVauc7DNWpFp43ISo9eAzv1Ip5FcR3-Fs4-puUkMH4pE8k/w568-h640/examples-vacation-request-form-email.png" width="568" /></a></div><br /><div><br /></div><div>Emails are expected to serve as a way of notifying about task being assigned and not necessarily about the complete context behind the task. That's why a default template for emails in many cases will be good enough. But it is configurable as well so you can define an email notification template for every task separately. It uses the same approach as the user task forms - templates. </div><div><br /></div><div>In addition, tasks can be assigned to individuals and groups so somehow there must be a way to know the email addresses for them. By default Automatiko assumes users are represented as email addresses but that is not always the case. Don't worry, there is a simple way to solve it, by implementing a single interface you can provide your way of resolving user and group identifiers to email addresses. To learn more head to the <a href="https://docs.automatiko.io/main/0.4.0/components/user-tasks.html">Automatiko documentation</a>.</div><div><br /></div><div><br /></div><div>At the end I'd like to give you an opportunity to see it in action, have a look at this short video showing both features in action.</div><div><br /></div><center><iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/m9AvgFszf1w" title="YouTube video player" width="560"></iframe></center><div>If you have any questions or comments feel free to reach out on twitter or mailing list (@automatiko_io) automatiko-dev@googlegroups.com).</div><p></p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-37751596726782656362021-04-14T01:55:00.001-07:002021-04-14T01:55:04.703-07:00Version workflow data with ease<p> A common scenario when working with workflows is to handle data objects and their changes. In most of the situations workflow instance will only keep the last value of it and to realise use cases like comparing what was just sent to the instance with what was already in there requires having duplicated data object definitions. This is not the best approach as it makes the workflow definition "corrupted" with details less important from the business goal perspective.</p><p>With Automatiko (since version 0.3.0) there is an alternative way to this problem. This is to version data objects by annotating it with data object tag called <b>versioned</b>.</p><p>So what happens when you make data object versioned?</p><p>Automatiko engine will record every change to the variable as new version. These versions are then available to be accessed as any other variable but will require additional suffix to the variable name</p><p><br /></p><p></p><ul style="text-align: left;"><li>suffix <span style="font-family: courier;">$</span> will give access to complete version list of the variable e.g. <span style="font-family: courier;">person$</span></li><li>suffix <span style="font-family: courier;">$X</span> where X is a number of the version to retrieve it can be a negative (-1) to fetch latest version e.g. <span style="font-family: courier;">person$5</span> or <span style="font-family: courier;">person$-1</span></li></ul><div><br /></div><div>Sometimes referring to versions directly might result in errors like attempting to get the version that does not exist. To make it simpler, Automatiko provides ready to use functions that can be used from </div><div><br /></div><div><ul style="text-align: left;"><li>script tasks</li><li>gateway conditions</li></ul><div><br /></div><div>The functions you can use are as follows:</div></div><div><ul style="text-align: left;"><li><span style="font-family: courier;">previousVersion(versions) </span>allows to get latest version of the variable list - <span style="font-family: courier;">previousVersion(person$)</span></li><li><span style="font-family: courier;">variableVersion(versions, number)</span> allows to get variable version stored under version number - <span style="font-family: courier;">variableVersion(person$, 4)</span> - note that this one is safe and will return null when given version number does not exist</li><li><span style="font-family: courier;">isEqual(var1, var2)</span> allows to easily compare two versions of the variable - isEqual(person, previousVersion(person$))</li></ul><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihcxRyoGeJqXEETszjOoIIu9Y8QFUwQk1hun5LtkNnNNu1nV-9x34iwJCnxy9oRbJ2gQBr7ghorfS6s9zhHluVl_c3jHYWCVoTi9ZuyAZsNSF2Sqb7BLLEIfL7Jhqfyvi_3Sp6hYL16Ao/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="918" data-original-width="1406" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihcxRyoGeJqXEETszjOoIIu9Y8QFUwQk1hun5LtkNnNNu1nV-9x34iwJCnxy9oRbJ2gQBr7ghorfS6s9zhHluVl_c3jHYWCVoTi9ZuyAZsNSF2Sqb7BLLEIfL7Jhqfyvi_3Sp6hYL16Ao/w640-h418/image.png" width="640" /></a></div><br /><br /></div><div>Another aspect is that you can easily create your custom functions by simply implementing <span style="font-family: courier;">io.automatiko.engine.api.Functions</span> interface and implementing public static methods that will become functions and will be available in the workflow definition. You can read up more in <a href="https://docs.automatiko.io/main/0.3.0/best-practice.html#_use_functions_for_custom_logic" target="_blank">Automatiko documentation</a>.</div></div><div><br /></div><div>In addition to that Process Management UI also provides quick access to variable versions and allows to also revert to given version of the data object. Once you have process management addon in your service it provides both UI and REST api to interact with versions of the data objects.</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYj8uKD3nYkeQEezna5c5K3eHYfVo8NnxQLSWaNOG98yz8mKLj6D92-paVSl_EyKR-7re-8XYC4px2fV9bMEn2C2n0qBoAnqfAhtl9SWvKGxMFnxwxhoPmdhAg4l7uC1TE9-wz05DmSxo/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="865" data-original-width="1173" height="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYj8uKD3nYkeQEezna5c5K3eHYfVo8NnxQLSWaNOG98yz8mKLj6D92-paVSl_EyKR-7re-8XYC4px2fV9bMEn2C2n0qBoAnqfAhtl9SWvKGxMFnxwxhoPmdhAg4l7uC1TE9-wz05DmSxo/w640-h472/image.png" width="640" /></a></div><br /><br /></div><div><br /></div><div>Following video shows this in action and the value it brings.</div><div><br /></div><div style="text-align: center;"><iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/7-C_CyMl3HA" title="YouTube video player" width="560"></iframe></div><div style="text-align: center;"><br /></div><div>Stay tuned for more updates around Automatiko project. If you have any questions or comments join our community either on <a href="mailto:automatiko-dev@googlegroups.com" target="_blank">mailing list</a> or <a href="https://github.com/automatiko-io/automatiko-engine/discussions" target="_blank">GitHub discussions</a>.</div><p></p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-78803729580912696582021-03-17T00:43:00.003-07:002021-03-17T00:44:51.230-07:00Kubernetes Operator with Automatiko<p>Here is more of a developer view on the recently published article on <a href="https://blog.automatiko.io/2021/03/06/kube-operator-workflow.html" target="_blank">Automatiko blog about building Kubernetes Operators with workflows</a>. It shows that is brings significant value to the overall visibility of the operator logic and makes it really approachable for non kubernetes gurus.</p><p><br /></p><p>I'd like to take it a bit further and show how efficient it can be thanks to the internals of Automatiko. Automatiko takes advantage of <a href="https://quarkus.io/" target="_blank">Quarkus</a> that provide the runtime mechanics so to say. Quarkus comes with an outstanding feature called <a href="https://quarkus.io/guides/maven-tooling#development-mode" target="_blank">dev mode</a>. Everyone who heard about Quarkus most likely heard about dev mode and live reload. But there is more to it!!!</p><p><a href="https://quarkus.io/guides/maven-tooling#remote-development-mode" target="_blank">Remote dev mode</a> - is a sibling to the dev mode but it allows you to live reload application remotely. A perfect fit for in-container development or even better in kubernetes cluster development. This brings us to the unbelievable efficient developer experience when building Kubernetes operators - you can build them directly inside the Kubernetes cluster. No need for rebuilding the image, no need to redeploying the container and so on... it just works like a charm.</p><p><br /></p><p>Have a look at this video illustrating how you can easily work on your operator logic that runs inside the kubernetes cluster. Make modifications to the logic and try it out almost instantly (assuming your kubernetes cluster and deployed container have enough resources to make it efficient ;)).</p><p><br /></p><div style="text-align: center;"><iframe width="560" height="315" src="https://www.youtube.com/embed/3qRZ6LhPoA4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p></p><p>The video showed number of features</p><p></p><ul style="text-align: left;"><li>how to configure the application to run in remote dev mode</li><li>how to make changes to the workflow definition</li><li>how to make modification to application code</li><li>automatic reload of the application that includes both workflow and java classes</li></ul><div>All working smoothly and efficiently without much of a hassle </div><div><br /></div><div>A huge kudos to Quarkus team for making it a fantastic piece of software that makes developer life easier... a truly cloud native as it enables direct in cluster development that speeds the work up significantly!!!</div><p></p>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-27059612300076663822021-02-25T05:54:00.001-08:002021-02-25T05:54:59.143-08:00Getting Started with Automatiko - IoT and MQTT - Part 2<p>As a follow up of <a href="http://mswiderski.blogspot.com/2021/02/getting-started-with-automatiko-iot-and.html" target="_blank">part 1</a> of the <a href="https://automatiko.io" target="_blank">Automatiko</a> IoT and MQTT I'd like to take you further in exploration around workflows and IoT with MQTT. </p><p><br /></p><p>This time we look at the details of how to take advantage of some MQTT features (e.g. wildcard topics), collect sensor data into a bucket (or to make this simple - a list) and then assign user tasks based on amount of data collected instead of for every event.</p><p>In addition to that, we look into Automatiko features that makes using workflows for IoT way easier...</p><h2 style="text-align: left;">Wildcard topics</h2><div>Let's start with MQTT feature for subscribers - this is actually what workflow in our sample is - a MQTT topic subscriber. So let's first look like how does it work under the hood in Automatiko.</div><div><br /></div><div>Automatiko uses message events (start or intermediate) of BPMN to integrate with message broker - in this case MQTT. Message events are referencing message which describes the way how it can connect to the broker</div><div><br /></div><div><ul style="text-align: left;"><li>by default uses name as the topic name </li><li>data type of the message defines what type will be used to unmarshall incoming event into</li><li>supports custom attributes to alter defaults</li></ul><div><br /></div></div><div>In this article we are going to use custom attributes to define both topic that will use wildcard and the correlation expression to extract information out of the topic instead of the message (as we did in part 1).</div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><br /></div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijcq0cYR041BVCIzCSLGxMxoYaL72s4M4V51T5llROSdrsNOLXeabJOKOTDPo9d8xansGs2n8K4YyiUYRKKUxXkx6HdqBPe9KMVU4fgvqGEMvjx-F8fI55XhNczYXEK4d9QLh-JjhXQTo/s925/Screenshot+2021-02-25+at+14.20.10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="472" data-original-width="925" height="326" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijcq0cYR041BVCIzCSLGxMxoYaL72s4M4V51T5llROSdrsNOLXeabJOKOTDPo9d8xansGs2n8K4YyiUYRKKUxXkx6HdqBPe9KMVU4fgvqGEMvjx-F8fI55XhNczYXEK4d9QLh-JjhXQTo/w640-h326/Screenshot+2021-02-25+at+14.20.10.png" width="640" /></a></div><br /><br /><br /></div>In the screenshot above you can see two custom attributes</div><div><ul style="text-align: left;"><li>topic</li><li>correlationExpression</li></ul><div><b>Topic</b> is used to define the actual topic in MQTT that the workflow definition will be connected to and listening to incoming events. </div><div><br /></div><div><b>Correlation expression</b> on the other side defines an expression that will be used for each incoming event to extract a key to be used for both identification and correlation.</div><div><br /></div><div>Correlation expression uses special function "topic" that accepts following parameters</div><div><ul style="text-align: left;"><li><b>message</b> - references the incoming message</li><li><b>index</b> - an index that will reference different parts of the topic - it starts with 0</li></ul><div>So for this example <span style="font-family: courier;">topic(message, 1)</span> and the topic <span style="font-family: courier;">home/kitchen/temp</span> the extracted correlation key will be <b>kitchen</b>. This in turn will be used as identifier of the workflow instance and thus you can use it in the service api calls.</div></div><br /></div><div>You can read up more on the messaging support in automatiko in <a href="https://docs.automatiko.io/main/0.2.0/components/messaging.html" target="_blank">documentation</a>.</div><div><br /></div><h2 style="text-align: left;">Data bucket to collect sensor data</h2><div>Next topic for today is the collection of sensor data. In part one we simply assign it to a data object of the same type. This time we expand and make sure we can accumulate the data.</div><div><br /></div><div>So with that said there are few things that must be done</div><div><br /></div><div><ul style="text-align: left;"><li>data object must be of type list</li><li>data object of type list needs to be initialized so it can easily get new items</li><li>message events received from MQTT need to be added to the list instead of assigned to data object (which would mean overridden)</li></ul><div><br /></div></div><div>Changing type is rather simple but ensuring it is initialized might be a bit more complex... but not with automatiko :) It is as simple as adding a tag on data object - <b>auto-initialized</b></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcVCj8KhbIameM74bROJztF3trK44afGC31EQhTEkTE4Bl-spJDDeVfnV5zF0BB1gR821HMOCizzmOwxngU5-NXh-ZvdifcGiVFhKbYuxcZxtbYLZupUbgYl5hwvQkiNf3r6uHFOYVTq4/s822/Screenshot+2021-02-25+at+14.32.13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="392" data-original-width="822" height="306" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcVCj8KhbIameM74bROJztF3trK44afGC31EQhTEkTE4Bl-spJDDeVfnV5zF0BB1gR821HMOCizzmOwxngU5-NXh-ZvdifcGiVFhKbYuxcZxtbYLZupUbgYl5hwvQkiNf3r6uHFOYVTq4/w640-h306/Screenshot+2021-02-25+at+14.32.13.png" width="640" /></a></div><br /><div><br /></div><div>Configuring the message event to append to a list instead of assigning to the data object is also rather simple with automatiko, it is to use expression instead of direct mapping on the message event.<br /><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3aaoBHLqpjaTIaMj1ON9rjThYd4z5zowvzObD5BmQfFOnrcW2J9mXzMCeUSG98zJZxs0KBfdXKbE8bCpEyntkSC-MXGAN8XFFXMziRpH4FiybxT5aFlmlKl8YaANqIBVz7nv9jdL5Dfo/s1197/Screenshot+2021-02-25+at+14.31.58.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="544" data-original-width="1197" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3aaoBHLqpjaTIaMj1ON9rjThYd4z5zowvzObD5BmQfFOnrcW2J9mXzMCeUSG98zJZxs0KBfdXKbE8bCpEyntkSC-MXGAN8XFFXMziRpH4FiybxT5aFlmlKl8YaANqIBVz7nv9jdL5Dfo/w640-h290/Screenshot+2021-02-25+at+14.31.58.png" width="640" /></a></div><br /><div><br /></div><div>And that's it - we have now ready to use data bucket for our sensor data.</div><div><br /></div><div><br /></div><h2 style="text-align: left;">Decide when to include human actors</h2><div>In this simple example we are going to receive events from MQTT and collect them into a bucket. But we don't want to involve human actors on each event. So here we can use gateways - a construct that allows us to have different paths in the workflow.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAcmzGw4yES5f0QP6qct9N1AJIfCWsbYKD5499Is1TyJgo9iBnfN8-ynLpFTh6FDoqYs-9OEifEZeb-4auORaqMiNl9bqMVSfMFQ9LTTEK5CidU9SIltRNLQe94fmqHjiZhDHZMUERTJ4/s845/Screenshot+2021-02-25+at+14.35.52.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="685" data-original-width="845" height="518" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAcmzGw4yES5f0QP6qct9N1AJIfCWsbYKD5499Is1TyJgo9iBnfN8-ynLpFTh6FDoqYs-9OEifEZeb-4auORaqMiNl9bqMVSfMFQ9LTTEK5CidU9SIltRNLQe94fmqHjiZhDHZMUERTJ4/w640-h518/Screenshot+2021-02-25+at+14.35.52.png" width="640" /></a></div><br /><div>We only create a user task when the bucket has more than 5 events collected. Otherwise it simply end the path. But to prevent the workflow instance from finishing we make the workflow to be ad hoc - that allows it to stay active even though there are no active nodes in it. Marking workflow as ad hoc is done in the Properties -> Process panel.</div><div><br /></div><h2 style="text-align: left;">See it in action</h2><div>Have a look at this 10 min video showing all this in action. Note that this is live coding so you will see the errors as they might show up and you can imagine that this is not a scripted video where everything works from the start :)</div><div><br /></div>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/jBHrr1ZFUz8" width="560"></iframe><div><br /></div><div><br /></div><div>Code can be found in <a href="https://github.com/mswiderski/automatiko-iot" target="_blank">github</a> where each part of the series is a separate tag and main branch is pointing to latest version of the code base.</div><div><br /></div><h2 style="text-align: left;">Conclusions</h2><div>This part focused on bringing more advanced features of MQTT into the workflows to show the integration and how powerful these two can be. Using topic information as correlation, locating right workflow instances for incoming events and accumulating data is one of the most common use cases for IoT so workflows should make it simple to realize that.</div>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-79189159381355269782021-02-22T02:49:00.003-08:002021-02-25T05:09:46.727-08:00Getting Started with Automatiko - IoT and MQTT - Part 1<p>Around a month ago there was the first release of <a href="https://automatiko.io" target="_blank">Automatiko</a> project. It aims at providing an easy to use yet powerful toolkit to build services and functions based on workflows and decision. You can read up more information about the Automatiko project at the <a href="https://automatiko.io" target="_blank">website</a> or <a href="http://blog.automatiko.io" target="_blank">blog</a>.</p><p>This blog post is very basic introduction that attempts to address the first level of entry when starting with Automatiko. </p><h2 style="text-align: left;">Before you start...</h2><div>So first things first... to get you up and running you need few things on your local computer</div><div><br /></div><div><ul style="text-align: left;"><li>Java 11 +</li><li>Maven 3.6 +</li><li>Eclipse IDE and Automatiko plugin</li><li>Optionally docker or podman to run services as containers</li></ul><div><br /></div></div><div>Head directly to <a href="https://docs.automatiko.io/main/0.2.0/getting-started.html" target="_blank">documentation of Automatiko project</a> to follow step by step instruction how to get the above up and running.</div><div><br /></div><h2 style="text-align: left;">The use case</h2><div>The use case of this introductory sample is very simple - to connect to MQTT to receive data from the sensors that are being published there. It mainly focuses on the steps to get this working and further articles will provide more advanced features in action.</div><div><br /></div><h2 style="text-align: left;">Let's get started</h2><div><br /></div><div>To get started you need to create a project, a maven project to be precise. Luckily Automatiko comes with bunch of maven archetypes that makes this task way faster. One of the is `automatiko-iot-archetype` and this is the one we are going to use today.</div><div><br /></div><div>Archetype can be used from IDE or command line so whatever you prefer can be used and result will be exactly the same.</div><div><br /></div><div>Once the project is there, you need to define your data model that will be used by the workflow - as data objects. In this example you can create simple POJO like class names `Temperature` that will have two fields</div><div><br /></div><div><ul style="text-align: left;"><li>value - of type double that will contain the temperature value from the sensor</li><li>room - the location where the temperature was measured</li></ul><div><br /></div></div><div>Next step is to create a workflow definition that will be responsible for connection to MQTT broker. This is realised by message start event that allows not only to be the entry point for new instances but also allows to define some characteristics of the connectivity and processing.</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4fI5mA62t9AtfTtO9IOcIU4MQFgKeZWgqgCFD3FyMIRv_gHC9D2hsOVoHGkW2kB8DcFxJSE1oL3fWSqhW5q28gteuMtgOd4_4MoxP5yN1vCiN0cdSsAqYiN2bvH6rDMD87jcebyDXwDk/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="227" data-original-width="360" height="404" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4fI5mA62t9AtfTtO9IOcIU4MQFgKeZWgqgCFD3FyMIRv_gHC9D2hsOVoHGkW2kB8DcFxJSE1oL3fWSqhW5q28gteuMtgOd4_4MoxP5yN1vCiN0cdSsAqYiN2bvH6rDMD87jcebyDXwDk/w640-h404/image.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div>All that is needed to talk to the MQTT broker is defined directly in the workflow definition. In our sample case, the topic in MQTT broker is simple taken from the message defined on the start event.</div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIsshyphenhyphenkS4gy6ZiKxcSBemKyuEXjwReyctBE55VZVevZipCdhtUO-Y8m69coL5WS-GBSeLl5e4l2YREjE04bl1XiGKmC07nGAFNOQKS7G7jk0_Y0SzRp9_STw0hsdWxwtmUMQjPUQ4FoQw/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="398" data-original-width="1439" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIsshyphenhyphenkS4gy6ZiKxcSBemKyuEXjwReyctBE55VZVevZipCdhtUO-Y8m69coL5WS-GBSeLl5e4l2YREjE04bl1XiGKmC07nGAFNOQKS7G7jk0_Y0SzRp9_STw0hsdWxwtmUMQjPUQ4FoQw/w640-h178/image.png" width="640" /></a></div><br />At the same time, data that is received from the MQTT topic is automatically converted to the data model - represented as 'Temperature` class and mapped to a `temp` data object inside the workflow instance.</div><div><br /></div><div>Lastly, user task is also added to the workflow definition that introduces a human actor into the flow. That is mainly for demonstration purpose to show we receive data from MQTT that is properly converted into a Temperature class instance and set within the workflow instance data objects (aka variables).</div><div><br /></div><h3 style="text-align: left;">A bit of advance...</h3><div>As you will see when running this sample, ID of the workflow instance is auto generated (in UUID format). But that can be changed and take advantage of either data or the MQTT topic itself. By setting correlation or correlation expression on the message (via its custom attributes) you can set the id to be more domain specific.</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfA82af1FrZKBS2-dMSbjOrEk9f9TwWtZEQZkyxTjTtppjeYABxGOMBqlUHgeOI_TkkJheQrTZrv5jGDMdF1aGknujtXEnkVSPpINVfKpeLilGT_ZZQDal_YgnXRZziTzIU0yXiY2Fqbk/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="400" data-original-width="598" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfA82af1FrZKBS2-dMSbjOrEk9f9TwWtZEQZkyxTjTtppjeYABxGOMBqlUHgeOI_TkkJheQrTZrv5jGDMdF1aGknujtXEnkVSPpINVfKpeLilGT_ZZQDal_YgnXRZziTzIU0yXiY2Fqbk/w640-h428/image.png" width="640" /></a></div><br /><br /></div><div><br /></div><div>In this case, we take the room from the message and use it as correlation. Correlation upon start of the workflow instance becomes its id - aka business key and by that it can be used in exchange with the generated ID. With that said you can use this when interacting with service API.</div><div><br /></div><div><br /></div><div>You can look at the introduction video that covers the content of this article.</div><div><br /></div><iframe width="560" height="315" src="https://www.youtube.com/embed/UHn_Z_1LOqs" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><h2 style="text-align: left;">Let's get this running...</h2><div>To get this running we need a MQTT broker. Personally I find <a href="https://mosquitto.org/" target="_blank">Mosquitto</a> to be excellent choice but any MQTT compliant broker would work. </div><div><br /></div><div>You can get Mosqiutto running with just a simple command (docker required)</div><div><br /></div><div><span style="font-family: courier;">docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto</span></div><p>There are other ways to run mosquitto so visit website if docker is not an option.</p><h3 style="text-align: left;">Run the Automatiko service</h3><div>Since Automatiko generates fully functional service there is no much to do to see it in action. It is based on maven and leverages Quarkus as runtime so most Quarkus features are also available out of the box e.g. dev mode, Dev UI etc.</div><div><br /></div><div><span style="font-family: courier;">mvn clean quarkus:dev</span></div><div><br /></div><div>and then wait a bit for maven to download all the bits....</div><div><br /></div><div>Once it's started you should see similar log entries</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieZMqn542-kNiq_cmdi3v3DFSgWAhylXklf27tVBfJCD12i1sRkbOxKLZvvDYP7pv61ZGMWU6-Hf2W3KVxuOlUTaosxlJMH48V8x3HyY_B3H1ajRwBeE1K-Z1EXbHqjbtAK5iKE7cDMdM/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="503" data-original-width="1918" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieZMqn542-kNiq_cmdi3v3DFSgWAhylXklf27tVBfJCD12i1sRkbOxKLZvvDYP7pv61ZGMWU6-Hf2W3KVxuOlUTaosxlJMH48V8x3HyY_B3H1ajRwBeE1K-Z1EXbHqjbtAK5iKE7cDMdM/w640-h168/image.png" width="640" /></a></div><br />You can head directly to http://localhost:8080/swagger-ui and you will be presented with nicely document API of your service</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitpsinFoQIRgzheMgILYnipYi4udYTWyWirBtYOI-eHUAyn6WfmN_yPfMLTqPoX-zM3dUdGf4sgWQDg7_SR8sUIItVuRjrhPxxEBzoNHRnb6JKx7jmwMpM5ObFOCHh3fgx2368xlbdaf8/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="920" data-original-width="1899" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitpsinFoQIRgzheMgILYnipYi4udYTWyWirBtYOI-eHUAyn6WfmN_yPfMLTqPoX-zM3dUdGf4sgWQDg7_SR8sUIItVuRjrhPxxEBzoNHRnb6JKx7jmwMpM5ObFOCHh3fgx2368xlbdaf8/w640-h310/image.png" width="640" /></a></div><br />So it is now fully functional service connected to your local MQTT broker. With this you can start publishing sensor data to it and see how quickly they are consumed by Automatiko service.</div><div><br /></div><div>You can use mosquitto client command to publish messages from command line</div><div><br /></div><div><span style="font-family: courier;">mosquitto_pub -t temperature -m '{"room":"livingroom", "value" : 25.0}'</span></div><div><br /></div><div>use Swagger UI to see created instances based on incoming messages from MQTT.</div><div><br /></div><h3 style="text-align: left;">Running as container</h3><div>In case you would like to get this running as container then it is again dead simple, just run maven command with `container` profile enabled</div><div><br /></div><div>mvn clean package -Pcontainer</div><div><br /></div><div>And that's it. As soon as build is over you will have the container image in your local registry.</div><div><br /></div><h2 style="text-align: left;">Conclusion</h2><div>That's it for the first introduction - I hope it will get you interested and you will look forward for the next articles. They will come ever other week... at least that's the plan. Please share your feedback either here or via mailing list and twitter. </div><div><br /></div><div>If you have any ideas for the use cases to cover with Automatiko don't hesitate to let us know about them as we are here to help and explore.</div><div><br /></div><div>Thanks for reading!</div><div><br /></div><div><br /></div>Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-63695091395564999892019-10-22T09:58:00.001-07:002020-05-21T06:05:45.580-07:00Introducing jBPM's Human Task prediction APIIn this post, we’ll introduce a new jBPM API which allows for predictive models to be trained with Human Tasks (HT) data and for HT to incorporate model predictions as outputs and complete HT without user interaction.<br />
<br />
This API will allow you to add Machine Learning capabilities to your jBPM project by being able to use, for instance, models trained with historical task data to recommend the most likely output. The API also gives developers the flexibility to implement a “prediction-only” service (which only suggests outputs) as well as automatically completing the task if the prediction’s confidence meets a user-defined prediction confidence threshold.<br />
This API exposes the HT handling to a <i>prediction service</i>.<br />
A prediction service is simply any third-party class which implements the <code>org.kie.internal.task.api.prediction.PredictionService</code> interface.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUmz_qJ7smKiZNCUK8VhQDPk0aD5b9xEQhaZ6rmETPn-YCimcp5NE_YjYqOUzPzUzDvCvCI-vXWvE45bL0xpmqR-TsW1uPVSnIp9kL5JKhKEmU0rGaxmdoID2XMKMPBXxmkDdotlIFwVUt/s1600/diagram1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="396" data-original-width="1040" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUmz_qJ7smKiZNCUK8VhQDPk0aD5b9xEQhaZ6rmETPn-YCimcp5NE_YjYqOUzPzUzDvCvCI-vXWvE45bL0xpmqR-TsW1uPVSnIp9kL5JKhKEmU0rGaxmdoID2XMKMPBXxmkDdotlIFwVUt/s640/diagram1.png" width="640" /></a></div>
<br />
<br />
This interface consists of three methods:<br />
<br />
<ul>
<li><code>getIdentifier()</code> - a method which returns a unique (<code>String</code>) identifier for your prediction service</li>
<li><code>predict(Task task, Map<String, Object> inputData)</code> - a method that takes task information and the task's inputs from which we will derive the model's inputs, as a map. The method returns a <code>PredictionOutcome</code> instance, which we will look in closer detail later on</li>
<li><code>train(Task task, Map<String, Object> inputData, Map<String, Object> outputData)</code> - this method, similarly to predict, takes task info and the task's inputs, but now we also need to provide the task's outputs, as a map, for training </li>
</ul>
<br />
This class will consist of:<br />
<br />
<ul>
<li>A <code>Map<String, Object></code> outcome containing the prediction outputs, each entry represents an output attribute’s name and value. This map can be empty, which corresponds to the model not providing any prediction.</li>
<li>A <code>confidence</code> value. The meaning of this field is left to the developer (<i>e.g.</i> it could represent a probability between 0.0 and 1.0). It's relevance is related to the <code>confidenceThreshold</code> below.</li>
<li>A <code>confidenceThreshold</code> - this value represents the confidence cutoff after which an action can be taken by the HT item handler.</li>
</ul>
As an example, let's assume our confidence represents a prediction probability between 0.0 and 1.0. If the <code>confidenceThreshold</code> is 0.7, that would mean that for <code>confidence > 0.7</code> the HT outputs would be set to the outcome and the task automatically closed. If the <code>confidence <= 0.7</code>, then the HT would set the prediction outcome as suggested values, but the task would not be closed and still need human interaction. If the outcome is empty, then the HT life cycle would proceed as if no prediction was made.<br />
By defining a confidence threshold which is always higher than the confidence, developers can create a “prediction-only” service, which will assign predicted outputs to the task, but never complete it.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeqDbttnbiB4VMyhnTJ6ucDHDOz2v8Ngqw7r5wnNJA9Gw3nheFlun00pJabWe_8XA3r-0jsMwpbGqeAHhYQBKmiurlBMkdokKtgwBMplXrMVhX66NBeXm_Wy1uW5tyjBIdY7uOdbrYkSbh/s1600/sequence.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"> </a> </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIO3yPSb0Nkxr0oOX4cH8EH9jH_cGz1aiLJLYi3MFz6YPkgSA66UFLtheg0zrS1tADSdP8Ee_UzqvGONGIaMLuIb3YmuNuUau8RyGZXOd9T3pYmEop-0yV8jtIBu6bwzxIYrt1MOaF2bq9/s1600/diagram2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="731" data-original-width="1474" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIO3yPSb0Nkxr0oOX4cH8EH9jH_cGz1aiLJLYi3MFz6YPkgSA66UFLtheg0zrS1tADSdP8Ee_UzqvGONGIaMLuIb3YmuNuUau8RyGZXOd9T3pYmEop-0yV8jtIBu6bwzxIYrt1MOaF2bq9/s640/diagram2.png" width="640" /></a></div>
<br />
<br />
The initial step is then, as defined above, the <code>predict</code> step.
In the scenario where the prediction's confidence is above the threshold, the task is automatically completed. If the confidence is not above the threshold, however, when the task is eventually completed both the inputs and the outputs will then be used to further train the model by calling the prediction service's <code>train</code> method.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivSzQTnYcJxgNBqd0FRPRtQruwyEZo5UsFkW2f6PxBV3Kk7dI7PfOMU7uhLyry9d-2i2cdn2EST3UToDgpLTII_79trdTl5VvBSRkEEjzRHwdbBjsB4EW9YD2e5kQfZUJkjOHMyr19gIq9/s1600/diagram3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="822" data-original-width="1188" height="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivSzQTnYcJxgNBqd0FRPRtQruwyEZo5UsFkW2f6PxBV3Kk7dI7PfOMU7uhLyry9d-2i2cdn2EST3UToDgpLTII_79trdTl5VvBSRkEEjzRHwdbBjsB4EW9YD2e5kQfZUJkjOHMyr19gIq9/s640/diagram3.png" width="640" /></a></div>
<br />
<h3>
Example project</h3>
<br />
An example project is available <a href="https://github.com/ruivieira/jbpm-recommendation-demo">here</a>. This project consists of a single Human Task, which can be inspected using Business Central. The task is generic and simple enough in order to demonstrate the working of the jBPM's prediction API.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiujtEhIlYGco638FuDrKdKVUO7bFA3IPNYm4O1JdlkM-O5xGCMzxKimwyninApZG7nuYx5JFjiHzEV5xazxwtKmv81_6h1CeKiDd7wz68HBom_FQO9QKIJSK3_c72euy8yMtTBS2WLUrjl/s1600/human_task.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="223" data-original-width="866" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiujtEhIlYGco638FuDrKdKVUO7bFA3IPNYm4O1JdlkM-O5xGCMzxKimwyninApZG7nuYx5JFjiHzEV5xazxwtKmv81_6h1CeKiDd7wz68HBom_FQO9QKIJSK3_c72euy8yMtTBS2WLUrjl/s400/human_task.png" width="400" /></a></div>
<br />
<br />
For the purposes of the demonstration, this task will be used to model a simple purchasing system where the purchase of a laptop of a certain brand is requested and must be, eventually, manually approved. The tasks <b>inputs</b> are:<br />
<br />
<br />
<ul>
<li><code>item</code> - a <code>String</code> with the brand's name</li>
<li><code>price</code> - a <code>Float</code> representing the laptop's price</li>
<li><code>ActorId</code> - a <code>String</code> representing the user requesting the purchase<br /> </li>
</ul>
<br />
<br />
The task provides as <b>outputs</b>:<br />
<br />
<br />
<ul>
<li><code>approved</code> - a <code>Boolean</code> specifying whether the purchase was approved or not<br /> </li>
</ul>
<br />
<br />
This repository contains two example prediction service implementations as Maven modules and a REST client to populate the project with tasks to allow the predictive model training.<br />
<br />
Start by downloading, or alternatively cloning, the repository:<br />
<br />
<pre>$ git clone <a href="mailto:git@github.com">git@github.com</a>:ruivieira/jbpm-recommendation-demo.git</pre>
<pre> </pre>
For this demo, two random forest-based services, one using the<a href="https://github.com/haifengl/smile"> SMILE</a> library and another as a Predictive Model Markup Language (<a href="https://en.wikipedia.org/wiki/Predictive_Model_Markup_Language">PMML</a>) model, will be used. The services, located respectively in <code>services/jbpm-recommendation-smile-random-forest</code> and <code>services/jbpm-recommendation-pmml-random-forest</code>, can be built with (using SMILE as an example):<br />
<br />
<pre>$ cd services/jbpm-recommendation-smile-random-forest
$ mvn clean install
</pre>
<br />
The resulting JARs files can then be included in the Business Central’s <code>kie-server.war</code> located in <code>standalone/deployments</code> directory of your jBPM server installation. To do this, simply create a <code>WEB-INF/lib</code>, copy the compiled JARs into it and run<br />
<br />
<pre>$ zip -r kie-server.war WEB-INF
</pre>
<br />
The PMML-based service expects to find the PMML model in <code>META-INF</code>, so after copying the PMML file in <code>jbpm-recommendation-pmml-random-forest/src/main/resources/models/random_forest.pmml</code> into <code>META-INF</code>, it should also be included in the WAR by using<br />
<br />
<pre>$ zip -r kie-server.war META-INF
</pre>
<br />
jBPM will search for a prediction service with an identifier specified by a Java property named <code>org.jbpm.task.prediction.service</code>. Since in our demo, the random forest service has the identifier <code>SMILERandomForest</code>, we can set this value when starting Business Central, for instance as:<br />
<br />
<pre>$ ./standalone.sh -Dorg.jbpm.task.prediction.service=SMILERandomForest
</pre>
<br />
For the purpose of this documentation we will illustrate the steps using the SMILE-based service. The PMML-based service can be used by starting Business Central and setting the property as<br />
<br />
<pre>$ ./standalone.sh -Dorg.jbpm.task.prediction.service=PMMLRandomForest
</pre>
<br />
Once Business Central has completed the startup, you can go to<a href="http://localhost:8080/business-central/"> http://localhost:8080/business-central/</a> and login using the default admin credential <code>wbadmin/wbadmin</code>. After choosing the default workspace (or creating your own), then select "<i>Import project</i>" and use the project <code>git</code> URL:<br />
<br />
<pre>https://github.com/ruivieira/jbpm-recommendation-demo-project.git
</pre>
<br />
The repository also contains a REST client (under <code>client</code>) which allows to add Human Tasks in batch in order to have sufficient data points to train the model, so that we can have meaningful predictions.<br />
<i><br /></i>
<i>NOTE: Before running the REST client, make sure that Business Central is running and the demo project is deployed and also running.</i><br />
<br />
The class <code>org.jbpm.recommendation.demo.RESTClient</code> performs this task and can be executed from the client directory with:<br />
<br />
<pre>$ mvn exec:java -Dexec.mainClass="org.jbpm.recommendation.demo.RESTClient"
</pre>
<br />
The prices for Lenovo and Apple laptops are drawn from Normal distributions with respective means of 1500 and 2500 (pictured below). Although the prediction service is not aware of the deterministic rules we've used to set the task outcome, it will train the model based on the data it receives. The tasks' completion will adhere to the following logic:<br />
<br />
<ul>
<li>The purchase of a laptop of brand Lenovo requested by user John or Mary will be approved if the price is around $1500</li>
<li>The purchase of a laptop of brand Apple requested by user John or Mary will be approved if the price is around $2500</li>
<li>The purchase of a laptop of brand Lenovo requested by user John or Mary will be rejected if the price is around $2500 </li>
</ul>
<br />
<ul>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYnFqDlvcjqqI0qN8O1IuI7z4mvaeWQg0K5GvlAUTmPCwJC-lwf5XZPihgw1-9TQhpGMk689xZ04cmjbvmfdWPJ-UeeOtcffEXgJQS08bwfDx-QBNQfFi2Y5frn48WN_anawH6XMdw8zUQ/s1600/prices.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="534" data-original-width="1600" height="209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYnFqDlvcjqqI0qN8O1IuI7z4mvaeWQg0K5GvlAUTmPCwJC-lwf5XZPihgw1-9TQhpGMk689xZ04cmjbvmfdWPJ-UeeOtcffEXgJQS08bwfDx-QBNQfFi2Y5frn48WN_anawH6XMdw8zUQ/s640/prices.png" width="640" /></a></div>
<br />
<br />
The client will then simulate the creation and completion of human tasks, during which the model will be trained.<br />
<br />
<h3>
SMILE-based service</h3>
<br />
As we've seen, when creating and completing a batch of tasks (as previously) we are simultaneously training the predictive model. The service implementation is based on a random forest model a popular ensemble learning method.<br />
<br />
When running the <code>RESTClient</code>, 1200 tasks will be created and completed to allow for a reasonably sized training dataset. The prediction service initially has a confidence threshold of 1.0 and after a sufficiently large number (arbitrarily chosen as 1200) of observations are used for training, the confidence threshold drops to 0.75. This is simply to demonstrate the two possible actions, <i>i.e.</i> prediction without completing and completing the task. This also allows us to avoid any<a href="https://en.wikipedia.org/wiki/Cold_start_(computing)"> cold start</a> problems.<br />
<br />
After the model is trained with the task from <code>RESTClient</code>, we will now create a new Human Task.<br />
<br />
If we create a HT requesting the purchase of an "<i>Apple</i>" laptop from "<i>John</i>" with the price $2500, we should expect it to be approved.<br />
<br />
If fact, when claiming the task, we can see that the prediction service recommends the purchase to be approved with a "confidence" of 91%.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_zkiHpSOagaCaut5oiePlU9K0-BRw95ZIRc4WKG1rNC8CP8QWT0tncSyoEdyTfQ6p1a3HbGkUOszZD3Lq8YBUnyvaSSmh4D4BuRXjBQbcXXFvR-931nFHPHyNanx7TflI4ZGmxLmeLld2/s1600/form.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="665" data-original-width="706" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_zkiHpSOagaCaut5oiePlU9K0-BRw95ZIRc4WKG1rNC8CP8QWT0tncSyoEdyTfQ6p1a3HbGkUOszZD3Lq8YBUnyvaSSmh4D4BuRXjBQbcXXFvR-931nFHPHyNanx7TflI4ZGmxLmeLld2/s320/form.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
If he now create a task for the request of a "<i>Lenovo</i>" laptop from "<i>Mary</i>" with the price $1437, he would expect it to be approved. We can see that this is the case, where the form is filled in by the prediction service with an approved status with a "confidence" of 86.5%.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0r_UwsaLW_rytmGLYG-_sQF0K0d6fF5P_KvmnNNGFh84hObnE8_1lWd931fS1Sh46VGItxwXACF3mOYOjYkwIPWbj9njK8xm_M8mWZoNZRJRooBcPoXryxX4OxgrstJfesC-QxyDDhiwC/s1600/form2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="662" data-original-width="693" height="305" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0r_UwsaLW_rytmGLYG-_sQF0K0d6fF5P_KvmnNNGFh84hObnE8_1lWd931fS1Sh46VGItxwXACF3mOYOjYkwIPWbj9njK8xm_M8mWZoNZRJRooBcPoXryxX4OxgrstJfesC-QxyDDhiwC/s320/form2.png" width="320" /></a></div>
<br />
<br />
We can also see, as expected, what happens when "<i>John</i>" tries to order a "<i>Lenovo</i>" for $2700. The prediction service fills the form as "not approved" with a "confidence" of 71%.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd-UyOJX8EA1Qr4UbB5IPwaSQ7-sRIojYoZKwUv31KIA1Sr6Bi-HT8DM5vvXWrD0PZ6pei4W9AhgQau0Uf9mkIL04bYtkpvray7_SgT8BdV5MA5Olef0urxUqfmsx_slHJyKbOp8k5pKD2/s1600/form3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="662" data-original-width="777" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd-UyOJX8EA1Qr4UbB5IPwaSQ7-sRIojYoZKwUv31KIA1Sr6Bi-HT8DM5vvXWrD0PZ6pei4W9AhgQau0Uf9mkIL04bYtkpvray7_SgT8BdV5MA5Olef0urxUqfmsx_slHJyKbOp8k5pKD2/s320/form3.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
In this service, the confidence threshold is set as 1.0 and as such the task was not closed automatically.<br />
<br />
The minimum number of data points was purposely chosen so that after running the REST client and completing a single task, the service will drop the confidence threshold to 0.75.<br />
<br />
If we complete one of the above tasks manually, the next task you create will be automatically completed if the confidence is above 0.75. For instance, when creating a task we are pretty sure will be approved (<i>e.g.</i> John purchasing a Lenovo $1500) you can verify that the task is automatically completed.<br />
<br />
<h3>
PMML-based service</h3>
<br />
The second example implementation is the PMML-based prediction service. PMML is a predictive model interchange standard, which allows for a wide variety of models to be reused in different platforms and programming languages.<br />
<br />
The service included in this demo consists of pre-trained model (with a dataset similar to the one generated by <code>RESTClient</code>) which is executed by a PMML engine. For this demo, the engine used was<a href="https://github.com/jpmml/jpmml-evaluator"> jpmml-evaluator</a>, the <i>de facto</i> reference implementation of the PMML specification.<br />
<br />
There are two main differences when comparing this service to the SMILE-based one:<br />
<br />
<ul>
<li>The model doesn't need the training phase. The model has been already trained and serialised into the PMML format. This means that we can start using predictions straight away from jBPM.</li>
<li>The <code>train</code> API method is a no-op in this case. This means that whenever the service's <code>train</code> method is called, it will not be used for training in this example (only the <code>predict</code> method is needed for a "read-only" model), as we can see from the figure below.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigMS5oab0j4a3h56VMUM5iix8_llpRnrevAlPyxPezSMPqfCjJrxVnqe2y8-I4ER7QpQkNaZEhh1hb4Aayb9mbozjHY2H77-TY2y2qjr8iFs7TRr403WoAbK79R3rzrdup1i9h5HiSFHsT/s1600/diagram4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="838" data-original-width="1184" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigMS5oab0j4a3h56VMUM5iix8_llpRnrevAlPyxPezSMPqfCjJrxVnqe2y8-I4ER7QpQkNaZEhh1hb4Aayb9mbozjHY2H77-TY2y2qjr8iFs7TRr403WoAbK79R3rzrdup1i9h5HiSFHsT/s640/diagram4.png" width="640" /></a></div>
<br />
<br />
You can verify that the Business Central workflow is the same as with the SMILE service, although in this case no training is necessary.<br />
<br />
<br />
The above instructions on how to setup the demo project are also available in the following video (details are in the subtitles<i>)</i>:<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/bqMEPddhKkU/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/bqMEPddhKkU?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
In conclusion, in this post we’ve shown how to use a new API which allows for predictive models to suggest outputs and complete Human Tasks.<br />
<br />
We’ve also shown a project which can use different prediction service backends simply by registering them with jBPM without any changes to the project.<br />
<br />
<br />
Why not create your own jBPM prediction<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOKZJ13c8Trytr7BvgZtAKgTVZ3U5hTlRFUBTQTa7_WrOWr0RFuT3tjoD5Jw39rBtKX8WI0v5O1SnH59wfViaIK43I62bAOQ0av_vcvx-VkS67zGQgCQbBxzrHgRqbPim8DL6U_T0mCLYQ/s1600/diagram4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="838" data-original-width="1184" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOKZJ13c8Trytr7BvgZtAKgTVZ3U5hTlRFUBTQTa7_WrOWr0RFuT3tjoD5Jw39rBtKX8WI0v5O1SnH59wfViaIK43I62bAOQ0av_vcvx-VkS67zGQgCQbBxzrHgRqbPim8DL6U_T0mCLYQ/s320/diagram4.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
service using your favourite Machine Learning framework, today?<br />
<br />
<ul>
</ul>
<ul>
</ul>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-53401220039388919122019-06-24T18:16:00.000-07:002020-05-21T06:05:45.387-07:00jBPM monitoring using Prometheus and Grafana<div dir="ltr" id="docs-internal-guid-d1d4431a-7fff-5a7d-614e-457e448be628" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" id="docs-internal-guid-d1d4431a-7fff-5a7d-614e-457e448be628" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">In this post, we will introduce the new Prometheus Kie Server Extension, which has been released as part of jBPM version 7.21.0.Final. This extension aims to make extremely easy for you to publish metrics about your Kie Server runtime execution. Using </span><a href="https://prometheus.io/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Prometheus</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> and </span><a href="https://grafana.com/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Grafana</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> has become a standard for monitoring cloud services these days, and allowing the Kie Server to expose metrics related to processes, tasks, jobs and more, becomes a powerful integration not only for you to get a snapshot of the current status inside the server but also for combining it with information from different sources such as JVM, Linux and more. Not only in terms of infrastructure monitoring, but it is also a great tool to get insights into the execution of your business process.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">To get started with Prometheus, take a look in this </span><a href="https://prometheus.io/docs/introduction/overview/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">overview</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> and the full list of </span><a href="https://prometheus.io/docs/instrumenting/exporters/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">exporters and integrations.</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> Grafana is also another powerful tool that allows you to create nice looking dashboards, combining data from multiple sources, to get started take a look </span><a href="https://grafana.com/docs/guides/getting_started/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">here</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Here is an example based on the metrics exposed from the Kie Server:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><img height="300" src="https://lh6.googleusercontent.com/5jCTO6bp95_fusXvQrFOnUmq5jV_2BLH4B9XBzw12J3taqrd8Dw05t7RuYZgrjc4uZhi37hjCuR3g2AJxDZZAD9drjfkxfofY-HqblntXGcLP5pdO9AyhV9zXbPcJ8dydE44nlXT" style="border: none;" width="624" /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" id="docs-internal-guid-58e180b8-7fff-e4a9-d0b0-dc7e14c651e0" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">To enable this new extension, set the Prometheus system property to <b>org.kie.prometheus.server.ext.disabled=false</b>. When you enable this extension, a series of metrics will be collected, including information about deployments, start time, data sets, execution errors, jobs, tasks, processes, cases, and more. For the complete list of metrics, see the <a href="https://github.com/kiegroup/droolsjbpm-integration/tree/master/kie-server-parent/kie-server-services/kie-server-services-prometheus">Prometheus services repository</a> on GitHub.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">After the extension is started, you can access the available metrics at <i>${context}/services/rest/metrics</i>. </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">For example:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<b style="font-family: Arial; font-size: 11pt; white-space: pre-wrap;">curl -u wbadmin:wbadmin http://localhost:8080/kie-server/services/rest/metrics</b></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">To quickly demonstrate all the capabilities of this integration, we created a short video, with more details about how to get started, two example dashboards for Grafana, as well as a Docker compose configuration that you can use as a playground to explore all these tools working together.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<br /><iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/mbQh3vzddPU/0.jpg" src="https://www.youtube.com/embed/mbQh3vzddPU?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Docker compose example configuration is available </span><a href="https://github.com/jboss-dockerfiles/business-central/tree/master/docker-compose-examples" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">here</span></a><span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"> and to get started, simply run:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">docker-compose -f jbpm-kie-server-prometheus-grafana.yml up </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">After all images start, you have the following tools available:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Business Central: </span><a href="http://localhost:8080/business-central" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">http://localhost:8080/business-central</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Kie Server: </span><a href="http://localhost:8080/kie-server" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">http://localhost:8080/kie-server</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Grafana: </span><a href="http://localhost:3000/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">http://localhost:3000</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Prometheus: </span><a href="http://localhost:9090/" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">http://localhost:9090</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">To access the example dashboards, please login to Grafana using the default credentials: username </span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">admin</span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> and password </span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">admin</span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">. Then navigate to </span><span style="font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">Dashboards -></span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">Manage</span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">, in there you should have two examples: </span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">jBPM Dashboard</span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> and </span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;">jBPM Kie Server Jobs.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;"><span id="docs-internal-guid-0697cd65-7fff-0010-6b8b-1a123608bb8e" style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline;"><img height="199" src="https://lh5.googleusercontent.com/lDU9Ft9-a9X5jFuwlDwju9pmr9s7MZWbXCNsroqEfwvpkGdzV55rYARiaLyP60xMVrSKkXMM3XTv0owNqFjqKl2md_FS1Zjx0om46S343JPGvgEMPyWfFI7sKbyEkMT1uSENifrS" style="border: none;" width="624" /></span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline;"><br /></span></span></span></div>
<div dir="ltr" id="docs-internal-guid-f54482d6-7fff-23c8-b5c0-5d9c22096cc3" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">As you interact with your Kie Server and Business Central instances, like deploying and starting new process instances, you should notice the metrics values changing in the dashboard. Prometheus is configured to scrape data every 10 seconds.</span></div>
<div dir="ltr" id="docs-internal-guid-f54482d6-7fff-23c8-b5c0-5d9c22096cc3" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; vertical-align: baseline;"></span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "arial"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Hope you have fun monitoring your Kie Server!</span></div>
Cristiano Nicolaihttp://www.blogger.com/profile/07851251830752520735noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-13626553201989232632019-02-12T06:31:00.000-08:002020-05-21T06:05:44.764-07:00JHipster generator for jBPM Business Apps<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpi1kBl3BcB2NWwOZbes7w61Cg2rgACfjj3KkEPVJfugqf_mjmXgJK28P5ORhDakqrQ3x4_stEIcOhs96JG_qrdkUfZra02h-gYYmnOu9k1KA43tN7n4lGN3LEqbkVNnYQwHclJlvu0GKR/s1600/Screen+Shot+2019-02-12+at+9.22.17+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="434" data-original-width="1564" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpi1kBl3BcB2NWwOZbes7w61Cg2rgACfjj3KkEPVJfugqf_mjmXgJK28P5ORhDakqrQ3x4_stEIcOhs96JG_qrdkUfZra02h-gYYmnOu9k1KA43tN7n4lGN3LEqbkVNnYQwHclJlvu0GKR/s400/Screen+Shot+2019-02-12+at+9.22.17+AM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
If you are a fan of <a href="http://www.jhipster.tech/">JHipster</a> you can now generate <a href="http://jbpm.org/businessapps/gettingStarted.html">jBPM Business apps with it!</a> We created a <a href="https://www.npmjs.com/package/generator-jba">generator module</a> for it which you can use as follows:<br />
<br />
With <b>Yarn</b>:<br />
<br />
<i><b>yarn global add generator-jba</b></i><br />
<br />
Or with <b>NPM</b>:<br />
<br />
<i><b>npm install -g generator-jba</b></i><br />
<br />
Once installed generate your app with:<br />
<br />
<i><b>yo jba</b></i><br />
<br />
and follow the questions. If you want to generate the app with default settings, run:<br />
<br />
<i><b>yo jba --quick=true</b></i><br />
<i><b><br /></b></i>
<i><b><br /></b></i>Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-20079761824501608782019-02-01T11:38:00.001-08:002020-05-21T06:05:44.954-07:00jBPM Visual Studio Extension - New version 0.6.0 adds jBPM Business Apps debuggingHappy to announce a new 0.6.0 version of the <b>JBAVSC</b> extension for <b>Visual Studio Code</b>.<br />
<br />
This extension adds process <b>debugging</b> for your business apps!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgETo9cGZJnXhTkE2r_V-RRx7LjuW1ZgPhXf8pfwGPQUUQucr1UnYTEqt5gBPgSRwLXi08rSZ6s9kr_7ApgNp5DmM_yINRar1SaDah5N7Kwx_geJCLptUQoonEQQ2bt4OiaGO1abOe91srR/s1600/debugEditor.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="893" data-original-width="1600" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgETo9cGZJnXhTkE2r_V-RRx7LjuW1ZgPhXf8pfwGPQUUQucr1UnYTEqt5gBPgSRwLXi08rSZ6s9kr_7ApgNp5DmM_yINRar1SaDah5N7Kwx_geJCLptUQoonEQQ2bt4OiaGO1abOe91srR/s400/debugEditor.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Debugging business app process in Visual Studio Code</td></tr>
</tbody></table>
<br />
<br />
JBAVSC Github: https://github.com/BootstrapJBPM/jbavsc<br />
Visual Studio Code Marketplace: https://marketplace.visualstudio.com/items?itemName=tsurdilovic.jbavsc<br />
<br />
Here is a youtube vide showing off all the features of this extension:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Ay_eJSvCyUM/0.jpg" src="https://www.youtube.com/embed/Ay_eJSvCyUM?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
We can make this extension much much more powerful so if you are interested in helping please let us know!Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-46982099145837692262019-01-28T23:21:00.001-08:002020-05-21T06:05:45.339-07:00Enabling CORS in your jBPM Business ApplicationCurrently when you generate your jBPM Business Application (online via <a href="http://start.jbpm.org/">start.jbpm.org</a>, command-line via the <a href="https://www.npmjs.com/package/jba-cli">jba-cli package</a>, or in Visual Studio code via the<a href="https://marketplace.visualstudio.com/items?itemName=tsurdilovic.jbavsc"> jBPM extension</a>) your app will have CORS (Cross-origin resource sharing) disabled by default.<br />
<br />
With CORS disabled, if you have a consumer app (e.g. React frontend) which does not live on the same domain as your business app, it will not be able to query its REST api.<br />
<br />
CORS will be enabled by default with the next jBPM community release (7.18.0.Final), see Jira <a href="https://issues.jboss.org/browse/JBPM-8176">JBPM-8176</a>, but if you would like to enable this on you own now, it is very easy to do:<br />
<br />
In your generated business app service module edit the DefaultWebSecurityConfig.java file and replace it with the one in<a href="https://gist.github.com/tsurdilo/5ea1c2066fd982d2b360872d977cf3a6"> this Gist</a>. That's it :)<br />
<br />
With this change in place you will now be able to query your business apps REST api from any domain, for example if you are using jQuery.ajax and want to get your server information (/rest/server endpoint) you could do for example:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG1Od9Iykiw2_9RC0DD09UnrUuJK6V4C3feli_FoLnHY-rpsqbLimYzCeTP4iAa_Un5N_BMIsmUTi91qzVbbKEPGmMgn3E7il8hL81XNMrHimpB3ZSvv6EhDLCZ9fSuzNH1JutGRKWNO2W/s1600/Screen+Shot+2019-01-29+at+2.19.19+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="702" data-original-width="1098" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG1Od9Iykiw2_9RC0DD09UnrUuJK6V4C3feli_FoLnHY-rpsqbLimYzCeTP4iAa_Un5N_BMIsmUTi91qzVbbKEPGmMgn3E7il8hL81XNMrHimpB3ZSvv6EhDLCZ9fSuzNH1JutGRKWNO2W/s400/Screen+Shot+2019-01-29+at+2.19.19+AM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sample ajax request to /rest/server<br /></td></tr>
</tbody></table>
Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-17218363775559444442019-01-23T10:18:00.001-08:002020-05-21T06:05:44.859-07:00Visual Studio Code extension for generating jBPM Business Apps<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLJKaQ5Loj1yo9-NLiqi_5HWZwoLwesk7UK93S4Zcofc5fGlC5l0dPYiNYCuKOCaffQw-1obxvD3Ajy6US2kPnmWqVekDh6SQn9nhG185gpjSH0dLg82LX73QX5KFx7rN9lCS2NImURw6H/s1600/Screen+Shot+2019-01-23+at+1.13.44+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="607" data-original-width="1600" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLJKaQ5Loj1yo9-NLiqi_5HWZwoLwesk7UK93S4Zcofc5fGlC5l0dPYiNYCuKOCaffQw-1obxvD3Ajy6US2kPnmWqVekDh6SQn9nhG185gpjSH0dLg82LX73QX5KFx7rN9lCS2NImURw6H/s400/Screen+Shot+2019-01-23+at+1.13.44+PM.png" width="400" /></a></div>
<br />
If you are developing your apps using <a href="https://code.visualstudio.com/">Visual Studio Code</a> you can now install a new <a href="https://marketplace.visualstudio.com/items?itemName=tsurdilovic.jbavsc">jBPM Business Application extension</a>. With this extension and the great tooling support of VSC you can now generate, develop, and launch your jBPM business apps without ever leaving your development environment.<br />
<br />
Here is the youtube video showcasing how to install and use this extension:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Cc1Id2Cd8LU/0.jpg" src="https://www.youtube.com/embed/Cc1Id2Cd8LU?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
The sources of the extension are on <a href="https://github.com/BootstrapJBPM/jbavsc">github</a>. We are looking for contributions to make this extension better in the future.Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-22065345297138845592019-01-14T08:17:00.001-08:002020-05-21T06:05:45.003-07:00Generate jBPM Business Apps with Node.js Command-line interface (CLI)In addition to <a href="http://start.jbpm.org/">start.jbpm.org</a> there is now an command-line way to generate your jBPM Business Applications, namely with the <a href="https://www.npmjs.com/package/jba-cli">jba-cli Node package</a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5touUPUfpx3oG0drIcvtj_gPGRsrCUEjjZiNejL1muuqWwss21-phtZPCkaRZ6xfjyFUm72iaeogWJFtbsiLSCW0eVc8QvQA-WA3LvJSL16S18qM9Ze4iV7FfUnsOMHdfn8Y2OAB7WE6p/s1600/Screen+Shot+2019-01-14+at+11.06.23+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="528" data-original-width="1600" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5touUPUfpx3oG0drIcvtj_gPGRsrCUEjjZiNejL1muuqWwss21-phtZPCkaRZ6xfjyFUm72iaeogWJFtbsiLSCW0eVc8QvQA-WA3LvJSL16S18qM9Ze4iV7FfUnsOMHdfn8Y2OAB7WE6p/s400/Screen+Shot+2019-01-14+at+11.06.23+AM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">jba-cli package on npmjs.com</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC564P9HnQbrTVVhzRfmOVu9iXSczQvEXQq1OljX73zrmboYg_ZFCb7bRPjPme9m4G9d5bNBiqHUglCpKX5DtN05n1MLzqaFm1Xge38iWW3fGPvyjMXtA64axgwj2UfQkBWlg_tYES5ojb/s1600/jbausage.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="823" data-original-width="1600" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC564P9HnQbrTVVhzRfmOVu9iXSczQvEXQq1OljX73zrmboYg_ZFCb7bRPjPme9m4G9d5bNBiqHUglCpKX5DtN05n1MLzqaFm1Xge38iWW3fGPvyjMXtA64axgwj2UfQkBWlg_tYES5ojb/s400/jbausage.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sample CLI usage</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If you have Node installed locally you can install and run this package with:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<pre style="background: rgb(247, 247, 247); border-radius: 2px; box-sizing: border-box; color: #333333; font-family: monospace, monospace; font-size: 16px; margin-bottom: 24px; overflow-x: auto; padding: 13px 15px;"><code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-radius: 2px; box-sizing: border-box; font-family: "Fira Mono", "Andale Mono", Consolas, monospace; font-size: 1rem; font-variant-ligatures: none; letter-spacing: 0px; line-height: 24px; padding: 0px;">npm install jba-cli -g</code></pre>
<pre style="background: rgb(247, 247, 247); border-radius: 2px; box-sizing: border-box; color: #333333; font-size: 16px; margin-bottom: 24px; overflow-x: auto; padding: 13px 15px;"><span style="font-family: Fira Mono, Andale Mono, Consolas, monospace;"><span style="font-variant-ligatures: none;">jba gen</span></span></pre>
<div>
This allows your to build your jBPM Business app zip file without having to go through the browser. </div>
<div>
To contribute to this little cool project feel free to clone it and create pull requests from its <a href="https://github.com/BootstrapJBPM/jba-cli">github repo</a>.</div>
<div>
<br /></div>
<div>
Here is youtube video showing how to install and use the jba-cli command line interface to generate your app:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/_FHWkchCq_o/0.jpg" src="https://www.youtube.com/embed/_FHWkchCq_o?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div>
<br /></div>
<div>
<br /></div>
Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-44701923593562826372019-01-11T07:58:00.001-08:002020-05-21T06:05:45.292-07:00Service task repository integrated into Business Central<div dir="ltr" style="text-align: left;" trbidi="on">
Service tasks (aka work items) are of tremendous use in business processes. Users can build their custom logic into well defined tasks that can be reused across processes or even projects. jBPM comes with rather large set of service tasks out of the box, you can explore them in jbpm-work-items repository in GitHub.<br />
<br />
jBPM also provides standalone service repo that could be used from jBPM designer to import service tasks. Though that was just intermediate step towards better integration with authoring tooling - Business Central.<br />
<br />
Brand new integration between service task repository and business central is under development and I'd like to share a bit of news about this upcoming feature...<br />
<br />
<h3 style="text-align: left;">
Service Task administration</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-uNWPzkj_Xrd1pXWsCPdFz2singlK8Nlw-vjDbJOnaku5ccdcdVHa3yoTN70cAX1XOlGoMRc1x7UqTMRZ0vy3_726QUDK12WtGgtbTAI9XG5PdWFruD4KDN5P2AniVAxpbV_E1Oj5v4/s1600/Screenshot+2019-01-11+at+16.30.18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="875" data-original-width="1600" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-uNWPzkj_Xrd1pXWsCPdFz2singlK8Nlw-vjDbJOnaku5ccdcdVHa3yoTN70cAX1XOlGoMRc1x7UqTMRZ0vy3_726QUDK12WtGgtbTAI9XG5PdWFruD4KDN5P2AniVAxpbV_E1Oj5v4/s640/Screenshot+2019-01-11+at+16.30.18.png" width="640" /></a></div>
<br />
<br />
<br />
First and foremost there is global administration of service tasks. This allows to select what service tasks (that the authoring environment comes with) are allowed to be installed in projects.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVsSZD-dnPTO1Gt1TpKLaCwSVButnTcg4cTh4Voj_48yLoCxHG7Eay8PGpsKCcKHOUZkLxSLX4ToT-ABUA65BPcdrF2QHUsDYd1XYyN3DwPwc7uqmX0VlLRjDEgT4RLVO99ekr4B1BFGw/s1600/Screenshot+2019-01-11+at+16.30.37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="1600" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVsSZD-dnPTO1Gt1TpKLaCwSVButnTcg4cTh4Voj_48yLoCxHG7Eay8PGpsKCcKHOUZkLxSLX4ToT-ABUA65BPcdrF2QHUsDYd1XYyN3DwPwc7uqmX0VlLRjDEgT4RLVO99ekr4B1BFGw/s640/Screenshot+2019-01-11+at+16.30.37.png" width="640" /></a></div>
<br />
<br />
There are three configuration options<br />
<div>
<ul style="text-align: left;">
<li>Install as Maven artefact - will upload the jar file of the handler if it does not exist in the local or Business Central's maven repo</li>
<li>Install service tasks artefact as maven dependency of project - will update pom.xml of project upon installation of the service task</li>
<li>Use version range - when adding service task artefact as project dependency it will use version range instead of fixed version e.g. [7.16,) instead of 7.16.0.Final</li>
</ul>
<div>
<br /></div>
<h3 style="text-align: left;">
Service task installation - project settings</h3>
Once the service tasks are enabled they can be used within projects. Simply go into project settings page and install (or uninstall) service tasks of your desire. Note that this settings page will only list service tasks that are globally enabled.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UgOpVWXWvUMB22Vhp1SFQpyejCL5n5F2IdIN4HAAqb7Z-j5U4D4Z5nux0sJKrUocwTV3RNwMHJqfMcb-3EuWnZ9RgsZTGYcPXMOeqzO2KlY66fwuL50ozibaoCji_GQchllu4tCKJ80/s1600/Screenshot+2019-01-11+at+16.33.47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="691" data-original-width="1600" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UgOpVWXWvUMB22Vhp1SFQpyejCL5n5F2IdIN4HAAqb7Z-j5U4D4Z5nux0sJKrUocwTV3RNwMHJqfMcb-3EuWnZ9RgsZTGYcPXMOeqzO2KlY66fwuL50ozibaoCji_GQchllu4tCKJ80/s640/Screenshot+2019-01-11+at+16.33.47.png" width="640" /></a></div>
Service tasks can then be installed into projects. During installation following will be done<br />
<ul style="text-align: left;">
<li>dedicated wid (work definition) file is created for installed service task</li>
<li>custom icon for the service task is installed into project resources (if exists)</li>
<li>pom.xml of the project is updated to include dependencies (if it is enabled in the global settings)</li>
<li>deployment descriptor is updated to register work item handler for the service task</li>
</ul>
<div>
Similar steps are performed for uninstallation though to remove rather than add configuration.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Here is a short video (this time with audio.. not sure if that is good or bad ...) that illustrates the entire feature working together, including use of service task in business process.</div>
<br />
<br />
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/DKCallzn6-o" width="560"></iframe>
<br />
This is part one of this feature so stay tuned for more updates in coming weeks...<br />
<br />
Here is a complete video showing all features in action including<br />
<br />
<br />
<ul style="text-align: left;">
<li>service repository administration</li>
<li>uploading new service tasks</li>
<li>default service tasks (REST, Email, Decision, etc)</li>
<li>installing service tasks into project with prompt for required parameters</li>
</ul>
<div>
<br /></div>
<div>
<br /></div>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/5HptDzYa4VM" width="560"></iframe>
<div>
<br /></div>
<div>
This feature is planned for 7.17 so all the feedback is more than welcome.</div>
</div>
</div>
Maciej Swiderskihttp://www.blogger.com/profile/08297633201800941767noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-75296863121540675392019-01-08T07:59:00.002-08:002020-05-21T06:05:45.915-07:00Using React as frontend for jBPM Business Apps<div class="separator" style="clear: both; text-align: left;">
<a href="https://reactjs.org/">React</a> is a very popular and powerful JavaScript framework and is currently one of the best frontend development frameworks out there.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
In this demo we show how you can easily integrate React into your existing or new <a href="https://start.jbpm.org/">jBPM Business Application</a> and consume data from the the out-of-the-box Rest services via React components.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://github.com/business-applications/sample-react/raw/master/img/reactdemo1.png?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="370" data-original-width="800" height="183" src="https://github.com/business-applications/sample-react/raw/master/img/reactdemo1.png?raw=true" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
React Demo </div>
<br />
As usual all the sources of this demo are on <a href="https://github.com/business-applications/sample-react">GitHub</a>.<br />
The demo integrates the React front-end app with the service module of your jBPM Business application via the <a href="https://github.com/eirslett/frontend-maven-plugin">frontend-maven-plugin</a> and then bundles its resources in the generated business app jar. This way you can just start your business app with the provided launch scripts and both React frontend and your business app backend will be available and started together.<br />
<br />
When building the demo the same plugin will also attempt to install node and npm (which are needed for React apps) if they are not available on your machine. It will also build the React frontend for you, so no need to build it separately.<br />
<br />
Here is the youtube video for this demo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/D6T2IAD_YvM/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/D6T2IAD_YvM?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
<br />
Feel free to leave us any comments about this demo and ideas on how to improve it or what you would like to see next.Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-37852980714322647972019-01-04T10:50:00.004-08:002020-05-21T06:05:45.243-07:00Building jBPM Business Applications with Gradle<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVj7jHmLvzjDrrQzB2B67_b1ZWXWTi9zM5Yqxhm87A2QTB81pS2ewey0Jq8XpirhIhiMuTNOV0E6uRpQfAP6f8YS_UjPl6F34P0ly0vL5xhHJyeh5XzAgI8WyPxxN1qWKAx0bqge-lTGAG/s1600/gradle_logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="124" data-original-width="406" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVj7jHmLvzjDrrQzB2B67_b1ZWXWTi9zM5Yqxhm87A2QTB81pS2ewey0Jq8XpirhIhiMuTNOV0E6uRpQfAP6f8YS_UjPl6F34P0ly0vL5xhHJyeh5XzAgI8WyPxxN1qWKAx0bqge-lTGAG/s320/gradle_logo.png" width="320" /></a> </div>
<br />
<br />
<br />
By default <a href="http://jbpm.org/businessapps/gettingStarted.html">jBPM Business Applications</a> generated via <a href="http://start.jbpm.org/">start.jbpm.org</a> are build with <a href="https://maven.apache.org/">Apache Maven</a>. Your generated apps also include build scripts (for Unix, OSX, and Windows) which you can use out of the box to build all the apps modules, as well as launch your app in normal or dev modes.<br />
<br />
Using Maven is fine however it excludes <a href="https://gradle.org/">Gradle</a> users from being able to build and launch jBPM Business Applications using their favorite build tool.<br />
<br />
If you are using Gradle, take a look at <a href="https://github.com/tsurdilo/jbpm-business-apps-gradle">this GitHub repo</a> which includes Gradle build files as well as build scripts that call Gradle to build and launch your business application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEf84z6STybrhvuoLu3J23wZyYikXopYX-ctwAofwGn6JIINpBXFhUtilTuQWCCgZ7i5fdiR8TPoH7S7cBJ4yIIPGGdB-5YlQjAYshFMhRHk2LJqchTv_wl_J0St74h-1ZE09dZd7P2mDm/s1600/Screen+Shot+2019-01-04+at+1.49.44+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="902" data-original-width="1600" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEf84z6STybrhvuoLu3J23wZyYikXopYX-ctwAofwGn6JIINpBXFhUtilTuQWCCgZ7i5fdiR8TPoH7S7cBJ4yIIPGGdB-5YlQjAYshFMhRHk2LJqchTv_wl_J0St74h-1ZE09dZd7P2mDm/s320/Screen+Shot+2019-01-04+at+1.49.44+PM.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Follow the documentation there to set up your Gradle build environment for your generated jBPM business app.<br />
<br />
Note that the out-of-the-box Maven build scripts are still the preferred choice when building your app. This is because the limitation of the Gradle scripts not being able to deploy your app on Docker and Openshift. We use the <a href="https://maven.fabric8.io/">fabric8 plugin</a> to help us do that and this plugin is not currently available for Gradle unfortunately (you can get more info on that <a href="https://github.com/fabric8io/fabric8-maven-plugin/issues/609">here</a>).<br />
<br />
Also to note we are not Gradle experts and it would be <b>really</b> helpful if our <b>jBPM community</b> could <b>help</b> us with making the Gradle build for jBPM Business Applications better. If you are interested please clone <a href="https://github.com/tsurdilo/jbpm-business-apps-gradle">https://github.com/tsurdilo/jbpm-business-apps-gradle</a> and submit changes via git pull requests and share it to our community. We would really appreciate that!!<br />
<br />Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-72977325445696596762019-01-02T10:16:00.000-08:002020-05-21T06:05:45.772-07:00jBPM Business Apps and Okta Single Sign-on (SSO)Wanted to showcase a new <a href="https://start.jbpm.org/">jBPM Business Applications </a>demo that includes easy<br />
integration with the <a href="https://www.okta.com/">Okta</a> identity management service.<br />
<br />
The demo uses the developer.okta.com setup and the <a href="https://github.com/okta/okta-spring-boot">Okta Spring boot starter</a> to quickly set up SSO for our jBPM Business App. It also shows how easy it is to restrict access to certain pages of your jBPM Business Application using the authentication info and identity setup in Okta.<br />
<br />
Demo source code is on <a href="https://github.com/business-applications/sample-okta">github</a>.<br />
<br />
The demo requires you to make an account on <a href="http://developer.okta.com/">developer.okta.com</a> (its free) and create an Okta application and set up two group called "Admin" and "Sales"<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://github.com/business-applications/sample-okta/raw/master/img/oktademo5.png?raw=true" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="459" data-original-width="800" height="228" src="https://github.com/business-applications/sample-okta/raw/master/img/oktademo5.png?raw=true" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Okta group setup<br /></td></tr>
</tbody></table>
<br />Only other configuration is in the your apps application.properties file:<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid7QR-t7lHxpg31tbXjeTZzcC5xOV2tLQQtxOrBBEip8y-wTuJCGNAzV7auW-nUMx2Bd8KtNMucsqxt3D2ylQYekkQkeEqZXUNp4Z0eIfxrffjYVrw8QG-4ys3qcgWBzKLd5fibudjV7iE/s1600/Screen+Shot+2019-01-02+at+12.57.47+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="212" data-original-width="1600" height="83" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid7QR-t7lHxpg31tbXjeTZzcC5xOV2tLQQtxOrBBEip8y-wTuJCGNAzV7auW-nUMx2Bd8KtNMucsqxt3D2ylQYekkQkeEqZXUNp4Z0eIfxrffjYVrw8QG-4ys3qcgWBzKLd5fibudjV7iE/s640/Screen+Shot+2019-01-02+at+12.57.47+PM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">application.properties setup</td></tr>
</tbody></table>
<br />All of this information you get for free once you create an account and an application on the Okta developer site.<div>
<br /></div>
<div>
Once you have completed this setup and start the Okta demo app, go to localhost:8090 and to authenticate and access your app. Note that since there is no logout feature in the demo app, in order to simulate the logout simply delete your recent browser cookies.</div>
<div>
<br /></div>
<div>
If you don't create and set up the "Sales" group in Okta for your application there accessing localhost:8090/sales will give you a "403" page:</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://github.com/business-applications/sample-okta/raw/master/img/oktademo4.png?raw=true" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="230" data-original-width="800" height="115" src="https://github.com/business-applications/sample-okta/raw/master/img/oktademo4.png?raw=true" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Demo app 403 page</td></tr>
</tbody></table>
<br />Otherwise you will be able to access it:<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcbweaehV-Ei0m4tjuX13pD4XmK614ws_uoqEIR8qDpsei_spNaDf8X7LaDp_1huHl0Va1RU2akp5b2FLUdV75x5ML1sFgxwwNfVAowI2N5MO_V-SisCCMLeyJy3O2JUwXlhTBrSN2UTqe/s1600/Screen+Shot+2019-01-02+at+1.01.47+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="539" data-original-width="1600" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcbweaehV-Ei0m4tjuX13pD4XmK614ws_uoqEIR8qDpsei_spNaDf8X7LaDp_1huHl0Va1RU2akp5b2FLUdV75x5ML1sFgxwwNfVAowI2N5MO_V-SisCCMLeyJy3O2JUwXlhTBrSN2UTqe/s400/Screen+Shot+2019-01-02+at+1.01.47+PM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Demo sales page</td></tr>
</tbody></table>
<br />The apps index page is authorized to users that are in the "Admin" group that you have set up in Okta.<div>
<br /></div>
<div>
Here is a youtube video which walks you through the Okta demo and shows how simple it is to set </div>
<div>
this all up:</div>
<div>
<br /></div>
<div>
<br /><div class="separator" style="clear: both; text-align: center;">
<br /><iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/luIiXnYxE5I/0.jpg" src="https://www.youtube.com/embed/luIiXnYxE5I?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div>
<br /><div>
<br /><div>
<br /><div>
<br /><br /></div>
</div>
</div>
</div>
</div>
Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-81165406151450994162018-12-11T10:14:00.000-08:002020-05-21T06:05:46.011-07:00Deploying jBPM Business Apps on DockerjBPM Business Applications have an out-of-the-box configurations to deploy them as docker containers. We have created the video below to show you how easy it is to do that. The video also shows some useful docker commands to run after you have deployed your jBPM Business app as docker container. Enjoy.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/y1JUPaJBoVI/0.jpg" src="https://www.youtube.com/embed/y1JUPaJBoVI?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-62833215143232163802018-12-10T07:22:00.003-08:002020-05-21T06:05:45.532-07:00jBPM Business Applications Demo - Process terminal using Spring Shell<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbU26WQ0_L8qImxnlf3X-bH2FQxmjy8jMejNT_OafnkutildmGtmqnoXhKPN0pJMaFdDiITasmTIlFoE5oaSdTKs1EvJySP280ee_ZSwXqN_dz2zKsfltdFGHcpaTNf-m0Tw1E-9ajp5Kv/s1600/Screen+Shot+2018-12-09+at+11.49.19+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1162" data-original-width="1600" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbU26WQ0_L8qImxnlf3X-bH2FQxmjy8jMejNT_OafnkutildmGtmqnoXhKPN0pJMaFdDiITasmTIlFoE5oaSdTKs1EvJySP280ee_ZSwXqN_dz2zKsfltdFGHcpaTNf-m0Tw1E-9ajp5Kv/s320/Screen+Shot+2018-12-09+at+11.49.19+PM.png" width="320" /></a></div>
<br />
<br />
So far our <a href="https://github.com/business-applications">jBPM Business Applications demos</a> have involved some sort of web-based UI for interacting with our business processes. Sometimes a web-ui is not needed and working with processes via an interactive terminal is the best way to get this done.<br />
<br />
In this demo we show how to use <a href="https://docs.spring.io/spring-shell/docs/current-SNAPSHOT/reference/htmlsingle/">Spring Shell</a> inside your jBPM Business Application created via <a href="http://start.jbpm.org/">start.jbpm.org</a>. Here is a quick screenshot of the demo application:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyVE4lmoxBLtOfgqC6eea3zFqeB1bNLdeKiK8kcNYJZtOL8NevTEL4-xzeLiaFlPvo2yBAn3tfHSRhby1rh6gMRRfuSk7VNgnDpLqKWbxEt8z52DwyXr9dVhfRn75DqDFjbWioS4kq3H0e/s1600/shell-demo.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="943" data-original-width="1600" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyVE4lmoxBLtOfgqC6eea3zFqeB1bNLdeKiK8kcNYJZtOL8NevTEL4-xzeLiaFlPvo2yBAn3tfHSRhby1rh6gMRRfuSk7VNgnDpLqKWbxEt8z52DwyXr9dVhfRn75DqDFjbWioS4kq3H0e/s320/shell-demo.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Demo schreenshot</td></tr>
</tbody></table>
<br />
We start our demo app as usual using the already provided launch scripts but once it starts we do not launch our browser and go to localhost:8090 (default) to access it, but instead we are presented with a prompt and can start typing in our commands to interact with our business processes.<br />
<div>
<br /></div>
<div>
Spring Shell provides some very useful commands out of the box, such as "help", "clear", "exit", "history", and "stacktrace". Our demo app defined ontop of that our own custom commands to interact with our business processes. </div>
<div>
<br /></div>
<div>
Commands that we define in our business app demo are:</div>
<div>
<ul>
<li><b>deploy</b> <groupId> <artifactId> <version></li>
<li><b>processdefs</b></li>
<li><b>processinstances</b></li>
<li><b>startprocess</b> <processDefId> <deploymentId></li>
</ul>
<div>
Our <b>deploy</b> command allows us to deploy a kjar module which is available in our local maven repository. The demo app comes with <a href="https://github.com/business-applications/sample-shell/tree/master/sample-shell-secondkjar">one such module</a> which you can use to deploy after the application has started with the command:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQGdtaGGvl06F7sD-oPxSEcB9xamaQO-ggLgOOL0aExwl0jAGHkuoNhp0PQ6rDU-IItR8M7-1bD9jNheVmueVwGgDMIK5jla3NinabkV4Z8umg6NCCKpggu7xLnHvoR81GncMPxAZoaMzZ/s1600/Screen+Shot+2018-12-10+at+10.14.31+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="250" data-original-width="986" height="101" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQGdtaGGvl06F7sD-oPxSEcB9xamaQO-ggLgOOL0aExwl0jAGHkuoNhp0PQ6rDU-IItR8M7-1bD9jNheVmueVwGgDMIK5jla3NinabkV4Z8umg6NCCKpggu7xLnHvoR81GncMPxAZoaMzZ/s400/Screen+Shot+2018-12-10+at+10.14.31+AM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The <b>processdefs</b> command simply shows all currently available process definition (across all deployments):</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDp63MQVSAoNmMPWF1R3KwuCVclH1ZD-Llu93jN4Px1coGJu-FuACZN7A3q3Bk0EsrtSNSfKIYTVwVht-quo-KgG6PPnjmcHeQJ6_RZuhdyzam811VKVnbP_516BwJuotBJeM3jk_Mnoa-/s1600/Screen+Shot+2018-12-10+at+10.15.54+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="348" data-original-width="1600" height="86" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDp63MQVSAoNmMPWF1R3KwuCVclH1ZD-Llu93jN4Px1coGJu-FuACZN7A3q3Bk0EsrtSNSfKIYTVwVht-quo-KgG6PPnjmcHeQJ6_RZuhdyzam811VKVnbP_516BwJuotBJeM3jk_Mnoa-/s400/Screen+Shot+2018-12-10+at+10.15.54+AM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
The <b>startprocess </b>command allows you to start a business process. It takes in the process definition id and the deployment unit id (if deployment unit id is not specified, the default one is assumed). So for example to start our "firstTestProcess" business process we can do:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEignlx_YrCtDqWIWEannioii85Gr5hJPh-9ZjPepbg0XgBeo0WEnTF64-uXEj95tyziILmwN_oB6T004wz6Mw6Wh0bwmGHX_PZCSxomhXETC5Z-Di5dwAWR66pBuW4LsW2SZxCm8aFMNU3W/s1600/Screen+Shot+2018-12-10+at+10.17.55+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="178" data-original-width="1264" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEignlx_YrCtDqWIWEannioii85Gr5hJPh-9ZjPepbg0XgBeo0WEnTF64-uXEj95tyziILmwN_oB6T004wz6Mw6Wh0bwmGHX_PZCSxomhXETC5Z-Di5dwAWR66pBuW4LsW2SZxCm8aFMNU3W/s400/Screen+Shot+2018-12-10+at+10.17.55+AM.png" width="400" /></a></div>
<div>
<br /></div>
Lastly, the <b>processinstances</b> command shows all process instances that are available, for example:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ7XaemGD2vx17fsJSPJyGAaAkcm9s-u7TNSe2sANRT65UsSAldSGwFXIQ5GXv9ImXZBpIfExAs3pGLMVRLDeEQMot-pySagJ4n3YHIDfFwnGZZOuJ7jIND3iSvJysk4ZY431JjglBjVkS/s1600/Screen+Shot+2018-12-10+at+10.19.35+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="316" data-original-width="716" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ7XaemGD2vx17fsJSPJyGAaAkcm9s-u7TNSe2sANRT65UsSAldSGwFXIQ5GXv9ImXZBpIfExAs3pGLMVRLDeEQMot-pySagJ4n3YHIDfFwnGZZOuJ7jIND3iSvJysk4ZY431JjglBjVkS/s400/Screen+Shot+2018-12-10+at+10.19.35+AM.png" width="400" /></a></div>
<div>
<br />
<br />
Finally here is a youtube video where we run the demo and show off all the commands. The video also explains the code and how to create custom commands using Spring Boot and Spring Shell.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/pq3lGAUzlKQ/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/pq3lGAUzlKQ?feature=player_embedded" width="320"></iframe></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
(This is the first time I tried creating a youtube video intro so <b>please don't laug</b>h ....too much :) )<br />
<br />
Hope this demo helps you guys get some ideas on how to create cool jBPM business apps.</div>
Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.comtag:blogger.com,1999:blog-4917805307126105128.post-60510605990733218822018-12-09T19:26:00.001-08:002020-05-21T06:05:45.436-07:00Starting your jBPM Business Application as a Service<span style="color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif;"><span style="background-color: white;">In addition to starting your jBPM Business Application generated via <a href="http://start.jbpm.org/">start.jbpm.org</a> using the provided launch scripts, for example:</span></span><br />
<span style="color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif;"><span style="background-color: white;"><br /></span></span>
<span style="color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif;"><span style="background-color: white;"><code style="background-color: #f9f2f4; border-radius: 4px; box-sizing: border-box; color: #c7254e; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.6px; padding: 2px 4px; white-space: nowrap;">./launch.sh clean install</code><span style="font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"> for unix or </span><code style="background-color: #f9f2f4; border-radius: 4px; box-sizing: border-box; color: #c7254e; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.6px; padding: 2px 4px; white-space: nowrap;">launch.bat clean install</code><span style="font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"> for windows, you can also start and manage your business application as a service. This provides you with extra control of your app especially in production environments. </span></span></span><br />
<span style="color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif;"><span style="background-color: white;"><span style="font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"><br /></span></span></span>
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">Weather you are on Unix based system, Windows, or OSX the first step is to configure the business application to generate a fully executable jar. To do this locate your </span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="background-color: #f9f2f4; font-size: 12.6px; white-space: nowrap;">service</span></span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"> module of your business app and modify its</span><span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;"> pom.xml</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"> to configure the </span><span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">spring-boot-maven-plugin</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"> as follows:</span><br />
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7PKaYnM4kDfXxovFNHIdH3YujK7y51jTdScLij6DWvogD-Nxal-ISgwr89HE7zPrQYzGavrpbUJ4yTh-pZmS7a51MiKrW_9dEKFYOAQg3hAJTTN_c7RuG3h-rDdqVTQ5F_Jiw5G4QoihT/s1600/Screen+Shot+2018-12-09+at+9.15.49+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="376" data-original-width="850" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7PKaYnM4kDfXxovFNHIdH3YujK7y51jTdScLij6DWvogD-Nxal-ISgwr89HE7zPrQYzGavrpbUJ4yTh-pZmS7a51MiKrW_9dEKFYOAQg3hAJTTN_c7RuG3h-rDdqVTQ5F_Jiw5G4QoihT/s320/Screen+Shot+2018-12-09+at+9.15.49+PM.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
With this configuration building your business app will produce a fully executable jar. </div>
<div class="separator" style="clear: both; text-align: left;">
Now let's see how we can start the business app as a service under different operating systems.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>1. Unix/Linux Service</b></div>
<div class="separator" style="clear: both; text-align: left;">
Here we have two options, using <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">init.d </span>or <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">systemd</span> . </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
a) To install our business app as an init.d service we need to create symlink to our executable jar, for example (using the default setup on start.jbpm.org):</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">sudo ln -s ~/business-application/business-application-service/target/</span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.jar </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">/etc/init.d/</span></span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.jar</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
after this you can start your business app with for example:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">service </span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.jar start</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
b) To install our business app as a systemd service we need to create a script called <span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.service</span> in the <span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">on-service-1.0.SNAPS </span>directory (again we assume the default business app setup, the actual name has to reflect the real app name you have created during app creation on start.jbpm.org). </div>
<div class="separator" style="clear: both; text-align: left;">
The script could look as follows:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">[Unit]</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">Description=</span></span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT</span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">After=syslog.target</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;"><br /></span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">[Service]</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">User=</span></span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT</span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">ExecStart=</span></span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">~/business-application/business-application-service/target/</span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.jar </span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">SuccessExitStatus=143</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;"><br /></span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">[Install]</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">WantedBy=multi-user.target</span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;"><br /></span></span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;"><br /></span></span></div>
<div class="separator" style="clear: both;">
Don't forget to change the description, user and execstart parameters to match your installation.</div>
<div class="separator" style="clear: both;">
Now we can tell systemd to start our business app on system boot with for example:</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">systemctl enable </span></span><span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.service</span></div>
<div class="separator" style="clear: both;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;"><br /></span></div>
<div class="separator" style="clear: both;">
<b>2. Windows Service</b></div>
<div class="separator" style="clear: both;">
You can start your business application as a Windows service using <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">winsw</span> command. For details on how to do this please read detailed instructions on <a href="https://github.com/snicoll/spring-boot-daemon">https://github.com/snicoll/spring-boot-daemon</a>.</div>
<div class="separator" style="clear: both;">
<b><br /></b></div>
<div class="separator" style="clear: both;">
<b>3. OSX Service</b></div>
<div class="separator" style="clear: both;">
If you are on OSX, you can use the <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">launchctl</span> command. To get started first we need to create our launch configuration under <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">~/Library/LaunchAgents</span> directory. So let's create a launch config file called <span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">business-application-service-1.0.SNAPSHOT.plist </span>which can look as follows (again, assuming the default generation settings):</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVtKKvUWTfdiFMOJNijfG1QP_Sdm1ESQpTKRxY1Y0pF_5bM0N4BZia3RvRUywvUGR74QLzwTQcv74XgYAvDGAYZKy1sFaQC23e4s3U3DzHnqZ-DBMlRIYe8WHysKGmeAO5DY79WoAfT7Rl/s1600/Screen+Shot+2018-12-09+at+9.16.40+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="306" data-original-width="1600" height="121" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVtKKvUWTfdiFMOJNijfG1QP_Sdm1ESQpTKRxY1Y0pF_5bM0N4BZia3RvRUywvUGR74QLzwTQcv74XgYAvDGAYZKy1sFaQC23e4s3U3DzHnqZ-DBMlRIYe8WHysKGmeAO5DY79WoAfT7Rl/s640/Screen+Shot+2018-12-09+at+9.16.40+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
With the launch config created log out with your current user and log back in. Your business application has been started and you can right away access it under <a href="localhost:8090">locahost:8090 </a>in your browser. </div>
<div class="separator" style="clear: both; text-align: left;">
You can manage your business app service at this point using the <span style="background-color: #f9f2f4; color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace; font-size: 12.6px; white-space: nowrap;">launchctl</span> command. For example to stop our business app service we would run:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;">launchctl stop business-application-service-1.0-SNAPSHOT</span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: #c7254e; font-family: "menlo" , "monaco" , "consolas" , "courier new" , monospace;"><span style="font-size: 12.6px; white-space: nowrap;"><br /></span></span></div>
<div class="separator" style="clear: both; text-align: left;">
and to stop our business application from being started automatically on system startup/login we can simply remove our launch configuration .plist file from ~/Library/LaunchAgents directory.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Hope this information is useful to some of you guys when choosing options on how to launch/deploy/manage your jBPM Business Applications.</div>
<span style="color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif;"><span style="background-color: white;"><span style="font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;"><br /></span></span></span>Tihomir Surdilovichttp://www.blogger.com/profile/03367503430786800722noreply@blogger.com