Posts in Category: Alfresco

Launching Activiti version 6 in Paris (June 10th)!

The Activiti engine was born five years ago and started with version 5.0 (a cheeky reference to the jBPM past). In those five years we’ve seen Activiti grow beyond our wildest dreams. It is used all across the globe in all kinds of cool companies.

activiti_6

The last couple of months we’ve been working very hard at the next evolution of the Activiti engine. The core engine is undergoing a huge refactoring and we’ve got plenty of cool new stuff enabled by these changes up our sleeves. So after five years of version 5, we believe it is time for Activiti version 6!

We’re currently working on having all unit tests we have to run green on the Activiti 6 engine (almost there!). And yes, because that question will come first thing in the comments anyway, version 6 is fully compatible with version 5 (database schema, API’s, concepts, etc.).

We’re launching the new engine and unfolding all the core changes and plans at our Activiti Community Day in Paris (10th of June – only three weeks away). So let me repeat what I said in my previous postIf you are working with Activiti today, you don’t want to miss it. If you plan to use Activiti, you don’t want to miss it. It will be a major milestone and you will have the opportunity to witness it from the front line and influence it.

Attending the Community Day is easy, it’s completely free and you just need to register here: https://www.alfresco.com/events/global-activiti-user-day. Places are limited, so be quick!

Hope to see you there! And looking forward to show all the Activiti 6 sweetness!

Registration for Activiti Community Day (June 10th, Paris) is OPEN!

As I wrote two days ago, we are organising an Activiti Community Day, 10th of June in Paris. In case you missed that post, read all about it here.

I’m very happy to announce that the registration is now live for this awesome event: http://www.alfresco.com/events/activiti-user-day . So register quickly and make sure your spot is reserved!

 

Block your agenda: Activiti Community Day, 10th of June in Paris!

 

It’s been a while since the last one, but now it’s back (and how!): the Activiti Community Day!

And it’s going to be a Community Day that will go in the history books: not only have we arranged a superb location right in the heart of Paris (with a panoramic view over the city), we also have huge news which we will announce at the event. Activiti is now five years old, and it has grown more than we ever anticipated and it is used all over the globe in all kinds of industries and ways beyond our imagination. In those five years, we’ve learned a ton of how people use Activiti and how they want to use it going forward. So, in the past months, we’ve been working hard at the next evolution of the core Activiti Engine. And what better place to announce and show it than on the Activiti Community Day?

Do I hear mumbling of Activiti v6? No Comment. 😉

And if that wasn’t enough already, we’re currently lining up some top-notch speakers with real-life Activiti experience in very interesting environments. More about that soon once we have further fleshed out the agenda.

 

If you are working with Activiti today, you don’t want to miss it. If you plan to use Activiti, you don’t want to miss it. It will be a major milestone and you will have the opportunity to witness it from the front line and influence it. We don’t just plan to show it, we plan to really discuss the roadmap and ideas for the very future of Activiti! 

Oh yeah, did I already mention it’s completely free? No entrance fee thanks to sponsoring from Alfresco!

So block your agenda and arrange your travel:

10th of June 2015, Espace Montmartre : 5, rue Saint Eleuthère 75018 Paris (very close to the Sacré-Cœur basilique)

Details of the venue: http://www.groupe-pearl.com/location-salles-paris/espace-montmartre. When there’s a registration page live, I’ll post a new blog.

Interested in doing a talk during the Community Day? Do reach out to us (here below this post, on twitter, email, …)! We still have a couple of slots open!

Interview about Activiti on Software Engineering Radio

My good friend Josh Long did an interview with me about Activiti and Business Process Management in general. I must admit, I was quite nervous before the recording, as I had never done a podcast before (note : the editors at SE radio did a really great job 😉 ).

Here’s the link: http://www.se-radio.net/2015/03/episode-223-joram-barrez-on-the-activiti-business-process-management-platform/

All feedback, as always, much appreciated!

Activiti + Spring Boot docs and example

With the Activiti 5.17.0 release going out any minute now, one of the things we did was writing down documentation on how to use this release together with Spring Boot. If you missed it, me and my Spring friend Josh Long did a webinar a while ago about this.

You can find the new docs already on github master (scroll down to ‘Spring Boot’ section): https://github.com/Activiti/Activiti/blob/master/userguide/src/en/ch05-Spring.adoc#spring-boot. You can also see we switched to Asciidoc for our docs a couple of weeks ago. And GitHub renders that natively, which is awesome.

While I was writing the documentation, I created a sample application to verify all the stuff in there actually works.  You can find that example here: https://github.com/jbarrez/spring-boot-activiti-example. It has tags for each of the steps (which match the steps in the docs). So to start, checkout tag step-1 and so forth.

This is the first ‘official’ release of the integration (it was in snapshot versions before), so do give it a spin and let us know what you think about it!

 

How to create an Activiti pull request

Once every while, the question on how to create a pull request for Activiti is asked in the Forum. It isn’t hard to do, but specially for people that don’t know git it can be daunting.

So, I created a short movie that shows you how easy it is and what you need to do to:

 

Looking forward to your awesome fixes and features in a pull request!

 

Edit: Zoltan Alfattar mentioned to me on Skype there is a better way using branches:

altfatterz
@jbarrez Nice, however creating separate branch would be the better https://t.co/nco8rRZlk3
05/11/14 15:06

With which I agree fully. However, for people who are new to Git, it might be too complex to grasp. But surely have a look at the link if you are interested in doing it in the ‘proper’ way.

My Five Rules for Remote Working

A couple of weeks ago, there was a stir (again) about remote working and its succes and/or failure: it was reported that Reddit, the website where many people lose countless of hours, were forcing all their employees to move to SF. After a similar thing happened at Yahoo last year it made me think about why remote work is such a huge success for us at Activiti and Alfresco.

You see, I’m a remote worker for more than five years now. First at Red Hat and then at Alfresco. I worked a couple of years as Java consultant before that, so I’ve seen my share of office environments (checking my Linkedin, it comes down to about 10 different office environments). I had to go to these offices each day.

Comparing those experiences, I can – without exaggeration – say that I’m way more productive nowadays, working from home. Many people (both in and outside IT) ask me how I do it. They say “they couldn’t do it”. Maybe that’s true. Maybe some people need a lot of people around them. But for the kind of job I am into – developing software – I believe having a lot of people around me doesn’t aid me in writing higher quality software faster.

Anyway, like I said, I did some thinking around it and I came to the following “rules” which I have been following all these years which I believe are crucial (at least for me!) to making remote working a success.

dilbert_remote

(comic from http://www.dilbert.com/ )

Rule 1: The Door

Having a separate space to work is crucial when wanting do serious remote working. Mentally it is important that you can close “The Door” of your office space when you finished working. It brings some kind of closure to the working day.

Many people, when they work from home, put their laptop on let’s say the kitchen table. That doesn’t work. It is not a space that encourages work. There are distractions everywhere (kids that come home, food very close by, …). But most importantly, there is no distinction between when you are working and when you are not.

My wife and kids they know and understand that when The Door is closed, I’m at work. I can’t be disturbed until that Door opens. But when I close The Door in the evening and come downstairs, they also know that I’m fully available for them.

My door!

My door!

Rule 2: The Gear

The second rule is related to the first one: what to put in that room. The answer is simple: only the best. A huge desk, a big-ass 27″ monitor (or bigger), a comfortable chair (your ass spends a lot of time on it), the fastest internet you can buy, some quality speakers, a couple of cool posters and family pictures on the wall, ….

This is the room where you spend most of your time in the week, so you need to make it a place where you love to go to.

My setup

My setup

Often, I hear from people which company allows for remote work that their company should pay for all of this. I think that’s wrong. It’s a two-way street: your company gives you the choice, privilege and trust to work from home, so you from your side must take care that your home office isn’t decreasing anything compared to the office gear you have. Internet connection, chair and computer monitor are probably the most important bits here. If you try to be cheap on any of those, you’ll repay it in decreased productivity.

Rule 3: The Partner

Your partner is of utmost importance to make remote work a success. Don’t be fooled by the third place here, when your partner is not into it, all the other points are useless.

It’s pretty simple and comes down to one core agreement you need to make when working from home: when you are working from home you are not “at home”. When you work, there is no time for cleaning the house, doing the dishes, mowing the grass, etc … You are at work, and that needs to be seen as a full-time, serious thing. Your partner needs to understand that when you would do any of these things, it would be bad for your career.

Many people think this is easy, but I’ve seen many fail. A lot of people still see working from home as something that is not the same as “regular work”. They think you’ve got all the time in the world now. Wrong. Talk it through with your partner. If he/she doesn’t see it (or is jealous), don’t do it.

Rule 4: Communicate, communicate, communicate

More than a team in an office, you need to communicate. If you don’t communicate, you simply don’t exist.

At Activiti, we are skyping a lot during the day. We all know exactly what the other team members are currently doing. We have an informal agreement that we don’t announce a call typically. You just press the ‘call’ button and the other side has to pick it up and respond. It’s the only way remote work can work. Communicate often.

Also important: when you are away from your laptop, say it in a common chat window. There is nothing as damaging for remote workers as not picking up Skype/Phone for no reason.

Rule 5: Trust People

The last rule is crucial. Working remote is based on trust. Unlike in the office, there is no physical proof that you are actually working (although being physically in an office is not correlated with being productive!). You need to trust people that they do their job. But at the same time, don’t be afraid to check up on people’s work (for us, those are the commits) and ask the questions why something is taking longer than expected. Trust grows both ways.

The second part of this trust-story is that there needs to be trust from the company to the team. If that trust is missing, your team won’t be working remote for long. At Activiti, we are very lucky to have Paul Holmes Higgin as our manager. He is often in the office of Alfresco and makes sure that whatever we are doing is known to the company and vice versa. He attends many of the (online) meetings that happen company wide all the time so that we are free to code. There is nothing as bad for a remote team as working in isolation.

 

Conclusion

So those are my five (personal!) rules I follow when working from home. With all these bad press from the likes of Reddit and Yahoo, I thought it was time for some positive feedback. Remote work is perfect for me: it allows me to be very productive, while still being able to see my family a lot. Even though I put in a lot of hours every week, I’m still seeing my kids grow up every single day and I am there for them when they need me. And that is something priceless.

Does this sound cool to you? Well, at Alfresco we are still hiring people to work on Activiti!

Upcoming Webinar: Process Driven Spring Applications with Activiti – Sept 23rd

 

Next week, I’ll be doing a webinar together with my friend Josh Long (he’s a Spring Developer Advocate, committer to many open source projects and of course Activiti). I will show some of the new Activiti tooling we’ve been working on recently, while Josh will demonstrate with live coding how easy it is to use Activiti in Spring Boot (spoiler: really easy).

You can register for the webinar for free here: https://spring.io/blog/2014/07/29/webinar-process-driven-spring-applications-with-activiti-sept-23rd

One day later, the Alfresco Summit will be kicked off in San Francisco. I’m joining two talks there:

For those who can’t make it to San Francisco: don’t worry, we’ll be landing in London two weeks later, Oct 7-9!

Execute Custom queries in Activiti

(This will probably end up in the user guide of the Activiti 5.15 release, but I wanted to share it already)

The Activiti API allows for interacting with the database using a high level API. For example, for retrieving data the Query API and the Native Query API are powerful in its usage. However, for some use cases they might not be flexible enough. The following section described how a completely custom SQL statement (select, insert, updated and deletes are possible) can be executed against the Activiti data store, but completely within the configured Process Engine (and thus levering the transaction setup for example).

To define custom SQL statements, the Activiti engine leverages the capabilities of its underlying framework, MyBatis. The first thing to do when using custom SQL, is to create a MyBatis mapper class. More info can be read in the MyBatis user guide. For example, suppose that for some use case not the whole task data is needed, but only a small subset of it. A Mapper that could do this, looks as follows:

public interface MyTestMapper {

  @Select("SELECT ID_ as id, NAME_ as name, CREATE_TIME_ as createTime FROM ACT_RU_TASK")
  List<Map<String, Object>> selectTasks();

}

This mapper must be provided to the Process Engine configuration as follows:

...
<property name="customMybatisMappers">
  <set>
    <value>org.activiti.standalone.cfg.MyTestMapper</value>
  </set>
</property>
...

Notice that this is an interface. The underlying MyBatis framework will make an instance of it that can be used at runtime. Also notice that the return value of the method is not typed, but a list of maps (which corresponds to the list of rows with column values). Typing is possible with the MyBatis mappers if wanted.

To execute the query above, the managementService.executeCustomSql method must be used. This method takes in a CustomSqlExecution instance. This is a wrapper that hides the internal bits of the engine otherwise needed to make it work.

Unfortunately, Java generics make it a bit less readable than it could have been. The two generic types below are the mapper class and the return type class. However, the actual logic is simply to call the mapper method and return its results (if applicable).

CustomSqlExecution<MyTestMapper, List<Map<String, Object>>> customSqlExecution =
    new AbstractCustomSqlExecution<MyTestMapper, List<Map<String, Object>>>(MyTestMapper.class) {

  public List<Map<String, Object>> execute(MyTestMapper customMapper) {
    return customMapper.selectTasks();
  }

};

List<Map<String, Object>> results = managementService.executeCustomSql(customSqlExecution);

The Map entries in the list above will only contain id, name and create time in this case and not the full task object.

Any SQL is possible when using the approach above. Another more complex example:

  @Select({
    "SELECT task.ID_ as taskId, variable.LONG_ as variableValue FROM ACT_RU_VARIABLE variable",
    "inner join ACT_RU_TASK task on variable.TASK_ID_ = task.ID_",
    "where variable.NAME_ = #{variableName}"
  })
  List<Map<String, Object>> selectTaskWithSpecificVariable(String variableName);

Using this method, the task table will be joined with the variables table. Only where the variable has a certain name is retained, and the task id and the corresponding numerical value is returned.

This will be possible in Activiti 5.15. However, the code (and more specifically the Command implementation and the wrapper interface) can be used in any older version of Activiti.

Reporting capabilities in Activiti 5.12

In the Activiti 5.12 release, we added reporting capabilities on top of the Activiti engine, demonstrating the concepts through the Activiti Explorer web application (but of course usable everywhere).

Now, don’t be fooled: since a very long time , the Activiti engine has the capability of gathering historical or audit data when you execute business processes. All this data is stored in the historical database tables and can thus be easily queried. Which means that any reporting tool such as JasperReports, Birt, Crystal Reports etc. can just use the historical tables as a datasource to produce reports in any format you’d like (Word, PDF, …) to get insight how your business is executing its business processes. I’ll probably blog such an example pretty soon.

Eating our own dogfood

But the thing where I’d like to focus on today is the web side of things: web charts/reports which can be combined into a dashboard for example. The first thing we must be able to do is to expose the historical data in a way we can use it to create these charts. But where do you put the logic (the queries and data manipulation) to generate a dataset for the chart and/or the report? Do you embed the SQL in your UI-layer? Of course not. What if multiple applications want to use the data? What if we want to store the generated dataset to get a snapshot of the data at a certain point in time.

When we thought about this problem we first though about it in the traditional way. A new service with reporting capabilities, probably using some sort of DSL to define the dataset generation which are stored in some kind of data store. Anyway, a whole new things and concepts to learn and master. Not to mention extra implementation and maintenance.

But then it hit us. Everything we needed is already available in the Activiti engine. If we use a process to define the logic to create the dataset for the report, we can leverage all the facilities of the engine. The only requirement for this process is that it generates the JSON data which follows a fixed format. Some benefits

  • The process has straight access to the internals of the Activiti engine. It has direct access to the database used by the engine.
  • The dataset that is generated can be stored in the historical tables of Activiti if wanted. So we have a ‘save report data’ mechanism for free.
  • The job executor can be used as for any other process. This means that you can asynchronously generate the process or only execute certain steps asynchronously. It also means you can use timers, eg. to generate the report data on certain points in time.
  • Creating a new report can be done with known tools and known concepts. Also, no new concepts, services or applications are needed. Deploying or uploading a new report is the same as deploying a new process. Generating a report is the same as running a process instance.
  • It allows to use the BPMN 2.0 constructs. This means that all things like parallel steps, do branching based on data or even request user input during the generation are possible out-of-the-box.

Screen Shot 2013-03-22 at 13.22.49

A dash of Javascript

Since the generation of the dataset is done by a process, everything possible in a process can be used. So you can use Java delegate classes or whatever you fancy.

But since the kool kids nowadays are using Javascript, we added some example process to the demo data of Activiti Explorer that use the scripting functionality in the engine. The nice thing about Javascript is that JSON is native to it, and creating a JSON object is really easy. As said above, the only requirement for such a process is that it must generate the JSON dataset following the predefined format.

Screen Shot 2013-03-22 at 10.43.20

For example to generate an overview of all past process instances we could have a process like this:


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
 xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
 xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
 expressionLanguage="http://www.w3.org/1999/XPath"
 targetNamespace="activiti-report">

<process id="process-instance-overview-report" name="Process Instance Overview" isExecutable="true">

 <startEvent id="startevent1" name="Start" />
 <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="generateDataset" />

 <scriptTask id="generateDataset" name="Execute script" scriptFormat="JavaScript" activiti:autoStoreVariables="false">
 <script><![CDATA[

  importPackage(java.sql);
  importPackage(java.lang);
  importPackage(org.activiti.explorer.reporting);

  var result = ReportingUtil.executeSelectSqlQuery("SELECT PD.NAME_, PD.VERSION_ , count(*) FROM ACT_HI_PROCINST PI
       inner join ACT_RE_PROCDEF PD on PI.PROC_DEF_ID_ = PD.ID_ group by PROC_DEF_ID_");

  var reportData = {};
  reportData.datasets = [];
  
  // Native json usage
  var dataset = {};
  dataset.type = "pieChart";
  dataset.description = "Process instance overview (" + new java.util.Date() + ")";
  dataset.data = {};

  while (result.next()) { // process results one row at a time
    var name = result.getString(1);
    var version = result.getLong(2)
    var count = result.getLong(3);
    dataset.data[name + " (v" + version + ")"] = count;
  }
  reportData.datasets.push(dataset);

  // Storing the json as process variable
  execution.setVariable("reportData", new java.lang.String(JSON.stringify(reportData)).getBytes("UTF-8"));
 ]]></script>
 </scriptTask>
 <sequenceFlow id="flow3" sourceRef="generateDataset" targetRef="theEnd" />

 <endEvent id="theEnd" />

 </process></em>

</definitions>

The script is pretty easy to understand. All it does is querying the database, creating a json object with the data and storing it as process variable. Since it is stored as a variable, it is basically a snapshot of the dataset. So at any time in the future you can just fetch the json data and look at the report as it was at that point in time.

The json produced by the process above can then easily be used to generate charts, as demonstrated by the Activiti Explorer application:

Screen Shot 2013-03-22 at 13.30.45

 

It is also very easy to see how easy it is to create a dashboard app with the same approach. But that’ll be for a next blogpost.

Thanks for reading!