Skip navigation
All Places > Alfresco Process Services & Activiti (BPM) > Blog > 2018 > August
2018

Hi everyone, it has been long since the last Roadmap update, this blog post address the main reasons why we delayed Activiti Core & Activiti Cloud Beta1and how the work is going to come moving forward. It is important to notice that this update represent the work that is being done in the Open Source community for Activiti Core and Activiti Cloud and we encourage anyone reading this article to join us in our journey.

This blog post is divided into 3 sections, Past, Present and Future. For the sake of transparency, and in addition to our weekly blog posts, we wanted to summarise our work (community) during the last 5 months.

Past: Some background about Beta1

Before Beta1, while we were doing Early Access Releases, we were defining the shape of Activiti Cloud. As in every experimentation exercise, we create a set of Proof of Concepts to demonstrate how an Activiti Cloud Applications were supposed to be built. We started with Spring Cloud and Docker, and it made a lot of sense at that point to use Spring Cloud Netflix OSS libraries to build Cloud Native applications. These libraries and services such as the Eureka Service Registry, Zuul (Gateway) and Spring Cloud Config Server helped us to demonstrate our points for Cloud Native Applications.

While looking at Kubernetes, we knew that there were some overlaps, all of the Early Access releases and examples contained dependencies to client libraries to connect to these infrastructural services. After getting the initial examples using Docker Compose, we started testing on Minikube, but quickly we realise that we better work in real life clusters than in local VMs. While testing on real life clusters such as GKE and AWS + Kops we realise that we didn’t need much of the Netflix OSS libraries, so we start moving away from them and started collaborating with the Spring Cloud Kubernetes project.

Once the PoCs were done, we defined a new set of APIs for the Runtime Services. These APIs needed to be defined at all levels, meaning Activiti Core, Java Services and at Activiti Cloud REST and Message Driven Endpoints level. This was a very interesting exercise, because previous version of Activiti didn’t define a public/private APIs that we can reuse. For this new APIs we focused on the Runtime aspects first but more APIs will come to cover others (such as data consumption, modeling, etc.).
At the same time we did another two important and related pieces of work around HELM and Jenkins X. The team presented at a set of conferences and prepared the Trending Topic Campaigns Workshop with heavy focus on building a real scenario that can be used to demonstrate the power of Activiti Cloud.

These large pieces of work(moving away from Netflix OSS, the new APIs definitions, HELM, Jenkins X and workshop examples) took us 5 months of work to stabilise and validate our ideas with the Java, Containers and Kubernetes communities. During these 5 months of work, it became clear that after Beta1 we couldn’t keep working in the same way to be efficient, we decided that we needed to spend time in our internal workflows in order to accelerate the project speed and in order to propagate those working practices to our consumers.

Present: Beta1

Beta1is focused on the main Runtime building blocks for Activiti Cloud Applications in Kubernetes. These building blocks can now be consumed using the provided [HELM charts](h) as templates for building custom applications. These HELM Charts has been tested in AWS+Kops, GKE and PKS (EKS is coming). If you are interested in testing in Openshift, Azure or any other Cloud Provider please get in touch, we are more than happy to help.

As mention in the release post, these building blocks are: Runtime Bundle, Audit & Query Services. These Services expose REST and Message Driven endpoints using Spring Cloud Streams ( we test with RabbitMQ as our Message Broker). These services work on top of a common infrastructure composed by: A gateway, A Service Registry, Config Maps and Keycloak for SSO and IDM.

If we build for the Cloud, we need to work in the Cloud. In the Cloud not everything is perfect, so we have the basics now, we have a huge road ahead to simplify the experience for our customers. Jenkins X helped a lot on this front, for that reason we are collaborating with them to improve their tools for all of us.

Because Beta1 targeted Kubernetes deployments the release is not supposed to support other deployments (Local Spring Boot / Docker) as it is. Docker Compose is currently not working due the fact that we moved away from the Netflix OSS libraries. We can still support a Docker Compose scenario for getting started experiences, but we will need customised Docker Images for that (adding extra Netflix OSS dependencies for such environment). Get in touch if you want to help us on that front.

As you might notice, because Beta1 was focused on the Runtime Services, Modeling services were included but they need more polishing. Also the Application Service which is not considered as a Core Building Block was included but there are still more work to be done in order to be stable.

If you want to get started with Beta1, we recommend the following blog posts:

Future: Beta2 (work in progress)

We are aiming to have Beta2 released by the end of September, and as mentioned before, we are making a lot of emphasis into our community process for building these release using a Continuous Deployment and Continuous Delivery approach. We believe that this change is crucial for 2 big reasons:

  1. It will allow the community to evolve faster, allowing innovation streams to be included in the releases faster, enabling different components to evolve at their own pace and free engineering time to work on features instead of releases
  2. Similar practices will be needed by whoever wants to consume these tools. We want to make sure that we lead the way (by eating our own dog food and generating recommendations and examples based on our experience) to our community and private customers.

For Beta2 we are aiming to have a set of CI/CD pipelines for all our libraries and building blocks as well as an environment where we can test in a continuous deployment fashion the impact of our changes at every level in our stack. Hence Beta2 will include a larger set of Acceptance Tests which will be validated after any pull request get merged at any level of the chain.
We are aiming to change the versioning strategy for Activiti Core & Activiti Cloud to be able to evolve each library and building block independently without being tied to a single version for all of our components. We will use semantic versioning for all our artefacts (Major.Minor.Patch) and we should be able to generate and test a new release for every Pull Request that gets merged into our develop branches. We are still defining some of these details, so expect a new blog post about this subject soon.

We aim to not only have basic (conformance) examples plus their acceptance tests running in an environment 24/7, but we also want to have our workshop Trending Topic Campaigns being used to check that new releases can support more complex scenarios.

For Beta2 we are also spending time on our Modeling Services and we expect to release a new Modeling Application along our refined Runtime building blocks to be able to demonstrate an initial full cycle of how to build Activiti Cloud Applications from Modeling to Runtime in Kubernetes.

 

Summary and Future (Post Beta2)

After Beta2 our focus will be on hardening our core services and to simplify the experience of building Activiti Cloud Applications for Developers. There are some big topics that we want to cover before going to Release Candidate and those include:

  • Further refinements to our CI/CD approach, we know that we cannot get it right in the first time
  • Istio is the most natural option in Kubernetes to support in an uniform way cross cutting concerns, so we want to make sure that we do some initial testing with it for our Cloud deployments
  • Distributed BPMN Timers should be covered and added to our acceptance tests suite
  • Spring Cloud Kubernetes enhancements for Distributed Timers
  • Trending Topics Campaigns example / workshop running 24/7 in an environment.
  • Performance Tests introduction (still under discussion)
  • Pluggable Pipelines (still under discussion)

I hope that this blog post give you an overview about what is going on in the Activiti Core and Activiti Cloud projects, if there is something that you are interested that is not covered here, drop us a message or join our Gitter channel and we will be more than happy to expand the information provided here.

Alfresco Process Services (APS) 1.9 provides support for authentication through Keycloak. The integration with Keycloak gives us access to many advanced Identity Provider features, such as SAML 2.0, oAuth, OpenID, Identity Brokering and User Federation. In this article, we will review the integration of APS, and AIS (Alfresco Identity Service) in a multi-domain LDAP environment.

With the introduction of AIS into the architecture, APS can now support authentication through multiple LDAP Domains, or other federated Identity Providers. However, in order to use APS integration with AIS, users are required to be preloaded in APS. Currently the APS-AIS Integration provided in APS 1.9 does not support user synchronization, so users will need to be loaded into APS via other means, such as the LDAP User Sync feature that APS supports.

In the following article: "User Synchronization in APS from Keycloak,"  I capture the technical details about synchronizing users and groups into APS from Keycloak. The article also includes a functional APS module that can be installed, or adapted to similar use cases.

Start Signal Event with REST example


Using Alfresco Process Services powered by Activiti, this example will demonstrate how to throw a signal in the global scope of the tenant for other processes to catch.

 

I am going to show one example of how to use a signal to start a process, but there a several ways to use the signal event.

You may choose to send a REST signal instead of using the REST call when there are several processes you wish to start at the same time or you don't know the ID of the process you want to start.

 

Configuring the REST call

  1. Define the REST header authentication in the under "Basic Auths" in the Identity Management > Tenants > Endpoints section Defining the Basic Auth header
  2. Define the REST endpoint under "Endpoints" in the Identity Management > Tenants > Endpoints section. For the Protocol, Host, and Port sections, enter the relevant information for your activiti-app configuration.
    Defining the REST endpoing
  3. In your process, add a REST call task activity.
  4. Configure the REST call task:
  5. Request mapping:

      The JSON of the request mapping should be similar to:

{
   "signalName":"mysignal",
   "tenantId":"tenant_1",
   "async":"false",
   "variables":
   [
      {
         "name":"varFromSignal",
         "value":"This is a string"
      }
   ]
}

      The values are:
         signalName - The name of the signal you are throwing and catching. You will need to define this in the process          that you want to catch the signal.
         tenantId - The ID of the tenant in which to throw the signal. In a non-MT environment, the tenantId will be          "tenant_1"
         async - If you want the throw to be executed asynchronously
         variables - Any variables you want to pass to catch events. You will need to define these in the catch process.

   6. Request header:

         Header name: Content-Type
         Header value: application/json

   7. Endpoint:
         HTTP method: POST
         Base endpoint: http://<aps_host>:<aps_port>
         Rest URL: /activiti-app/api/runtime/signals?tenantId=<your_tenant_id>

Defining the step REST endpoint

REST configuration is complete

 

Configuring the Start Signal Event

  1. In the editor for the process that will catch the signal, open up the signal definition and add a new signal:Defining the Signal
  2. The signal name, defined under the "Signal Definitions", needs to match what you defined in the REST call, or vice versa:
    Defining the Signal values
  3. The scope needs to be global
  4. Next, add a Start Signal Event to the process
  5. Under the configuration for the event, select your defined signal from the drop down under Signal Reference
    Defining the Signal reference
  6. If you are passing variables with the signal, as defined in your REST call, define those variables in the global space of the process
  7. Build out the rest of your process

 

Notes

You can find sample apps and process on my Github

The example files may not work with the community edition of Activiti, but the concepts are the same.

 

References

 

https://www.activiti.org/5.x/userguide/#_signal_event_received

 

Last week we started with a major clean up in our repositories to better decouple each project responsibility. This will enable us to build and version each module individually to allow faster development cycles. This week we will be setting up these pipelines to test the whole process for our libraries first followed by our service layer. We are still looking for Beta testers, if you want to get involved we recommend you to try the following two tutorials and get in touch via Gitter if you want to jump into more advanced topics:

@mteodori- holidays -

@lucianoprea- holidays -

@constantin-ciobotaru - holidays - 

@balsaroriworked on initial design of the Forms Router components.

@igdianovworked on pipelines for Activiti Cloud Applications

@cristina-sirbuContinued working on Activiti Cloud Events Adapter Service. Changed communication with RabbitMq (used Spring Cloud Stream). Helm Chart for this in progress. Also discovered the new Activiti Full Example App.

 

@daisuke-yoshimotois working on applying new audit service API interface to

https://github.com/Activiti/activiti-cloud-audit-service-mongo.

@almerico Created presentation cluster based on new Activiti Cloud version.

@miguelruizdevworked on the ttc workshop, trying it out against the Beta1 version and identifying the changes that need to be implemented for it to work again.

@ryandawsonukSetup acceptance tests to run in a new custer against a JX-deployed example as part of review of CI/CD practices. Submitted PRs to Jenkins-X draft packs to help keep Activiti charts close to JX default practices. Helped Elias with package name refactoring to refine the API clarity/readability.

@erdemedeirosworked with @Salaboy and @ryandawsonuk to get Activiti API and Activiti Cloud API extracted to dedicated repositories (https://github.com/Activiti/activiti-apiand https://github.com/Activiti/activiti-cloud-api). Maven modules has been renamed and package structure has changed.

@salaboyworked on the next round of refactoring with @erdemedeirosand @ryandawsonukwe aligned package names, maven module names and repositories to follow the same conventions. This will make it easy to document and easy to maintain in the long run. This changes are also helping us to move forward Continuous Delivery and we will keep our experimentation with Jenkins X to build each repository.

Get in touch if you want to contribute: https://gitter.im/Activiti/Activiti7

We are looking forward to mentor people on the technologies that we are using to submit their first Pull Request ;)

Last week we worked on the release of Activiti Core and Activiti Cloud Beta1. We wrote some Getting Started guides and we tested the maven artifacts and example services and deployment descriptors quite extensively. We got the Beta1 release deployed in PKS and also tested that the released example services can work in a Minikube deployment using the same Activiti Cloud Full Example HELM charts. Congrats to everyone involved in the release and thanks a lot for all of you who are providing early feedback about this release.

This week we already started with some large refactorings regarding source code organization and improving our work practice to fully switch to Continuous Deployment. We will aim for doing a Beta2 release quite soon, and we will be updating the Gitbook and the Roadmap accordingly this week.

@almericoUpgrades according to latest release with our google cluster.

@miguelruizdevworked on the overall testing of the third API refactoring, fixing tests in the acceptance test security module, reporting issues on faulty endpoints for future fixes beyond Beta1, and, along with @erdemedeiros, created new clusters within the company organization in GKE using Jenkins X.

@balsarori initial Form Router discussions

@mteodori - holidays - 

@cristina-sirbuWorked on Activiti Cloud Events Adapter Service ( a Spring Boot Application which gets the events from RabbitMq, enrich them to a new format and pushes them to an ActiveMq instance). Communication between RabbitMq and ActiveMq done. Enrichment of the events is still in progress.

@constantin-ciobotaruworked for adding import/export applications/models endpoints in modeling.

@ryandawsonukAdded minikube instructions to activiti-cloud-full-example chart. Updated the audit-service module to follow the query-service module in using the newly-refactored versions of the services for security and identity. Added tests for an example cloud connector to the serenity-based BDD acceptance tests and updated the tests so that the security-policies tests work together with the deployment conditions for runtime tests. Updated the release scripts for building and tagging the example-level repos using their new structure.

@erdemedeirosworked with @Salaboy to get all the API related PRs ready to merge. Set up a GKE cluster using Jenkins X to test the latest changes in the APIs.

@salaboy worked on the release process and creating tutorials and examples.

Get in touch if you want to contribute: https://gitter.im/Activiti/Activiti7

We are looking forward to mentor people on the technologies that we are using to submit their first Pull Request ;)

I am happy to announce that after more than a year of hard work and particularly intense work over the last 4 months we are ready to release the first Beta version of all the Java Artifacts. You can consume them all from Maven Central.

During this release, we focused on providing the first iteration of Activiti Cloud and from now on we will harden each service in an incremental way. We are happy with the foundation and now it is time to test and polish the next generation of Activiti. We are eager to get early feedback, please get in touch via Gitterif you find any problem or have questions about the released artifacts.

What is included in Activiti Core and Activiti Cloud Beta1

 

Beta1 is focused on providing the foundation for both our Java (embedded) and Cloud Native implementations.

This release is divided into two big categories: Activiti Core and Activiti Cloud Building Blocks.

Activiti Core

On the Core, we have provided a new set of APIs for the Task and Process Runtime that enable a simple migration from embedded to the Cloud Approach. We believe that this is a fundamental change in order to provide long-term API support focused on Runtimes and following the Command Pattern. We also added security, identity and security policy abstractions to make sure that you can quickly integrate with different implementations when you embed the process & task runtime into your Spring Boot applications.

Activiti Core is now based on top of Spring Boot 2. On the Core, you should expect further integrations with Spring Boot 2. There are plans to adopt all the reactive capabilities included in Spring 5. A big part of refactoring the Core layer was about simplifying the runtimes to make sure that they don’t clash with other frameworks’ responsibilities.

The new set of Runtime APIs was conceived to promote Services that are Stateless and immutable, which allow us to write testing, verification and conformance tools to guarantee that your business processes are safe and sound to run in production environments. These Runtime APIs include new responsibilities and don’t deprecate the Activiti 6.x APIs. These new Runtime APIs are replicated at the service level (REST and Message Driven Endpoints) in the Activiti Cloud Layers.

If you want to get started with using Activiti Core 7.0.0.Beta1take a look at the following tutorials which highlight the ProcessRuntime and TaskRuntime API usage in Spring Boot 2 applications.

Getting Started with Activiti Core Beta1

Activiti Cloud Building Blocks

On the Activiti Cloud front, we are providing the initial Beta1 versions of our foundational building blocks:

  • Activiti Cloud Runtime Bundle
  • Activiti Cloud Query
  • Activiti Cloud Audit
  • Activiti Cloud Connectors

These building blocks were designed with a Cloud Native Architecture in mind and all of them are built on top of Spring Cloud Finchley.  Together, these components form the foundation for a new bread of Activiti Cloud Applications which can be distributed and scaled independently.  All these building blocks can be used as independent Spring Boot applications, but for large-scale deployments, these components have been designed and tested using Docker Containers and Kubernetes as the main target platform. We have been using Jenkins X to build components that need to be managed, upgraded and monitored in very dynamic environments.

 

All these building blocks understand the environment in which they are running, so they are enabled to work with components such SSO/IDM, Service Registry, Data Streams, Configuration Server, and Gateways. By being aware of the environment, our applications can be managed,configured and scaled independently.

It is important to understand that we have also included some experimental services in this release including:

  • Application Service
  • Modelling backend services
  • GraphQL support for the Query Service / Notification Service
  • An alternative Mongo DB implementation for Audit Service

 

If you want to start with the Cloud Native approach we recommend looking at the Activiti Cloud HELM charts for Kubernetes: https://github.com/Activiti/activiti-cloud-charts/tree/master/activiti-cloud-full-example

 

These example HELM Charts can be used to get all the services up and running.

 

Check the following blog post if you want to get started with Activiti Cloud in GKE.

Getting Started with Activiti Cloud Beta1

What is coming next?

In this release, we didn’t include any UI bits, and we focused on core services to build Cloud Native applications. In the following Beta2 and RC releases we will include new backend services to support the new Activiti BPMN2 Modeler application. This new set of modeling services and the new Activiti Modeler application is currently being designed to enable our Cloud Deployments by providing a simplified packaging mechanism for our Activiti Cloud Applications.

 

On future releases we will be hardening our building blocks, improving documentation and examples and adding new services to simplify implementations.  We are actively looking at tools such as Istioand KNativeto provide out of the box integration with other services and tools that rely on such technologies.

 

We are also contributing and collaborating with the Spring Cloud community to make sure that our components are easy to use and adopt rather than clash with any of the other Spring Cloud infrastructure components. This also involves testing our core building blocks in Pivotal Containers Services (PKS) which is based on Kubernetes.

 

We want to provide a continuous stream of community innovation and for that reason, we will change how the Core and Cloud artefacts are versioned and their release lifecycles. We are moving to a Continuous Delivery approach for each of the libraries that we build following the practices mentioned in the Accelerate book. We will, of course, update the structure of our projects but the services and APIs will remain the same.

 

You should expect some naming changes between Beta and RC artifacts. We are still polishing new service names and configurations. This will be all documented in the release notes for each release. You can always keep an eye on our public Roadmap document (that will be updated in the following days)for the future Beta, RC and GA releases.

 

As always, this is a great moment to join the community and provide feedback. If you are looking into building Cloud Native applications, we are more than happy to share and get feedback from people going through the same journey. Feel free to join our daily open standups or ping us in our Gitterchannel.

We have just released Activiti Core and Activiti Cloud 7.0.0.Beta1to Maven Centraland we wanted to highlight the new Process and Task Runtime APIs.

The new APIs were created with a clear purpose to address the following requirements:

  • Provide a clear path to our Cloud approach
  • Isolate internal and external APIs to provide backward compatibility moving forward
  • Provide a future path to modularity by following the single responsibility approach
  • Reduce the clutter of the previous version of APIs
  • Include Security and Identity Management as first-class citizens
  • Reduce time to value for common use cases, where you want to rely on the conventions provided by popular frameworks
  • Provide alternative implementations of the underlying services
  • Enable the community to innovate while respecting well-established contracts

We haven’t deprecated the old API, so you are still free to use it, but we strongly recommend the usage of the new API for long-term support.

This API is in a beta review, meaning that we might change and polish it before the GA release. We will appreciate all the feedback that we can get from our community users and if you want to get involved with the project please get in touch.

Time to get our hands dirty with a couple of example projects.

TaskRuntime API

If you are building business applications, creating Tasks for users and groups in your organisation is something that you might find handy.

The TaskRuntimeAPIs are here to help you.

You can clone this example from GitHub: https://github.com/Activiti/activiti-examples

The code from this section can be found inside the “activiti-api-basic-task-example” maven module.

If you are running inside a Spring Boot 2 application you only need to add the activiti-spring-boot-starter dependency and a DB driver you can use H2 for an in-memory storage.

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/pom.xml#L45

[sourcecode language="xml"]org.activiti activiti-spring-boot-starter com.h2database h2 [/sourcecode]

We recommend using our BOM (bill of materials

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/pom.xml#L30

[sourcecode language="xml"]org.activitiactiviti-dependencies7.0.0.Beta1importpom[/sourcecode]

Now let’s switch to our DemoApplication.class: https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L25

Then you will be able to use the TaskRuntime

 

| @Autowired

| private TaskRuntime taskRuntime; 

 

Once you have the bean injected into your app you should be able to create tasks and interact with tasks.

 

public interface TaskRuntime {
  TaskRuntimeConfiguration configuration();
  Task task(String taskId); Page |tasks(Pageable pageable);
  Page tasks(Pageable pageable, GetTasksPayload payload);
  Task create(CreateTaskPayload |payload);
  Task claim(ClaimTaskPayload payload);
  Task release(ReleaseTaskPayload payload);
  Task complete(CompleteTaskPayload payload);
  Task update(UpdateTaskPayload payload);
  Task delete(DeleteTaskPayload payload);
  ...
}

 

For example, you can create a task by doing:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L45

 

taskRuntime.create( TaskPayloadBuilder.create() 
.withName("First Team Task")
.withDescription("This is something really important")
.withGroup("activitiTeam")
.withPriority(10)
.build());

This task will be only visible by users belonging to the activitiTeamand the owner (the current logged in user).

As you might have noticed, you can use TaskPayloadBuilder to parameterize the information that is going to be sent to the TaskRuntime in a fluent way.

In order to deal with Security, Roles and Groups we are relying on Spring Security modules. Because we are inside a Spring Boot application, we can use the UserDetailsService to configure the available users and their respective groups and roles. We are currently doing this inside a @Configurationclass: https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplicationConfiguration.java#L26

Something important to notice here, is that in order to interact with the TaskRuntime API as a user, you need to have the role:ACTIVITI_USER (Granted Authority: ROLE_ACTIVITI_USER) .

While interacting with REST endpoints the Authorization mechanism will set up the currently logged in user, but for the sake of the example we are using an utility class (https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/src/main/java/org/activiti/examples/SecurityUtil.java#L26) that allows us to set in the context a manually selected user.  Notice that you should never do this unless you are trying things out and you want to change users without going through a REST endpoint. Look into the “web” examples to see more real scenarios where this utility class is not needed at all.

One last thing to highlight from the example is the registration of Task Event Listeners:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L89

@Bean public TaskRuntimeEventListener taskAssignedListener() { 
  return taskAssigned -> logger.info( ">>> Task Assigned: '" +
                         taskAssigned.getEntity().getName() +
                         "' We can send a notification to the assignee: " +
                          taskAssigned.getEntity().getAssignee());
}

You can register as many TaskRuntimeEventListeners as you want. This will enable your application to be notified with Runtime events are triggered by the services.

ProcessRuntime API

In a similar fashion, if you want to start using the ProcessRuntime APIs, you need to include the same dependencies as before. We aim to provide more flexibility and separate runtimes in the future, but for now the same Spring Boot Starter is providing both TaskRuntime and ProcessRuntime API.

The code from this section can be found inside the “activiti-api-basic-process-example” maven module.

public interface ProcessRuntime { 
  ProcessRuntimeConfiguration configuration();
  ProcessDefinition processDefinition(String processDefinitionId);
  Page processDefinitions(Pageable pageable);
  Page processDefinitions(Pageable pageable, GetProcessDefinitionsPayload payload);
  ProcessInstance start(StartProcessPayload payload);
  Page processInstances(Pageable pageable);
  Page processInstances(Pageable pageable, GetProcessInstancesPayload payload);
  ProcessInstance processInstance(String processInstanceId);
  ProcessInstance suspend(SuspendProcessPayload payload);
  ProcessInstance resume(ResumeProcessPayload payload);
  ProcessInstance delete(DeleteProcessPayload payload);
  void signal(SignalPayload payload);
  ...
}

 

Similarly to the TaskRuntime APIs, in order to interact with the ProcessRuntime API the currently logged user is required to have the role “ACTIVITI_USER”.

First things first, let’s autowire our ProcessRuntime:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L32

[sourcecode language="java"] @Autowired private ProcessRuntime processRuntime; @Autowired private SecurityUtil securityUtil; [/sourcecode]

Same as before, we need our SecurityUtil helper to define in behalf of which user we are interacting with our APIs.  

Now we can start interacting with the ProcessRuntime:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L47

[sourcecode language="java"] Page processDefinitionPage = processRuntime .processDefinitions(Pageable.of(0, 10)); logger.info("> Available Process definitions: " + processDefinitionPage.getTotalItems()); for (ProcessDefinition pd : processDefinitionPage.getContent()) { logger.info("\t > Process definition: " + pd); } [/sourcecode]

Process Definitions needs to be placed inside the /src/main/resources/processes/. For this example we have the following process defined:

process-with-service-task

We are using Spring Scheduling capabilities to start a process every second picking up random values from an array to process:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L67

@Scheduled(initialDelay = 1000, fixedDelay = 1000) 
public void processText() {
  securityUtil.logInAs("system");
  String content = pickRandomString();
  SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
  logger.info("> Processing content: " + content + " at "
          + formatter.format(new Date()));
  ProcessInstance processInstance = processRuntime
                    .start(ProcessPayloadBuilder
                          .start()
                          .withProcessDefinitionKey("categorizeProcess")
                          .withProcessInstanceName("Processing Content: " + content)
                          .withVariable("content", content)
                          .build());
  logger.info(">>> Created Process Instance: " + processInstance);
}

Same as before, we are using the ProcessPayloadBuilderto parameterize which process do we want to start and with which process variables in a fluent way.

Now if we look back at the Process Definition, you will find 3 Service Tasks. In order to provide the implementation for these service tasks you need to define Connectors:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L81

[sourcecode language="java"] @Bean public Connector processTextConnector() { return integrationContext -> { Map inBoundVariables = integrationContext.getInBoundVariables(); String contentToProcess = (String) inBoundVariables.get("content") // Logic Here to decide if content is approved or not if (contentToProcess.contains("activiti")) { logger.info("> Approving content: " + contentToProcess); integrationContext.addOutBoundVariable("approved",true); } else { logger.info("> Discarding content: " + contentToProcess); integrationContext.addOutBoundVariable("approved",false); } return integrationContext; }; } [/sourcecode]

These connectors are wired up automatically to the ProcessRuntimeusing the Bean name, in this example “processTextConnector”. This bean name is picked up from the implementationproperty of the serviceTaskelement inside our process definition:

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-process-example/src/main/resources/processes/categorize-content.bpmn20.xml#L22

<bpmn:serviceTask id="Task_1ylvdew" name="Process Content" implementation="processTextConnector">

This new Connector interface is the natural evolution of JavaDelegates, and the new version of Activiti Core will try to reuse your JavaDelagates by wrapping them up inside a Connector implementation:

public interface Connector { 
  IntegrationContext execute(IntegrationContext integrationContext);
}

Connectors receive an IntegrationContext with the process variables and return a modified IntegrationContextwith the results that needs to be mapped back to process variables.

In the previous example, the connector implementation is receiving a “content” variable and adding an “approved” variables based on the content processing logic.

Inside these connectors you are likely to include System to System calls, such as REST calls and message based interactions. These interactions tends to become more and more complex and for such reason we will see in future tutorials how these connectors can be extracted from running outside of the context of the ProcessRuntime(Cloud Connectors), to decouple the responsibility of such external interactions outside of the ProcessRuntimescope.  

Check the maven module activiti-api-spring-integration-examplefor a more advanced example using Spring Integrations to kickstart processes based on a File poller.

Full Example

You can find an example using both, the ProcessRuntimeand TaskRuntimeAPIs to automate the following process:

process-with-user-task

The code from this section can be found inside the “activiti-api-basic-full-example” maven module.

As the ProcessRuntime only example this is also categorizing some input content, but in this case, the process relies on a Human Actor to make the decision to approve the content or not. We have a schedule task as before that creates new process instances every 5 seconds and a simulated user checking if there are available tasks to work on.

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-full-example/src/main/java/org/activiti/examples/DemoApplication.java#L63

And

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-full-example/src/main/java/org/activiti/examples/DemoApplication.java#L85

The UserTaskis created to a group of potentialOwners, in this example the “activitiTeam” group. But in this case, we are not creating the task manually as in the first example. The process instance is creating the task for us, every time that a process is started.

https://github.com/Activiti/activiti-examples/blob/develop/activiti-api-basic-full-example/src/main/resources/processes/categorize-human-content.bpmn20.xml#L38

 

<bpmn:userTask id="Task_1ylvdew" name="Process Content"> 
  <bpmn:incoming>SequenceFlow_09xowo4</bpmn:incoming>
  <bpmn:outgoing>SequenceFlow_1jzbgkj</bpmn:outgoing>
  <bpmn:potentialOwner>
    <bpmn:resourceAssignmentExpression>
      <bpmn:formalExpression>activitiTeam</bpmn:formalExpression>
    </bpmn:resourceAssignmentExpression>
  </bpmn:potentialOwner>
</bpmn:userTask>

 

Users belonging to this group will be able to claim and work on the task.

We encourage you to run these examples and experiment with them and get in touch if you have questions or if you find issues.

Summary

In this blog post we have seen how to get started using the new ProcessRuntimeand TaskRuntimeAPI from the new Activiti Core Beta1 project.

We recommend you to check the Activiti Examples repository, for more examples: https://github.com/Activiti/activiti-examples

Helping us to write more of these examples might be a very good initial community contribution. Get in touch if you are interested, we are more than happy to guide you.

As always feel free to get in touch with us via Gitter: https://gitter.im/Activiti/Activiti7?utm_source=share-link&utm_medium=link&utm_campaign=share-linkif you have questions or feedback about these examples and tutorials.

More blog posts are coming to introduce the Runtime Admin APIs and how these examples can be adapted to be executed in our new Activiti Cloud approach.  

We have just released Activiti Core and Activiti Cloud 7.0.0.Beta1to Maven Centraland we wanted to highlight the new Cloud Native capabilities of Activiti Cloud. For those who haven’t followed what we have been doing over the last year, Activiti Cloud is a set of Cloud Native components designed from the ground up to work in distributed environments. We have chosen Kubernetesas our main deployment infrastructure and we are using Spring Cloud/Spring Bootalong with Dockerfor containerization of these components.

We have gone through a very valuable journey, meeting very passionate developers, communities and existing and potential customers who are looking to leverage these technologies (and business automation solutions) to reduce time to market and improve business agility in the Cloud. We have also contributed with these communities, making sure that the Open Source projects that we consume get back our valuable feedback and contributions. 

As part of the first Beta1 release, we are providing 4 foundational Building Blocks

  • Activiti Cloud Runtime Bundle
  • Activiti Cloud Query
  • Activiti Cloud Audit
  • Activiti Cloud Connectors

These Building Blocks are Spring Boot Starters that can be attached to any Spring Boot (2.x) application. These Building Blocks are enhanced with Spring Cloud functionalities which provide the Cloud Native capabilities.

By using these components you can create Activiti Cloud applications that:

  • Can be scaled independently based on demand
  • Can be managed in completely isolated cycles
  • Can be upgraded and maintained independently
  • Can provide domain specific features using the right tool for the job

You can read more about Activiti Cloud in our Gitbook: https://activiti.gitbook.io/activiti-7-developers-guide/

On this blog post, we wanted to show how to get started by deploying an example set of these building blocks in Kubernetes. We strongly recommend having a real Kubernetes Cluster such as GKE, PKS or EKS. We have tested the content of this blog post in AWS (Using Kops, PKS, GKE and also with Jenkins X)

Let’s get our hands dirty with Kubernetes, HELM and Activiti Cloud.

Kubernetes Deployment & HELM Charts

The quickest and easiest way to deploy things to Kubernetes is by using HELM charts. HELM, as described by their own documentation, is: “a tool that streamlines installing and managing Kubernetes applications. Think of it like apt/yum/homebrew for Kubernetes.”

As part of the Beta1 release, we have created a set of hierarchical HELM charts that can be used to deploy several components, some related to infrastructure (such as SSO and Gateway) and some Application specific components like Runtime Bundle, Audit Service, Query Service and a Cloud Connector.

These HELM charts can be found here: https://github.com/Activiti/activiti-cloud-charts.

In this blog post, we will be looking more specifically at: https://github.com/Activiti/activiti-cloud-charts/tree/master/activiti-cloud-full-example

This “Activiti Cloud Full Example” deploys the following components:

activiti-cloud-full-example-chart

One important thing to notice is that each of the Activiti Cloud components can be used independently. This example is intended to show a large-scale deployment scenario. You can start small with a Runtime Bundle (which provides the process and task runtimes), but if you want to scale things up you need to know what you are aiming for, and this charts shows you exactly that.

Now, moving forward you will need to download and install the following tools:

And as I mentioned before having a real life cluster is recommended.

The Google Cloud Platform offers a $300 free credit if you don’t have a Google Cloud account. See https://console.cloud.google.com/freetrial

If you choose GKE, you will also need to install the Google Cloud SDK CLI tool:

Creating and configuring the Cluster

Before we start, make sure that you clone the https://github.com/Activiti/activiti-cloud-chartsand go to the “activiti-cloud-full-example” directory, we will use some files from there.

Following using GKE we are demonstrating how to  create a cluster by going to your Google Cloud Home Page and selecting Kubernetes Engine: https://console.cloud.google.com/

home-select-k8s-engine

Then create a new Cluster:

create-new-cluster

Enter the Cluster Name, select the Zone based on your location and I’ve selected 2 vCPUs and left the Size to the default value (3). 

create-cluster-parameters

Once the cluster is created click on the Connect Button on the right hand side of the table:

cluster-connect

This will open a popup to show you how to connect with the cluster, open a terminal and copy the command that was displayed in the previous pop up.

running-connect-to-cluster

Now you have your Cluster configured and ready to be used.

Note: If you are working with an existing cluster, you will need to check if you have an Ingress Controller already installed, you can skip the following steps if that is the case.

Now let's configure HELM to work in the Cluster.

First, we need to start by giving HELM permissions to deploy things into the cluster. There are tons of articles on how to do this (https://medium.com/google-cloud/helm-on-gke-cluster-quick-hands-on-guide-ecffad94b0)   by running in a terminal the following command (you can copy/clone/download the helm-service-account-role.yaml file from here: https://github.com/Activiti/activiti-cloud-charts/blob/master/activiti-cloud-full-example/helm-service-account-role.yaml):

| kubectl apply -f helm-service-account-role.yaml

| helm init --service-account helm

helm-initi-service-account

One more thing that we need to do in order to be able to expose our services to be accessed from outside the cluster is to set up an Ingress Controller, which will automatically create routes to the internal services that we want to expose, in order to do this we just need to run the following command:

| helm install stable/nginx-ingress

helm-install-nginx

Now that NGINX Ingress Controller is being deployed, we need to wait for it to expose itself using a Public IP. We need this Public IP to interact with our services from outside the cluster. You can find this IP by running the following command:

| kubectl get services

kubectl-get-services-ip

Notice that you might need to run kubectl get services serveral times until you can see the External IP for your ingress controller. If you see PENDING, wait for a few seconds and run the command again.

We will use nip.ioas DNS service to map our services to this External IP which will follow the following format: ..nip.io

Deploying Activiti Cloud Full Example

Now that we have our Cluster in place, HELM installed and an Ingress Controller to access our services from outside the cluster we are ready to deploy the Activiti Cloud Full Example HELM Chart.

The first step is to register the Activiti Cloud HELM charts into HELM. We do this by running the following commands:

| helm repo add activiti-cloud-charts https://activiti.github.io/activiti-cloud-charts/

| helm repo update

The next step is to parameterize your deployment to your cluster. The Activiti Cloud Full Example Chart can be customized to turn on and off different features, but there is one mandatory parameter that needs to be provided which is the external domain name that is going to be used by this installation.

In order to do this, you can copy or modify the values.yamlfile located here: https://github.com/Activiti/activiti-cloud-charts/blob/master/activiti-cloud-full-example/values.yaml. You need to replace the string “REPLACEME” to <EXTERNAL-IP>.nip.io.

For my cluster that was:

104.155.53.158.nip.ioin every occurrence of “REPLACEME”.

value-yaml-with-external-ip

Once you made all these changes you are ready to deploy the chart by running the following command:

| helm install -f values.yaml activiti-cloud-charts/activiti-cloud-full-example

deploy-activiti-cloud
This will trigger the deployment process, and you need to wait until the services are up and running. You can check this by running:

| kubectl get pods

pods-services-up
Notice the READY column 1/1 in all the pods, that means that we have 1 pod in Kubernetes running our service. It is also important to notice that HELM created a release of our CHART. Because we haven’t specified a name for this release HELM choose one random name, in my case, it was: bumptious-yak. This means that we can manage this release independently of other Activiti Cloud Applications that we want to deploy using the same approach. You can run helm list and then helm delete to remove all the Activiti Cloud Services for this release.

In order to access to your services now, you can run the following command:

| kubectl get ingress

kubectl-get-ingress

Interacting with your Application

We recommend to download our Activiti Cloud Postman collection for Postman (https://www.getpostman.com) from our Activiti Cloud Examples repository:

https://github.com/Activiti/activiti-cloud-examples

You can clone or download the files in that repository and then import into Postman the collection

https://github.com/Activiti/activiti-cloud-examples/blob/develop/Activiti%20v7%20REST%20API.postman_collection.json

Before calling any service you will need to create a new Environment in Postman. You can do that by going to the Manage Environmenticon (cog)
postman-manage-environment.png

Then “Add” a new environment and add a name to it. Now you need to configure the variables for the environment: “gateway”, “idm” and “realm”

For gateway you need to copy the url associated with your Ingress, the same for idm which is SSO and IDM using Keycloak. For the realm enter “activiti”:

postman-env-variables

Click Save or Update and then you are ready to start using that Environment. Make sure that you select the environment in the dropdown of the right:

postman-select-env-and-get-a-token.png

As shown in the previous screenshot, if you go to the keycloakdirectory and select the “getKeycloakToken for testuser”you will get the token which will be used to authenticate further requests. Notice that this token is time sensitive and it will be automatically invalidated so you might need to get it again if you start getting unauthorized errors.

Once you get the token for a user, you can interact with all the user endpoints. For example, you can create a request to see which Process Definitions are deployed inside our Example Runtime Bundle:

postman-get-processdef.png

Now you can also start a new Process Instance from our SimpleProcess:

postman-start-processinstance

You can check that the audit service contains the events associated to the just started process instance.

postman-get-audit-events.png

And that the query service already contains information about the process execution:

postman-query-processinstances

You are now ready to start consuming these services to automate your own business processes.

Finally, you can access to all services Swagger documentation by pointing your browser to:

swagger-ui

All our services are using SpringFox to generate this documentation and provide a UI for it.

Summary

In this blog post we have seen how to get started with Activiti Cloud and more specifically with the Activiti Cloud HELM charts in GKE. If you are not familiar with Kubernetes, Docker and GKE this might look like a lot of new information and it is our mission to simplify all the steps covered in these getting started guide. For that reason, we recommend you to checkout the Jenkins Xproject, which greatly simplifies the first two sections about creating clusters and configuring the basic infrastructure for your projects.

As part of the Activiti Cloud initiative we are making sure that we follow best practices coming from the Kubernetes, Docker and Spring Cloud communities and we are contributing back with fixes and feedback to make this technology stack the best for Cloud Native applications.

As always feel free to get in touch with us via Gitter: https://gitter.im/Activiti/Activiti7?utm_source=share-link&utm_medium=link&utm_campaign=share-linkif you have questions or feedback about these examples and tutorials.