Occurrent 0.5.0 is now available. It contains a new subscription api, a much improved in-memory event store (that now supports queries), as well as in-memory subscription component. Several components have been also moved and switched name (see below). Most noteworthy is that “Subscription” has been renamed to “SubscriptionModel”. It was very confusing in the previous version since before you created a subscription (instance) from a subscription, but they both had the same name. Now you create a subscription (instance) from a subscription model instead. For example:

InMemorySubscriptionModel inMemorySubscriptionModel = new InMemorySubscriptionModel();
InMemoryEventStore inMemoryEventStore = new InMemoryEventStore(inMemorySubscriptionModel);

inMemorySubscriptionModel.subscribe("subscription1", System.out::println);

This version also introduces a new subscription dsl for Java and Kotlin (depend on org.occurrent:subscription-dsl). It allows you to configure subscriptions in a more concise way, for example you can do like this in Kotlin:

val subscriptionModel = SpringMongoSubscriptionModel(..)
val cloudEventConverter = GenericCloudEventConverter<DomainEvent>(..)

subscriptions(subscriptionModel, cloudEventConverter) {
    subscribe<GameStarted>("id1") { gameStarted ->
        log.info("Game was started $gameStarted")
    }
    subscribe<GameWon, GameLost>("id2") { domainEvent ->
        log.info("Game was either won or lost: $domainEvent")
    }
    subscribe("everything") { domainEvent ->
        log.info("I subscribe to every event: $domainEvent")
    }
} 

In Java, you can do like this:

var subscriptions = new Subscriptions<DomainEvent>();
subscriptions.subscribe("id1", GameStarted.class, event -> System.out.println("Event was received: " + event.getClass().getSimpleName()));

Here are all changes:

  • Renamed org.occurrent.subscription.api.blocking.BlockingSubscription to org.occurrent.subscription.api.blocking.SubscriptionModel. The reason for this is that it was previously very confusing to differentiate between a org.occurrent.subscription.api.blocking.BlockingSubscription (where you start/cancel subscriptions) and a org.occurrent.subscription.api.blocking.Subscription (the actual subscription instance). The same thinking has been applied to the reactor counterparts as well (org.occurrent.subscription.api.reactor.ReactorSubscription has now been renamed to org.occurrent.subscription.api.reactor.SubscriptionModel).
  • Derivatives of org.occurrent.subscription.api.blocking.BlockingSubscription such as PositionAwareBlockingSubscription has been renamed to org.occurrent.subscription.api.blockking.PositionAwareSubscriptionModel.
  • Derivatives of the reactor counterpart, org.occurrent.subscription.api.reactor.PositionAwareReactorSubscription has been renamed to, such as has been renamed to org.occurrent.subscription.api.reactor.PositionAwareSubscriptionModel.
  • org.occurrent.subscription.util.blocking.catchup.subscription.CatchupSubscriptionModelConfig has been renamed to org.occurrent.subscription.blocking.catchup.CatchupSubscriptionModelConfig.
  • org.occurrent.subscription.util.blocking.catchup.subscription.CatchupSubscriptionModel has been renamed to org.occurrent.subscription.blocking.catchup.CatchupSubscriptionModel.
  • org.occurrent.subscription.util.blocking.AutoPersistingSubscriptionModelConfig has been renamed to org.occurrent.subscription.blocking.durable.DurableSubscriptionModelConfig.
  • org.occurrent.subscription.util.blocking.BlockingSubscriptionWithAutomaticPositionPersistence has been renamed to org.occurrent.subscription.blocking.durable.DurableSubscriptionModel.
  • org.occurrent.subscription.mongodb.nativedriver.blocking.BlockingSubscriptionForMongoDB has been renamed to NativeMongoSubscriptionModel.
  • org.occurrent.subscription.mongodb.nativedriver.blocking.BlockingSubscriptionPositionStorageForMongoDB has been renamed to NativeMongoSubscriptionPositionStorage.
  • Removed org.occurrent.subscription.mongodb.nativedriver.blocking.BlockingSubscriptionWithPositionPersistenceInMongoDB. Use an org.occurrent.subscription.blocking.DurableSubscriptionModel from module org.occurrent:durable-subscription instead.
  • org.occurrent.subscription.mongodb.spring.blocking.MongoDBSpringSubscription has been renamed to SpringMongoSubscription.
  • org.occurrent.subscription.mongodb.spring.blocking.SpringBlockingSubscriptionForMongoDB has been renamed to SpringMongoSubscription.
  • org.occurrent.subscription.mongodb.spring.blocking.SpringMongoDBSubscriptionPositionStorage has been renamed to SpringMongoSubscriptionPositionStorage.
  • org.occurrent.subscription.mongodb.spring.reactor.SpringReactorSubscriptionForMongoDB has been renamed to ReactorMongoSubscription.
  • org.occurrent.subscription.mongodb.spring.reactor.SpringReactorSubscriptionPositionStorageForMongoDB has been renamed to ReactorSubscriptionPositionStorage.
  • org.occurrent.subscription.util.reactor.ReactorSubscriptionWithAutomaticPositionPersistence has been renamed to org.occurrent.subscription.reactor.durable.ReactorDurableSubscriptionModel.
  • org.occurrent.subscription.util.reactor.ReactorSubscriptionWithAutomaticPositionPersistenceConfig has been renamed to org.occurrent.subscription.reactor.durable.ReactorDurableSubscriptionConfig.
  • org.occurrent.eventstore.mongodb.spring.reactor.SpringReactorMongoEventStore has been renamed to ReactorMongoEventStore since “Spring” is implicit.
  • org.occurrent.subscription.mongodb.MongoDBFilterSpecification has been renamed to MongoFilterSpecification.
  • org.occurrent.subscription.mongodb.MongoDBFilterSpecification.JsonMongoDBFilterSpecification has been renamed to MongoJsonFilterSpecification.
  • org.occurrent.subscription.mongodb.MongoDBFilterSpecification.BsonMongoDBFilterSpecification has been renamed to MongoBsonFilterSpecification.
  • org.occurrent.subscription.mongodb.internal.MongoDBCloudEventsToJsonDeserializer has been renamed to MongoCloudEventsToJsonDeserializer.
  • org.occurrent.subscription.mongodb.internal.MongoDBCommons has been renamed to MongoCommons.
  • org.occurrent.subscription.mongodb.MongoDBOperationTimeBasedSubscriptionPosition has been renamed to MongoOperationTimeSubscriptionPosition.
  • org.occurrent.subscription.mongodb.MongoDBResumeTokenBasedSubscriptionPosition has been renamed to MongoResumeTokenSubscriptionPosition.
  • org.occurrent.eventstore.mongodb.internal.OccurrentCloudEventMongoDBDocumentMapper has been renamed to OccurrentCloudEventMongoDocumentMapper.
  • org.occurrent.eventstore.mongodb.spring.blocking.SpringBlockingMongoEventStore has been renamed to SpringMongoEventStore.
  • Renamed module org.occurrent:subscription-util-blocking-catchup-subscription to org.occurrent:catchup-subscription.
  • Renamed module org.occurrent:subscription-util-blocking-automatic-position-persistence to org.occurrent:durable-subscription.
  • Renamed module org.occurrent:subscription-util-reactor-automatic-position-persistence to org.occurrent:reactor-durable-subscription.
  • Moved org.occurrent.application.converter.implementation.GenericCloudEventConverter to org.occurrent.application.converter.generic.GenericCloudEventConverter.
  • Moved org.occurrent.application.service.blocking.implementation.GenericApplicationService to org.occurrent.application.service.blocking.generic.GenericApplicationService.
  • Added a new “Subscription DSL” module that adds a domain event specific abstraction on-top of the existing subscription model api’s. This DSL makes it easier to create subscriptions that are using domain events instead of cloud events. The module is called org.occurrent:subscription-dsl. For example:

    val subscriptionModel = SpringMongoSubscriptionModel(..)
    val cloudEventConverter = GenericCloudEventConverter<DomainEvent>(..)
      
    // Subscription DSL
    subscriptions(subscriptionModel, cloudEventConverter) {
      subscribe<GameStarted>("id1") { gameStarted ->
          log.info("Game was started $gameStarted")
      }
      subscribe<GameWon, GameLost>("id2") { domainEvent ->
          log.info("Game was either won or lost: $domainEvent")
      }
     subscribe("everything") { domainEvent ->
          log.info("I subscribe to every event: $domainEvent")
      }
    } 
    
  • Implemented ability to delete cloud events by a filter in the in-memory event store.
  • Added “listener” support to the in-memory event store. This means that you can supply a “listener” (a consumer) to the InMemoryEventStore constructor that will be invoked (synchronously) after new events have been written. This is mainly useful to allow in-memory subscription models.
  • Added an in-memory subscription model that can be used to subscribe to events from the in-memory event store. Add module org.occurrent:subscription-inmemory and then instantiate it using:

    InMemorySubscriptionModel inMemorySubscriptionModel = new InMemorySubscriptionModel();
    InMemoryEventStore inMemoryEventStore = new InMemoryEventStore(inMemorySubscriptionModel);
      
    inMemorySubscriptionModel.subscribe("subscription1", System.out::println);
    
  • Renamed groupId org.occurrent.inmemory to org.occurrent for consistency. This means that you should depend on module org.occurrent:eventstore-inmemory instead of org.occurrent.inmemory:eventstore-inmemory when using the in-memory event store.
  • Added support for querying the in-memory event store (all fields expect the “data” field works)
  • Changed from Executor to ExecutorService in NativeMongoSubscriptionModel in the org.occurrent:subscription-mongodb-native-blocking module.
  • Added a @PreDestroy annotation to the shutdown method in the NativeMongoSubscriptionModel implementation so that, if you’re frameworks such as Spring Boot, you don’t need to explicitly call the shutdown method when stopping.
  • Added partial extension functions for List<DomainEvent>, import from the partial method from org.occurrent.application.composition.command.