Haskell TDD kickstart with HSpec and Guard

You’ll need:

  • Haskell Platform. It includes (among other things) Cabal – Haskell build system.
  • HSpec – Haskell testing library
cabal update && cabal install hspec
  • Ruby – install through rvm, your OS package manager or use system-provided Ruby interpreter.
  • RubyGems
  • Guard and guard-haskell – for watching your code and executing tests on change
gem install guard-haskell
  • in your project – Guardfile and your-project-name.cabal build descriptor (and of course some code and its tests)

I created a sample project – hspec-kicstart – that bundles everything together.
It has a minimal Guard and Cabal configuration, more-than-trivial production code and the test.

After cloning the project

cabal test

should tell you 1 of 1 test suites (1 of 1 test cases) passed.

guard

and then Enter (runs all tests) yields 1 example, 0 failures.

Clone it, play with it and enjoy!

Activiti and database transactions

In my current project we use Activiti as a business process orchestrator. Recently we ran into problems with database transactions. We had webservice calls to an external in one of process steps (service task). We wanted to have everything committed before the call, just in case the webservice fails. Ideally, every process step should be executed in a separate transaction

We (naively) thought every service task was wrapped into an individual transaction. We discovered that there was one big transaction spanning the entire process.

This blog post is a recording of spikes I did to understand when transactions are started and completed in Activiti processes.

Initial configuration

In our Grails application Activiti ProcessEngine was configured with SpringProcessEngineConfiguration. It requires a Spring TransactionManager. We duly supplied the manager created by Grails.

Transaction demarcation

According to the documentation

The ProcessEngineFactoryBean will have added an extra interceptor to the services that applies Propagation.REQUIRED transaction semantics on the Activiti service methods.

It implies:
* every Activiti service is transactional (RuntimeService, RepositoryService, etc.). It either starts a transaction or participates in an existing one.
* if RuntimeService is used to launch a process, every service task during the process execution ‘inherits’ the transaction from the RuntimeService
* same transaction for the duration of the process execution

Service tasks – how to get control of transactions?

Use REQUIRES_NEW semantics

Mark service classes or individual methods methods as @Transactional(propagation = Propagation.REQUIRES_NEW).

Note: be careful when mixing process steps participating in the ‘parent’ transaction triggered by the RuntimeService and those wrapped in their own transaction. If the ‘parent’ transaction is rolled back, individual transactions may be committed. If service tasks with individual transactions depend on some modifications made before (in tasks inside the ‘parent’ transaction) the changes may not be visible to them.

StandaloneProcessEngineConfiguration

Configure process engine with StandaloneProcessEngineConfiguration.

Once again, documentation says it clearly:

the process engine is used in a standalone way. Activiti will take care of the transactions.

The configuration is simple:

However, you lose the automatic deployment of processes. This could be mend by borrowing the code from the org.activiti.spring.SpringProcessEngineConfiguration#autoDeployResources method.

Quest for (persistable) Groovy immutability

This is my first post about how to implement DDD concepts with Groovy and deliver them with Grails. My goal is to have real domain logic, without any (or as few as possible) dependencies on surrounding frameworks.

Grails is, at first glance, very pervasive and induces you to mix your business logic with concerns that should be treated separately. On the other hand, the framework is more modular with every release – which means you can disable some parts of it. Under the hood uses some popular libraries (which can be used directly by circumventing the framework).

This article is about implementing immutable Value Objects in Groovy and plugging in the persistence in a Grails application. First part discusses strategies of achieving immutability with Groovy. Second part describes how to persist our Value Object with in a relational database with Hibernate and in document-oriented database (MongoDB).

Create an immutable Value Object class

Value Objects, a building block of DDD should be implemented as immutable. Which options do we have in Groovy?

  • annotate your VO with @Immutable annotation
    • very straightforward, however, no customization options. You get a tuple/map constructor for free, but it sets all your VO properties to null by default. No way to specify mandatory properties and validate them.
  • declare all fields as final (with the default Groovy visibility). Fields will have getters but no setters. Then:
    • use @TupleConstructor
      • no boilerplate code
      • map constructor provided by this annotation is useless with final fields. It calls first the no-arg constructor and then tries to set fields with provided values. As there no setters, you will get a nice groovy.lang.ReadOnlyPropertyException exception.
      • all parameters of the tuple constructor have a default null value. As for @Immutable, no way to enforce mandatoriness.
    • implement custom constructor(s)
      • some boilerplate code, reduced with AST transformations GContracts
      • fully customizable

Example of an immutable Value Object with custom constructor:

Persist the FullName Value Object inside an aggregate

Our sample FullName VO is a part of a larger Person aggregate:

To persist it, I won’t use GORM (at least not directly).

Relational DB, Hibernate

I’m going to use external Hibernate mapping. With this approach my Person aggregate won’t be coupled at the source code level to any persistence configuration.

Hibernate imposes some restrictions on what your objects should provide in order to be persistable. The ORM must be able to instantiate an empty object. It requires a default constructor, although it can be protected.

At this point I have to make a small concession to Hibernate and add a default constructor1 to FullName:

protected FullName() {}

For filling the object with values read from the database, it doesn’t require to have setters. Hibernate is able to ‘reach’ a field through Java reflection (even if it’s final).

I map the VO as Hibernate component (an object mapped to the same table as the aggregate). As there are no setters, I instruct Hibernate to access VO properties directly with access="field":

As the gateway to the persistence I use a repository, an object that can provide the illusion of an in-memory collection (Eric Evans, Domain-Driven Design). As a rule of thumb, there is one repository per aggregate.

I don’t define an explicit interface; I’m going to use a duck type thorough the domain. The implementation is a delivery detail and I put it in the infrastructure layer.

By mapping the Person aggregate as an external Grails entity, it gets all persistence and query methods provided by GORM. However, the rest of domain and infrastructure code doesn’t notice them. The repository (PersonGormRepository) is the only component allowed to use the GORM API on Person.

Result: GORM becomes a plugin to the domain, totally unaware of it. There is only one place where the coupling application – GORM happens – in the implementation of the repository.

The code is pretty straightforward:

MongoDB

Mongo is a document-oriented database perfectly suited for storing objects modelled with composition – one document per each aggregate instance, together with all contained entities and value objects.

There is a MongoDB GORM plugin for Grails. I won’t use it, since I had to pollute my aggregate with mapping configuration (and it should be oblivious to the persistence). I’m going to use GMongo library, a Groovy wrapper over the official MongoDB driver. MongoDB for GORM offers no such thing like external MongoDB mapping.

My repository implementation uses quite a low-level API (compared to GORM). I don’t have to tweak my FullName value object. I can use all-property constructor when filling the VO from the Mongo document.

findById method is quite simple:

save method is more complex comparing with the Hibernate repository. It has to deal with the insert and update semantics.

Additionally, it’s in charge of generating numerical ids (in case of a relational database, we relied on the DB engine). I copied the implementation from the GORM MongoDB plugin source code. It uses a collection with single document containing the recently used ID. When obtaining it I use the Mongo atomic operation findAndModify, increasing the id by one and getting the increased value.

Summary

It is relatively easy to decouple your domain from persistence and make the latter a pluggable detail. You are leaving a well-trodden path of GORM, but the journey outside of it is not scary. You enter other safe routes guarded with decade old patterns and implementation techniques. Sometimes there are few signposts. You have to dig inside blogs and scarce documentation in order to move forward. Sometimes you just wander around and need to make some experiments in order to find the right way.

As reward you will get a cohesive object-oriented domain code that focuses only on one thing: solve problems of your/your customer’s business. Code that shifts data back and forth is strictly separated. Two worlds meet together at the repository frontier. And that’s fine, why should your business deal with database quirks?

Full source code

You find the complete source code in grails-ddd GitHub repo:
* master branch does not implement any persistence (yet)
* MongoDB and Hibernate (with H2 embedded database) repositories are implemented in mongo and hibernate branches, respectively.


  1. before adding a default protected constructor, I tried implementing a CompositeUserType and a custom tuplizer. Unfortunately, both need to create an empty object before filling it from the database result set. 

Functional programming open space

Open space about functional programming

March 15th. Saturday. 20 geeks. 5 sessions in 1-2 tracks. At Madrid on Rails.

Idea and arrangements

I’m quite interested in functional programming, both theory and practice. The initial idea dates back to 2013, when FP Madrid community was created. I simply wanted to gather during all the day and chatter about FP.

In January 2014 I suggested the idea on a FP Madrid meetup. Initial feedback was encouraging, so I chose a date (March 15th) and a venue (Madrid on Rails). By the way, it is hard to find a venue that is: 1. within Madrid city limits, 2. free, 3. open on Saturdays, 4. and open all day.

A week before the scheduled date I got the final confirmation from Estela from Madrid Emprende. I started up the marketing machine – spamming local communities and dusting off my Twitter account. The company I work for, Osoco, provided us with a delicious breakfast (big thank you!). Friday night before the event there was 35 confirmed attendees.

D-Day

marketplace

Finally about 20 fellow programmers made it to the meeting. We started by with the typical introduction about open space principles and rules. After explaining how the schedule was going to be built, there was a round of topic proposals. We filled three tracks, five sessions each. Not a bad result for twenty person group. Though many topics died a natural death due to lack of participants.

Although I facilitated the meeting, I had enough time and energy to attend all sessions of my interest:

  • Intro to Haskell – we went over basic Haskell syntax which I’m still getting used to.

  • Web applications using functional approach – I arrived quite late (we were continuing the Haskell session around the coffee table) and missed the most of discussion. What I proposed was to sketch some Clojure code implementing business logic of some imaginary use cases.

Intro to Haskell

  • Java 8 lambdas – fail; we wanted to do a kata with lambdas. Nobody had JDK8 installed and it was impossible to download it.

  • DDD in Clojure (or in another functional language) – we went through two basic use cases (creation and modification) and wrote some code implementing it with DDD patterns. I felt confused, because I associate DDD with objects having data and behaviour. In Clojure you separate those two into dumb data structures (maps) and functions performing business operations on them (and returning copies of modified data).

  • Category theory – I felt like having a theoretical session about category theory. I struggle to understand it and I wanted to get some tangible examples of categories, arrows and so on. It seemed that everyone was equally confused as me. The conversation shifted to algebraic structures and their counterparts in Haskell. Another question raised was: “do I have to understand all the theory behind functional programming and to be a proficient functional programmer”?

Wrap-up and retrospective

Good open space should close with wrap-up and retrospective. What did we enjoy (or not)? What can be improved in case we, as the community, want to repeat this event?

We did two rounds: personal reflections and a perfection game. Here is the summary of feedback we gathered (I hope I’m not missing any important point):

  • Open the idea marketplace before the event (using a wiki or a more sophisticated tool like Ideascale). It would allow to have more prepared sessions.

  • Not all sessions were run because lack of interest. Voting system with stickers and a reduced number of tracks would have filtered out such sessions.

  • Representations from many communities – FP is a cross cutting paradigm, implemented to lesser or greater extent in a lot of languages. Different backgrounds yield diverse points of view, which enrich discussions.

  • Some more experiences functional programmers expected more engagement from novices (questions, doubts, requests for introductory tutorials). Both parties learn. And this is the purpose of an open space.

  • More facilitation to break the ice at the beginning (I’m the culprit, I was my first facilitation :))

  • Drowsiness after lunch. Maybe we should reduce the duration and finish before (late lunch) – e.g. 9:30 – 14:30 with 4 sessions?

Overall, it was a grateful and enlightening experience for all who sacrificed their Saturday and me as participant and facilitator.

Thanks to