Skip to content

Fire events and inquiry

This section describes how to fire sensory events into a Baker process, and how to query information from a running Baker process.

Note

For the Java API most methods return a CompletableFuture<A>, in the Scala API they return Future<A>. The Kotlin API makes use of suspending functions, and thus does not wrap the return type. To keep things readable, the descriptions in this section reason from Java's perspective.

Fire sensory events

To trigger a Baker process you'll need to fire a sensory event. After firing an event, you may want to continue your asynchronous computation at one of four different moments:

  1. Right after the event was received, but before any interactions are executed.
  2. After all interactions have completed. At this point the process is either finished, or requires other sensory events to continue.
  3. You want to do something on both the previously mentioned moments.
  4. As soon one of the interactions fires a specific event.

To this end, the Baker interface exposes four different methods to fire events. We'll discuss each of those in more detail.

Fire event and resolve when received

This method returns a CompletableFuture<SensoryEventStatus>. It completes right after the event was received, but before any interactions are executed. The SensoryEventStatus is an enum containing information about the outcome of the event (Received, Completed, FiringLimitMet, etc).

package examples.java.application;

import com.ing.baker.runtime.javadsl.Baker;
import com.ing.baker.runtime.javadsl.EventInstance;
import examples.java.events.OrderPlaced;

public class FireEventAndResolveWhenReceived {

    private final Baker baker;

    public FireEventAndResolveWhenReceived(Baker baker) {
        this.baker = baker;
    }

    public void example(String recipeInstanceId, OrderPlaced orderPlaced) {
        var eventInstance = EventInstance.from(orderPlaced);
        var sensoryEventStatus = baker.fireEventAndResolveWhenReceived(recipeInstanceId, eventInstance).join();
    }
}
package examples.kotlin.application

import com.ing.baker.runtime.javadsl.EventInstance
import com.ing.baker.runtime.kotlindsl.Baker
import examples.kotlin.events.OrderPlaced

class FireEventAndResolveWhenReceived(private val baker: Baker) {

    suspend fun example(recipeInstanceId: String, orderPlaced: OrderPlaced) {
        val orderPlacedEvent = EventInstance.from(orderPlaced)
        val sensoryEventStatus = baker.fireEventAndResolveWhenReceived(recipeInstanceId, orderPlacedEvent)
    }
}
package examples.scala.application

import com.ing.baker.runtime.scaladsl.{Baker, EventInstance}
import examples.scala.events.OrderPlaced

class FireEventAndResolveWhenReceived(val baker: Baker) {

  def example(recipeInstanceId: String, orderPlaced: OrderPlaced): Unit = {
    val eventInstance = EventInstance.unsafeFrom(orderPlaced)
    val sensoryEventStatus = baker.fireEventAndResolveWhenReceived(recipeInstanceId, eventInstance)
  }
}

Fire event and resolve when completed

Returns a CompletableFuture<SensoryEventResult>. It completes when additional sensory events are required to continue the process, or when the process has finished. The SensoryEventResult contains the SensoryEventStatus and a list of all events names triggered as a result of this sensory event.

package examples.java.application;

import com.ing.baker.runtime.javadsl.Baker;
import com.ing.baker.runtime.javadsl.EventInstance;
import examples.java.events.OrderPlaced;

public class FireEventAndResolveWhenCompleted {

    private final Baker baker;

    public FireEventAndResolveWhenCompleted(Baker baker) {
        this.baker = baker;
    }

    public void example(String recipeInstanceId, OrderPlaced orderPlaced) {
        var eventInstance = EventInstance.from(orderPlaced);
        var sensoryEventResult = baker.fireEventAndResolveWhenCompleted(recipeInstanceId, eventInstance).join();
    }
}
package examples.kotlin.application

import com.ing.baker.runtime.javadsl.EventInstance
import com.ing.baker.runtime.kotlindsl.Baker
import examples.kotlin.events.OrderPlaced

class FireEventAndResolveWhenCompleted(private val baker: Baker) {

    suspend fun example(recipeInstanceId: String, orderPlaced: OrderPlaced) {
        val orderPlacedEvent = EventInstance.from(orderPlaced)
        val sensoryEventResult = baker.fireEventAndResolveWhenCompleted(recipeInstanceId, orderPlacedEvent)
    }
}
package examples.scala.application

import com.ing.baker.runtime.scaladsl.{Baker, EventInstance}
import examples.scala.events.OrderPlaced

class FireEventAndResolveWhenCompleted(val baker: Baker) {

  def example(recipeInstanceId: String, orderPlaced: OrderPlaced): Unit = {
    val eventInstance = EventInstance.unsafeFrom(orderPlaced)
    val sensoryEventResult = baker.fireEventAndResolveWhenCompleted(recipeInstanceId, eventInstance)
  }
}

Fire event

This method is useful if you want to do something after the event was received and after all interactions have completed. The method returns an EventResolutions object consisting of a CompletableFuture<SensoryEventStatus> and CompletableFuture<SensoryEventResult>. The former completes on receiving the event, the latter on completion of the interactions.

package examples.java.application;

import com.ing.baker.runtime.javadsl.Baker;
import com.ing.baker.runtime.javadsl.EventInstance;
import examples.java.events.OrderPlaced;

public class FireEvent {

    private final Baker baker;

    public FireEvent(Baker baker) {
        this.baker = baker;
    }

    public void example(String recipeInstanceId, OrderPlaced orderPlaced) {
        var eventInstance = EventInstance.from(orderPlaced);

        var eventResolutions = baker.fireEvent(recipeInstanceId, eventInstance);
        var sensoryEventStatus = eventResolutions.getResolveWhenReceived().join();
        var sensoryEventResult = eventResolutions.getResolveWhenCompleted().join();
    }
}
package examples.kotlin.application

import com.ing.baker.runtime.javadsl.EventInstance
import com.ing.baker.runtime.kotlindsl.Baker
import examples.kotlin.events.OrderPlaced

class FireEvent(private val baker: Baker) {

    suspend fun example(recipeInstanceId: String, orderPlaced: OrderPlaced) {
        val orderPlacedEvent = EventInstance.from(orderPlaced)

        val eventResolutions = baker.fireEvent(recipeInstanceId, orderPlacedEvent)
        val sensoryEventStatus = eventResolutions.resolveWhenReceived.await()
        val sensoryEventResult = eventResolutions.resolveWhenCompleted.await()
    }
}
package examples.scala.application

import com.ing.baker.runtime.scaladsl.{Baker, EventInstance}
import examples.scala.events.OrderPlaced

class FireEvent(val baker: Baker) {

  def example(recipeInstanceId: String, orderPlaced: OrderPlaced): Unit = {
    val eventInstance = EventInstance.unsafeFrom(orderPlaced)

    val eventResolutions = baker.fireEvent(recipeInstanceId, eventInstance)
    val sensoryEventStatus = eventResolutions.resolveWhenReceived
    val sensoryEventResult = eventResolutions.resolveWhenCompleted
  }
}

Fire event and resolve on event

This method returns a CompletableFuture<SensoryEventResult>. It completes when one of the interactions fires an event with a specified name.

package examples.java.application;

import com.ing.baker.runtime.javadsl.Baker;
import com.ing.baker.runtime.javadsl.EventInstance;
import examples.java.events.OrderPlaced;

public class FireEventAndResolveOnEvent {

    private final Baker baker;

    public FireEventAndResolveOnEvent(Baker baker) {
        this.baker = baker;
    }

    public void example(String recipeInstanceId, OrderPlaced orderPlaced) {
        var eventInstance = EventInstance.from(orderPlaced);
        var sensoryEventResult = baker.fireEventAndResolveOnEvent(recipeInstanceId, eventInstance, "ExpectedEvent").join();
    }
}
package examples.kotlin.application

import com.ing.baker.runtime.javadsl.EventInstance
import com.ing.baker.runtime.kotlindsl.Baker
import examples.kotlin.events.OrderPlaced

class FireEventAndResolveOnEvent(private val baker: Baker) {

    suspend fun example(recipeInstanceId: String, orderPlaced: OrderPlaced) {
        val orderPlacedEvent = EventInstance.from(orderPlaced)
        val sensoryEventResult = baker.fireEventAndResolveOnEvent(recipeInstanceId, orderPlacedEvent, "ExpectedEvent")
    }
}
package examples.scala.application

import com.ing.baker.runtime.scaladsl.{Baker, EventInstance}
import examples.scala.events.OrderPlaced

class FireEventAndResolveOnEvent(val baker: Baker) {

  def example(recipeInstanceId: String, orderPlaced: OrderPlaced): Unit = {
    val eventInstance = EventInstance.unsafeFrom(orderPlaced)
    val sensoryEventResult = baker.fireEventAndResolveWhenCompleted(recipeInstanceId, eventInstance)
  }
}

Inquiry

Baker allows you to query the state of a recipe instance at any given moment. To this end, Baker exposes a couple of different methods that allow you to fetch information about events, ingredients, and interactions from a running process.

package examples.java.application;

import com.ing.baker.runtime.javadsl.Baker;

public class InquiryExample {

    private final Baker baker;

    public InquiryExample(Baker baker) {
        this.baker = baker;
    }

    public void example(String recipeInstanceId) {
        var ingredient = baker.getIngredient(recipeInstanceId, "orderId").join();

        var ingredients = baker.getIngredients(recipeInstanceId).join();

        var events = baker.getEvents(recipeInstanceId).join();

        var eventNames = baker.getEventNames(recipeInstanceId).join();

        var recipeInstanceState = baker.getRecipeInstanceState(recipeInstanceId).join();
    }
}
package examples.kotlin.application

import com.ing.baker.runtime.kotlindsl.Baker

class InquiryExample(private val baker: Baker) {

    suspend fun example(recipeInstanceId: String) {
        val ingredient = baker.getIngredient(recipeInstanceId, "orderId")

        val ingredients = baker.getIngredients(recipeInstanceId)

        val events = baker.getEvents(recipeInstanceId)

        val eventNames = baker.getEventNames(recipeInstanceId)

        val recipeInstanceState = baker.getRecipeInstanceState(recipeInstanceId)
    }
}
package examples.scala.application

import com.ing.baker.runtime.scaladsl.Baker

class InquiryExample(val baker: Baker) {

  def example(recipeInstanceId: String): Unit = {
    val ingredient = baker.getIngredient(recipeInstanceId, "orderId")

    val ingredients = baker.getIngredients(recipeInstanceId)

    val events = baker.getEvents(recipeInstanceId)

    val eventNames = baker.getEventNames(recipeInstanceId)

    val recipeInstanceState = baker.getRecipeInstanceState(recipeInstanceId)
  }
}