Posted on 

Spine 0.7.0

CoreJvm 

New artifact IDs for CoreJvm modules 

Gradle:

repositories {

   // Spine releases repository.
   maven { url = 'http://maven.teamdev.com/repository/spine' }

}

dependencies {

    compile 'org.spine3:spine-server-core:0.7.0'
    compile 'org.spine3:spine-client-core:0.7.0'

    compile 'org.spine3:spine-users:0.7.0'
    compile 'org.spine3:spine-values:0.7.0'

    testCompile 'org.spine3:spine-testutil-core:0.7.0'
}

Handling changes and mismatches of values 

This version introduces Protobuf types for describing field changes. Examples are StringChange, TimestampChange, Int64Change, etc. For more types, please see the spine/change/change.proto file.

These types are for being used in commands (to request a change) and events (to describe the change made).

The ValueMismatch type allows to fire a failure when an entity already had a value of a field, which differs from one described as a previousValue of corresponding change request. Please also see Java utility classes in the org.spine3.change package for details.

Wildcard (by) option was introduced for enrichments 

Now a single enrichment message can be used with multiple target events. E.g.

message EnrichmentForSeveralEvents {
     string username = 1 [(by) = "*.user_id"];
}

message EventOne {
     option (enrichment) = "EnrichmentForSeveralEvents";

     int32 user_id = 1;
}

message EventTwo {
     option (enrichment) = "EnrichmentForSeveralEvents";

     int32 user_id = 1;
}

Behavioural changes and improvements 

Automatic ProjectionRepository catch-up after #initStorage 

As we discovered from the real-world cases, the catch-up for the ProjectionRepository is typically initiated right after the storage factory is set. E.g.

// Spine 0.6.0: 
repository.initStorage(storageFactory);
repository.catchUp()

Now the default behaviour is to invoke #catchUp automatically. So less code, less mistakes. E.g.

// Spine 0.7.0: 
repository.initStorage(storageFactory);

Of course, you can always turn off the automatic catch-up passing false to the ProjectionRepository constructor.

ProcessManager changes 

ProcessManagers may now have no commands handled. So it is now possible to build the process on top of events only.

Syntax sugar for type names 

Some sugar is now available to get the type name for a Message. E.g.

// Spine 0.6.0:
String name =  TypeUrl.of(msg).getTypeName();

// Spine 0.7.0.
String name = TypeName.of(msg);

System and runtime improvements 

Aggregate state double-checking upon update 

Improvements were made to keep the Aggregate state consistent across different threads or even scaled instances of the application. Now Aggregate repository checks that no new events have arrived to the event storage since the start of the command processing.

In case any new events are detected, the processing of this command is repeated.

CommandBus configuration 

CommandBus can now be configured to avoid spawning new threads during the bus operation. It is helpful for sensitive target runtimes such as Google AppEngine. E.g.

final CommandBus commandBus = CommandBus.newBuilder()
                                        // Allowed by default. Let's disable.
                                        .setThreadSpawnAllowed(false)
                                        .build();

Core singletons made thread-safe 

ConverterRegistry and DefaultStateRegistry made thread-safe.

Validation 

Goes option introduced 

Declarative validation rules for the Protobuf model were extended with (goes) option. It is now possible to declare a message field that can only be present if another field is present. E.g.

message ScheduledItem {
     ...
     spine.time.LocalDate date = 4;
     spine.time.LocalTime time = 5 [(goes).with = "date"];
}

Required option simplified 

(required) Protobuf option has been simplified and is now a bool instead of a RequiredOption message. E.g.

// Spine 0.6.0:
MyMessage field = 1 [(required).value = true];

// Spine 0.7.0.
MyMessage field = 1 [(required) = true];

Structural Changes: 

  • CommandBus made configurable via CommandBus.Builder instead of CommandBus#newInstance.

General Improvements 

  • Date/Time API improvements.
  • Entity version is now propagated to Stand upon an update. That allows to store the version properly in StandStorage.

Dependency Updates 

  • Guava 20.0
  • gRPC 1.0.2
  • Protobuf 3.1.0

Spine is now integrated with Codacy, exposing the code quality metrics to everyone.