Axon with Scala

Hi all,

I think Axon looks promising and well-crafted, but Java is just such a setback that I’ll not consider Axon if a Scala setup is too painful and convoluted to get flying.

I am used to C# and .NET and know of all the CQRS stuff in that camp, but given that we evaluate a proper platform for our application my attention is on Axon now.

Is anyone here using Axon with Scala?

Hi,

a former colleague of mine (currently working for Ebay) has given a workshop there on how to use Axon with scala. He published his slides as well as the code used in the exercises:
http://prezi.com/9bziaituejuo/cqrs/
https://github.com/erikvanoosten/tictactoe-axon

Hope this helps you on your way for now.
Meanwhile, I am talking to some people to build a Scala API on Axon. But don’t count on that being done before the 2.0 release.

Cheers,

Allard

Hi ahjohannessen,

Using Axon from Scala is a breeze. Its so much easier to write a bunch of commands and events as case classes (instead of many line immutable POJOs) that I have no clue why not more people are doing this.

The code at https://github.com/erikvanoosten/tictactoe-axon is set up as an exercise. The intention is that you clone and then make the tests pass. For the impatient: there is a solution branch also. Note: I did not update the exercise for Axon 2.

If you are used to C#, Axon is a good bet. If you want a more functional approach and are ready to do some more groundwork (Axon is quite complete) take a look at eventsourced. https://groups.google.com/d/msg/eventsourced/XruwMIHcBOs/yPl8LyDMZI4J

Good luck,
     Erik.

Op 02-11-12 17:47, ahjohannessen wrote:

Thanks for the pointers :slight_smile: Axon sure has some nice things to it!

One thing that makes me a bit sceptical is all that Spring ceremony. This might of course be related to my C# / StructureMap background.

Erik, yep I have been following the progress Martin has done with EventSourced. Also impressive stuff :slight_smile:

Cheers,
ahjohannessen

I'm all for scala, but if you are stuck with java and are looking for
less bloated commands and events (and other data classes for that
matter) I can recommend Lombok, http://projectlombok.org/
All getters and setters are history and you get alot of other nice
things like @ToString, @EqualsAndHashCode etc.

I have been reviewing Scala since reviewing your tic-tac-toe example and the simple integration with Axon. Thank you for sharing that code. I am very new to Scala so the following issues may have better fixes than what I found.

I took one section my Java code and converted it to Scala. It consists of several classes: event listener, JPA entity and JPA repository. The code savings in terms of lines of code was 50.4% by using Scala.

I then converted one of my events to a Scala case class. I did not follow your example of using a Scala object (Events.scala) to hold the events as I wanted a drop-in replacement for my existing code.

The first issue I noticed was a lack of a “get” method for my attributes. That was easy to fix: getCompanyId() converts to companyId().

The second issue was a Axon saga using annotations. The associated property was defined as “companyId” but there is a private static helper method named “methodForProperty” which will convert that string to “getCompanyId” to which is passed to the Java reflection library to find the method. No such method exists of course (see the first issue). Again it was a relatively easy fix to add a function: def getCompanyId() = companyId

case class CompanyAssociationEstablishedEvent(orderId: OrderId, revisionId: RevisionId, companyId: String) extends OrderEvent(orderId) {

def getRevisionId() = revisionId

}

Only a few events are actually used in the saga lifecycle so this is a small trade off.

The third issue are events which extend a base class and the XML serialisation in the event store. The tic-tac-toe example extends an Axon v1 DomainEvent class but since I’ve moved to Axon v2 I no longer have that class. I do however have a base class for like events, ie: abstract OrderEvent. Events have changed from:

<org.example.api.events.CompanyAssociationEstablishedEvent>

44b2c875-d391-49c1-81e2-cc18d9b82d11


de4b20c7-91d8-4e5b-a217-8ba04b7e3595

ABCINC
</org.example.api.events.CompanyAssociationEstablishedEvent>

to:

<org.example.api.events.CompanyAssociationEstablishedEvent>

44b2c875-d391-49c1-81e2-cc18d9b82d11



de4b20c7-91d8-4e5b-a217-8ba04b7e3595

ABCINC
</org.example.api.events.CompanyAssociationEstablishedEvent>

The OrderEvent.java class has an attribute for orderId and the getter getOrderId() defined. The CompanyAssociationEstablishedEvent.scala, when referenced from a Java object, has two methods: companyId() and getCompanyId(). If the first event is loaded (ie: legacy) then “getCompanyId()” will return a null. I am not sure how I can pass an “orderId” to a super class without duplicating the field in my case class.

I will certainly continue to exercise Scala

A possible solution to my third issue is to use a trait instead of an abstract class. This conversion however cannot happen until all my events which extend OrderEvent have been converted to a Scala equivalent. I suppose this depends on the ordering for compiling as I am current set to Java then Scala.

Hi guys,

I am not at all a scala expert (just written 2 scala classes in my life), but happened to be among a group of 10 scala experts last week. We have been applying Axon in a scala project.

Using case classes for commands and events is fairly easy. To ensure a getter is in placemfor a specific property, you can annotate it with (if I recall properly) @PropertyGetter or something. My internet access is very limited now, but Google should be able to provide more info.

The serialization issue described below is the result of having 2 classes extending eachoter that both have a field orderId. There is an XStream converter, by the way, that serializes Scala lists in a more concise way. Once your events contain lists, you’ll definitely want to use that one.

With the scala pro’s, I’ll be investigating ways to simplify using Axon in Scala. If you have any recommendations (or are interested in contributig), let me know. Support for the scala way of propert access (without the get, which I wished Java would have done) is a good example hereof.

Cheers,

Allard

PS. I converted the tic-tac-toe solution branch to Axon 2. See github.com/olger.

import scala.reflect.BeanProperty

case class X(@BeanProperty id: String)

-> (via javap)

public class X extends java.lang.Object implements scala.Product,scala.Serializable{
public scala.collection.Iterator productIterator();
public scala.collection.Iterator productElements();
public java.lang.String id();
public X copy(java.lang.String);
public java.lang.String getId();
public java.lang.String copy$default$1();
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public boolean canEqual(java.lang.Object);
public X(java.lang.String);
}

However, it would be nice if one could avoid all the annotation sprinkling.