Download presentation
Presentation is loading. Please wait.
Published byKelley O’Connor’ Modified over 7 years ago
1
Getting Activiti to “Talk” to an External Database
Koorosh Vakhshoori Software Architect/Senior developer at Synopsys Inc. Hello everyone, my name is Koorosh Vakhshoori. I work at Synopsys, we provide software solutions for designing computer chips. Today’s talk is on ‘Getting Activiti linked to an External Database’.
2
Activiti in Alfresco ‘talking’ to a database
Goals Activiti in Alfresco ‘talking’ to a database Use cases How to Unit Testing Activiti is the workflow engine embedded in Alfresco. I will discuss a number of use cases on why you want this functionality, I will go over how to implement one simple use case, and how to unit test it.
3
Use Cases: Activiti DataBase
Sending to DB Reporting Logging Dashboard Retrieving from DB Populating some form field Signal for action or NO action Let’s consider some use cases. Say there is an external reporting system which needs to report on document review activities. Or there is a dashboard system that shows status of all documents in review.
4
Use Cases: Activiti DataBase
Sending to DB Reporting Logging Dashboard Retrieving from DB Populating some form field Signal for action or NO action Another use case would be populating an Activiti form field from an external DB table. Yet another one would be to check an external DB for availability of reviewers before assigning review tasks to them.
5
A Simple Activiti Workflow
Let’s consider a simple Activit content review workflow. This one comes out of the box with Alfresco. Here when a document is submitted for review, it is either approved or rejected.
6
A Simple Activiti Workflow
Now consider the requirement where all review actions needs to be recorded in an external database. Let’s consider what Activiti and by extension Alfresco has to offer to implement this use case.
7
Activiti Solution: Leveraging
alfresco-global.properties Spring Dependency Injection Apache BasicDataSource Spring JdbcTemplate Activiti User Task Listener Service Task The alfresco-global.properties file is the central Alfresco configuration file. It is also visible to Activiti. Additionally, we could use Spring’s Dependency Injection to pass the information to Activit.
8
Activiti Solution: Leveraging
alfresco-global.properties Spring Dependency Injection Apache BasicDataSource Spring JdbcTemplate Activiti User Task Listener Service Task Apache BacisDataSource class is for managing the DB connection and pooling. Spring JdbcTemplate class is for building and running your DB queries. Finally listener or a service task could be used to implement the logic.
9
alfresco-global.properties
Activiti Leveraging Alfresco configuration alfresco-global.properties activiti-context.xml LogActionListener.java ... ### database connection properties ### external_db.driver=org.gjt.mm.mysql.Driver external_db.username=activiti_app external_db.password=activiti_password external_db.name=ext_db external_db.url=jdbc:mysql://localhost:3306/ext_db?useUnicode=yes&characterEncoding=UTF-8 Here a number of database properties defined in an alfresco-global.properties file. They are database connection and credential information. In this case, we are talking to an MySql database instance.
10
alfresco-global.properties
Activiti Leveraging Dependency Injection - extDataSource alfresco-global.properties activiti-context.xml LogActionListener.java ... <bean id=“extDataSource“ class="org.apache.commons.dbcp.BasicDataSource“ destroy-method="close"> <property name="driverClassName“ value="${external_db.driver}"/> <property name="url" value="${external_db.url}"/> <property name="username" value="${external_db.username}"/> <property name="password" value="${external_db.password}"/> </bean> Next we are defining the DataSource bean in our activiti-context.xml file using Apache’s BacisDataSource class. Here the database properties are being substituted from alfresco-global.properties file.
11
alfresco-global.properties
Activiti Leveraging Dependency Injection - LogActionListener alfresco-global.properties activiti-context.xml LogActionListener.java ... <bean id=“extDataSource“ </bean> <bean id="LogActionClass" parent="AbstractUserTaskDelegate" class="com.example.activiti.workflow.LogActionListener"> <property name=“extDBSource" ref="extDataSource" /> In the same context file, our listener bean, LogActionListerner, is defined. This bean would be referencing the DataSource bean defined earlier.
12
Activiti Leveraging – Listener Code
Spring JdbcTemplate - 1 alfresco-global.properties activiti-context.xml LogActionListener.java package com.example.workflow.listener; … public class LogTaskActionListener extends BaseJavaDelegate implements TaskListener { public void notify(DelegateTask task) { String query = "INSERT INTO article_actions (user, article_id, action) VALUES (?, ?, ?)"; jdbcTemplate.update(query, new Object[] { userName, articleId, action }); } public void setExtDBSource(DataSource extDBSource) { this.jdbcTemplate = new JdbcTemplate(extDBSource); This is the relevant listener code. Look at the setter method. It is instantiating a JdbcTemplate object using our DataSource bean.
13
Activiti Leveraging – Listener Code
Spring JdbcTemplate - 2 alfresco-global.properties activiti-context.xml LogActionListener.java package com.example.workflow.listener; … public class LogTaskActionListener extends BaseJavaDelegate implements TaskListener { public void notify(DelegateTask task) { String query = "INSERT INTO article_actions (user, article_id, action) VALUES (?, ?, ?)"; jdbcTemplate.update(query, new Object[] { userName, articleId, action }); } public void setExtDBSource(DataSource extDBSource) { this.jdbcTemplate = new JdbcTemplate(extDBSource); Every time a reviewer approves or rejects a document as part of user task action, the notify() method is called. Here the query statement is populated and executed against our database. Look at how simple and elegant it is!
14
Activiti Unit Testing Challenges
Keep it concise Has to be fast Focus on target code Make it light weight Let’s consider the challenges around unit testing our Activiti listener. A unit test has to be concise. It should not take too long to run. It should target the code under test and no more. Finally, it should not depend on any external system. Photo from Flickr by Guy Sie
15
Activiti Unit Testing Inspiration
Keep it simple Has to be fast Focus on target code Make it light weight Check out Alfresco test class: AbstractActivitiComponentTest Rather than reinventing the wheel, let see how Alfresco has done it. Remember Alfresco is Open Source; check out AbstractActivitiComponent class.
16
Unit Testing Components
JUnit framework Mock framework (mockito) Spring framework SpringJUnit4ClassRunner JdbcTemplate H2 database engine Here are our test components. Junit, it is the well established framework for unit testing Java applications. Most importantly, Alfresco is using it and we want to reuse their work whenever possible.
17
Unit Testing Components
JUnit framework Mocking framework (mockito) Spring framework SpringJUnit4ClassRunner JdbcTemplate H2 database engine Can you image starting and stopping an Alfresco server for every test. Mocking Alfresco services is a good solution here. ‘mockito’ is the Mock Framework used by Alfresco.
18
Unit Testing Components
JUnit framework Mock framework (mockito) Spring framework SpringJUnit4ClassRunner JdbcTemplate H2 database engine For Spring support, leverage SpringJUnit4ClassRunner. And to pre-populate our test database, JdbcTemplate comes to our rescue again.
19
Unit Testing Components
JUnit framework Mock framework (mockito) Spring framework SpringJUnit4ClassRunner JdbcTemplate H2 database engine What about our test database server? Can you imagine having an Oracle or MySql demon running for test! Let's use an embedded database, H2 is a good option here.
20
Test Execution Flow Initialize H2 schema Record behavior (mock)
Run test scenario Validate database table Drop table and cleanup The test runs as follows: First a test schema is created, Alfresco services are mocked, a workflow instance starts and completes, the database table is checked for expected row and finally the database is cleaned up.
21
Test Execution Flow Initialize H2 schema Record behavior (mock)
Run test scenario Validate database table Drop table and cleanup For additional information check out my blogs or come and talk to me later. Thanks.
22
Resources Blog Post on How to Implement Blog Post on How to test For additional information check out my blogs or come and talk to me later. Thanks.
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.