Uncategorized
Dropwizard, CDI and Activiti
As I like Dropwizard and CDI and as I started to study Activiti, I wanted to see how they could work together. The idea is to deploy a test bpmn that outputs a “hello world” and run it with a simple Dropwizard REST call using only pure Activiti Java API.
Ingredients
Dropwizard 0.9.2 (http://www.dropwizard.io/0.9.2/docs/)
CDI (http://weld.cdi-spec.org/)
Activiti 6.0.0. Beta2 (http://activiti.org/download.html)
Postgresql 9.5 (http://www.postgresql.org/)
I’ve already created a Github project on Dropwizard and CDI demonstrating how they work together. I’ve used that as a base. The sources are available here: https://github.com/mpevec/dwtest-weld.
From the Activiti stack I’ve only taken Activiti Engine and embedded it in Dropwizard (java) app. I haven’t used neither Activiti REST (it’s a WAR file that needs to be deployed on servlet container) nor Spring to configure Activiti Engine. For the Activiti database, the Postgresql database has been used.
Creating Activiti DB
After downloading and installing Postgresql I’ve prepared the database for Activiti. I’ve created a Role “activiti” and with it created a database “activiti”.
In a zip file of Activiti 6.0.0.Beta2 there is a folder “database” and subfolder “create”. Inside, there are three SQL scripts that create all the DB objects needed by Activiti. You can easily run them within the newly created db.
Then I’ve created a DB configuration needed by Activiti inside the Dropwizard config.yml:
activiti: jdbcUrl: jdbc:postgresql://localhost:5432/activiti jdbcUsername: activiti jdbcPassword: activiti jdbcDriver: org.postgresql.Driver
POM configuration
There are the following dependencies within the POM file (for convenience I’ve left out the dependencies on CDI):
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>6.0.0.Beta2</version> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.5</version> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.1-901-1.jdbc4</version> </dependency>
I’ve used groovy to output “Hello world” inside bpmn; hence we need its dependency.
Dropwizard
There’s nothing special here. I’ve just registered a REST resource and stored the reference to the Dropwizard configuration:
@Override public void run(DwConfiguration config, Environment environment) throws Exception { ConfigurationHolder.set(config); environment.jersey().register(DwActivitResource.class); }
CDI producer
I’ve used a producer method for creating the Activiti Process Engine:
public class ProjectEngineFactory { @ApplicationScoped @StandaloneBinding @Produces public ProcessEngine getProcessEngine() { ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration() .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE) .setJdbcUrl(ConfigurationHolder.get().getActiviti().getJdbcUrl()) .setJdbcUsername(ConfigurationHolder.get().getActiviti().getJdbcUsername()) .setJdbcPassword(ConfigurationHolder.get().getActiviti().getJdbcPassword()) .setJdbcDriver(ConfigurationHolder.get().getActiviti().getJdbcDriver()) .setAsyncExecutorEnabled(true) .setAsyncExecutorActivate(false) .buildProcessEngine(); return processEngine; } }
REST resource
I’ve injected Activiti Process Engine, deployed test flow, run it and returned its id:
@Path("activiti") public class DwActivitResource { @Inject @StandaloneBinding private ProcessEngine processEngine; @GET @Path("hello") @Produces(MediaType.TEXT_PLAIN) public String justTextMessage() { RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); Deployment deployment = repositoryService .createDeployment() .addClasspathResource("helloWorldGroovy.bpmn20.xml").deploy(); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("helloWorld"); return processInstance.getId(); } ... }
Now when you call http://localhost:9999/v2/activiti/hello you should see the process instance id and “hello world” in the console.
That’s it, pretty simple. The entire code is on the Github: https://github.com/mpevec/dwtest-activiti.
2012 ?
Novoletne resolucije
Evo, I’m back.. ena od novoletnih resolucij je tudi ta, da začnem ponovno in redno pisati blog. Danes bo en kratek, sicer ravno o tematiki novoletnih resolucij.
Odločanje, odločanje…
Pred dnevi sem bral en dober blog (http://www.reallifee.com/) na to temo. Če na kratko povzamem, si v kontekstu novoletnih resolucij moramo odgovoriti na naslednja vprašanja:
1.) Česa si ne želim več početi sploh ?
2.) Za katere stvari želim porabiti manj časa ?
3.) Za katere stvari si ustvarjam nepotreben pritisk ?
4.) S katerimi stvarmi osrečujem druge, vendar samemu sebi škodujem ?
5.) Za katere stvari si več ne želim, da bi se izboljšal ?
Sam sem si že pripravil odgovore, kaj pa vi ?
Vloga managementa pri iterativnem razvoju
Vemo, da je vsaka posamezna iteracija videti kot en mini projekt. S stališča programerja – razvoja – vsebuje vse aktivnosti RADIT (Requirements, Analysis, Design, Implementation, Test). Kaj pa s stališča managementa? Kakšna je njegova vloga pri iterativnem razvoju?
Ponavadi se razmišlja v naslednji smeri:
- management samo zaustavlja birokracijo (oz. neke ovire), da ne pride do razvojne ekipe, ta pa dejansko (edina) naredi celotno delo;
- management skrbi samo za budget in za spremljanje načrta dela;
- management dejansko ni potreben;
Takšno razmišljanje ponavadi privede do neuspeha. Management mora storiti več.
Razmišljamo lahko dvoravensko. Na nižji ravni mora management poskrbeti, da bo vsaka iteracija imela:
- jasne cilje (koliko novih funkcionalnosti bo razvitih, koliko manj bugov glede na prejšnjo iteracijo bo proizvedenih, koliko nalog iz t. i. risk list bo rešenih ipd.). Glej tudi OPOMBO 1.
- merljive kriterije za oceno uspešnosti
- ekipo, ki se zaveže, da bo dosegla cilje
- definiran začetek in konec ter njena umestitev v razvoj celotnega projekta
- začrtane dejavnosti glede na resurse
- ocenjevanje uspešnosti ob njenem koncu
OPOMBA 1: Česar nismo omenili zgoraj (ker je samoumevno), je naslednje: osnovni cilj vsake iteracije je release – delujoča različica programske opreme. Ta je v osnovni obliki lahko samo t. i. Proof of Concept, lahko je delujoč prototip, različica beta ipd.
Zgornje bi lahko ponazorili s ciklom: Agree – Execute – Assess.
Na višji ravni pa mora management prevzeti vlogo leadershipa. Tako mora:
- poskrbeti mora za dolgoročno osredotočanje in usmerjanje ekipe. Tu ne gre za usmerjanje znotraj posamezne iteracije, ampak za usmerjanje glede na celoten projekt. Razvoj ne sme potekati po naključni poti. Treba je vedeti, koliko resursov bo še potrebno do konca in kdaj bodo ti resursi potrebni.
To lahko ponazorimo s ciklom: Monitor – Control Direction – Focus. Velja, da se oba omenjena cikla ponavljata nenehno skozi celotni razvoj.
Zaradi opisane pomembnosti managementa lahko njegovo dejavnost dodamo med iterativne dejavnosti. Zato ne govorimo več o dejavnostih RADIT, ampak o dejavnostih MRADIT (Management, Requirements, Analysis, Design, Implementation, Test).