# Introduction

VLINGO XOOM: Simple. Rapid. Delivered.

Welcome to the VLINGO XOOM documentation!

Strategic digital transformation initiatives execute too slowly and regularly overrun budgets. Event-driven architectures are often wrong and cause organizational pain. Architects and engineers want to experience successes with Domain-Driven Design (DDD).

The VLINGO XOOM and VLINGO XOOM Cloud platforms and SDK clear a path for success in transformative, domain-driven strategies, while employing microservices and event-driven architectures along with cloud infrastructure. Our tooling and runtime are ideal for organizations that want business-driven innovation with high performance responsiveness at elastic scale, and resilience to failure using bulkheading and fast recovery. Our APIs are fluent and our guidance enables teams to achieve domain-driven success by facilitating sturdy, yet flexible, communication structures that blend business visionaries, domain experts, and software architects and engineers. The VLINGO XOOM Designer supports driving innovation by means of discovery-based, rapid learning tools, such as EventStorming, into bug-free microservices in record time.

![The VLINGO XOOM platform ecosystem delivers digital transformation in record time.](/files/-MYYkuk8Zf2Y5MG6q95F)

Our platform and SDK include everything you need to support distributed process choreography and orchestration by way of its coordination components, including type- and version-safe broadcasting of events and sending messages directly with peer-to-peer. You can use object-oriented database mapping, key-value full-state persistence, and event sourcing as needed. Develop use-case-optimal queries by means of the command-query responsibility segregation (CQRS) pattern, while separating database writes and reads for different scales. Use our data grid to distribute shared data across a large cluster of compute nodes to keep frequently consumed data near the software operations that consume it. It's all provided through our simple yet powerful and modern SDK.

![VLINGO XOOM facilitates Domain-Driven Design with event-driven architectures using choreography and orchestration.](/files/-M7aeWqWWAfUs8PnLru6)

The full platform is made available as open source software (OSS) that is free to use and open for community contributions. Learn how to rapidly design architecture and bug-free microservices for cloud deployment for hassle-free application and systems runtime management. Give it a try and pay as you go. Top-tier consulting services and development are available from our team of experts.

Use the open source (OSS) VLINGO XOOM platform to experience the ultimate simplification of application and microservices with rapid delivery. Your solutions will possess distinguished and advanced properties, such as Reactive programming and architecture, along with distributed, concurrent, event-driven, and microservices-based systems that just work.

<figure><img src="/files/izTIQDjDCq2ODnDJkdiF" alt=""><figcaption><p>Reactive value, form, and means.</p></figcaption></figure>

Reactive programming and architecture, as described by the [Reactive Manifesto](https://www.reactivemanifesto.org/), provide responsive value in the form of elasticity and resiliency, all by means of a message-driven foundation. That describes XOOM from individual components to the entire platform SDK.

Together with [Domain-Driven Design](https://kalele.io/books/) (DDD) and [Domain-Oriented Microservices Architecture](https://eng.uber.com/microservice-architecture/) (DOMA), this is the crossroads where business strategy and modern technology meet.

Our platform is a full ecosystem with visual modeling tools and a rich array of components that enable digital transformation with leading-edge architectures in record time.&#x20;

## Getting Started Quickly

To jump directly into the use of the VLINGO XOOM platform, we suggest that you review the [Getting Started](/getting-started) chapter along with the [Hello, World!](/getting-started/hello-world-1) example. With a basic understanding of the underlying SDK and APIs, the next step is the use the [XOOM Designer](/xoom-designer) to bypass the architecture details by starting in experimentation mode with a microservice that you design visually. You can use the [XOOM Designer](/xoom-designer) with no platform SDK experience.

![EventStorming to visual modeling to new apps and microservices in under 30 minutes.](/files/-MYYmlbekzLfZyz97qr_)

The remainder of this chapter and the Overview in the next chapter give you a brief yet thorough introduction to the VLINGO XOOM platform SDK and its full complement of components.

## How Our XOOM Platform SDK Helps

The VLINGO XOOM platform SDK is a toolset to enable your systems, applications, and services to apply modern distributed systems patterns, to be highly scalable and performant, and to realize advanced architectures with minimal risk. Use our platform SDK to:

* Developing Event-Driven and microservices architectures with ease
* Implement your DOMA and DDD-based system using fluent business language

See just below for the [detailed advantages](/#advantages).

As platform developers, we've done the heavy lifting so that you can focus on your customers' solutions. You may use our platform as a general-purpose toolset for developing Event-Driven and Microservices Architectures with the DOMA mindset. You may also choose to use our platform to implement your DDD-based system. In any case, your systems, applications, and services will be up and running quickly with scale, throughput, and overall performance that is difficult to match.

When using DOMA and DDD, our platform doesn’t get in your way as you build your DDD Bounded Context with its Ubiquitous Language. Rather, VLINGO XOOM facilitates the explicit and fluent linguistic expressions of your core business models. Consider our platform a DOMA enabler and *DDD-friendly.* Together with simplified Reactive multi-core enablement, your teams are supplied with a powerful toolbox full of versatile components supporting your most advanced innovations.

### Advantages

The following diagram shows the primary tools available with the XOOM platform. From top to bottom, consider how each of these helps.

![The primary components of the XOOM platform shown in layers of lightweight containers.](/files/-M9H0FwLGxPXIMkLGEwd)

* **VLINGO XOOM Advantages** accelerate your architecture and design to deployment. You go from idea to model design to delivered, quickly. As you collaborate with your customer, possibly using *EventStorming,* your designs will be fully operational much more rapidly, and reflect the fluent conversations your team speaks while realizing your Ubiquitous Language in a Bounded Context. By means of our service-based *Compressed Architecture* and acceleration tools, Event-Driven and Microservices Architectures have never been so simple.
* **VLINGO XOOM** **Designer** helps you rapidly design any DOMA-based Microservices and DDD solutions by providing a modeling tool that delivers a compressed *Ports and Adapters* architecture with all the parts of your Microservice, including infrastructure and domain model. Following [Designer](/xoom-designer) modeling and generation, just build and run, and enhance your model with additional business logic to fit the needs of your customers. Our quick-booting Turbo container ties together all platform components. Learn more [here](/xoom-turbo).
* **XOOM HTTP** is our Reactive HTTP server, which scales to an incredible number of concurrent, non-blocking requests. With our lightweight architecture, your HTTP request handlers (a.k.a endpoints) are super simple to define, either by a fluent API or a configuration-based file mapping. Using the [XOOM annotations](/xoom-turbo/annotations), you get HTTP request auto-dispatch directly to your domain model, meaning there is no need for you to implement your own request handlers. The server also supports [Server-Sent Events](/xoom-http#server-sent-events-sse) (SSE) and continuous Event-Driven Feeds via REST log resources.
* **XOOM Lattice** is a *distributed grid* over which any number of objects are partitioned. The objects may be Aggregates/Entities, Processes/Sagas, Data Tuples, Message Exchanges, Stateless Services, State Projections, and many others. Sending a message to any such object is opaque to the sender, and the message arrives at the single, specific location of where specific object is pinned in the grid. All of the objects that contain persistent data, such as Aggregates/Entities and Processes/Sagas, may be stored in a variety of ways: Key-Value State Storage, Event Sourcing, and Object Mapped. This is all backed by resilient [cluster](/xoom-cluster) management. When receiving Exchange messages from other services, the XOOM annotations are used to auto-dispatch directly to your domain model. There are many other benefits, which can be read [here](/xoom-lattice).
* **XOOM Streams** provides our implementation of the *Reactive Streams* standard. The component enables you to continuously stream over any number of elements, whether from an in-memory or persisted data collection, a database query result, other streams, and many other use cases. Included with our streaming is the ability to define back-pressure to the publisher of the stream, preventing the stream of many elements in rapid succession to overwhelm the subscriber. Learn how to use our streaming [here](/xoom-streams).
* **XOOM GraphQL** is a server that accepts GraphQL queries by HTTP requests and runs them asynchronously. The asynchronous execution nature, resulting in both concurrent and parallel queries, is unknown to the GraphQL client, unless it uses our HTTP client interface which also enables a non-blocking client side. Our GraphQL server is the simplest and most convenient interface to massive numbers of aggregating queries.
* **XOOM Schemata** is our platform's schema registry. It provides the means for systems, applications, and services (possibly as Bounded Contexts), to publish standard types that are made available to client services. The published standard types are known as schemas, and the registry hosts the schemas for given organizations and the services within. From a DOMA and DDD perspective, this supports establishing exchangeable Published Languages for event-driven systems. [Learn how to use the schema registry](/xoom-schemata) to protect against strong coupling between Microservices and the problems that arise from it.
* **XOOM Symbio** introduces Reactive storage in three different varieties and with several different backing persistence databases. Use any of our diverse storage types: Key-Value State Storage, Event Sourcing, and Object Mapped. For backing databases,  employ asynchronous DynamoDB, Postgres, MySQL, MariaDB, YugaByte, and others, all with non-blocking throughput. Our storage is non-blocking to provide the greatest level of low-latency throughput and ultimate performance. Choose your storage preferences inside the [XOOM Designer](/xoom-designer) and get fully operational Reactive storage effortlessly.
* **XOOM Actors** is the Reactive foundation runtime underlying the entire platform. It supports high-scalability with fully asynchronous type-safe messaging. To accomplish this, our toolkit is an implementation of the Actor Model, and all primary platform components are built on our Actor Model implementation. You will be amazed when you learn the [full benefits of using XOOM Actors](/xoom-actors).

Multi-threaded programming has traditionally been complex and error prone, especially given sophisticated modern microprocessors that employ numerous code execution optimization techniques. To simplify this, the VLINGO XOOM platform provides an object-based threading model in which individual objects are run single-threaded, while the overall process execution is massively concurrent and even parallel.

{% hint style="info" %}
There is far too much complexity in the software industry. The overarching vision for the VLINGO XOOM platform puts extreme emphasis on simplicity, efficiency, rapid and delivery. With our platform components, preconfigured for common use cases, you can be productive within minutes, not an untold number of weeks or months. Start with the XOOM Designer and get ready to blast off.
{% endhint %}

Our platform provides a JVM and .NET SDK ecosystem for building high-performance, Reactive microservices and well-modularized monoliths. Explore our DOMA-compatible and DDD-friendly toolkit and see how it provides the key benefits to reach the future of business-driven software at scale.

## Collaboration

Our team very much appreciates collaboration. It increases the value that the VLINGO XOOM offers. Also, the more viewpoints and contributors that we have the more competent and mature the VLINGO XOOM community becomes. If you want to be a catalyst for moving the platform forward, the first step is to submit an issue. Next, create a pull request on one of our [platform repositories](https://github.com/vlingo) that provides a non-trivial contribution. Following approval and a merge of your pull request, you are eligible to work with our team as a regular contributor and maintainer. Get in touch with us!

We are here to help you and your teams. Learn about our [support, training, consulting, and project development offerings](https://docs.vlingo.io/getting-started#training-consulting-and-project-development).


# Overview

How you can expect to benefit from the VLINGO XOOM platform's rich ecosystem.

The software industry needs to achieve greater success with cleaner solutions more quickly. Filling these needs is the vision behind the VLINGO XOOM platform. Achieving that vision has resulted in a software development platform that enables these vital capabilities:

* Laser focus on business value and away from technologies
* Rapid, bug-free software development and delivery with minimal source code
* Minimal source code that forms a clean, robust, and flexible architecture

Here's how we afford that.

### Laser Focus on Business Value

Our platform promotes and supports the [Domain-Driven Design (DDD)](https://kalele.io/books/) approach to software development. By using DDD, teams are assisted with tools that emphasize software from the viewpoint of strategic innovation. The tools help pinpoint opportunities to reach competitive advantage through experimentation leading to deep learning and discovery of previously unknown value. The nature of the VLINGO XOOM platform SDK provides a sound foundation that does not interfere with these ambitions, but rather encourages them by assisting teams of business experts and software developers.

Further, DDD stresses the use of fluent language to model solutions in complex digital business problem spaces. Most technology frameworks greatly detract from this goal. The VLINGO XOOM platform SDK not only enables, but also enhances the DDD experience. In addition to helping teams reflect their business modeling language in the model, the APIs support fluency by expressing fluency that blends with the business software model.

### Rapid and Bug-Free Delivery

By using the [XOOM Designer](/xoom-designer), business-driven, bug-free software solutions, such as applications, microservices, and subsystems, can be delivered within several minutes or a few hours.

![Use the XOOM Designer to accelerate software model development and delivery.](/files/-MY0chsDJ6B_H6HnVuSO)

There is no better way to achieve this level of accuracy in business-critical software solutions that is: fully tested and bug-free, highly efficient, broadly scalable, as well as flexible and accommodating of change.

### Minimal Source in Clean and Robust Architecture

The [XOOM Designer](/xoom-designer) helps you produce a software development project with minimal source code. It's a low-code solution that immediately transitions to a full-code software development life cycle (SDLC).

The XOOM Designer helps teams deliver a clean and robust architecture for each application and microservice project that it assists in producing. Emphasis is given to these factors:

* [Compressed Ports and Adapters Architecture](/architecture), making the solution flexible and accommodating of change, yet with only two layers that are "baggage-free."
* Event-Driven Architecture that provides [automatic translation and dispatch](/xoom-designer) from incoming requests and event notifications to the business-driven domain model, and from the domain model outward to other applications and microservices.
* [Type-safe and version-safe integration](/xoom-schemata) across applications and microservices with the assurance and confidence that seamless operations will continue deployment after deployment.
* [Domain-Oriented Microservices Architecture (DOMA)](https://eng.uber.com/microservice-architecture/), inspired by DDD, focusing on the long-term delivery and maintainability of microservices.

With our clean and robust architecture focus, including DOMA, you and your team are availed the most powerful SDK to express your software models, subsystems, and whole system solutions with business-driven accuracy and innovation, loose coupling, along with the longevity of the overall system.

### Platform Benefits

A generous toolset of prebuilt, clean and robust abstractions, designed for use in implementing Reactive DOMA- and DDD-based full system solutions, is yours when adopting the VLINGO XOOM platform. You gain an environment for rapid, low-code as well as full-code SDLC, supporting fluent, highly scaleable, and concurrent models, with precision and type safe integration across subsystems. Capabilities include Reactive REST services over HTTP, domain object aggregates, key-value aggregates, event sourced aggregates, CQRS with projections, compute grid, actor/object caching, object spaces, cluster cross-node actor messaging, enterprise message exchanges, and long-running processes (aka Sagas).

## **Simplistic Power**—**Actor Model Foundation**

A charter member of the [Reactive Foundation](https://reactive.foundation/), VLINGO and the XOOM teams are leaders in Reactive software architecture and development. Whether with DDD or a different approach, you can count on our platform to help you deliver scalable and performant event-driven solutions. At the foundation of XOOM, our runtime is built with a combination of the simplest and most efficient way to delivery Reactive applications, microservices, and whole systems. That foundation is the Actor Model.

In 1973, Dr. Carl Hewitt and his colleagues formulated the Actor Model. In recent years, the inventor of object orientation, Alan Kay, has stated that the Actor Model retained more of what he thought were the important object ideas. So, when you think of the Actor Model, think of objects done right.

![A Resource actor sending a command message to a Model Entity actor.](/files/-M9CQm0xaXGxpQmk9Rk6)

The XOOM Actors toolkit is an implementation of the Actor Model. The ideas behind the Actor Model are powerful, and the XOOM Actors toolkit elegantly implements the concepts behind it with simplicity. Components created with XOOM Actors are type safe by design. Services use Actors by defining and implementing domain-specific interfaces, known as *protocols.* This box shows how actors work and what they do.

| How actors work and what they do                                                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| An actor receives messages in its mailbox, and processes one message at a time when a thread is available.                                                                                              |
| Fundamentally, actors are non-blocking and share none of their mutable state with the outside, not even with other actors.                                                                              |
| Actors use available threads, and you can’t run more threads simultaneously than there are available cores, e.g. `Runtime.getRuntime().availableProcessors()`                                           |
| The basic unit of computation is expressed through actors. Actors send and receive messages asynchronously.                                                                                             |
| As objects create other objects, actors can create other actors.                                                                                                                                        |
| Each actor can designate the behavior it will exhibit for the next message it receives. With XOOM Actors this can be accomplished by actors implementing multiple type-safe domain-specific interfaces. |

As objects are typically used, software developers have become accustomed, even addicted, to the blocking paradigm. In the *blocking diagram* a Client object invokes a method on a Server object. This is an in-process (in-VM) invocation, not a remote client and a remote server. The point is, when a method invocation occurs, the Client is blocked until the Server returns from the method invocation. This means that the Client can perform no additional operations while the Server is handling its request.

![A Client object invoking a method on a Server object, which blocks the Client.](/files/-M9CRQGKMEEkaRv8yOWQ)

In contrast, the Actor Model works differently, as is shown in the *message-driven* diagram. When the `Sender` actor wants another actor to provide a service, it sends that actor a message. The message is sent to the `Receiver` actor and handled asynchronously when a thread is available. The `Sender` is not blocked, but continues moving forward with its current activities, and when those complete, it returns from its own message handling. As a result the thread previously used by the `Sender` is now available for another actor. This achieves maximum efficiency across all actors in your service instance. The more cores that are available, the greater the overall throughput and the greater the efficiency.

![The Actor Model is message-driven and processes messages asynchronously.](/files/-M9CS49Bwq5q-GqtaGmM)

With XOOM Actor&#x73;*,* type-safe messages are the fundamental building block. For those that depend on static typing, a strongly-typed Actor Model implementation is crucial to reassure developers that they are sending the correct and intended message to each actor. This is guaranteed by the compiler, and adds no overhead beyond a typeless implementation.

There is far too much complexity in the software industry. The overarching vision for the VLINGO XOOM platform puts extreme emphasis on simplicity and rapid development. In a few moments you can download the platform components through your build definition, with the whole platform fully conﬁgured for common use cases. You can be productive within minutes, rather than the typical untold number of weeks or months. Try it!

The XOOM Actors toolkit is the bedrock on which our other platform tools are implemented. You don't necessarily have to use actors directly, but you still have all the advantages of the Reactive runtime.

## More...

To read more introductory explanations about our platform, see [Quick Reference,](/overview/quick-reference) a brief guide to the components that comprise the VLINGO XOOM platform. Otherwise, jump to [Getting Started](/getting-started).


# Quick Reference

A quick reference to the components that comprise the VLINGO XOOM platform.

The following components are available for use.

| Component                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [XOOM Designer and Turbo Container](/xoom-turbo) | The platform adoption accelerator for Java and other JVM languages, C# and F# .NET, including a lightning fast quick boot and model designer for a quick starter for every new application and microservice.                                                                                                                                                                                                                                                                                                     |
| [XOOM HTTP](/xoom-http)                          | A reactive HTTP server that provides request-response services that can be embedded into any given service, and supports both REST and RPC. It is small, fast, and promotes fluent APIs that adhere to your DDD Ubiquitous Language as a first-class concern.                                                                                                                                                                                                                                                    |
| [XOOM Lattice](/xoom-lattice)                    | Tooling for reactive Domain-Driven Design projects, and featuring highly concurrent models. Includes compute grid, actor/object caching, object spaces, cross-node cluster messaging, object aggregates, state aggregates, event sourced aggregates, CQRS with projections, messaging exchanges, and long-running processes (aka Sagas).                                                                                                                                                                         |
| [XOOM Streams](/xoom-streams)                    | The Reactive Streams implementation built on the XOOM Actors Reactive, concurrent, asynchronous runtime foundation.                                                                                                                                                                                                                                                                                                                                                                                              |
| [XOOM Schemata](/xoom-schemata)                  | An advanced schema registry provides the means to safely publish standard types that are made available to client services. Provides command-line interface and Web-based UI.                                                                                                                                                                                                                                                                                                                                    |
| [XOOM Symbio](/xoom-symbio)                      | The Reactive, scalable, and resilient CQRS, Event Sourcing, Key-Value, and Object storage for services and applications. With three major persistence types, all based on reactive and actors, there is no strong opinion about a given approach to persistence. Teams are the best to determine their needs, which may be different between Entity types and from one Bounded Context to another. We support a number of cloud and traditional storage engines: DynamoDB, Apache Geode, and various JDBC types. |
| [XOOM Actors](/xoom-actors)                      | The type-safe Actor Model toolkit for reactive concurrency, scalability, and resiliency using Java and other JVM languages, serving as the foundation for the message-driven platform. Actors are objects, but without direct method invocations. Instead actors send and receive messages asynchronously.                                                                                                                                                                                                       |
| [XOOM Cluster](/xoom-cluster)                    | The way to scale your services across a number of nodes, whose components can communicate and collaborate with components on any given node.                                                                                                                                                                                                                                                                                                                                                                     |
| [XOOM Directory](/xoom-directory)                | The means by which services register with the system and discover collaborators. It's not a passive "look-up registry." It is a publisher of service availability and access.                                                                                                                                                                                                                                                                                                                                    |
| [XOOM Common](/xoom-common)                      | A small set of reusable components used by multiple platform components. (Don't worry, this is not a catchall.)                                                                                                                                                                                                                                                                                                                                                                                                  |
| [XOOM Wire](/xoom-wire)                          | Wire protocol messaging implementations, such as with full-duplex TCP, UDP multicast, and RSocket, using XOOM Actors.                                                                                                                                                                                                                                                                                                                                                                                            |
| [XOOM Auth](/xoom-auth)                          | An identity and access management tool used by the VLINGO XOOM platform where data and its use must be secured. Your services may use this facility but are not required to. (Currently experimental.)                                                                                                                                                                                                                                                                                                           |
| [XOOM Telemetry](/xoom-telemetry)                | The reactive metrics collector plugin for the VLINGO XOOM platform, including support for HTTP, Lattice, Streams, Actors, and others.                                                                                                                                                                                                                                                                                                                                                                            |
| [XOOM Build Tools](/xoom-build-plugins)          | A set of tool plugins supporting build automation for Actors and accessing the REST-based API of XOOM Schemata using Maven.                                                                                                                                                                                                                                                                                                                                                                                      |

See each of the documents for guidance on how to use the individual platform components.


# Getting Started

How to start using the VLINGO XOOM platform.

The VLINGO XOOM platform SDK is distributed as a set of libraries as well as some executable components. The documentation is available online, and that's what you are reading. The following sections explain how to access both.

To get started quickly with your first example, see the [Hello, World!](/getting-started/hello-world-1) project.

## Quick Start

Simply stated, use XOOM Designer. There are more detailed how-to instructions [a few chapters later](/xoom-designer). Here you are helped to get the XOOM Designer running quickly.

{% hint style="info" %}
At this time the XOOM Designer runs locally as a Java executable process. Soon we will have the XOOM Designer running in the cloud and will thus require no local installation. Users will also benefit from our continuous delivery of new features, improvements, and any necessary fixes.
{% endhint %}

Even though installed locally, the setup is quite painless. It's explained next.

### Setup

The setup process is short. Before you start, ensure that you have the following installed:

* Java 8+
* Maven 3.x.x
* Docker Desktop 18.x

Download the `xoom-designer` compressed distribution file via `curl`.

If you want to use the `zip` format, download it as follows:

```
curl -L -O https://github.com/vlingo/xoom-designer/releases/latest/download/designer.zip
```

If you want to use the `tar` format, download it as follows:

```
curl -L -O https://github.com/vlingo/xoom-designer/releases/latest/download/designer.tar
```

Extract the file content inside a parent directory that is meant to contain it. After that, set an environment variable named `VLINGO_XOOM_DESIGNER_HOME` indicating the absolute path of the uncompressed folder; that is, the root of the installation folder, not the parent directory where it was decompressed. Using a \*nix shell, such as `bash`, do this:

```
 $ VLINGO_XOOM_DESIGNER_HOME=[installation-path]
 $ export VLINGO_XOOM_DESIGNER_HOME
```

You should include the previous step in your login script, such as `.bash_profile`, for example. This makes the XOOM Designer ready for use after logout followed by login.

On Windows you can use the *System Properties > Advanced > Environment Variables...* to set the property permanently. For a one-time setting before running the design tool you can use the command line:

```
 C:\> set VLINGO_XOOM_DESIGNER_HOME=[installation-path]
```

Additionally, on \*nix systems, it is necessary to set *read* and *execute* access on executable shell script that is within root installation directory:

```
 $ chmod 755 xoom
```

Verify that the setup was successful by requesting the XOOM Designer version. On \*nix use the `xoom` shell script to run the XOOM Designer:

```
 $ ./xoom -version
 1.7.0
```

On Windows do the same, which uses `xoom.bat` to execute the XOOM Designer software:

```
C:\> xoom -version
```

Once running, the XOOM Designer presents a web UI that guides you intuitively. If you require more details on some aspect of the Designer, see the [full details in a later chapter](/xoom-designer).

### Source Code and Deployable Artifacts

From the XOOM Designer you will generate your project source, including compressed Ports and Adapters architecture, domain model, and build. See the resulting source code. You will find, for example, that the Maven `pom.xml` already references the XOOM libraries needed to support the build and runtime execution of the microservice. The build is ready to run.

Before building and running, assuming that you are using databases/storage other than in-memory implementations, edit your `xoom-turbo.properties` file to support the proper database connections. Defaults are generated for databases such as Postgres and MariaDB, and others, but these might not match your local environment. Additionally, if your microservice is event driven and receives incoming event messages or produces outgoing event messages, specify the proper connection configurations for your message broker/bus in the same properties file, namely`xoom-turbo.properties`.

The following example assumes that your first XOOM Designer project is a microservice that you gave the name `my-xoom-microservice`, which has an initial version `0.1.0`.&#x20;

To build and run on \*nix do the following:

```
$ mvn clean package
...
$ java -jar target/my-xoom-microservice-0.1.0
...
```

To build and run on Windows do the following:

```
C:\> mvn clean package
...
C:\> java -jar target\my-xoom-microservice-0.1.0
...
```

The service is now running. You can use `curl` or *Postman* to send HTTP request messages to the service according to your REST API design.

## Using Artifacts—Development Without XOOM Designer

As noted above, the XOOM Designer generates the basic build definition for a new microservice (or larger application) so that it is ready to run. The Maven `pom.xml` already references and includes all of the XOOM library dependencies needed in order to build and run the microservice.

If you are not starting with the advantage of using XOOM Designer to create your initial project, you will need to pick and choose the XOOM library artifacts on your own. The artifacts for the Java Development Kit are available as `jar` files from three primary public repositories [GitHub](https://github.com/vlingo), [Sonatype](https://oss.sonatype.org/#nexus-search;quick~xoom-), and [Maven Central](https://search.maven.org/search?q=vlingo).

{% hint style="info" %}
Our platform CI builds are performed on [Github](https://github.com/vlingo) Actions, and GitHub is also our base artifacts repository. When we create a release we replicate the GitHub artifacts to Sonatype, which in turn automatically replicates to Maven Central.

We also support daily `SNAPSHOT` builds on Github. If you want to use the latest code you may reference it as `artifactId-x.y.z-SNAPSHOT`. You must provide Github credentials to Maven in order to pull snapshots.

See below for details.
{% endhint %}

You may use any number of build tools to retrieve the JAR files that you need for a project. We generally recommend using either Maven or Gradle. You can include the following in your Maven `pom.xml` file to reference the XOOM Turbo toolkit:

```
...
  <repositories>
    <repository>
      <id>central</id>
      <url>http://repo1.maven.org/maven2/</url>
    </repository>
  </repositories>
  <dependencies>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-turbo</artifactId>
      <version>x.y.z</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
...
```

Depending on the selected dependency, you can get a number of separate dependencies that are resolved by a single `jar` file. For example, `xoom-turbo` references other libraries such as `xoom-lattice`, `xoom-http`, `xoom-actors`, and others. In other words, you need only reference `xoom-turbo` as a dependency and all others required will be resolved automatically.

The release and snapshot repositories are available as follows.

```
...
  </repositories>
      <repository>
      <id>github</id>
      <url>https://maven.pkg.github.com/vlingo/xoom-platform</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>github</id>
      <url>https://maven.pkg.github.com/vlingo/xoom-platform</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
...
  <dependencies>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-turbo</artifactId>
      <version>1.7.1-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
...
```

For use with Gradle you will need something like the following. Refer to the above Maven `pom.xml` for the location of our snapshots.

```
dependencies {
    compile 'io.vlingo.xoom:xoom-turbo:x.y.z'
}

repositories {
    jcenter()
    // or
    mavenCentral()
    // ??? GitHub how-to
}
```

Of course the `x.y.z` is representative placeholder of the semantic version number of the given artifact. Both stable releases and daily snapshot builds are provided on [Sonatype](https://oss.sonatype.org/#nexus-search;quick~vlingo), and release artifacts are hosted by [Maven Central](https://search.maven.org/search?q=vlingo). Generally the tip revision of each JAR file listed in the repository is the one that will work together with all others as a whole platform.

Full open source for the Java platform is available on <https://github.com/vlingo>. Our baseline JDK is 1.8, but we have successfully used on JDK 1.14. On GitHub you see each of the components that are available, and the above dependency information applies to each of the platform components, but you must supply the actual component name. We maintain version numbers consistent across the entire platform, such that if version `1.7.0` applies to `xoom-turbo` then it also applies to `xoom-lattice` and the remaining platform components. The following is an example that uses platform version `1.7.0`, but the version should be adjusted to your specific dependencies.

```
...
  <dependencies>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-turbo</artifactId>
      <version>1.7.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-lattice</artifactId>
      <version>1.7.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-http</artifactId>
      <version>1.4.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-symbio</artifactId>
      <version>1.7.0</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
...
```

Or as an alternative to including several individual components, you can use all of the above by creating a single dependency:

```
...
  <dependencies>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-turbo</artifactId>
      <version>1.7.0</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
...
```

There, that was simple.

## Support, Training, Consulting, and Project Development

Our VLINGO XOOM [enterprise-grade developer and production support are available here](https://vlingo.io/services/).

Our team offers [live, virtual training](https://kalele.io/live-training/rddd/) for the VLINGO XOOM platform SDK. [Consulting and project development are also available through our consulting partners](https://kalele.io/consulting/). When you engage with our team you receive the best possible guidance and workforce available for Reactive architecture, software development, [DOMA](https://kalele.io/live-training/iddd-2/), and [Domain-Driven Design](https://kalele.io/live-training/iddd-2/).

## Documentation and Examples

You have already found our primary platform SDK documentation. You are reading it.

Our full Javadoc is available [here](https://javadoc.io/doc/io.vlingo). Individual components are accessible, such as [the actors Javadoc](https://javadoc.io/doc/io.vlingo/vlingo-actors/latest/index.html). You can even change to the old releases by using the version dropdown. The `README.md` for each open source artifact also references the current API-based Javadoc. For an example see the [`vlingo-actors README.md`](https://github.com/vlingo/vlingo-actors).

Architecture and programming sample projects  are available in source form in the [vlingo-examples repo](https://github.com/vlingo/vlingo-examples). There are several projects. Within them you will find highlights of usage for various platform components. Some are generated by XOOM Designer and some are implemented with full manually written source code. This gives you a feel for both approaches.

Public support is available. You may register for access to our [public Slack workspace](https://join.slack.com/t/vlingoplatfor-i6o3730/shared_invite/zt-bv6chhpw-u7s4kqb1qvVvVMUUH3wqng) for both Java and .NET.

Follow us on Twitter [@vlingo\_io](https://twitter.com/vlingo_io).


# Hello, World!

The obligatory "Hello, World!", but it's a pretty cool design and implementation that you will really love. That's because it's a service that demonstrates the reactive platform components.

## Your First Program

The `xoom-helloworld` example is a pinned repository on our [GitHub VLINGO organization](https://github.com/vlingo/vlingo-helloworld). To use to it learn, first clone the repository and build the project. Open a console/command window so you can build the `xoom-helloworld` artifact and start it by executing the built `jar` file.

{% hint style="info" %}
Note that snapshot artifacts are hosted on GitHub, which requires credentials to be provided to Maven by way of it's `~/.m2/settings.xml`. This is [explained in more detail and with an example here](/getting-started).
{% endhint %}

```
$ git clone https://github.com/vlingo/xoom-helloworld.git
...
$ cd xoom-helloworld
$ mvn package
...
java -jar target/xoom-helloworld-withdeps.jar
...
$ 
```

The above `java` command executes the `jar` on the default port `18080`. If you would like to use a different port, you must provide it on the command line. This command uses port `8080`.

```
$ java -jar target/xoom-helloworld.jar 8080
```

The following examples assume that you have started the service with the default port, `18080`.

There are two resources, each with multiple endpoints. These are discussed next.

### Hello Resource

The first resource is used to get `"Hello, World!"` and similar messages.

You may `curl` with `GET` methods on the following resources.

```
$ curl -i -X GET http://localhost:18080/hello
```

The above `curl` responds with `200 OK` and the content body entity `"Hello, World!"`

You may also provide a path parameter to indicate to whom the service should say `"Hello"`. The second example responds with `200 OK` and the content body entity `"Hello, Me!"`

```
$ curl -i -X GET http://localhost:18080/hello/Me
```

In this Hello resource example there is only one component involved,[`io.vlingo.xoom.hello.infra.resource.HelloResource`](https://github.com/vlingo/xoom-helloworld/blob/master/src/main/java/io/vlingo/xoom/hello/infra/resource/HelloResource.java).

### Greeting Resource

The second resource is a bit more involved, and is used to maintain any number of `Greeting` messages. These greetings have the following data associated with them.

* `id`: a unique identity
* `message`: a text message
* `messageChangedCount`: the number of times the message text has changed since first being defined
* `description`: a text description of the message
* `descriptionChangedCount`: the number of times the description text has changed since first being defined

The first operation used is to define a new `Greeting`. To do so you `POST` a `JSON` object to the `/greetings` URI.

```
$ curl -i -X POST -H "Content-Type: application/json" -d '{"id":"","message":"Hey","messageChangedCount":"0","description":"Says Hey","descriptionChangedCount":"0" }' http://localhost:18080/greetings
```

The resource will respond with (only the id could be different):

```
HTTP/1.1 201 Created
Location: /greetings/242
Content-Length: 105

{"id":"242","message":"Hey","messageChangedCount":0,"description":"Says Hey","descriptionChangedCount":0}
```

Following this you may query the new `Greeting`. The `Location` of the new `Greeting` resource is `/greetings/{someId}`. Let's `GET` that resource.

```
$ curl -i -X GET http://localhost:18080/greetings/242
```

You should see the following:

```
HTTP/1.1 200 OK
Content-Length: 105

{"id":"242","message":"Hey","messageChangedCount":0,"description":"Says Hey","descriptionChangedCount":0}
```

Next `PATCH` the `Greeting` resource's `message`.

```
$ curl -i -X PATCH -H "Content-Type: application/json" -d '{"value":"Yo"}' http://localhost:18080/greetings/242/message
```

The resource responds with the following. Note that the `message` has changed to `"Yo"`, and the `messageChangedCount` is now `1`. Also notice that the `description` and the `descriptionChangedCount` remain unchanged.

```
HTTP/1.1 200 OK
Content-Length: 104

{"id":"242","message":"Yo","messageChangedCount":1,"description":"Says Hey","descriptionChangedCount":0}
```

Next `PATCH` the `Greeting` resource's `description`.

```
$ curl -i -X PATCH -H "Content-Type: application/json" -d '{"value":"Says Yo"}' http://localhost:18080/greetings/242/description
```

The resource responds with the following. Note that the `description` has changed to `"Says Yo"`, and the `descriptionChangedCount` is now `1`.

```
HTTP/1.1 200 OK
Content-Length: 103

{"id":"242","message":"Yo","messageChangedCount":1,"description":"Says Yo","descriptionChangedCount":1}
```

Now both the `message` and the `description` and the corresponding counts have all changed.

In this `Greeting` resource example there are various component sets involved. See the following source code.

```
io.vlingo.xoom.hello.Bootstrap

io.vlingo.xoom.hello.resource.GreetingResource

io.vlingo.xoom.hello.model.Greeting
io.vlingo.xoom.hello.model.GreetingEntity
io.vlingo.xoom.hello.model.GreetingState

io.vlingo.xoom.hello.infra.persistence.GreetingProjectionActor

io.vlingo.xoom.hello.infra.persistence.Queries
io.vlingo.xoom.hello.infra.persistence.QueriesActor

io.vlingo.xoom.hello.infra.persistence.* - lower-level persistence setup and storage access
```

Documentation for the above components is found in the following links.

[Starting the World](https://docs.vlingo.io/vlingo-actors#starting-and-terminating-the-actor-runtime)

[CQRS Command and Query Models](https://docs.vlingo.io/vlingo-lattice/entity-cqrs)

[StatefulEntity](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#statefulentity-example)

[StateStore Persistence](https://docs.vlingo.io/vlingo-symbio/state-storage)

[Query Model Projections](https://docs.vlingo.io/vlingo-lattice/projections)

[Reactive Storage](https://docs.vlingo.io/vlingo-symbio)


# Architecture

Learn about the VLINGO XOOM architecture for building DOMA- and DDD-based microservices.

The VLINGO XOOM platform is built fully on a highly concurrent, reactive, message-driven foundation. The bedrock of the platform is actor-based using [XOOM Actors](/xoom-actors), but is made extremely simple and with rapid delivery with a service-based *Compressed Architecture* and the [XOOM Turbo container](/xoom-turbo) and [Designer](/xoom-designer) acceleration tools. This foundation implements the Actor Model of computation. All other platform components are actor-based. Thus, it's appropriate to first discuss the architecture of the actor-based, message-driven runtime.

## Message-Driven Runtime

The Actor Model provides an outstanding, non-leaky, abstraction of concurrency. Given that your hardware supports multiple cores, and even many cores, you can expect tremendous levels of parallelism among many actors that carry out application-level service requests.

The major architectural abstractions of the [XOOM Actors](/xoom-actors) Actor Model toolkit are:

* `World`: This is the container abstraction within which actors live and operate. A `World` can have a number of `Stage` instances in which the life cycles of a subset of live actors are managed. When the `World` is started, actors can be created. When the `World` terminates, all `Stage` and `Actor` instances are terminated/stopped.
* `Stage`: Every `World` has at least one `Stage`, known as the default. The `Stage` is specifically where actors are managed and within which they play or execute. There may be multiple `Stage` instances, each with several or many actors (even millions) under its management. Each `Stage` has an internal `Directory` within which live actors are held, and through which they can be found.
* `Actor`: Each actor is an object, but one that reacts to incoming asynchronous messages, and that sends outgoing messages asynchronously. Each actor is assigned a `Mailbox`, and a `Mailbox` delivers messages though a `Dispatcher`. When the actor receives a message, it performs some business behavior internally, and then completes that specific message-handling context. All actors are type safe in that their behaviors are defined by Java method signatures rather than arbitrary object types. Every actor may implement any (practical) number of behavioral interfaces, known as actor protocols.
* `Supervisor`: A recent account of cascading failure describes tens of thousands of nodes lost during a Kafka failure that caused a Kubernetes cluster to self destruct, taking out an entire infrastructure. Using supervision as bulkheads can save your system from catastrophic failure. Actors are supervised in order to deal with failure. When an actor experiences an exception while handling a message, the exception is caught by the message dispatcher and is relayed to the actor’s supervisor as a message. When received by the supervisor, the exceptional message is interpreted to determine the appropriate step to correct the actor’s problem. The corrective action can be one of the following: *resume,* *restart,* *stop,* or *escalate.* In the case of supervision escalation, the exceptional message is relayed to this supervisor’s supervisor, for it to take some action. There are four kinds of supervision: *direct parent,* *default public root,* *override of public root,* and *registered common supervisors* for specific actor protocols (behavioral interfaces).
* `Scheduler`: Each `Stage` has a scheduler that can be used to schedule future tasks, and that may be repeated on time intervals. An actor determines the timeframe that is needed, and each occasion on which the interval is reached, the actor receives an interval signal message indicating that it is time to perform some task. The receiving actor can then execute some necessary behavior in response to the interval signal. The actor that creates the scheduled task need not be the target actor of the interval signal message.
* `Logger`: Logging capabilities are provided to every actor, and different loggers may be assigned to different actors. Log output occurs asynchronously because loggers are run as actors.
* Plugins: The VLINGO XOOM platform in general, and XOOM Actors specifically, support a plugin architecture. New kinds of plugins can be created at any time to extend the features of vlingo/actors, and any other platform component. In particular, mailboxes and dispatchers, supervision, and logging can be extended via plugins.
* Testkit: There is a very simple *testkit* that accompanies XOOM Actors, making it quite easy to test individual and collaborating actors for adherence to protocol and for correctness.

The following is a XOOM Actors architecture diagram.

![The general architecture of a XOOM Actors World with multiple Stages.](/files/-M9H6mN_fDOdJsXTpsIx)

The components seen in this diagram can be traced back to the above names and descriptions. In the default `Stage` notice that there are three special actors, one that is **{bright yellow}** with a **#**, one that is **{bright yellow**} with a **\***, and one that is **{red}** with an **X**. Respectively, these are:

**#** The *`private root actor`,* which is the parent of the *public root actor* and the *dead letters actor*

**\*** The *`public root actor,`* which is the default parent and supervisor if no others are specified

**X** The *`dead letters actor`,* which receives actor messages that could not be delivered

### Actor Proxy

An important architectural design feature is the *actor proxy.* This supports type-safe, asynchronous message sending to an actor per a protocol (interface) that it implements.

Every actor must support at least one protocol. Here the `Proposal` protocol is used. It is unimportant exactly what behavior the `Proposal` supports, but you can imagine some sort of description that serves to propose something, such as a job or an expensive product purchase. Further, let's say that the actor that implements the `Proposal` protocol is named `ProposalActor`.

```java
World world = World.startWithDefaults("Proposals");
...
Proposal proposal = world.actorFor(Proposal.class, ProposalActor.class);
```

When a client component creates a `Proposal` as an actor through the `World` or a `Stage`, their are two parts that are created. One part is an instantiation of the `ProposalActor` itself. The created second part is a *proxy* instance, which also implements the `Proposal` protocol. When the answer from the actor creation is given to the client, it is the `Proposal` that is backed by the proxy implementation. In other words, in the above code, the proxy is the `Proposal proposal` instance returned from `World#actorFor()`. Internally the `Proposal` proxy knows how to send messages asynchronously to the `ProposalActor` instance. The `ProposalActor` exists in memory, and any component that has its `Proposal` proxy instance may send asynchronous messages to it.

The following are facts about how the proxy and actor instances interact.

* A client invokes methods on the `Proposal` proxy, never directly on the `ProposalActor`
* The proxy reifies the method invocation into a message. To do so the proxy uses the parameters (if any) and creates a `java.util.function.Consumer` that holds the intention to invoke the actual method with any parameters on the `ProposalActor` instance
* The `Consumer` is wrapped in a `io.vlingo.xoom.actors.Message`, which when sent within the local JVM, is implemented by `LocalMessage` of the same package
* The `Message` containing the `Consumer` is queued to the actor's `Mailbox`, which causes the scheduling of the message for delivery
* Once the new `Message` is queued in the actor's `Mailbox`, the proxy invocation returns to the client
* When a thread becomes available, the `Message` is polled from the `Mailbox` and dispatched to the `ProposalActor`
* The above points describe how asynchronous type-safe messages are sent and delivered

Specifically for the `Proposal` protocol, the following describes how proxy classes are created.

* When a client creates a new `Proposal` using `actorFor(protocol, actorType[, args...])`, internally the XOOM Actors queries for a class named `Proposal__Proxy`
* If it does not yet exist, XOOM Actors dynamically generates the `Proposal__Proxy.java`, compiles it, and loads it into its private class loader
* The `Stage` can now create instances of the `Proposal__Proxy`
* When `actorFor(protocol, actorType[, args...])` is used, XOOM Actors actually returns a new instance of `Proposal__Proxy` which implements `Proposal`

Next, the [XOOM Cluster](/xoom-cluster) is discussed, and following that there are comments on the overall platform architecture.

## Scale and Resilience with the Multi-Node Cluster Architecture

The [XOOM Cluster](/xoom-cluster) is a key component that sits on top of XOOM Actors, to support the development of scalable and fault-tolerant tools and applications. A number of additional tools building out the VLINGO Xoom platform are built on top of XOOM Cluster. The XOOM Lattice grid is built on the XOOM Cluster, and your applications and microservices will run on XOOM Lattice. This, all cluster properties also apply to the grid.

Generally a cluster will be composed of multiple nodes of an odd number (not just one, but for example, 3, 5, 21, or 127). The reason for choosing an odd number of nodes is to make it possible to determine whether there is a quorum of nodes (`totalNodes / 2 + 1`) that can form a healthy cluster. Choosing an even number of nodes works, but in that case, when loosing one node, it doesn’t improve the quorum determination, nor does it strengthen the cluster when all nodes are available.

When a quorum of nodes are available and communicating with one another, a leader is elected. The leader is responsible for making certain decisions in behalf of the cluster, and also announces newly joined nodes and those that have left the cluster.

{% hint style="info" %}
The cluster consensus protocol is one known by the name *Bully Algorithm.* Although an unpleasant name, the protocol is simple but powerful. This consensus protocol chooses a leader by determining the node with the "greatest id value." The identity may be numeric or alphanumeric. If numeric the "greatest node id" is determined with numeric comparisons. If alphanumeric, the "greatest node id" is determined lexicographically. Any node that senses that the previous leader has been lost (left the cluster for any reason), messages the other known "nodes with greater ids" asking for an election to take place. Any "nodes with greater ids" tell the "lesser id node" that it will not be the leader. Finally when there are no nodes of "greater id" than a given node--known because it receives no "you aren't the leader" messages--that "greatest id node" declares itself leader. In essence the "node of the greatest id" bullies its way into the leadership position, asserting that it is currently greatest. Any latent message received from a "node of even greater id" than the current declared leader will not take leadership away from it, because it is a healthy leader node.

It's possible that our consensus protocol will be augmented in the future with the *Gossip Protocol* to support very large clusters. We also have the option to swap out the *Bully Algorithm* for another, or to provide multiple consensus strategies.
{% endhint %}

The XOOM Cluster works in full-duplex mode, with two kinds of cluster node communication channels. There are the operational channels, which the cluster nodes use to maintain the health of the cluster. There are also application channels, which the services/applications use to pass messages between nodes. Using two different channel types allows for tuning each type in different ways. For example, application channels may be assigned to a faster network than the operational channels. It also opens the possibility for either channel type to use TCP or UDP independently of the other channel type.

Besides scalable fault-tolerance, the XOOM Cluster also provides cluster-wide, synchronizing attributes of name-value pairs. This enables the cluster to share live and mutating operational state among all nodes. Likewise, application-level services can also make use of cluster-wide, synchronizing attributes in order to enhance shared application/service values.

The following diagram shows a three-node XOOM Cluster.

![The XOOM Cluster is build on the XOOM Actors reactive runtime.](/files/-M9HABxHuQEtoli1JN0U)

The cluster depicted here is composed of three nodes. If one node is lost the cluster will still maintain a quorum. However, if two nodes are lost and only one node remains in a running, healthy state, the quorum is lost and the cluster as a whole is considered unhealthy. In that case the one remaining node goes into idle state and awaits one or more of the other nodes to return to a healthy operational state, which will again constitute a quorum and enable a healthy running cluster. A leader is elected using the cluster consensus protocol.

### Inter-Node Messaging

Each cluster member maintains communication with the others by means of an *operational channel.* Over this channel is sent cluster node health information and notifications of nodes joining and leaving the cluster. When a leader is elected, whether when the cluster first starts or when a leader node leaves the cluster, the election and final declaration of leadership are announced over the operational channel. At appropriate times the leader sends cluster directory messages to all nodes so that each node can be aware of all other available nodes.

There is a second kind of channel on each cluster node, the *application channel.* This channel is used strictly for application-level messages, those between actors that reside on different nodes. There are benefits to separating operational and application messages. Potentially the traffic of each channel could be separated by different networks and use different protocols. For example, the operational channels could be on a slower network because operational messages are fewer and relatively infrequent. The application channel, on the other hand, may need to transport many millions of messages over short timeframes, and thus may require a faster network than the operational one. Further, the protocol used for application channel messages could be different; one having the capacity for much higher throughput.

The actor-to-actor cross-cluster messaging is provided by [XOOM Lattice](/xoom-lattice) components. The components include those for Reactive Domain-Oriented Microservices Architecture (DOMA) and Domain-Driven Design (DDD) projects, featuring highly concurrent models. The tools include compute grid, actor/object caching, object spaces, cross-node cluster messaging, object aggregates, state aggregates, event sourced aggregates, CQRS with projections, messaging exchanges, and long-running processes (aka Sagas).

### Cluster Configuration

Using file-based cluster configuration, this defines the nodes of a three-node cluster, each with a unique `op` or operations `port` and `app` or application `port`.

```
node.accounts1.id = 1
node.accounts1.name = accounts1
node.accounts1.host = accounts-svr1
node.accounts1.op.port = 37371
node.accounts1.app.port = 37372

node.accounts2.id = 2
node.accounts2.name = accounts2
node.accounts2.host = accounts-svr2
node.accounts2.op.port = 37371
node.accounts2.app.port = 37372

# highest id, default leader
node.accounts3.id = 3
node.accounts3.name = accounts3
node.accounts3.host = accounts-svr3
node.accounts3.op.port = 37371
node.accounts3.app.port = 37372
```

When one node connects with another node, it opens a connection on both its operational and application channels. These channels facilitate only unidirectional communication. In other words, when a node receives a message on its incoming operational channel, it does not send an outgoing response to the originating node on that same bidirectional channel. Instead, the responding node uses the operational channel of the client node that originated the message. The directory messages circulated by the cluster leader contain the operational and application address information for each node in the cluster.

### Cluster-Wide Attributes

The XOOM Cluster component also provides cluster-wide, synchronizing attributes. This enables the cluster to share live and mutating operational state among all nodes. These attributes may be operational in nature, or application attributes. Either way, the creation, modification, and removal of an attribute is handled over the operational channel (see previous section). Each attribute has a `name`, any supported simple `datatype` such as `String`, `Boolean`, `Integer`, `Double`, etc., and a `value`.&#x20;

Any time that a new attribute is created, or when its value is modified, or when it is deleted, the operation is made known to all live cluster nodes, allowing them to synchronize. The attribute operational protocol includes configurable retries, and any node to newly join the cluster is informed of all current live attributes, and then will be included in ongoing activity notifications.

## Platform Architecture

The overall platform architecture includes any number of nodes, between 1 and N. If there is more than one node, it is recommended to use the [XOOM Cluster](/architecture#scale-and-resilience-with-the-multi-node-cluster-architecture) (above). Each node, whether one or many as illustrated in the above cluster topography, may use an array of VLINGO XOOM platform components.

![The commonly used VLINGO XOOM components of a single node.](/files/-M9CMkpHdPL-JqKoHAIh)

In addition to those pictured here, additional components include the [XOOM Directory](/xoom-directory) for service registration and discovery, and the [XOOM Schemata](/xoom-schemata) schema registry.

Each of these components are covered throughout this documentation, most of which may be perused in the [Quick Reference](/overview/quick-reference) or the sidebar Table of Contents.


# XOOM Cloud

Use the VLINGO XOOM platform optimized for cloud-based microservices architecture.

XOOM Cloud provides the means to run applications built with [XOOM Platform](https://github.com/vlingo/) and [XOOM Cluster](https://github.com/vlingo/xoom-cluster) in the cloud with most of the cloud integration work done for you. At this time we support the [Amazon Cloud Services](https://aws.amazon.com/) cloud provider. The following documents are provided to explain the use of XOOM Cloud, and should be consumed in the order shown:

1. [AWS Infrastructure](/xoom-cloud/aws-infrastructure)
2. [XOOM Cloud Operator](/xoom-cloud/xoom-cloud-operator)
3. [XOOM Cloud Demo](/xoom-cloud/xoom-cloud-demo)

Running your reactive services or application on the cloud is only moments away.


# AWS Infrastructure

Describes the steps necessary to provision and decommission AWS Infrastructure for XOOM Cloud

## Prerequisite Tools

It is helpful to have prior knowledge of Kubernetes (and kubectl), AWS Command Line Interface (CLI), Amazon EKS, AWS IAM, HELM, HELM, and YAML.

Throughout this documentation `123456789012` has been used as an example of an AWS Account Id. Please replace it with your AWS Account Id.

### Kubernetes and kubectl

To use XOOM Cloud you will need to install some tools. The following provides the most common options.

This is the installation guide for `kubectl`:

* [https://kubernetes.io/docs/tasks/tools](https://kubernetes.io/docs/tasks/tools/)

As an alternative, Docker Desktop (free for small businesses) can be used as well. It provides a Kubernetes development environment and comes together with `kubectl` command. Here are the installation instructions for Docker Desktop:

* <https://www.docker.com/products/docker-desktop>

### AWS Command Line Interface (CLI)

This is the installation guide for `aws` command line tool:

* [https://aws.amazon.com/cli](https://aws.amazon.com/cli/)

It is recommended that you install **v2** of the AWS CLI. Configure this tool by running:

```
$ aws configure
```

### Amazon EKS

You will use EKS, the Amazon Elastic Kubernetes Service. See the documentation for EKS:

* &#x20;[https://aws.amazon.com/eks](https://aws.amazon.com/eks/)

See also the Installation guide for the `eksctl` command line tool:

* <https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html>

### AWS IAM

There will be some use of the AWS IAM, the Identity and Access Management components. You will find the documentation here:

* <https://aws.amazon.com/iam/>

### HELM

HELM is a package manager for Kubernetes. To installation the tool, see the quite-start guide for the `helm` command line tool:

* [https://helm.sh/docs/intro/quickstart](https://helm.sh/docs/intro/quickstart/)

## Kubernetes Cluster

You will create a Kubernetes Cluster to deploy an application built with [XOOM Platform SDK](https://github.com/vlingo) and XOOM Cloud product. The following ins an example using the [XOOM Cloud Demo](/xoom-cloud/xoom-cloud-demo):

```
eksctl create cluster \
  --name xoom-cloud-demo \
  --version 1.23 \
  --region us-east-1 \
  --nodegroup-name xoom-cloud-demo-nodes \
  --node-type t2.large \
  --nodes 2 \
  --nodes-min 1 \
  --nodes-max 2 \
  --with-oidc \
  --managed
```

Please replace `xoom-cloud-demo` and `us-east-1` values with the ones most appropriate for your service or application. Note that the creation of a Kubernetes Cluster requires approximately *30 minutes.*

To decommission the cluster, use the following command, which is also parameterized with the `xoom-cloud-demo` that must be replaced with your service or application name:

```
eksctl delete cluster --name xoom-cloud-demo --region us-east-1
```

## AWS IAM

The XOOM Cloud Operator requires a Kubernetes Service Account with IAM roles in order to access Amazon Marketplace Metering API.

### IAM Policy

Create an AWS IAM policy:

```
aws iam create-policy \
  --policy-name XoomCloudPodPolicy \
  --policy-document file://xoom-cloud-pod-policy.json
```

Content for `xoom-cloud-pod-policy.json`:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "aws-marketplace:RegisterUsage"
            ],
            "Resource": "*"
        }
    ]
}
```

The command will output policy information including policy ARN. Please save this ARN. You will need it at the next step.

Alternatively, you can check the policies by running the following command and save `XoomCloudPodPolicy` policy ARN for later usage:

```
aws iam list-policies --scope Local
```

The policy's ARN looks like this:

```
arn:aws:iam::123456789012:policy/XoomCloudPodPolicy
```

Policy decommission command:

```
aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/XoomCloudPodPolicy
```

### Service Account for Kubernetes

Create a Kubernetes IAM Service Account:

```
eksctl create iamserviceaccount \
  --name xoom-cloud-service-account \
  --namespace xoom \
  --cluster xoom-cloud-demo \
  --attach-policy-arn arn:aws:iam::123456789012:policy/XoomCloudPodPolicy \
  --approve \
  --override-existing-serviceaccounts \
  --region us-east-1
```

The following is a service account decommission command:

```
eksctl delete iamserviceaccount  \
  --name xoom-cloud-service-account \
  --namespace xoom \
  --cluster xoom-cloud-demo \
  --region us-east-1
```

{% hint style="info" %}
The name `xoom-cloud-service-account` must not be changed because it is used by XOOM Cloud HELM Chart.
{% endhint %}


# XOOM Cloud Operator

Describes the installation of XOOM Cloud Operator

The XOOM Cloud Operator runs and monitors applications built with [XOOM Platform](https://github.com/vlingo) and [XOOM Cluster](https://github.com/vlingo/xoom-cluster) on Kubernetes. It also cares for the AWS-required integration with the AWS Marketplace.

## Prerequisites

Subscribe to **VLINGO XOOM Cloud** product on [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-we6f7e5nm5y5s).

All of the steps described in our XOOM Cloud [AWS Infrastructure](/xoom-cloud/aws-infrastructure) documentation must be completed.

## Install XOOM Cloud Operator

The XOOM Cloud Operator is deployed as HELM Chart hosted by the `xoom-cloud` AWS Marketplace repository.

Since HELM Chart support is still an experimental feature of ECR repositories, it must be enabled explicitly:

```
export HELM_EXPERIMENTAL_OCI=1
```

Log in to AWS Marketplace registry:

```
aws ecr get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin 709825985650.dkr.ecr.us-east-1.amazonaws.com
```

Pull the `xoom-cloud` HELM Chart locally. Replace `<version>` with a valid value. We recommend you to choose the latest version published on [VLINGO XOOM Cloud product page](https://aws.amazon.com/marketplace/pp/prodview-we6f7e5nm5y5s).

```
helm pull oci://709825985650.dkr.ecr.us-east-1.amazonaws.com/vlingo/xoom-cloud --version <version>
```

Install `xoom-cloud` along with the Operator. Replace `<version>` with a valid value.

```
helm install xoom-cloud ./xoom-cloud-<version>.tgz -n xoom --create-namespace
```

To decommission the `xoom-cloud` HELM Chart, use the following command.

```
helm uninstall xoom-cloud -n xoom
```


# XOOM Cloud Demo

Describes the installation of XOOM Cloud Demo application

This demo showcases the use of the **VLINGO XOOM Cloud** product that is published on the AWS Marketplace.

For convenience, a Docker image with this application is published automatically to `xoom-cloud-demo`, which is the VLINGO public repository for AWS. In practice, the application has to be built, packaged, and deployed using the your own AWS ECR repository.

## Prerequisites

All the steps described in the XOOM Cloud [AWS Infrastructure](/xoom-cloud/aws-infrastructure) and [XOOM Cloud Operator](/xoom-cloud/xoom-cloud-operator) documentation must be completed before using this demo.

## Get the Demo Application

Clone the XOOM Cloud Platform repository that is hosted on GitHub. It contains the demo application.

* <https://github.com/vlingo/xoom-cloud-platform>

## Run the Demo Application

To run the XOOM Cloud Demo application, use the following command.

```
kubectl create -f aws-demo/nodes.yml
```

You may decommission the demo application as follows.

```
kubectl delete -f aws-demo/nodes.yml
```


# XOOM Designer

The visual model designer for DOMA, DDD, and compressed Ports and Adapters architecture providing low-code project delivery for the VLINGO XOOM platform.

## Introduction

Welcome to the VLINGO XOOM Designer!

You are in the right place if you are interested in accelerating your learning and application of Domain-Driven Design, Microservices Architecture, as well as Reactive Architecture and Reactive Programming. These approaches have proven to be a strong foundation for building modern services, applications, and systems that are robust, modularized, scalable, and that use modern architectures.

Accelerate your learning and use of DDD and Microservices with XOOM Designer.

To accelerate learning and the use of these approaches to software development you need some very direct instruction and to employ opinionated tooling. That's why we provide the XOOM Designer and the overall XOOM platform SDK.

Our bottom line: We want you to succeed!

The VLINGO XOOM platform was created to help you and your fellow software developers to confidently move forward and modernize their skills and the systems that are developed by you and your teams. With the XOOM Designer you can greatly accelerate development of business modernization efforts. Just look at what you can do with XOOM Designer:

* Use visual modeling to define your services, applications, and systems
* Create a compressed Ports and Adapters (i.e. Clean) Architecture that includes
  * REST API
  * Domain Model&#x20;
  * Persistence
  * Messaging
  * Container Configurations (native, Docker, and Kubernetes)
* You get DOMA and DDD patterns support with no additional effort
* Generate and immediately build and run your design

### **Design and Run Your Services and Applications Within Minutes**

You are learning some advanced software development approaches, techniques, and architectures and you have limited time. Consider the potential of applying the following rapidly, rather than taking months or years to absorb all the details:

* Domain-Driven Design (DDD)
* Domain-Oriented Microservices Architecture (DOMA)
* Microservices Architecture
* Reactive Architecture and Programming

If you or your team face a steep learning curve, don't give up and fall back to familiar, yet outdated, frameworks and tools. Let XOOM Designer help.

![The XOOM Designer provides modeling tools to rapidly deliver software solutions.](/files/-M_-F0e91qOiTHTveetz)

The VLINGO XOOM platform was created to help you and your fellow software developers who face such challenges to confidently move forward and modernize their skills and the systems that are developed by you and your teams. One platform component that greatly accelerates developer modernization efforts is the XOOM Designe&#x72;*.* Our Designer supports visual model definition, along with a compressed Ports and Adapters architecture that includes REST API, persistence, and container definitions. Following design, your DOMA and DDD project is generated and immediately built. Your applications and microservices can be running within minutes.

Here's how simple it is to create a new Bounded Context with Reactive, Event-Driven, and Microservice Architectures:

1. Select a Programming Language and Platform (currently Java only)
2. Define your top-level Bounded Context name and module
3. Visually design Aggregates, even with Value Objects, collections, and Domain Events
4. Choose persistence type options, including Event Sourcing, Key-Value, and CQRS
5. Specify how your Bounded Context will be deployed
6. Select code generation options and generate your entire architecture and domain model

With instantly executable microservices and applications, you and your teams are in a position to quickly implement custom business logic within the pre-generated model as you take over and employ a full software development life-cycle. The XOOM Designer can be used to rapidly generate alternative models so teams can experiment with DOMA and DDD results. This is also a great way to learn Microservices and Reactive Architecture along with DOMA and DDD. You will learn both DDD strategic and tactical modeling as they are powered by an actor-based ecosystem.

## XOOM Designer Usage Options

Before you can design a model and surrounding architecture with the XOOM Designer, you must gain access to it. The following explains both cloud and local access. There are currently three ways to run XOOM Designer, each is discussed exclusively from the others.

{% hint style="info" %}
XOOM Designer now integrates with [XOOM Schemata](/xoom-schemata) making event and other schema types easier to create and distribute to dependents. You must run Schemata along with XOOM Designer to support the integration.

There is a `docker-compose.yml` that can be used to make starting both tools together. Yet, Docker will start Schemata on your local development computer. If you prefer to [run Schemata on another computer](/xoom-schemata#running-xoom-schemata), such as a team or organizational server, there is no need to start Schemata locally.

See below for custom configuration of [Schemata access](/xoom-designer#xoom-schemata-integration).
{% endhint %}

### Quick Start

&#x20;The quickest way to start XOOM Designer is to run it on Docker. Taking advantage of the `docker-compose` file created by the VLINGO XOOM team, you can initialize Designer simply using these two commands:

```
 $ curl -L -O https://raw.githubusercontent.com/vlingo/xoom-designer/master/docker-compose.yml
 $ docker-compose pull
 $ docker-compose up -d
```

Then, XOOM Designer can be accessed at <http://localhost:19090/context>. When you start XOOM Designer from `docker-compose`, [XOOM Schemata](https://docs.vlingo.io/xoom-schemata) also will be started and initialized, and can be accessed at [http://localhost:9019](http://localhost:9019/). Learn more about the XOOM Designer/Schemata integration [here](https://docs.vlingo.io/xoom-designer#architecture-api-producer-exchange-and-consumer-exchange-s).

#### XOOM Schemata Integration

XOOM Designer integrates directly with XOOM Schemata to define both producer and consumer schema references. We recommend that you use the Docker image for XOOM Schemata. The quickest way to do so is to use the [docker image](https://hub.docker.com/r/vlingo/xoom-schemata) published by the VLINGO XOOM Team:

```bash
docker run -it --rm -eXOOM_ENV=dev -p '9019:9019' vlingo/xoom-schemata
```

**TIP:** When using Docker to run XOOM Designer integrated with XOOM Schemata, name your Schemata container with `--name xoom-schemata` so that you can reference it in Designer-Schemata integration options:

```bash
docker run -it --rm -eXOOM_ENV=dev -p9019:9019 --name xoom-schemata vlingo/xoom-schemata
```

Select the Designer menu OPTIONS, and use the image name as the host.

![Set the Schemata host and port, which will often be remote.](/files/-Mf58G5gBNAUtjyn-YXB)

### Using the XOOM Designer on the Cloud

\[This section will be provided soon.]

### Using a Locally Installed XOOM Designer

To use the Designer on your own development computer requires an installation step. The installation process is short. Before you start, just check if you have these tools already installed:

* Java 8+
* Maven 3.8.1

Download the XOOM Designer compressed distribution file using `curl`.

{% hint style="info" %}
Note that the version examples that follow show a version that is not necessarily current.
{% endhint %}

#### **File type:** `zip`

```
$ curl -L -O https://github.com/vlingo/xoom-designer/releases/download/1.9.0/designer.zip
```

#### **File type:** `tar`

```
$ curl -L -O https://github.com/vlingo/xoom-designer/releases/download/1.9.0/designer.tar
```

Extract the file content, then set an environment variable named `VLINGO_XOOM_DESIGNER_HOME` indicating the absolute path for the uncompressed folder. Additionally, on Unix-based operating systems, it is necessary to enabled *read* and *execute* access on executable script as following:

```
 $ chmod 755 xoom
```

Ensure it's all set by verifying the version:

```
 $ ./xoom -version
 1.9.0
```

The XOOM Designer provides a web/graphical user interface for a rapid application generation. Simply open a terminal window and run the Designer.

```
$ ./xoom gui
```

Following this your preferred browser will open with a wizard-fashioned screen, consisting of five steps.

If you would like to contribute development efforts for the XOOM Designer, there are specific instructions available in the project [README](https://github.com/vlingo/xoom-designer).

The next section shows you how to model with the XOOM Designer. Let's get started!

## Modeling With the XOOM Designer

There are only a few primary steps required to create a new subsystem solution with the XOOM Designer. Remember this this tool provides an opinionated approach to Microservices and Reactive Architectures, which makes it very straightforward to delivery bug-free solutions in record time.

{% hint style="info" %}
In the examples that follow, the source code shown is that generated by the XOOM Designer based on the model information provided by the developer. You will not (currently) see the source code during design mode.
{% endhint %}

### Opinionated Software Modeling

The VLINGO XOOM team considers EventStorming to be a vital activity in the exploration and learning within a software system. Therefore, we have made the XOOM Designer work from the results of EventStorming sessions.

This requires that the EventStorming sessions produce not only a *big-picture* model but also a *design-level* model. The design-level model includes the following:

* Command messages that are to be sent to an instance of an Aggregate type
* The Aggregate types that receive command messages and handle them by performing business rules, emit events, and transitioning the Aggregate's state from previous to new
* Events that are emitted by the Aggregate command handlers

This is depicted in the following EventStorming model:

![An EventStorming session segment of a design-level model.](/files/-M_2y4pzZjx6Yk8lY2Mi)

The EventStorming model indicates that the following model collaborations and outcomes happen:

1. The `Register` command message is sent to the `Investor` Aggregate, which is a new instance and is initialized by handling the `Register` message
2. The `Investor` runs any business rules, validates the command, and applies the new `InvestorRegistered` event
3. An external subsystem, in this case the *Account* (Bounded) *Context,* publishes the `AccountClosed` event which is consumed by the *Investor Context* (the current model context under design)
4. The incoming event is translated to a `Suspend` command that is sent as a command message to the `Investor`
5. The `Investor` accepts the `Suspend` command message, validates it, and applies the new `InvestorSuspended` event

We prepare this EventStorming result for use in our DDD-based model for the *Investor Context,* which is the modeling project that will be created as an example herein. This preparation is done by stacking the EventStorming elements as they are used in the context. This is seen in the following figure:

![Stack the elements of the design-level EventStorming results by Aggregate type.](/files/-M_305tQThWnpMLadRUU)

The `Investor` Aggregate is now the focus of this part of the model. The `Investor` first receives an initializing `Register` command message and emit the `InvestorRegistered` event. Following this, at some point the AccountClosed event is received from the external *Accounts Context,* translated to the `Suspend` command message, and dispatched to the `Investor` Aggregate. The `Investor` subsequently validates the `Suspend` command message and causes the `InvestorSuspended` event to be emitted.

The Aggregate types are arranged for view within the XOOM Designer quite similarly as the `Investor` model element stack in the previous figure. Thus, the slices through each subsystem, or Bounded Context, are appropriately visualized. This is shown in the following figure:

![As EventStorming elements are stacked, the XOOM Designer displays Aggregates similarly.](/files/-M_35Zc8HT4zV4TgI_85)

Corresponding to the above EventStorming model design, we consider that the basic pattern of design should be based on slices through the architecture. We find this to be a clear way to implement use cases. This is how we see an architectural slice:

1. A REST request arrives a resource request handler registered with XOOM HTTP
2. The REST request handler adapts the incoming request to data that can be consumed by the inner domain model and dispatches to an Aggregate by sending it a command message
3. The Aggregate receives the command message, executes and validating domain logic, and assuming the command is valid and accepted, applies a new event and/or state
4. The application of the new event and/or state results in the atomic, transactional persistence of the model elements, and sends a confirmation message to the Aggregate
5. When the persistence confirmation is received by the underlying Aggregate base class implementation, the concrete Aggregate is informed to mutate its state accordingly
6. Simultaneously with step 5, the persistent storage mechanism dispatches the event and/or state to projections that are responsible for creating and updating queryable views and publishing events to a producer exchange

The following are the principles behind the XOOM Designer software model tool.

1. Currently you may model for the Java platform or the .NET platform (available soon).
2. A domain model is the primary focus of the modeling, and the model is designed using DDD tactical modeling tools.
3. All architectural decisions are made to support the domain model, and the architectural mechanisms include the application of the DDD Context Mapping patterns.
4. There are six total modeling steps: Platform (available soon), Context, Aggregates, Persistence, Deployment, and Generation.

The individual steps follow.

### Step 1: Platform

Currently there is no Platform selection step because only the Java platform is available at this time. Soon there will be a Platform selection step. This is the current Platform step.

![Step 1: Select your target programming platform and language.](/files/-MfdtCr3sLCC_voJmnvI)

| Platform Choices | Language Choices; Select One | Current Availability                               |
| ---------------- | ---------------------------- | -------------------------------------------------- |
| JVM              | Java or Kotlin               | JVM with Java available now; Kotlin available soon |
| .NET             | C# or F#                     | .NET with C# available soon                        |

* Kotlin is already supported as a JVM language. XOOM Designer with Kotlin code generation support is under development.
* .NET with C# support will be provided first, followed by F# support.

The Context step is next (and currently the first step).

### Step 2: Context

The Context step defines the Context name with project artifact and service packaging, an opinionated step.

* A Context is provided as a DDD Bounded Context with a Ubiquitous Language. The Ubiquitous Language is expressed as a domain model, such is primarily supported in the Aggregates step.
* For the JVM Platform:
  * ***Group Id**:* Enter the Maven `pom.xml` standard `groupId`. An example of such is `io.vlingo.brokerage`, which will be inserted in the project's `pom.xml` as the following: `<groupdId>io.vlingo.brokerage</groupId>`
  * ***Artifact Id**:* Enter the Maven `pom.xml` standard `artifactId`. An example of such is `investor`, which will be inserted in the project's `pom.xml` as the following: `<artifactId>investor</artifactId>`. This also serves as the name of the Bounded Context, such as *Investor Context.*
  * ***Artifact Version**:* Enter the Maven `pom.xml` standard artifact `version`, which is a semantic version. An example of such is `1.0.0`, which will be inserted in the project's `pom.xml` as the following: `<version>1.0.0</version>`.
  * ***Base Package Name**:* Enter the base package name that will serve as the prefix for all Java packages. An example of such is `io.vlingo.brokerage.investor`, which will be used to derive all other package names in the generated project. The example project would have: `io.vlingo.brokerage.investor.infrastructure` and `io.vlingo.brokerage.investor.model`, which serve as the two major layers of the Compressed Ports and Adapters Architecture.

The following is an example of the Context page.

![Step 2: JVM Platform: Enter the Context information.](/files/-MfdsA42TULJHyw348Gu)

Currently Maven build is supported. You may easily convert the generated project build to Gradle by using the [Gradle conversion task](https://docs.gradle.org/current/userguide/migrating_from_maven.html#migmvn:automatic_conversion).

### Step 3: Aggregates

The third step designs the feature-based slices through the architecture, another opinionated step.

* In DDD, the [Aggregate](https://docs.vlingo.io/xoom-lattice/entity-cqrs) is an important tactical pattern. It represents a transactional boundary around a major domain model concept.
* An Aggregate is a domain model [Entity](https://docs.vlingo.io/xoom-lattice/entity-cqrs#entity-types), which has a unique identity and a [state](https://docs.vlingo.io/xoom-lattice/entity-cqrs#entity-types). An Aggregate designed in the *Investor Context* is `Investor`. Another is `BuyOrder`.
* The tool presents an op inion that Aggregates accept command messages, transition state, and emit events.
* The [state object type](https://docs.vlingo.io/xoom-lattice/entity-cqrs#entity-types) is named with the Aggregate type name with the word `State` appended. For example, the Aggregate named Investor has a state type named `InvestorState`.
* [Command](https://docs.vlingo.io/xoom-lattice/entity-cqrs#commands-domain-events-and-identified-domain-events) messages are sent to an Aggregate to transition its current state to a new state, and to emit a [Domain Event](https://docs.vlingo.io/xoom-lattice/entity-cqrs#commands-domain-events-and-identified-domain-events) that captures this happening in the model.

The user interface for declaring Aggregate types is shown in the next figure.

![Step 3: Declare a new Aggregate type.](/files/-Mfdu0VPbbhGVvPtaDWQ)

Click the `+ NEW AGGREGATE` button to open the Aggregate dialog box. This is where you declare the details about an Aggregate type to be included in your domain model. When the dialog displays, fill in the appropriate sections of the dialog.

![Step 3.1: Fill in the Aggregate type name, state, events, commands, API, and exchange data.](/files/-MfdxSZMqgrS14Prjf1B)

There are a number of sections in which to enter model type design information.

#### Aggregate Name

Every Aggregate type has a unique name, which serves as the type name of the Root Entity protocol. A protocol is the way that clients send messages to the Aggregate, which is generally know as an interface in Java and C#. This is the name not only of the Root Entity type, but represents the overall Aggregate concept. As a convention, if the Aggregate protocol/interface has the name `Investor`, the implementing class is named `InvestorEntity`.

#### State Fields

The state of the Aggregate is prefixed with the name of the Aggregate type's protocol/interface followed by the word `State`. If the protocol name is `Investor` then the state type name is `InvestorState`. The state type is the only value directly held by the Root Entity. The fields of the state type are also known as attributes or properties. Each field has a name and a type. In the above example the `Investor` type has three declared state fields, one named `name` of type`FullName`, one named `suspended` of type `boolean`, and another named `balanceSheet` of type `BalanceSheet`.

{% hint style="info" %}
Any state field type can be declared as one of two collection types, `List<T>` or `Set<T>`, or it can be left a "bare" type, which means without a collection.
{% endhint %}

By convention the state type is immutable. Transitioning from one state to the next is accomplished by full state object replacement. That is, the methods on the state type are functions; that is, side-effect-free behavior. This means that every state business behavior method returns a new state instance that contains the pre-existing field values merged with all new field values.

{% hint style="info" %}
***Reminder**:* In the examples that follow, the source code shown is that generated by the XOOM Designer based on the model information provided by the developer. You will not (currently) see the source code during design mode.
{% endhint %}

For example, assume that the `name` of an `Investor` is Zoe Doe, and when Zoe gets married, her name changes to Zoe Jones-Doe. The `InvestorState` would contain the same first/given name of Zoe, but the family/sir name of Doe would be replaced with Jones-Doe.

```java
package io.vlingo.brokerage.investor.model.investor;

import io.vlingo.brokerage.investor.model.*;

public final class InvestorState {

  public final String id;
  public final FullName name;

  public static InvestorState identifiedBy(final String id) {
    return new InvestorState(id, null);
  }

  public InvestorState(final String id, final FullName name) {
    this.id = id;
    this.name = name;
  }

  public InvestorState changeName(final FullName name) {
    return new InvestorState(this.id, name);
  }
  
  public InvestorState register(final FullName name) {
    return new InvestorState(this.id, name);
  }
  ...
}
```

The Aggregate accepts and handles the `changeName(FullName)` command message, which causes the state to transition.

```java
public class InvestorEntity extends EventSourced implements Investor {
  private InvestorState state;
  ...

  @Override
  public Completes<InvestorState> changeName(final FullName name) {
    final InvestorState stateArg = state.changeName(name);
    return apply(new InvestorNameChanged(stateArg), () -> state);
  }

  private void applyInvestorNameChanged(final InvestorSuspended event) {
    state = state.changeName(event.name);
  }
  ...  
}
```

The state can have any appropriate number of fields. For example, if an `Investor` could be suspended from trading, there could be a `suspended` field of type `boolean` in addition to the `name`.

```java
package io.vlingo.brokerage.investor.model.investor;

import io.vlingo.brokerage.investor.model.*;

public final class InvestorState {

  public final String id;
  public final FullName name;
  public final boolean suspended;
  public final List<Money> balanceSheet = new ArrayList<>();

  public static InvestorState identifiedBy(final String id) {
    return new InvestorState(id, null, false);
  }

  public InvestorState(final String id, final FullName name, final boolean suspended) {
    this.id = id;
    this.name = name;
    this.suspended = suspended;
  }

  public InvestorState changeName(final FullName name) {
    return new InvestorState(this.id, name, this.suspended);
  }

  public InvestorState register(final FullName name) {
    return new InvestorState(this.id, name, this.suspended);
  }

  public InvestorState suspend() {
    return new InvestorState(this.id, this.name, true);
  }
  ...
}
```

The `FullName` type is a Value Object, which can be defined by clicking the button named `+ NEW VALUE OBJECT` that sits just below the Aggregate Name field. You define the Value Object by giving it a type name and some number of fields/attributes. For example, `FullName` has the following definition:

![Step 3.2: Define one or more Value Objects to be used by at least one Aggregate type.](/files/-MfdvGRtnCHzXtRXVinr)

The following table shows the Value Object types defined for an used in the *Investor Contexts.*

| Value Object Type | Field Name     | Field Type          |
| ----------------- | -------------- | ------------------- |
| `BalanceSheet`    |                |                     |
|                   | `transactions` | `List<Transaction>` |
| `BuyDetails`      |                |                     |
|                   | `symbol`       | `String`            |
|                   | `price`        | `Money`             |
|                   | `shares`       | `int`               |
| `FullName`        |                |                     |
|                   | `first`        | `String`            |
|                   | `last`         | `String`            |
| `Money`           |                |                     |
|                   | `value`        | `String`            |
| `Transaction`     |                |                     |
|                   | `datetime`     | `DateTime`          |
|                   | `amount`       | `Money`             |
|                   | `type`         | `TransactionType`   |
| `TransactionType` |                |                     |
|                   | `value`        | `int`               |

After defining Value Object types you can edit any one of them using the Value Object dialog box by clicking the`EDIT VALUE OBJECT` button.

{% hint style="info" %}
You probably noticed the field named `balanceSheet` of type `List<Money>`, and may have wondered if it really belongs as a member of the `Investor`. Let's say initially it seemed like a good idea, but then later it seemed much less desirable. It likely belongs on an `Account`, which isn't even in our *Investor Context.*

Okay, great, but we must admit that it was included only to show off the ability to declare a `List<T>` or `Set<T>` of any type, such as `List<Money>`.

So, yes, factor out the `balanceSheet` from the `Investor` type.
{% endhint %}

Next up: Declare the Domain Events that can be emitted from the Aggregate in reaction to command message handling.

#### Events

Our opinion is that an Aggregate likely emits Domain Events in response to handling command messages that it receives. This section is where you declare the Domain Events that the Aggregate will emit under various command stimuli. An event is named as a fact, generally with a noun prefix and a postfix of a verb in past tense. For example, such as fact capturing event name is `InvestorRegistered`.&#x20;

```java
package io.vlingo.brokerage.investor.model.investor;

import io.vlingo.xoom.common.version.SemanticVersion;
import io.vlingo.xoom.lattice.model.IdentifiedDomainEvent;

import io.vlingo.brokerage.investor.model.*;

public final class InvestorRegistered extends IdentifiedDomainEvent {

  public final String id;
  public final FullName name;

  public InvestorRegistered(final InvestorState state) {
    super(SemanticVersion.from("1.0.0").toValue());
    this.id = state.id;
    this.name = state.name;
  }

  @Override
  public String identity() {
    return id;
  }
}
```

The event is designed to contain one or more specific state fields. The event must always contain the unique identity of the Aggregate, namely the `id` of type `String`. In the case of `InvestorRegistered`, it will contain both the `id` and the `name` of type `FullName` of the `Investor`.

{% hint style="info" %}
When defining zero-parameter message handling methods and *self-describing* events—those that have no state beyond the unique identity of the Aggregate—there must be some specific handling. Such events are said to be self-describing because the name of the event itself indicates that a specific action has occurred and will/may be taken downstream. They are the result of command messages that require no parameters. For example, `suspend()` needs no parameters, and the resulting `InvestorSuspended` event need not have any state other than the `Investor` unique identity. Still, the event indicates that a state transition has occurred, and ultimately requires setting the `suspended` field to `true`. Since no state transition is obvious to the Designer and its code generation step, the post generation source code will require some modifications. This is explained in further detail below in this same subsection.
{% endhint %}

#### Command Methods

The protocol of the Aggregate type declares the messages that may be sent to an Aggregate object instance. In the XOOM Designer these are opinionated and limited to Command Methods. In brief, you will provide the

1. Command Method Name, which is the name of the message handler method and also the name of the message that can be sent by a client to the Aggregate instance
2. Parameters, which are selected among those declared as [State Fields](https://docs.vlingo.io/xoom-designer#state-fields), or none
3. Event, which is selected from among those declared in the [Events](https://docs.vlingo.io/xoom-designer#events) section

The following figure shows this, and following it more detail is provided.

![Step 3.3: The Aggregate information includes Event and Command Method declarations.](/files/-Mfe2oT2PVaCrmsu0ldo)

For the `Investor` type, one such message with a corresponding message handler is the method `register(FullName name)`.&#x20;

1. Enter the message handler method name `register`
2. Select the parameters to the message that the `register()` method accepts drop-down. In this case the only parameter is `name`. For this message handler, as explained next, there is no need to select the `id` as a parameter.
3. The `register()` method is a creational or factory method because it is used to initialize the `Investor` state.  Thus, toggle on the option: Involves creation of entity?

There is a special why to select a parameter that is intended for use with a collection-based state field. There are four basic types supported, as shown in the following table. The example uses the field named `credentials`, which has the type `Set<Credential>`:

| Collection Name & Symbol | Type of Operation                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `credentials*`           | <p>Add all elements in the given collection parameter to the state field collection. Example:<br><br><code>void declareAll(List\<Credential> credentials)</code></p>                                                                                                                                                                                                                                   |
| `credentials#`           | <p>Merge all elements in the collection, if any, with the elements in the given collection parameter. If elements in the given parameter collection already exist in the state's collection, they are replaced. If elements in the given parameter collection do not exist in the state's collection, they are added. Example:</p><p></p><p><code>void merge(List\<Credential> credentials)</code></p> |
| `credential+`            | <p>The parameter is a single element that will be added to the state field collection. Example:</p><p></p><p><code>void declare(Credential credential)</code></p>                                                                                                                                                                                                                                      |
| `credential-`            | <p>The parameter is a single element, that if existing in the state field collection, will be removed. Example:</p><p></p><p><code>void discard(Credential credential)</code></p>                                                                                                                                                                                                                      |

In actuality, the above `add-all`, `merge`, `add`, `remove` are implementation dependent. The actual implementation can be as desired. The idea behind the symbols is to provide standard operations that are common with collections.

It is unnecessary for the unique `id` to be passed with this creational `register()` message because the unique `String id` is always provided with construction. You can see that in the following code that is generated by the XOOM Designer:

```java
public class InvestorEntity extends EventSourced implements Investor {
  private InvestorState state;

  public InvestorEntity(final String id) {
    super(id);
    this.state = InvestorState.identifiedBy(id);
  }
  ...

  @Override
  public Completes<InvestorState> register(final FullName name) {
    final InvestorState stateArg = state.register(name);
    return apply(new InvestorRegistered(stateArg), () -> state);
  }

  private void applyInvestorRegistered(final InvestorRegistered event) {
    state = state.register(event.name);
  }
  ...  
}
```

As seen in the previous code example, pass only the arguments other than the unique identity that are used to initialize the state.

{% hint style="info" %}
Since an Aggregate instance always has it's `id` available from construction, it would be rare if the `id` where passed as a parameter, if ever.
{% endhint %}

{% hint style="info" %}
Previously zero-parameter message handlers and *self-describing* events were discussed and the refactoring currently required to deal with the assumptions made by the Designer code generation. What follows explains how those situations can be handled.
{% endhint %}

Some messages can be sent with no parameters because the state's transition is implied by the message name. For example, if an `Investor` could be suspended from trading, the non-parameter `suspend()` message could be sent, which implies that a `boolean suspended` field/attribute on the `InvestorState` would be transitioned to `true`.&#x20;

```java
public class InvestorEntity extends EventSourced implements Investor {
  private InvestorState state;
  ...

  @Override
  public Completes<InvestorState> suspend() {
    final InvestorState stateArg = state.suspend();
    return apply(new InvestorSuspended(stateArg), () -> state);
  }

  private void applyInvestorSuspended(final InvestorSuspended event) {
    state = state.suspend();
  }
  ...  
}
```

Since there are no explicit hints about the state to be transitioned by a command message handler that takes no parameters, the state type has a `// TODO` comment generated because the developer must determine and write the code for what the state transition means. As seen above, this involves replacing the `// TODO` comment in the `suspend()` function with a single line of code. As a reminder, here's a small snippet of code that shows the edits:

```java
package io.vlingo.brokerage.investor.model.investor;

import io.vlingo.brokerage.investor.model.*;

public final class InvestorState {

  public final String id;
  public final FullName name;
  public final boolean suspended;

  ...
  public InvestorState suspend() {
    // from: return new InvestorState(this.id, this.name, this.suspended);
    // to:
    return new InvestorState(this.id, this.name, true);
  }
  ...
}
```

Take another look at the `InvestorEntity` source used to transition state:

```java
public class InvestorEntity extends EventSourced implements Investor {
  private InvestorState state;
  ...

  @Override
  public Completes<InvestorState> suspend() {
    final InvestorState stateArg = state.suspend();
    return apply(new InvestorSuspended(stateArg), () -> state);
  }

  private void applyInvestorSuspended(final InvestorSuspended event) {
    state = state.suspend();
  }
  ...  
}
```

Even before the `InvestorSuspended` event is applied (i.e. emitted) the `InvestorState` is temporarily transitioned. This is generally always the case because the newly transitioned Aggregate state will be used to provide the fields/attributes to the event. In the case of `InvestorSuspended` this is not absolutely necessary because the event requires only the unique identity (i.e. `id`) of the Aggregate. The state is *permanently* (see the below Info box) transitioned by the `applyInvestorSuspended()` after the initial `apply()` is confirmed.

{% hint style="info" %}
The Aggregate state might now retain the suspended state for all times forward because the `Investor` suspension can be reversed later. The point of "permanently" is that the `InvestorSuspended` event will be applied for that moment in time when the Aggregate state is reconstituted. If an event that reverses the suspension occurs later in time, it will also be reapplied during reconstitution for the point in time that happened later.
{% endhint %}

When an event is applied with the `apply...()` method it is persisted asynchronously without the Aggregate's knowledge.

{% hint style="info" %}
In the case of the Aggregate being a `StatefulEntity` subclass as opposed to an `EventSourced` subclass, the state can be applied without an event. You determine this by you selection in Step 4: Persistence (see below). The following selection causes all Aggregates to extend `StatefulEntity`:

* State Store for Key-Value Persistence

This is a choice made instead of the following, which would cause all Aggregates to extend `EventSourced`:

* Journal for Event Sourcing

Note that when using Event Sourcing, all message handlers ***must*** emit an event.
{% endhint %}

Once the message handler method name is entered and parameters are selected, optionally select an event that the message handler method emits. The choices of event types are from the Events section of the dialog. You can see this illustrated in the previous figure that shows the `suspend()` message handler's declaration.

When self-describing events, such as `InvestorSuspended`, are used, the Designer has no hints to transition the state on its own. (There will be future attention given to this by tooling, but currently state transition hinting is not supported.) There are two places where this must be cared for.

1. The state objects function that deals with the specific transition must be refactored. This was just explained above.
2. Some tests will almost certainly require some minor refactoring to assert state transitions that are non-default values.

Consider some refactoring required for tests:

* The default value of `suspended` is `false`, but the Designer will inevitably generate tests with `true`, because we consider that the positive state perspective is more common. All test cases that consider the default state as `true` must be adjusted to `false` instead.
* It might seem that all cases where the state is transitioned from `false` to `true` require adjustment, but actually the default of `true` is also used in those cases.
* The simplest way to find the required refactoring locations is the run the tests, which is built in to the build process. All failed tests will be due to the wrong default state assumption.

All of the above refactoring state will require only a few minutes to complete.

#### Architecture: API, Producer Exchange, and Consumer Exchange(s)

The vital parts of the architecture responsibilities are specified while defining the domain model. There are three parts to the architecture that are available from within the Aggregates dialog box:

1. Declare the [REST API](https://docs.vlingo.io/xoom-http#use-with-domain-driven-design-context-mapping-patterns) for incoming requests, such as from browser-based user interfaces and to offer an [*Open-Host Service*](https://docs.vlingo.io/xoom-schemata#concepts-and-design) for integration with other subsystems
2. Declare the Producer Exchange (a.k.a. messaging topic) for outgoing events as well as how the events will be registered with XOOM Schemata, which supports providing a [Published Language](https://docs.vlingo.io/xoom-schemata#published-language) that are provided to consumers
3. Declare one or more Consumer Exchange points (a.k.a. messaging topic) for incoming commands and/or events, as well as the paths for pulling type-safe event schemas from XOOM Schemata, which supports the consumption of one or more [*Published Languages*](https://docs.vlingo.io/xoom-schemata#published-language)

All three of these are derived from the Aggregate currently under model design. The following figure shows the API section and the Producer Exchange section for the Investor type Aggregate:

![Step 3.4: The architecture elements surround the Aggregate are driven by it.](/files/-Mfe5WAMs3X1U-4_Qf1m)

***API**:* The REST API for a given Aggregate provides a place for a slice through the architecture to begin. The following API parts must be provided:

1. ***Root Path**:* The root or anchor URI path that all detailed REST requests will have, which is often a collection of resources, such as `/investors`.
2. ***Path**:* The resource URI path that extends beyond the Root Path. Often a `POST` to a collection will be the same as the Root Path, in which case `*` can be used to indicate that Path is the same as Root Path. Otherwise, a fully identified entity URI is required to which a request will `PUT`, `PATCH`, or `DELETE` the resource. This is seen in the second example.
3. ***HTTP Request Method**:* `POST`, `GET`, `PUT`, `PATCH`, `DELETE`, `HEAD`, or `OPTIONS`.
4. ***Aggregate Method**:* The command message to be sent to and instance of this Aggregate type and the message handler method that will process the command, which is selected from among the Command Methods previously declared.

When the REST request arrives it is translated into a message that is immediately and directly dispatched to the domain model Aggregate instance. There is no need for a layer between the REST request handlers because the domain model requires no special setup or transaction management. That is all coordinated between the request handlers and the Aggregate.

***Producer Exchange**:* This is a publish-subscribe messaging exchange, often called a topic, through which outgoing events will be sent/published as messages. Refer to the following figures for a visual mapping of the concepts expressed next.

These exchange parts must be provided:

1. ***Exchange Name**:* By default, it is assumed and recommended that only one exchange should be used for each generated project. Therefore, this field is always read-only and its value is predefined from the pattern `{projectArtifactId}-exchange` . Depending on the architectural messaging mechanism in use, this might be called a topic name rather than an exchange name. For example, RabbitMQ uses exchanges and Kafka uses topics. Having that in mind, after the project is generated, you can edit the [XOOM properties file](https://github.com/vlingo/xoom-examples/blob/master/xoom-e2e-sys-airline-ops/air-traffic-control/src/main/resources/xoom-turbo.properties#L22) and, if you find it necessary, change the default exchange name.
2. ***Schema Registry Path**:* The following figure shows the UI that prompts for the the `Org:Unit:Context` pattern for the Registry Path. It serves as the prefix path to where the event schemas will be registered in XOOM Schemata. The *Org* is the name of the organization that owns the schema. The *Unit* is the business unit or division within the organization. The *Context* is the name of the fully-qualified package name or namespace of the Bounded Context of which the schemas are a part. Note that the Context will likely be the same used in the Context page for the Base Package Name. This path can be created and selected using the Schemata integration. Click the`Org:Unit:Context` field to use the Schemata UI.
3. ***Schema Name(s)**:* The one or more domain events declared in the Events section of the Aggregate dialog that are to be pushed into the schema registry. Just because an Aggregate emits a given event doesn't automatically qualify it as required sharing with other subsystems.

This following figure shows the Producer Exchange under design:

![Step 3.5: The Producer Exchange publishes Aggregate events as messages.](/files/-Mfe5WAMs3X1U-4_Qf1m)

This Schema Registry Path is selected through the XOOM Schemata integration, as was [previously discussed](/xoom-designer#xoom-schemata-integration). If your Organization, Unit, and/or Context is not already defined for this model, you can define them directly through the integration, as follows. The following figures show how the `Org:Unit:Context` is created and selected

![3.6: Define the organization for this set of schemas.](/files/-MfeMEaizn8q01qIW7US)

![3.7: Define the organization unit responsible for this set of schemas.](/files/-MfeMPB-zSoVpJEpl8Fd)

![3.8: Define the context within the organization unit of this set of schemas.](/files/-MfeMWvOATm6UrFTCGS0)

![3.9: Define the context within the organization unit of this set of schemas.](/files/-MfeEba-oovbInIfUJkm)

![3.10: Select the schemas that will be pushed into the selected context during build.](/files/-MfeNB2p-D3R3QoOO33l)

All of the schemas are pushed during the initial build of the project. Thus, the [XOOM Schemata tool must (or should) be running during that time](https://docs.vlingo.io/xoom-schemata#running-xoom-schemata). The event can be pushed in a subsequent build, but they will not be available to for other Bounded Context that depend on them until they are pushed into the schema registry.

***Consumer Exchange**:* This is the section where the Aggregate under design can declare its dependency on an exchange/topic, and the specific schema types that it requires.

![Step 3.11: Subscribe to Consumer Exchange for events to dispatched to the Aggregate.](/files/-MfePZ1ERXz4_WkE3PT0)

The Consumer Exchange shown in the above figure is `accounts-topic`. Each schema type to be received on that topic is declared on separate lines, followed by the Aggregate's message handler method that will receive the resulting command. In the case show above, the Accounts Context can emit the `AccountClosed` event when an investor discontinues their relationship with the brokerage, or if a corrective measure is taken by the brokerage itself. The fully-qualified schema registry path is:

```
VLINGO:Brokerage:io.vlingo.brokerage.accounts:AccountClosed:1.0.0
```

That is, the *Org* is named `VLINGO`, the *Unit* is named `Brokerage`, and the *Context* is named from the project's base package name `io.vlingo.brokerage.accounts`. Following the basic path to the *Context,* the *Schema Name* is provided as `AccountsClosed` and the *Schema Version* is `1.0.0`. This event schema and version is registered with XOOM Schemata, selected through the UI integration, and will be automatically pulled from the registry as a Java class source file. The included schema source is an unmodifiable dependency. Thus, type safety is retained across the system, even in messages exchanged between subsystems.

#### Exchange Configuration

By default the producer/consumer exchanges are backed by the RabbitMQ implementation of [XOOM Lattice Exchange](https://docs.vlingo.io/xoom-lattice/exchange#usage). The generated project will contain the required properties and classes to connect the service/application to the message broker. Also, when the service/application is initialized, the exchanges and its listening queues will be automatically created if any do not exist.

{% hint style="info" %}
Although RabbitMQ is the default messaging system that we provide with code generation, you are certainly not limited to its use. The XOOM Lattice Exchange implementations include one for Apache Camel, which supports 320 or more messaging mechanisms. Among the supported brokers and buses are [Kafka](https://camel.apache.org/components/3.7.x/kafka-component.html), [AWS SNS](https://camel.apache.org/components/latest/aws2-sns-component.html) and [SQS](https://camel.apache.org/components/3.7.x/aws-sqs-component.html), [Google Cloud Pub/Sub](https://camel.apache.org/components/3.11.x/google-pubsub-component.html), [Azure ServiceBus](https://camel.apache.org/components/latest/azure-servicebus-component.html), and many others.
{% endhint %}

The exchange settings can be found at `/src/main/resources/xoom-turbo.properties` in your generated project directory. The following shows how this works for our running example:

```java
exchange.names=investor-topic

exchange.investor-topic.hostname=localhost
exchange.investor-topic.username=guest
exchange.investor-topic.password=guest
exchange.investor-topic.port=5672
exchange.investor-topic.virtual.host=/
```

Based on these settings, XOOM Lattice Exchange will create a fanout exchange. Thus, before starting your application, ensure that RabbitMQ is running on the configured host/port and that the credentials are valid. In addition, the listening queues of a consumer exchange need to be wired to the producer exchange. There are different ways to set up the exchange queues. One of them is to manually bind the queues using the [RabbitMQ Management](https://www.rabbitmq.com/management.html). The management console has a self-explanatory user interface making the exchange configuration straightforward. Below is a demonstration of how to bind the queues of a service/application to the proper exchanges.

The first step is to access the Exchanges section on RabbitMQ management.

<div align="center"><img src="/files/-MlHDZlpazu1HGrH3O9k" alt="The Exchanges section of RabbitMQ Management."></div>

Keep in mind that this example demonstrates that the `Investor` context consumes events from `Account` context. So, the next step is to click on the `Account` topic and bind the `Investor` listening queue. As the following image shows, the `Account` topic initially publishes messages only to its own listening queue.<br>

![The Account Exchange within RabbitMQ Management.](/files/-MlHGSxsdLULuCeeVJ55)

The first field of the *Add binding from this exchange* form needs to be filled in with the queue name of the consumer exchange. In this case, the *self-listening* queue related to the `Investor` exchange as seen in the following screenshot.

![Queue binding of the Investor exchange to Account exchange within RabbitMQ Management.](/files/-MlHLnkF865BKRl-4HV8)

After filling in the queue name and clicking on the *Bind* button, the Investor queue is present in the binded queues list and all messages published through the `Account` exchange will be delivered to the Investor context.

![Both the Account queue and Investor queue are bound to the Account exchange.](/files/-MlHOQoSK3HmzbzOCr9m)

The `Account` exchange can now be consumed by the `Investor` service.

### Step 4: Persistence

The fourth step is used to define the persistence [Storage Type](/xoom-symbio), whether or not [CQRS](/xoom-lattice/cqrs) is to be used, how [Query/Read Model projections](/xoom-lattice/projections) are to work, and what database storage engines are to be used.

![Step 4: Persistence is determined by Storage Type, CQRS, Projections, and database(s).](/files/-MfeSHD3CzOAU-GWWwJp)

{% hint style="info" %}
Note that when using Event Sourcing, all message handlers ***must*** emit an event.
{% endhint %}

The selection of Storage Type is important to determining the underlaying Aggregate base class. Consider the two possible options:

* Journal for Event Sourcing
* State Store for Key-Value Persistence

When Journal for Event Sourcing is selected, all Aggregates in this model will be subclasses of `EventSourced`, meaning that they will use Event Sourcing persistence.

When State Store for Key-Value Persistence is selected, all Aggregates in this model will be subclasses of `StatefulEntity`, meaning that persistence will be to key-value (i.e. NoSQL) database.

If using [CQRS](/xoom-lattice/cqrs), there will be both a Command Model and a Query Model. That means two basic things:

* Query Model views must be projected from either `StatefulEntity` full state, or from events emitted out of `EventSourced` entities. Actually `StatefulEntity` types may also project Query Model views from events. Yet, this requires every command message handler to emit and event, which might go against the desired model design.
* A database storage engine must be selected for both models, one for the Command Model and one for the Query Model.

There are several database storage engines available and more will be available in the future.

### Step 5: Deployment

The fifth step defines the deployment container types.

![Step 5: Select deployment type and runtime environment options.](/files/-MfeT2c3EROuIEFk0KlB)

The project generator provides native packaging, such as Java JAR (choice Default). You may instead use containerization files facilitating Docker and Kubernetes deployment.

* ***Local Docker Image**:* The name of the Docker image.
* ***Published Docker Image**:* For Kubernetes only; name of published image.
* ***Kubernetes POD**:* For Kubernetes only; name of POD.
* ***HTTP Server Port**:* The port on which the REST requests are made to this service.
* ***Producer Exchange Port**:* For future use.
* ***Cluster Port**:* The start of port range for each cluster node, [two per node](/xoom-cluster#cluster-node-configurations); total ports used will be *Cluster Total Nodes* \* 2, with port numbers increasing from this port.
* ***Cluster Total Nodes**:* The maximum number of cluster nodes.

### Step 6: Generation

The sixth and final step defines project component types, and generates the project.

![Step 6: Generate the project and automatically download it as a ZIP file.](/files/-MfeVu06B1NRv903A7ll)

You may choose to generate a *ReactJS* scaffolding UI for basic REST resource editing.

We highly recommend using both annotations and auto-dispatch features. The XOOM platform does not provide many annotations, but the ones that it does provide are very useful. The auto-dispatch feature is how incoming REST requests and consumer exchange/topic messages to automatically translated and dispatched to the appropriate Aggregate instance in the domain model.

The user interface show in the previous figure supports generating and downloading the project as a ZIP file. This runtime mode of the XOOM Designer is available by including a specific command-line option when executing the application, namely `zip-download`. This is the only possible choice when running XOOM Designer from a Docker image:

```
$ java -jar target/xoom-designer-1.7.7.jar gui --target zip-download
```

If you don't run with that option the XOOM Designer will generate projects directly to a local hard drive directory. The following figure shows the user interface for the local file-based generation:

![Step 6.1: Generate the project directly to a directory on local filesystem hard drive.](/files/-M_3F4qjS-fN2APY2tk6)

In this case, a local filesystem directory will be generated for you, but you may override it by entering a different project parent folder. In addition, select whether VLINGO XOOM annotations and auto-dispatch are preferred, or not. Click Generate to start cause the project generation to the specified directory.

Once the six steps have been completed and the service project is generated, take full advantage of the power of the VLINGO XOOM acceleration components. Use the platform comprehensive [documentation ](https://docs.vlingo.io/)and its collaborative [community ](https://gitter.im/vlingo-platform-java/community)that supports you and other developers on your journey. Now, go have fun!

## Collaboration

Our team really appreciates collaboration, not only because it boosts VLINGO XOOM to greater value, but also for the fact that the more viewpoints we have the more competent and mature the VLINGO XOOM community becomes. If you want to be a catalyst for moving the platform forward, take a tour of our [development guide](https://docs.vlingo.io/vlingo-xoom/xoom-starter/development-guide).


# Development Guide

In this section, practical development steps are discussed for anyone interested in contributing to the VLINGO XOOM Designer project.

## Features

The XOOM Designer codebase mainly contains the implementation of the following features:&#x20;

* `XOOM Designer`: the visual model designer itself that, besides the project generation, provides a rapid configuration for VLINGO XOOM components.
* `XOOM CLI`: provides shortcuts for initializing XOOM Designer and interacting with Docker, Gloo Gateway API, and Kubernetes;

Although sharing the same codebase, these two features are not strongly dependent, so it's meant to be kept semantically and structurally separate. In that sense, the Designer and CLI implementations are respectively placed under the package `io.vlingo.xoom.designer` and `io.vlingo.xoom.cli`.&#x20;

Next, the practical sections show how to maintain and expand both features.

## Introduction to CLI

Once the XOOM Designer is correctly [installed](https://github.com/vlingo/xoom-designer/blob/8fee869be2bb257ae98b4a5a328826a95d757f04/src/main/java/io/vlingo/xoom/cli/CommandLineInterfaceInitializer.java#L33), the CLI is accessed from the terminal by calling the executable bash script (ex. `./xoom docker package`). Internally, this script runs the `Designer` jar and passes the command, i.e. `docker package`, to the [CommandLineInterfaceInitializer ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/cli/CommandLineInterfaceInitializer.java#L33)class:

```java
public class CommandLineInterfaceInitializer { 

  public static void main(final String[] args) {  
      ...
      
      final Task task = Task.triggeredBy(resolveCommand(args));      
      
      runTask(task, Arrays.asList(args));  
  }
 
  ...
}
```

The code snippet above shows that an implementation of `io.vlingo.xoom.cli.task.Task` is triggered by the user command, implying that there is one `Task` subclass for each supported task. Next, the task [implementation ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/cli/task/designer/DesignerTask.java)responsible for initializing the Designer service is demonstrated:

```java
public class DesignerTask extends Task {  
    
    private final DesignerInitializer initializer;  
    
    ...
    
    @Override  
    public void run(final List<String> args) {    
        this.initializer.start(OptionValue.mapValues(options, args));  
    }

}
```

The  `OptionValue` class helps tasks to support execution *options*, which are passed along with the bash command. For instance, the designer server port can be customized as follows:&#x20;

```bash
$ ./xoom designer --port 8081
```

The concluding step of a `Task` implementation is to edit the [ComponentRegistration ](https://github.com/vlingo/xoom-designer/blob/939c320735b1f7f3676fd9fbdc397cea42aa0da8/src/main/java/io/vlingo/xoom/cli/ComponentsRegistration.java)class mapping the task as an element of the `cliTasks` list. That makes XOOM CLI able to run the task when the corresponding command is executed:

```java

public class ComponentsRegistration {

  public static void registerWith(final Logger logger,
                                  final CommandExecutionProcess commandExecutionProcess,
                                  final XoomTurboProperties properties) {
    ComponentRegistry.register("cliTasks", Arrays.asList(new DesignerTask(commandExecutionProcess),  new DockerPackageTask(commandExecutionProcess) ...);
}
```

## Introduction to Designer

The following diagram gives us an overview of how the Designer components interact for generating a project:

![XOOM Designer components](/files/XADsYFZ5bK6dQfHm2cDa)

The Designer-embedded user interface illustrated above is built with [Svelte](https://svelte.dev/). It consumes a Rest API submitting the model details to the server-side. Once successfully processed, XOOM Designer uses [Apache FreeMarker](https://freemarker.apache.org/) for generating classes, configuration, and deployment files. That said, let's see how to add templates at the code level.

{% hint style="info" %}
For any development on XOOM Designer you must set an environment variable named `VLINGO_XOOM_STARTER_HOME`. Although you have likely already set this property in order to use the XOOM Designer, that was as an enduser, which has a different value. As a developer working on the Designer, you must set this to the absolute path of a directory relative to where the `vlingo-xoom-starter` repository has been cloned.

Using a \*nix shell, such as `bash`, set like this:

```
$ VLINGO_XOOM_DESIGNER_HOME=[git-clone-path]/dist/designer
$ export VLINGO_XOOM_DESIGNER_HOME
```

On Windows you can use the *System Properties > Advanced > Environment Variables...* to set the property permanently. For a one-time setting before running the design tool you can use the command line:

```
C:\> set VLINGO_XOOM_DESIGNER_HOME=[git-clone-path]\dist\designer
```

After making changes, from the root project directory, build and run the Designer. On \*nix run these commands:

```
$ mvn clean package -P frontend
...
$ java -jar target/xoom-designer-1.6.1-SNAPSHOT.jar gui
```

This works on Windows:

```
C:\[git-clone-path]> mvn clean package -P frontend
...
C:\[git-clone-path]> java -jar target\xoom-designer-1.6.1-SNAPSHOT.jar gui
```

For more details see `README.md` in the `xoom-designer` repository.
{% endhint %}

## Model Processing Steps

While the previous section provides a quick introduction to the Designer components, this section focuses on explaining each step involved in the Designer Model processing, going through the layers, from the external to the inner,   API to the full project generation.&#x20;

First, let's consider how the web-based UI interacts with the Rest API when the project generation is requested:

![Project Generation - UI and Rest API communication](/files/SXNkBxkeXJTCdJbleZFY)

The figure above shows the two requests submitted when the user finishes the Designer model and clicks [the *generate* button](https://docs.vlingo.io/~/files/v0/b/gitbook-28427.appspot.com/o/assets%2F-LLB-V2sJmANuWISDmBf%2F-M_3Au8_e8T8pab_PbuH%2F-M_3F4qjS-fN2APY2tk6%2FXOOM-Designer-Step-06b.png?alt=media\&token=986c44b9-1461-4067-a3fe-b25860829b51). The first request checks if the generation path is valid by creating the full directory tree where the generated project is going to be installed. If it succeeds, the project generation is subsequently requested. The handler methods responsible for processing these requests are presented below:&#x20;

```java
package io.vlingo.xoom.designer.infrastructure.restapi;

public class ModelProcessingResource extends DynamicResourceHandler {

  private final ModelProcessingManager modelProcessingManager;
  
  ...

  public Completes<Response> startGeneration(final DesignerModel model) {
    return modelProcessingManager.generate(model, modelProcessingInformation, logger).andThenTo(scene -> {
              final Response.Status responseStatus = scene.isFailed() ? InternalServerError : Ok;
              return Completes.withSuccess(Response.of(responseStatus, serialized(scene.report)));
            });
  }
  
  public Completes<Response> makeGenerationPath(final GenerationPath path) {
    try {
      modelProcessingManager.createGenerationPath(new File(path.path));
      return Completes.withSuccess(Response.of(Created, headers(of(Location, path.path)), path.serialized()));
    } catch (final GenerationPathAlreadyExistsException e) {
      return Completes.withSuccess(Response.of(Conflict, path.serialized()));
    } catch (final GenerationPathCreationException e) {
      return Completes.withSuccess(Response.of(Forbidden, path.serialized()));
    }
  }
  
  ...
}
```

[ModelProcessingResource ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/ModelProcessingResource.java)depends on [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)for making the generation path and generating the project. Let's get deeper into the code and see how [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)implements the project generation.

```java
public class ModelProcessingManager {

  private final List<CodeGenerationStep> codeGenerationSteps = new ArrayList<>();

  public ModelProcessingManager(final List<CodeGenerationStep> codeGenerationSteps) {
    this.codeGenerationSteps.addAll(codeGenerationSteps);
  }

  public Completes<ModelProcessingScene> generate(final DesignerModel model,
                                                  final ModelProcessingInformation information,
                                                  final Logger logger) {
    return validate(model, information)
            .andThenTo(scene -> mapContext(scene, logger))
            .andThen(scene -> processSteps(scene));
  }
  
  private Completes<ModelProcessingScene> validate(final DesignerModel model,
                                                   final ModelProcessingInformation information) {
    final ModelProcessingScene scene = ModelProcessingScene.with(model, information);
    final String validationErrors = String.join(", ", model.validate());
    if(validationErrors.isEmpty()) {
      return Completes.withSuccess(scene);
    }
    return Completes.withFailure(scene.onValidationFail(validationErrors));
  }

  private Completes<ModelProcessingScene> mapContext(final ModelProcessingScene scene,
                                                     final Logger logger) {
    try {
      final CodeGenerationContext codeGenerationContext =
              CodeGenerationContextMapper.map(scene.designerModel,
                      scene.information.generationTarget, logger);

      return Completes.withSuccess(scene.addCodeGenerationContext(codeGenerationContext));
    } catch (final Exception exception) {
      exception.printStackTrace();
      return Completes.withFailure(scene.onContextMappingFail(exception));
    }
  }

  private ModelProcessingScene processSteps(final ModelProcessingScene scene) {
    try {
      codeGenerationSteps.stream()
              .filter(step -> step.shouldProcess(scene.codeGenerationContext))
              .forEach(step -> step.process(scene.codeGenerationContext));

      return scene.onCodeGenerationSucceed();
    } catch (final Exception exception) {
      ...
    }
  }
```

Reading the [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)code from the top, it's clear that its constructor receives a [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list. The details of this [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)dependency are explained later, but, for now, just keep in mind that the list elements are every step responsible for creating or customizing a piece of the generated project such as configuration files, source code, and other resources.

The `ModelProcessingManager.generate` is the high-level method for the project generation. It uses some auxiliary methods in order to keep the code more organized and readable. Here are the competencies of each one of these auxiliary methods:

* `ModelProcessingManager.validate` - checks if the submitted [DesignerModel ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/data/DesignerModel.java)is valid. Otherwise, the project generation fails.
* `ModelProcessingManager.mapContext` - maps a [DesignerModel ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/data/DesignerModel.java)to [CodeGenerationContext](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationContext.java) that gathers all the information required for the [CodeGenerationSteps](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java)
* `ModelProcessing.processSteps` - iterates through the [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list and processes the steps when the `CodeGenerationStep.shouldProcess` returns true.

That said, let's have a look at the elements of the [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list declared in `io.vlingo.xoom.designer.Configuration`:

```java
public class Configuration {
  
  ...
  
  private static List<CodeGenerationStep> codeGenerationSteps() {
    return Arrays.asList(
            //Preliminary
            new CodeGenerationParameterValidationStep(),
            new MainClassResolverStep(),
            new StagingFolderCleanUpStep(Phase.PRE_GENERATION),
            new TemporaryTaskFolderCreationStep(),
            //Java
            new ReadmeFileGenerationStep(),
            new ApplicationSettingsGenerationStep(),
            new ValueObjectGenerationStep(),
            new ModelGenerationStep(),
            new DataObjectGenerationStep(),
            new ProjectionGenerationStep(),
            new StorageGenerationStep(),
            new RestResourceGenerationStep(),
            new AutoDispatchMappingGenerationStep(),
            new ExchangeGenerationStep(),
            new SchemataGenerationStep(),
            new BootstrapGenerationStep(),
            new EntityUnitTestGenerationStep(),
            new QueriesUnitTestGenerationStep(),
            new ProjectionUnitTestGenerationStep(),
            new RestResourceAbstractUnitTestGenerationStep(),
            new RestResourceUnitTestGenerationStep(),
            new ClusterSettingsGenerationStep(),
            new DesignerModelGenerationStep(),
            new DockerfileGenerationStep(),
            new KubernetesManifestFileGenerationStep(),
            //React
            new StaticFilesGenerationStep(),
            new LayoutGenerationStep(),
            new AggregateManagementGenerationStep(),
            //Concluding
            new ContentCreationStep(),
            new MavenWrapperInstallationStep(),
            new SchemaPushStep(...),
            new SchemaPullStep(...),
            new StagingFolderCleanUpStep(Phase.POST_GENERATION)
    );
  }

}
```

The steps are grouped either by the generation phase or the programming language/technology on which a specific project part is generated. The preliminary steps are responsible for preparing the internal Designer resources for a new project generation and also defining [TemplateParameter ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)values to be used in the later steps.

The core steps, declared between the preliminary and concluding steps, extend [TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java) which is a subclass of [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java). This extension allows these steps to easily process Freemarker templates based on Java/React technologies.&#x20;

At last, the concluding steps, like the preliminary steps, are simple [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) extensions that respectively perform the following tasks:

* Physically create the template output processed in the core steps;
* Copy necessary resources to the generated project;
* Executes Maven-based Schemata goals;
* Clear leftovers of the generated project from Designer internals;

The next section discusses how to implement a [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) and create/update code templates.

## Create / Update Code Templates

The main constituent parts for every auto-generated class / project resouce are:

* A Freemarker template file
* A [io.vlingo.xoom.codegen.template.TemplateData](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L18) implementation
* A [io.vlingo.xoom.codegen.template.TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) implementation&#x20;

Considering those parts, let's take `AggregateProtocol` class generation as an example and go through the implementation details, starting from the template file:

```java
package ${packageName};

<#if imports?has_content>
<#list imports as import>
import ${import.qualifiedClassName};
</#list>
</#if>

public interface ${aggregateProtocolName} {
  <#if !useCQRS>

  /*
   * Returns my current state.
   *
   * @return {@code Completes<${stateName}>}
   */
  Completes<${stateName}> currentState();
  </#if>

}
```

The [Aggregate Protocol template file](https://github.com/vlingo/xoom-designer/blob/ce6c5466b1f1f5532f69dff28fb962455d04a860/src/main/resources/codegen/java/AggregateProtocol.ftl#L1-L23) requires some parameter values to generate an `Aggregate Protocol` class. The parameters handling and mapping are addressed by [AggregateProtocolTemplateData ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/aggregate/AggregateProtocolTemplateData.java#L24)as follows:

```java
public class AggregateProtocolTemplateData extends TemplateData {

  private final String protocolName;
  private final TemplateParameters parameters;

  public AggregateProtocolTemplateData(final String packageName,
                                       final CodeGenerationParameter aggregate,
                                       final List<Content> contents,
                                       final Boolean useCQRS) {
    this.protocolName = aggregate.value;
    this.parameters = TemplateParameters.with(TemplateParameter.PACKAGE_NAME, packageName)
            .addImports(resolveImports(aggregate, contents))
            .and(TemplateParameter.AGGREGATE_PROTOCOL_NAME, aggregate.value)
            .and(TemplateParameter.STATE_NAME, JavaTemplateStandard.AGGREGATE_STATE.resolveClassname(aggregate.value))
            .and(TemplateParameter.USE_CQRS, useCQRS);
  }

  private Set<String> resolveImports(final CodeGenerationParameter aggregate, final List<Content> contents) {
    return ValueObjectDetail.resolveImports(contents, aggregate.retrieveAllRelated(Label.STATE_FIELD));
  }

  @Override
  public String filename() {
    return standard().resolveFilename(protocolName, parameters);
  }

  @Override
  public TemplateParameters parameters() {
    return parameters;
  }

  @Override
  public TemplateStandard standard() {
    return JavaTemplateStandard.AGGREGATE_PROTOCOL;
  }

}
```

The full package name and the `AggregateProtocol` class name are mapped to the template parameters in `loadParameters`. Additionally, [TemplateData](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L18) requires the [filename method ](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L40)implementation, which commonly uses the filename resolution logic in the corresponding [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java).

```java
public class ModelGenerationStep extends TemplateProcessingStep {

  @Override
  protected List<TemplateData> buildTemplatesData(final CodeGenerationContext context) {
    return ModelTemplateDataFactory.from(context);
  }

  @Override
  public boolean shouldProcess(final CodeGenerationContext context) {
    return context.hasParameter(Label.AGGREGATE);
  }

}
```

[ModelGenerationStep ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/ModelGenerationStep.java#L17)implements the `buildTemplateData` method that passes parameter values, coming from the Web-based UI, to RestResourceTemplateData. In this particular scenario, [ModelTemplateDataFactory ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/ModelTemplateDataFactory.java#L29)is an additional and optional class that helps building [AggregateProtocolTemplateData](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/aggregate/AggregateProtocolTemplateData.java#L24). The [shouldProcess method ](https://github.com/vlingo/xoom-codegen/blob/0103c2664201b58f08f5100893a8a3efeaf53f2d/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java#L14)is also optional and useful when a [TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) subclass needs to be conditionally skipped.

Finally, [TemplateProcessingSteps](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) has to be added to the [Configuration ](https://github.com/vlingo/xoom-designer/blob/22c1fb3c3116e22ea7f12580a9af3a228140ff54/src/main/java/io/vlingo/xoom/designer/Configuration.java#L75)steps list:

```java

private static List<CodeGenerationStep> codeGenerationSteps() {
    return Arrays.asList(
                    ...
            //Java
            new ReadmeFileGenerationStep(),
            new ApplicationSettingsGenerationStep(),
            new ValueObjectGenerationStep(),
            new ModelGenerationStep(),
            new DataObjectGenerationStep()
            
            ....
    );

```

Eventually, some peripheral points in the code are also involved. The following list is mainly related when a new template file is added:

**1.** Create an enum value in [Template ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/Template.java#L10)passing the template filename (without extension) in the constructor. Example:

```java

    public enum Template {

        //Other template filenames

        AGGREGATE_PROTOCOL("AggregateProtocol")

        //Enum attributes
    }

```

**2.**  Map the new standard file to an existing [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java) or create one. Sometimes there are multiple files for the same standard. For instance, there is one `Aggregate` template file for each `Storage` (Journal, State Store, Object Store). That means [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java) is responsible for grouping template files by standard and helps the[ ](https://github.com/vlingo/vlingo-xoom/blob/50568b630d92e7dd9b3389496ebf5602d8a84755/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessor.java)[TemplateProcessor ](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessor.java#L12)to find the proper file based on [TemplateParameters ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)such as [StorageType](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/storage/StorageType.java). The examples below demonstrate the `Aggregate Protocol` and `Value Object` standards.

```java
public enum JavaTemplateStandard {
    
    AGGREGATE_PROTOCOL(parameters -> Template.AGGREGATE_PROTOCOL.filename),
    VALUE_OBJECT(parameters -> Template.VALUE_OBJECT.filename),

    //Other standards
}

```

**3.** In case it doesn't already exist, create an enum value in [TemplateParameter ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)for each template parameter.

To sum up, those are the common steps regarding `code template files` on `xoom-designer`. Our team is available to discuss and provide more information on [Gitter](https://gitter.im/vlingo-platform-java/community/) and our [public Slack workspace](https://join.slack.com/t/vlingoplatfor-i6o3730/shared_invite/zt-bv6chhpw-u7s4kqb1qvVvVMUUH3wqng).


# End-to-End Tests

Automated End-to-end testing to thoroughly corroborate the integrity of generated projects.

Considering the importance of a reliable testing process on the parts that constitute the XOOM Designer *codegen*, our team created a small library of classes and resources in order to facilitate the creation of broader test cases that, along with the usual testing approaches, readily checks the integrity of projects created from XOOM Designer. Thus, the following aspects are validated:

* Project model processing;
* Compilation;
* Initialization;
* API operations;
* Event projections;
* Schemas registration / transpilation;

In the next section, we'll understand how to run End-to-End tests and implement new ones.

## Execution

End-to-end tests are part of the Designer [build lifecycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html), so you can execute it by calling:

```
$ mvn verify -P e2e-supporting-services
```

Understanding what happens afterward, the sequence of Maven goals performed during the execution of this command is *unit tests*, *packaging*, *End-to-End tests*. So, in case you want to focus on the test results and skip the packaging step, add the `only-tests` profile:

```bash
$ mvn verify -P only-tests, e2e-supporting-service
```

{% hint style="info" %}
Some test cases depend on external resources (e.g. *XOOM Schemata*) which are meant to be up and running when tests are executed. Using `e2e-supporting-service` profile, these resources are automatically started via Docker. Alternatively, you can manually run these dependencies. Learn more in the [Dependencies ](https://docs.vlingo.io/xoom-designer/development-guide/e2e-tests#dependencies)section. &#x20;
{% endhint %}

## Implementation

Exploring the XOOM Designer codebase, End-to-End tests are found in the `src\e2e-test\` and its classes have to be under the package`io.vlingo.xoom.designer.codegen.e2e.*` extending`JavaBasedProjectGenerationTest`. Let's take a look at the basic structure of a test class:

```java
public class BookStoreServiceGenerationTest extends JavaBasedProjectGenerationTest {

  @BeforeAll
  public static void setUp() {
    JavaBasedProjectGenerationTest.init();
  }

  @Test
  public void testThatServiceWithStatefulEntitiesIsWorking() {
    //Load model
    //Generate and run the project
    //Assertions
  }

  @Test
  public void testThatServiceWithSourcedEntitiesIsWorking() {
    //Load model
    //Generate and run the project 
    //Assertions
  }

  @AfterEach
  public void tearDown() throws Exception {
    JavaBasedProjectGenerationTest.clear();
  }
}
```

&#x20;`JavaBasedProjectGenerationTest.init()`  prepares the test environment setting the internal components required for generating a project and runs the XOOM Designer Server. Whereas, `clear()` basically stops the application ran in each test case. As demonstrated above, ensure that both methods are invoked respectively at the right time of the test lifecycle.&#x20;

The main test input is a JSON file containing a XOOM Designer model. It should be saved under `src/e2e-test/resources/sample-models/[context-name]/` . the values of `deployment.httpServerPort` and `projectDiretory` have to be updated to a replacement token (`%s`) for the fact that these values will be dynamically resolved during the tests. Here's an example:

```javascript
{  
  "deployment": {
   "httpServerPort": "%s"
  },
  ...
 "projectDirectory": "%s"
}
```

In the test method, the model can be loaded by creating an`io.vlingo.xoom.designer.codegen.e2e.Project` object which is also used to generate the project.

```java
@Test
public void testThatGeneratedServiceWithStatefulEntitiesIsWorking() {
     
  //Loads the model passing the directory name and its name
  
  final Project projectWithStatefulEntities =
          Project.from("book-store-context", "book-store-with-stateful-entities");

  super.generateAndRun(projectWithStatefulEntities);
  
  ...
 }
```

The `generateAndRun` method receives the `Project` object carrying the model settings which is submitted to the XOOM Designer API. Still, this method internally asserts that the project is properly generated. If the generation succeeds, the project will also be compiled and initialized. Otherwise, a message assertion error will be shown.&#x20;

Afterward, the test statements refer to the API validation. The next code snippet gives some tips on how to perform requests and assertions:

```java
@Test
public void testThatServiceWithSourcedEntitiesIsWorking() {
 final Project projectWithStatefulEntities =
    Project.from("book-store-context", "book-store-with-sourced-entities");

 super.generateAndRun(projectWithStatefulEntities);

 final BookData newBook = BookData.sample();

 final Response response =
    super.apiOf(bookStoreProject).body(newBook).post("/books");

 final BookData responseBody =
    response.then().extract().body().as(BookData.class);

 Assertions.assertEquals(Status.Created.code, response.statusCode(), "Wrong http status while creating book " + bookStoreProject);
 Assertions.assertEquals(newBook, responseBody, "Wrong response while creating book " + bookStoreProject);
}
```

Other assertions should be added in order to make a meticulous verification of the project's consistency. It's also strongly recommended that each test method are commented on regarding the XOOM Designer model details.&#x20;

```java
/**
 * Test that the service is generated and working with:
 * - Stateful Entities containing only scalar-typed fields
 * - Operation-based projection
 * - Xoom Annotations + Auto-dispatch
 */
@Test
public void testThatServiceWithStatefulEntitiesIsWorking() {

  ...
}
```

See the full code used in this example [here](https://github.com/vlingo/xoom-designer/blob/master/src/e2e-test/java/io/vlingo/xoom/designer/codegen/e2e/java/bookstoreservice/BookStoreServiceGenerationTest.java).

## Dependencies

Whenever a XOOM Designer model is configured to produce or consume events, the generated project will depend on [XOOM Schemata](https://docs.vlingo.io/xoom-schemata) and [XOOM Lattice/Exchange](https://docs.vlingo.io/xoom-lattice/exchange) (*RabbitMQ*). Therefore, the installation, initialization, and closing of these resources are part of the End-to-End testing routine. The quickest way to handle this external resources management on a local environment is to use the `e2e-supporting-services` profile.

```java
$ mvn verify -P e2e-supporting-services
```

{% hint style="info" %}
The End-to-End test cases require that *XOOM Schemata* and *RabbitMQ* are respectively available on port *9019* and *5672.* Ensure that these ports are not in use before activating the `e2e-supporting-services` profile.
{% endhint %}

Then, call `SupportingServicesManager.run()` before the test cases are executed:

```java
public class CargoShippingServicesGenerationTest extends JavaBasedProjectGenerationTest {

  @BeforeAll
  public static void setUp() {
    SupportingServicesManager.run();
    JavaBasedProjectGenerationTest.init();
  }
  ...
}
```

The first statements of a test method that generates a project that has dependencies are meant to assert that the external resources are available:

```java
@Test
public void testThatGeneratedServicesAreWorking() {
  super.assertServiceIsAvailable(SupportingServicesManager.findPortOf(SCHEMATA), "Schemata service is not available");
  super.assertServiceIsAvailable(SupportingServicesManager.findPortOf(RABBIT_MQ), "RabbitMQ service is not available");
  
  //Generate the project
}
```

The `SupportingServicesManager` automatically shut down the managed services when the test cases execution is done.

## Constraints

Following the classical[ test pyramid concept](https://martinfowler.com/articles/practical-test-pyramid.html) that states that "*the more high-level you get the fewer tests you should have*", we should not have several End-to-End test cases once they are slower and hard to maintain. Rather, a small set of test cases that cover a number of corner cases and complex scenarios is the best goal.

Due to the complexity of covering user-interface functionalities on automated testing, the implementation of End-to-End tests on XOOM Designer does not validate the XOOM Designer UI. Also, when a XOOM Designer model has an embedded ReactJS app, the generated frontend code is not syntactically checked, taking into account that this additional validation would imply resolving the framework dependencies increasing significantly the time consumed on each test.


# Turbo

The VLINGO XOOM adoption and project accelerator for Java and other JVM languages.

This VLINGO XOOM component helps individual developers and architects, as well as whole teams, to speedily jump-start productivity with the platform. Our JVM  SDK boosts productivity in building high-scale, high-performance, Reactive microservices and well-modularized monoliths. Our [Designer](/xoom-designer) helps you models and deliver your project structure for each of your subsystems, such as Microservices: REST resource handlers; domain model aggregates/entities; events and state objects; Event Sourcing and CQRS command and query models; and persistence mechanisms.

![XOOM Turbo is a container around the platform components, making use fast and simple.](/files/-M9H0FwLGxPXIMkLGEwd)

Starting with from visual model definition, REST API, persistence, and container definitions, to generation, to immediate build and run, your services can be running within minutes.

## Startup Configuration and Initialization Wiring

A very important aspect of VLINGO XOOM is that all runtime wiring is achieved at compile time, not at startup time. This leads to very fast startup times for your services and applications. This means that adding new runtime nodes to your deployed system is performed very quickly. It also means that using the platform for FaaS-based solutions is a realistic and viable option.

This is achieved in one of two ways.

* Handwritten code including all necessary bootstrap boilerplate
* [Annotations](/xoom-turbo/annotations) that wire at compile-time, not runtime, and replace almost all of the handwritten boilerplate code

Although we are not fans of sprinkling Java annotations all over a codebase, we have found that supporting a few key annotations greatly reduces the amount of boilerplate code, including configuration and startup initialization, that is required. The use of annotations is completely optional. You may choose to implement all of the configuration and initialization code yourself. Yet, we think you will agree that using a few annotations in key places is more helpful than objectionable. And, of course, if you are a fan of annotations, you will find them indispensable.

We have even more good news. Most of the bootstrap, startup, configuration, and initialization code, may be generated for you—with or without annotations—when using the [VLINGO XOOM Designer](/xoom-designer).

## Stepwise Adoption

We have found that one of the blockers to learning reactive programming is, well, non-blocking. As a large body of programmers, the software industry has mostly supplied and socialized blocking or synchronizing languages and tooling. Because of this, developers have come to expect blocking—and for many of us that write software in teams—you've certainly inherited and contributed to blocking code in your projects. This legacy of blocking becomes continually more difficult to change. For these reasons, it comes as no surprise that a non-blocking approach will require a cooperative mind-bending effort for teams to fully adopt an asynchronous, concurrent, and parallelized programming culture.

For this reason, we've decided to introduce a familiar way to learn the different components of the VLINGO XOOM SDK—without the need to fully utilize asynchrony early on. We're keen on providing you with the stepping stones that help you and your team make the jump to asynchrony, concurrency, and parallelism, without the added burden of learning an entirely new way of writing code. We welcome you to explore our VLINGO XOOM tools so you can quickly learn the ropes, gradually adding in asynchrony as you feel more comfortable.&#x20;

It is our hope that this project will help you realize our platform's overarching goals of *aggressive simplicity combined with lightweight fluency*, with or without adopting Domain-Driven Design. After all, the best way to learn any language is to learn both the words and the grammar as you go, achieving fluency through both rapid and gradual practice.

Messaging is at the core of VLINGO XOOM, and as such, still uses messaging in the same way that you would with our asynchronous environment, but it conceals the learning discomfort.&#x20;

There's no mystery to actors and message sending. Here's a brief explanation of how actor messaging works, but with synchronous, single-threaded programming. Assume that a *sending actor* sends a message to a *receiving actor.* The *receiving actor* will see the message from the *sending actor* and react to it. After reacting to the message, the *receiving actor* will then return control back to the *sending actor* on the *same thread*.

Now consider that the *receiving actor* is a request handler that provides an HTTP response. As non-reactive blocking communication goes, all requests to the handler will be served responses on the same thread. It's easy to understand.

The only difference in this explanation above, to what you might be used to, is the idea of using actors as an abstraction instead of HTTP-based web services. Whether or not the underlying protocol, servlet, container, or driver enables reactive or blocking communication, the actor programming model itself is unchanged. An actor is an object that receives messages and sends messages in response.

Now, take a look at the VLINGO XOOM SDK to get started making strides toward full use of the full array of components.

## Boot and Start Up

To begin, you need the following dependency for your builds, the first being for Maven.

```markup
<dependency>
  <groupId>io.vlingo.xoom</groupId>
  <artifactId>xoom-turbo</artifactId>
  <version>x.y.z</version>
  <scope>compile</scope>
</dependency>
```

The second is for Gradle. In both examples, replace `x`, `y`, and `z` with the major version, minor version, and patch version, respectively, for the artifact.

```groovy
dependencies {
    compile 'io.vlingo.xoom:xoom-turbo:x.y.z'
}
```

You also need the configuration defined in the properties file `xoom-actors.properties` that is already provided when you use [Designer ](https://docs.vlingo.io/vlingo-xoom/xoom-starter)for generating your project. In case you prefer to create it manually, the [Actors documentation](https://docs.vlingo.io/vlingo-actors#using-the-vlingo-actors-properties-file) will be very useful.

To boot the VLINGO XOOM platform foundation, use the `Boot` API. There are three ways to do so. One way is through a `void main(String[] args)` boot method.

```java
Boot.main(new String[] { "xoom-boot-world-name" });

final World world = Boot.xoomBootWorld();
```

Of course the `main()` would normally be invoked by the Java runtime. This demonstrates that if any command-line arguments are received, the first argument will be used to name the `World`. If there are no command-line arguments, the `World` will be named `"vlingo-xoom"`.

A second way to boot the platform is to use the `Boot.start(String name)` method.

```java
final World world = Boot.start("xoom-boot-world-name");
```

The last and simpler way is to annotate a clean Java class with `@Xoom` annotation:

```java
@Xoom(name="xoom-boot-world-name")
public class AppInitializer {

}
```

As you can see, `@Xoom` does not require any method implementation because the annotation itself is sufficient to boot the application. Furthermore, you can add the `blocking` attribute to enable/disable synchronous actor messaging.

```java
@Xoom(name="xoom-boot-world-name", blocking=true)
public class AppInitializer {

}
```

Keep in mind that the default value for `blocking` is `false` and, when used, `@Xoom` annotation attributes always override what has been set in `xoom-turbo.properties`. In other words, if the Initializer class is annotated with `blocking=false` and `BlockingMailbox` is enabled in the properties file, the `@Xoom`attribute prevails, causing actors to communicate asynchronously.

One of the many cool things about VLINGO XOOM, whether using the XOOM Turbo container or the other component APIs directly, is that it boots within a few milliseconds. How cool is that? And you know that everybody loves cool!

Now you are ready to use the `World` and any living part of it to explore the marvels of the platform.

## Messaging

Messaging is accomplished the same simple way that it is with our standard platform environment. There are no surprises. Consider an example with a `DeliveryProtocol`.

```java
public interface DeliveryProtocol {
  void reactTo();
  void reactTo(final int x, final int y, final int z);
  void reactTo(final String text);
  Completes<List<String>> reactions();
}
```

This protocol provides three command messages and a forth used for querying. The actor that provides this protocol can react in three ways: using no parameters, three integer parameters, and with one text string parameter. Here is an actor that implements this protocol.

```java
public class DeliveryProtocolActor extends Actor implements DeliveryProtocol {
  private final List<String> reactions;

  public DeliveryProtocolActor() {
    this.reactions = new ArrayList<>();
  }

  @Override
  public void reactTo() {
    final String reaction = "reacting to no parameters";
    logger().debug(reaction);
    reactions.add(reaction);
  }

  @Override
  public void reactTo(final int x, final int y, final int z) {
    final String reaction = "reacting to: x=" + x + " y=" + y + " z=" + z;
    logger().debug(reaction);
    reactions.add(reaction);
  }

  @Override
  public void reactTo(final String text) {
    final String reaction = "reacting to: text=" + text;
    logger().debug(reaction);
    reactions.add(reaction);
  }

  @Override
  public Completes<List<String>> reactions() {
    logger().debug("reactions...");
    return completes().with(Collections.unmodifiableList(reactions));
  }
}
```

Focus on the first three `reactTo()` message handlers. This actor does just a few things when it receives each message type. It formats a string to indicate what happened. It logs that message through the standard `io.vlingo.xoom.actors.Logger` protocol that is available to all `io.vlingo.xoom.actors.Actor` extenders. Each of the message handlers appends the formatted text description to a `List` held by its state. This state is held so that a client of this actor can query for all its reactions.

That leads to the forth and last message handler, `reactions()`. It answers the full `List` resulting from the various `reactTo()` messages received. Note that it doesn't just answer the raw, mutable `List`. Instead it provides an immutable `List`, so that its state cannot be tampered with by anyone on the outside. In addition, it answers the immutable `List` as a `Completes<T>` outcome.

More detail may be read about `Completes<T>` [here](/xoom-common#completes). In brief it is a means for asynchronous query operations being executed on separate threads to provide eventual answers to a requester. Of course, this actor is running within a `World` on VLINGO XOOM, and thus is asynchronous. Still, we don't change the entire platform API to accommodate use in a blocking environment. We want you to learn in comfort, but learn something new and experience the API in a safe haven.

Here is a test that shows a usage example.

```java
final DeliveryProtocol protocol = world.actorFor(DeliveryProtocol.class, DeliveryProtocolActor.class);

protocol.reactTo();
protocol.reactTo(1, 2, 3);
protocol.reactTo("Hello, World!");

protocol.reactions().andThenConsume(reactions -> assertEquals(3, reactions.size()));
```

The test gets a reference from the `World` through which it may send messages to the actor that supplies the `DeliveryProtocol`.

### Blocking Mailbox

Note that the above example of the `DeliveryProtocolActor` uses the configured default mailbox. This is so because the code using `actorFor()` doesn't pass a specific mailbox name, meaning that the default mailbox is used. You can configure **VLINGO XOOM** to default to  the `BlockingMailbox`, by placing the following configuration in the `xoom-actors.properties;` note the line containing `...defaultMailbox = true`

```java
plugin.name.blockingMailbox = true
plugin.blockingMailbox.classname = io.vlingo.xoom.turbo.scooter.plugin.mailbox.blocking.BlockingMailboxPlugin
plugin.blockingMailbox.defaultMailbox = true
```

The test client of `DeliveryProtocol` then sends messages, each of the three types of `reactTo()` that can be sent. Finally, it asks the actor to answer its collected reactions by way of`Completes<List<String>>`. Note that the test client receives the outcome by using the `andThenConsume(function)`. Inside this lambda an assertion is made that the `List` is expected to have three elements, one for each of the command messages sent.

All of the above is executed on a single thread; the thread that the test is running on.

### Actor Request-Response

Here we discuss request-response from the perspective of one actor that sends a request message to a second actor, and that second actor sends a response as a message back to the first actor. Here are the protocols, with `RequestProtocol` being the first.

```java
public interface RequestProtocol extends Stoppable {
  void request(final int value, final ResponseProtocol respondTo);
}
```

The `RequestProtocol` may receive a `request()` and respond to the second protocol by sending it a `response()`. After some expected outcome of request-response, the second protocol can be queried for a total.

```java
public interface ResponseProtocol extends Stoppable {
  Completes<Integer> total();
  void response(final int value, final RequestProtocol requestOf);
}
```

The implementations of these two protocols are next.

```java
public class RequestProtocolActor extends Actor implements RequestProtocol {
  @Override
  public void request(int value, ResponseProtocol respondTo) {
    respondTo.response(value + 1, selfAs(RequestProtocol.class));
  }
}
```

This `RequestProtocolActor` responds to the received request by adding `1` to the `value` it receives. The response actor receives a response and tracks the `total` until a desired outcome.

```java
public class ResponseProtocolActor extends Actor implements ResponseProtocol, Stoppable {
  private final RequestProtocol requester;
  private int total;

  public ResponseProtocolActor(final RequestProtocol requester) {
    this.requester = requester;
    this.total = 0;
  }

  @Override
  public void start() {
    requester.request(total, selfAs(ResponseProtocol.class));
  }

  @Override
  public void response(final int value, final RequestProtocol requestOf) {
    if (value >= 10) {
      total = value;
    } else {
      requestOf.request(value + 1, selfAs(ResponseProtocol.class));
    }
  }

  @Override
  public Completes<Integer> total() {
    return completes().with(total);
  }
}
```

Note that the `start()` life cycle message is received just following construction. This is where the response actor starts the request-response process by sending a `total` of `0` to the request handler actor. The request-response continues until the response actor reaches a `value` of `10` or greater.

The following is a test that shows an example usage.

```java
final RequestProtocol requestOf = world.actorFor(RequestProtocol.class, RequestProtocolActor.class);
final ResponseProtocol respondTo = world.actorFor(ResponseProtocol.class, ResponseProtocolActor.class, requestOf);

respondTo.total().andThenConsume(value -> assertTrue(10 <= value));
```

## Other Tools

Explore the other tools available as part of the high-level XOOM components.

| Tool                                        | Description                                                                                                                                                                 |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [XOOM Designer](/xoom-designer)             | Be guided into the Reactive DOMA and DDD world by the application and microservice designer and generator for the VLINGO XOOM components.                                   |
| [XOOM Annotations](/xoom-turbo/annotations) | Using a few lines of code, activate and configure platform components.                                                                                                      |
| [XOOM Scooter](/xoom-turbo/scooter)         | An API for implementing Actors and DDD entities/aggregates with persistence using a familiar blocking paradigm, supporting stepwise adoption the our full reactive toolset. |


# Annotations

Using a few lines of code, activate and configure the VLINGO XOOM components.

There's an API defacto standard that developers always deserve freedom of choice in terms of either crafting each part of their own code, or to accelerate the development steps by taking advantage of default configurations and shorthand elements. The VLINGO XOOM platform aims to provide technical autonomy, no matter the strategy you choose, even allowing the combination of both.

Generally speaking, VLINGO XOOM annotations fit well when you want more succinct code. From the application initialization to the persistence resources, we provide a brief description of each annotation.

| Annotation                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`@Xoom`**                                                                                    | <p>Its main purpose is to instantiate and setup essential elements of a VLINGO XOOM application or microservice:</p><ul><li><a href="/pages/-LLBtnc7RFDT3LdT8DQi#starting-and-terminating-the-actor-runtime">World</a></li><li><a href="/pages/-LLBtnc7RFDT3LdT8DQi#a-stage-for-actors">Stage</a></li><li><a href="/pages/-LLBtnc7RFDT3LdT8DQi#creating-actors">AddressFactory</a></li><li><a href="/pages/-LLBtnc7RFDT3LdT8DQi#mailbox">Mailbox</a></li><li><a href="/pages/-LLBxsKxLTjRO2sB6Rd1">HTTP embedded server</a></li></ul> |
| **`@ResourceHandlers`**                                                                        | Maps and initializes [REST resource classes ](/xoom-http)along with its routes.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| **`@AutoDispatch`**                                                                            | Provides a faster and straightforward way to dispatch REST requests to the domain model.                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **`@Persistence`**                                                                             | Enables [XOOM SYMBIO](https://docs.vlingo.io/vlingo-symbio), allowing to set up database parameters, [CQRS](https://docs.vlingo.io/vlingo-lattice/entity-cqrs), and different [storage types](https://docs.vlingo.io/vlingo-symbio#what-is-symbio).                                                                                                                                                                                                                                                                                   |
| **`@EnableQueries`**                                                                           | Handles [QueryActors](/xoom-lattice/entity-cqrs#querying-a-statestore) by adding its configuration in the application startup.                                                                                                                                                                                                                                                                                                                                                                                                        |
| **`@Projections / @Projection`**                                                               | Determines [Domain Events](/xoom-lattice#feature-overview) processed by each [Projection Actor](/xoom-lattice/projections).                                                                                                                                                                                                                                                                                                                                                                                                           |
| <p><strong><code>@Adapters /</code></strong> </p><p><strong><code>@Adapter</code></strong></p> | Generates a default [State Adapter](/xoom-symbio/adapters) for an [Entity State](/xoom-lattice/entity-cqrs).                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **`@DataObjects`**                                                                             | Enables the auto-creation of database tables for *data objects*.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

{% hint style="info" %}
When using any kind of IDEs, be aware that they usually do not evaluate compile-time annotations as soon as you declare it or immediately when you open a project with an IDE for the first time. In this case, IDEs may notify one or more compilation errors. That can be easily avoided just by building your project when you first open it or at the time you declare annotation(s).
{% endhint %}

&#x20;For a practical understanding of annotations, the next section brings more details.

### `@Xoom`

It's widely known that the starting point of any Java program is a static `main()` method. In addition, when creating of a VLINGO XOOM application or microservice, we must instantiate `World`, and pass it to other classes that use it for actors operation. So, that's what the `@Xoom` annotation mainly provides.

* An `Initializer` class with a static `main()` method, which is the hook for JVM in the application execution
* Creation of `World` and `Stage` with the `AddressFactory` option, making the `Stage` instance accessible for classes that request `Actor` operations directly from it

Besides that,  `@Xoom` takes care of reading the [properties ](https://docs.vlingo.io/vlingo-xoom#boot-and-start-up)file with the `Mailbox` definition and starts a **XOOM HTTP** server. All of those tasks are achieved simply by annotating a basic class.

```java
@Xoom(name="xoom-app-name")
public class AppInitializer {

}
```

The application `name` attribute is the minimal information for running application with `@Xoom` but there are also other attributes. Here's the full list.

| Attribute        | Type         | Description                                                                                                                | Required |
| ---------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- | -------- |
| `name`           | `String`     | Sets the application name.                                                                                                 | Yes      |
| `blocking`       | `Boolean`    | True or false for respectively synchronous or asynchronous actor messaging. The default value is false.                    | No       |
| `addressFactory` | `Annotation` | Sets the `AddressFactory` type: `BASIC`, `UUID`, `GRID`; and `IdentityGenerator` type:`RANDOM`, `TIME_BASED`, `NAME_BASED` | No       |

&#x20;The next code snippet shows the `@Xoom` attributes with non-default values.

```java
@Xoom(name = "app-name", blocking = true,
        addressFactory = @AddressFactory(type = GRID, generator = RANDOM))
public class AppInitializer {

}
```

Often, application initialization tasks need to be refined by some handwritten code. In the case where this is needed when using the @Xoom annotation, an initializer class may implement the interface `io.vlingo.xoom.turbo.XoomInitializationAware`.

```java
@Xoom(name = "app-name")
public class AppInitializer implements XoomInitializationAware {
  
  @Override
  public void onInit(final Stage stage) { 
     //Here, add some logic that depends on Stage   
  }
  
  @Override
  public Configuration configureServer(final Stage stage, final String[] args) {
     //Define a custom server configuration
  }
}
```

### `@ResourceHandlers`

This is a `@Xoom`-related annotation for REST resources initialization. First, your custom resource class must extend `io.vlingo.xoom.http.resource.DynamicResourceHandler`. This resource class should implement a constructor that takes a `Stage` instance parameter. The resource class must also implement a  `routes()` method, through which fluent route mappings are possible, see [XOOM HTTP](/xoom-http).

```java
public class InsuranceResource extends DynamicResourceHandler {
    
    public InsuranceResource (final Stage stage) {
        super(stage);
    }

    public Completes<ObjectResponse<Insurance>> retrieveInsurances() {
       // retrieve Insurance instances
    }

    @Override
    public Resource<?> routes() {
        return resource("Insurances", get("/insurances").handle(this::retrieveInsurances));
    }
}
```

To wire an instance of an `InsuranceResource`, annotate the initializer class providing the package containing the REST resource classes.

```java
@Xoom(name = "app-name")
@ResourceHandlers(packages = {"io.vlingo.xoomapp.resources"})
public class AppInitializer {
  
}
```

Optionally you may decide to provide a number of resource classes instead of the package name.

```java
@Xoom(name = "app-name")
@ResourceHandlers({InsuranceResource.class, OtherResource.class ...})
public class AppInitializer {
  

}
```

As described below, `@ResourceHandlers` supports two optional attributes, but only one must be set.&#x20;

| Attribute  | Type                                          | Description                                                                                             | Required |
| ---------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------- |
| `value`    | `Class <? extends DynamicResourceHandler> []` | An array of `DynamicResourceHandler` subclasses.                                                        | No       |
| `packages` | `String []`                                   | An array of Java `package` names that each contains some number of `DynamicResourceHandler` subclasses. | No       |

### `@AutoDispatch`

Often, a considerable part of the effort while building an application is not on its vital elements but on recurrent and straightforward tasks such as mapping logic, components configuration, and general application settings. Facing this discrepancy, `@AutoDispatch` enables you to invest less in writing [REST resources](https://docs.vlingo.io/vlingo-http#reactive-rest) and broker/bus [exchange message listeners](/xoom-lattice/exchange) so that you are able to focus on the core of your application, that is, the domain model.&#x20;

The next code snippet shows how this convenient annotation transforms your REST resource implementation:

```java
@AutoDispatch(path="/products", handlers = ProductResourceHandlers.class)
@Queries(protocol = ProductQueries.class, actor = ProductQueriesActor.class)
@Model(protocol = Product.class, actor = ProductEntity.class, data = ProductData.class)
public interface ProductResource {

  @Route(method = POST, handler = ProductResourceHandlers.REGISTRATION)
  @ResponseAdapter(handler = ProductResourceHandlers.ADAPT_STATE)
  Completes<Response> register(@Body final ProductData data);

  @Route(method = PATCH, path = "/{id}/profit-margin", handler = ProductResourceHandlers.PROFIT_MARGIN)
  @ResponseAdapter(handler = ProductResourceHandlers.ADAPT_STATE)
  Completes<Response> applyProfitMargin(@Id final String id, @Body final ProductData data);

  @Route(method = GET, handler = ProductResourceHandlers.ALL_PRODUCTS)
  Completes<Response> allProducts();

}
```

Yes, an interface with only abstract methods is the primary piece for implementing an`@AutoDispatch` resource.  Now, following the order of how each annotation is placed in the code, let's understand how it works.

#### `@AutoDispatch`

Starting with `@AutoDispatch` , which is the root annotation and accepts these values:

| Attribute  | Type       | Description                                                                       | Required |
| ---------- | ---------- | --------------------------------------------------------------------------------- | -------- |
| `path`     | `String`   | URI root path                                                                     | Yes      |
| `handlers` | `Class<?>` | A mapping configuration class relating aggregate/queries methods and its indexes. | Yes      |

Here we open a parenthesis to clarify the `ProductResourceHandlers` class, declared in the `@AutoDispatch`*handler* attribute in the previous code snippet. Looking at it, we can see the aggregate methods to which REST requests are going to be forwarded.

```java
public class ProductResourceHandlers {

  public static final int REGISTRATION = 0;
  public static final int PROFIT_MARGIN = 1;
  public static final int ALL_PRODUCTS = 2;
  public static final int ADAPT_STATE = 3;

  public static final HandlerEntry<Three<Completes<ProductState>, Stage, ProductData>> REGISTRATION_HANDLER =
          HandlerEntry.of(REGISTRATION , ($stage, data) -> Product.open($stage, data.creditLimitThreshold));

  public static final HandlerEntry<Three<Completes<ProductState>, Product, ProductData>> PROFIT_MARGIN_HANDLER =
          HandlerEntry.of(PROFIT_MARGIN , (product, data) -> product.applyProfitMargin(data.profitMargin));

  public static final HandlerEntry<Two<ProductData, ProductState>> ADAPT_STATE_HANDLER =
          HandlerEntry.of(ADAPT_STATE, ProductData::from);

  public static final HandlerEntry<Two<Completes<Collection<ProductData>>, ProductQueries>> QUERY_ALL_HANDLER =
          HandlerEntry.of(ALL_PRODUCTS, $queries -> $queries.allProducts());

}
```

The `HandlerEntry` relates an integer index to a function that invokes an aggregate method. Through that index, an aggregate/queries method can be set as the handler of a specific route as showed in the `ProductResource` interface:

```java
@Route(method = POST, handler = ProductResourceHandlers.REGISTRATION)
...
Completes<Response> register(@Body final ProductData data);
```

The return type of the mapped method, along with the types of its parameters are respectively defined by the `HandlerEntry` generics. In other words, the first generic type, from left to right, is always the method return type, so, in the  `HandlerEntry` corresponding to the  *Product Registration,*`Completes<ProductState>` is the return type when `Product.register` is invoked while  `Stage` and `ProductData` are the parameter types.

```java
... HandlerEntry<Three<Completes<ProductState>, Stage, ProductData>> REGISTRATION_HANDLER =
     HandlerEntry.of(REGISTRATION , ($stage, data) -> Product.register($stage, data.name)); 
```

Usually, the generic types of a `HandlerEntry` match with the parameter types supported by its corresponding route. However, in the previous example, `Stage` is also a required parameter but it's not in the route signature. Fortunately, at compile-time, `Stage` and `Logger` are automatically included as an instance member in the auto-dispatch resource class. Just be aware that, for accessing any instance member inside a `HandlerEntry` function, you need always to use the `$ + memberName` pattern (e.g `$stage`, `$logger`).

Regarding the supported number of parameters, `HandlerEntry` is served by a set of interfaces for parameter type declaration which allow you to inform two to five parameter types:

```java
public interface Handler {

    @FunctionalInterface
    interface Two<A, B> extends Handler {
        A handle(B b);
    }

    @FunctionalInterface
    interface Three<A, B, C> extends Handler {
        A handle(B b, C c);
    }

    @FunctionalInterface
    interface Four<A, B, C, D> extends Handler {
        A handle(B b, C c, D d);
    }

    @FunctionalInterface
    interface Five<A, B, C, D, E> extends Handler {
        A handle(A a, B b, C c, D d, E e);
    }

}
```

{% hint style="info" %}
If your application only have`@AutoDispatch`resources, you are freed from annotating your bootstrap class with `@ResourceHandlers`.&#x20;
{% endhint %}

#### `@Model / @Queries`

The `@Model` and `@Queries` class-level annotations meets the condition that a `@AutoDispatch` route must perform operations on a specific [aggregate entity](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#actor-entity-lifecycles) or read data from a [query actor](/xoom-lattice/entity-cqrs#querying-a-statestore). That implies you have to use at least one of these annotations and, at most, one of each. Here's the supported field list:

| Attribute  | Type                                  | Description                                                                                                                                                 | Required |
| ---------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `protocol` | `Class<?>`                            | The aggregate / queries protocol (interface) class                                                                                                          | true     |
| `actor`    | `Class<? extends EntityActor/ Actor>` | The aggregate / queries actor class that has to extend respectively an [entity actor ](/xoom-lattice/entity-cqrs)and [Actor](/xoom-actors#creating-actors). | true     |
| `data`     | `Class<?>`                            | The adapted model type to be serialized in the response body. **Only supported in the @Model annotation.**                                                  | true     |

Note that, using `@Queries`,  you are able to access the *queries actor* inside the HandlerEntry function through the instance member named as `$queries` :

```java
public static final HandlerEntry<Two<Completes<Collection<ProductData>>, ProductQueries>> QUERY_ALL_HANDLER =
          HandlerEntry.of(ALL_PRODUCTS, $queries -> $queries.allProducts());
```

#### `@Route`

The `@Route` annotation has to be used at method-level mainly declaring a HTTP method. Optionally, you may inform a relative URI subpath and its handler index.

| Attribute | Type                         | Description                                                                                            | Required |
| --------- | ---------------------------- | ------------------------------------------------------------------------------------------------------ | -------- |
| `method`  | `io.vlingo.xoom.http.Method` | The supported HTTP method for a route                                                                  | Yes      |
| `path`    | `String`                     | The route subpath relative to the root path. If not informed, the root path is set by default.         | No       |
| `handler` | `int`                        | The index of the handler that will be invoked. If not informed, the annotated method must be concrete. | No       |

#### `@ResponseAdapter`

Also, a method-level annotation that enables a function call to adapt the request output. It only supports a single attribute.

| Attribute | Type  | Description                                                                | Required |
| --------- | ----- | -------------------------------------------------------------------------- | -------- |
| `handler` | `int` | The index of the handler that will be invoked to adapt the request output. | Yes      |

#### `@Id`

This useful annotation is applied to an entity id present in the route parameter. Under the hood, `@Id` indicates a route operation that is performed on an existing entity and makes VLINGO/XOOM responsible for loading it. So, the benefit is that you can just take care of using the loaded entity inside the `HandlerEntry` function.&#x20;

Let's go back to `ProductResource` and see how it works:

```java
...

public interface ProductResource {

  @Route(method = PATCH, path = "/{id}/profit-margin", handler = ProductResourceHandlers.PROFIT_MARGIN)
  @ResponseAdapter(handler = ProductResourceHandlers.ADAPT_STATE)
  Completes<Response> applyProfitMargin(@Id final String id, @Body final ProductData data);

  ...
}
```

The code slice above shows */profit-margin* route which has an id parameter properly annotated with `@Id` . Afterwards, its *handler* function is much simpler because it's benefited by the auto-loaded entity:

```java
  public static final HandlerEntry<Three<Completes<ProductState>, Product, ProductData>> PROFIT_MARGIN_HANDLER =
          HandlerEntry.of(PROFIT_MARGIN , (product, data) -> product.applyProfitMargin(data.profitMargin));
```

Finally, here, the `product` parameter is exactly the corresponding entity to the id passed in the route parameter.

#### `@Body`

Annotating a route parameter with `@Body` simply tells XOOM HTTP to deserialize the request payload into that parameter. In the following example, the payload is deserialized into a `ProductData` object.

```java
public interface ProductResource {

  @Route(method = POST, handler = ProductResourceHandlers.REGISTRATION)
  @ResponseAdapter(handler = ProductResourceHandlers.ADAPT_STATE)
  Completes<Response> register(@Body final ProductData data);
 
  ... 
}
```

### `@Persistence`

Regarding persistence configuration, through the `onInit()` method you can choose to manually create the code for the application infrastructure, as in the [Hello, World ](/getting-started/hello-world-1)example.

Alternatively, adopt`@Persistence` for a more succinct way to set up the persistence. By using that annotation, VLINGO XOOM supports auto-configuration of:

* The selected `Storage Type` for the Domain Model;
* When using CQRS, a `State Store`  for the Query Model and the selected `Storage Type` for the Command Model;
* Datasource connection, including schema/tables creation;

The example below shows how to enable persistence auto-configuration.&#x20;

```java
@Persistence(basePackage = "io.vlingo.xoom.turbo.annotation", storageType = STATE_STORE)
public class PersistenceSetup {

}
```

The next table describes `@Persistence` attributes:

| Attribute     | Type          | Description                                                                                                                                                              | Required |
| ------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `basePackage` | `String`      | The project's base package                                                                                                                                               | true     |
| `storageType` | `StorageType` | The [storage type](https://docs.vlingo.io/vlingo-symbio) for the Domain / Command model                                                                                  | true     |
| `cqrs`        | `Boolean`     | Using [CQRS](https://docs.vlingo.io/vlingo-lattice/entity-cqrs), two separate stores will be provided for the Command Model and Query Model. The default value is false. | false    |

The database credentials and other configuration parameters can be informed in three ways:

* `vlingo-xoom.properties`
* Environment variables;
* Combining both;

The supported properties and environment variables are listed below:

| Property Name         | Environment Variable              | Description                                                         | Required |
| --------------------- | --------------------------------- | ------------------------------------------------------------------- | -------- |
| `database`            | `VLINGO_XOOM_DATABASE`            | Database Type\*.  If IN\_MEMORY, other properties are not required. | true     |
| `database.name`       | `VLINGO_XOOM_DATABASE_NAME`       | Schema name.                                                        | true     |
| `database.driver`     | `VLINGO_XOOM_DATABASE_DRIVER`     | The qualified class name of JDBC Driver                             | true     |
| `database.url`        | `VLINGO_XOOM_DATABASE_URL`        | Connection URL                                                      | true     |
| `database.username`   | `VLINGO_XOOM_DATABASE_USERNAME`   | Database username                                                   | true     |
| `database.password`   | `VLINGO_XOOM_DATABASE_PASSWORD`   | Password                                                            | false    |
| `database.originator` | `VLINGO_XOOM_DATABASE_ORIGINATOR` | Id for the data origin                                              | true     |

\*Supported Database types: `IN_MEMORY, POSTGRES, HSQLDB, MYSQL, YUGA_BYTE`.

In case of CQRS, you can inform parameters of the Query Model Database just adding *"query"*  before the word *"database"*. For instance, the property `database` becomes `query.database`, the environment variable `VLINGO_XOOM_DATABASE` becomes `VLINGO_XOOM_QUERY_DATABASE.`

Here's an example of a database configuration in the `vlingo-xoom.properties`:

```java
database=POSTGRES
database.name=XOOM_APP_CMD_MODEL
database.driver=org.postgresql.Driver
database.url=jdbc:postgresql://localhost/
database.username=admin
database.password=pwd
database.originator=CMD

query.database=HSQLDB
query.database.name=XOOM_APP_QUERY_MODEL
query.database.driver=org.hsqldb.jdbcDriver
query.database.url=jdbc:hsqldb:mem:
query.database.username=sa
query.database.password=pwd
query.database.originator=QUERY
```

The following annotations are children of `@Persistence` and can be only used along with it.&#x20;

### @EnableQueries

`@EnableQueries` is an annotation correlated to `@Persistence` and provides the proper way to make VLINGO XOOM responsible for handling your [query actor](/xoom-lattice/entity-cqrs#querying-a-statestore) implementations. In other words, using this essential annotation, these implementations become a `QueryStateStoreProvider` property, so we only need to take care of accessing it and using it. For a practical understanding, take a look at the following configuration class:

```java
@Persistence(cqrs=true ...)
@EnableQueries({
        @QueriesEntry(protocol = CustomerQueries.class, actor = CustomerQueriesActor.class),
        @QueriesEntry(protocol = ProductQueries.class, actor = ProductQueriesActor.class),
})
public class PersistenceSetup {


}
```

`@EnableQueries` only accepts a combination of actor/protocol classes surrounded by the`@QueriesEntry` annotation which supports the following types:

| Attribute  | Type         | Description                            | Required |
| ---------- | ------------ | -------------------------------------- | -------- |
| `protocol` | `Class<?>`   | The`QueriesActor` protocol class       | true     |
| `actor`    | `Class<?>[]` | An `Array` of supported `DomainEvents` | true     |

Having the `@EnableQueries` properly configured, which also includes the attribute `cqrs`  of`@Persistence` set to *true***,** makes the compile-time generated `QueryStateStoreProvider`the holder of all mapped *queries actors*. So, as an illustration, let's say we need to use the `CustomerQueries` serving a *rest resource*:

```java
public class CustomerResource {

  public Completes<Response> queryAllCustomers() {
    final CustomerQueries customerQueries = QueryModelStateStoreProvider.instance().customerQueries;
    return customerQueries.allCustomers().andThenTo(data -> Completes.withSuccess(Response.of(Ok, serialized(data))));
  }
  
}
```

### @Projections

When using [CQRS](https://docs.vlingo.io/vlingo-lattice/entity-cqrs), `@Projections` relates the [projections ](/xoom-lattice/projections)to their supported events, so `DomainEvents` can be projected into the Query Model.

```java
@Persistence(...)
@Projections({
        @Projection(actor = CustomerProjectionActor.class, 
                becauseOf = {CustomerRegistered.class, CustomerNotified.class}),
        @Projection(actor = ProductProjectionActor.class, 
                becauseOf = {ProductDelivered.class, ProductSoldOut.class})
})
public class PersistenceSetup {

}
```

`@Projections` accepts only a list of `@Projection` with a pair of attributes:

| Attribute   | Type                                                                               | Description                            | Required |
| ----------- | ---------------------------------------------------------------------------------- | -------------------------------------- | -------- |
| `actor`     | <p><code>Class\<? extends</code></p><p><code>StateStoreProjectionActor></code></p> | A`ProjectionActor` class               | true     |
| `becauseOf` | `Class<?>[]`                                                                       | An `Array` of supported `DomainEvents` | true     |

### @Adapters

Add `@Adapters` for Aggregate/Entity state translation, so the object state within a service or application can be serialized to be persisted, and vice-versa. Here's how to set up:

```java
@Persistence(...)
@Adapters({CustomerState.class, ProductState.class})
public class PersistenceSetup {

}
```

Keep in mind that `@Adapters` and `@Projections` are not dependent but both can be naturally used together as follows:

```java
@Persistence(...)
@Projections({
        @Projection(actor = CustomerProjectionActor.class, 
                becauseOf = {CustomerRegistered.class, CustomerNotified.class}),
        @Projection(actor = ProductProjectionActor.class, 
                becauseOf = {ProductDelivered.class, ProductSoldOut.class})
})
@Adapters({CustomerState.class, ProductState.class})
public class PersistenceSetup {

}
```

### @DataObjects

With `@DataObjects` ,  VLINGO XOOM can also take care of the creation of database tables for *data objects*, which are commonly used for holding your query model data. All you need to do is to map the *data objects* as demonstrated below:

```java
@Persistence(...)
@DataObjects({CustomerData.class, ProductData.class})
public class PersistenceSetup {

}
```

Once *data objects* are mapped, if the database tables do not already exist, it will be automatically created during the application startup.


# Scooter

A VLINGO XOOM toolset for implementing Actors and DDD entities/aggregates with persistence using a familiar blocking paradigm, supporting stepwise adoption to our full Reactive toolset.

## A Gentle Introduction to Async

Admittedly most who refrain from the use of Reactive architectures, programming, and related tools, are generally concerned about the learning curve being too steep. Although a learning curve is indeed required, it's not as steep as most think. Whatever your expectations, we have provided a gentle path toward adopting Reactive. We think these will help you ease into Reactive.

Scooter offers a typical blocking paradigm for the purpose of gently introducing the tools and patterns generally used with DOMA and DDD.

## Modeling With Entities

In a typical object-based application or service that uses POJOs, the lifecycle of entities is different from that of actor-based entities. Here we can assume that Entity and Aggregate as defined by DDD are interchangeable; that is, what follows deals with both concepts.

### POJO Lifecycles

The following describes the typical lifecycle of a POJO Entity, which is what you will find when using Scooter:

* Non-existing Entity states are newly constructed and then persisted to storage
* Preexisting Entity states are reconstituted from storage, modified, and then persisted back to the same storage (updated).
* Across a single JVM or a multi-JVM cluster, there may be any number of duplicated Entity instances. This implies that any of the duplicate instances may simultaneously have different operations performed by different users. In such cases the database must provide optimistic concurrency and detect concurrency violations via state versions.
* The object reference is released after Entity persistence and the instance garbage collected.

To contrast this with the advantages of using Reactive Entities by means of XOOM Lattice, please see the [related documentation](/xoom-lattice/entity-cqrs#understanding-entity-actor-lifecycles).

### Implementing an `ObjectEntity`

Implementing a concrete entity that uses object-relational mapping requires that you extend the `ObjectEntity` type. First create a protocol in the same manner that would be used for a corresponding Reactive entity.

```java
import io.vlingo.xoom.lattice.model.DomainEvent;

public interface Employee {
  static Employee define() {
    return new EmployeeEntity();
  }

  void assign(final String number);
  void adjust(final int salary);
  void hire(final String number, final int salary);

  public static final class EmployeeHired extends DomainEvent { ... }
  public static final class EmployeeSalaryAdjusted extends DomainEvent { ... }
  public static final class EmployeeNumberAssigned extends DomainEvent { ... }
}
```

Next implement the concrete entity that implements the `Employee` protocol.

```java
import io.vlingo.xoom.lattice.model.DomainEvent;
import io.vlingo.xoom.turbo.scooter.model.object.ObjectEntity;

public class EmployeeEntity extends ObjectEntity<EmployeeState,DomainEvent> implements Employee {
  private EmployeeState employee;

  public EmployeeEntity() {
    this.employee = new EmployeeState(); // new; identified in state ctor
  }

  public EmployeeEntity(final long id) {
    this.employee = new EmployeeState(id); // recovery; see stateObject()
  }

  @Override
  public void assign(final String number) {
    apply(employee.with(number), new EmployeeNumberAssigned(...));
  }

  @Override
  public void adjust(final int salary) {
    apply(employee.with(salary), new EmployeeSalaryAdjusted(...));
  }

  @Override
  public void hire(final String number, final int salary) {
    apply(employee.with(number).with(salary), new EmployeeHired(...));
  }

  @Override
  public String id() {
    return String.valueOf(employee.persistenceId());
  }

  @Override
  protected void stateObject(final EmployeeState stateObject) {
    this.employee = stateObject;
  }
}
```

When reconstituting the `EmployeeEntity`, the `EmployeeState` will be read by the OR-Mapping `EmployeeRepository` and set in the `EmployeeEntity`.

The `EmployeeEntity` uses the `EmployeeState` type as the actual persistent object, and all mutations will be reflected in transitioning that type.

```java
import io.vlingo.xoom.common.identity.IdentityGenerator;

import java.util.concurrent.atomic.AtomicLong;

public class EmployeeState extends StateObject implements Comparable<EmployeeState> {
  private static final long serialVersionUID = 1L;

  private static final IdentityGenerator identityGenerator = new IdentityGenerator();

  public final int salary;
  public final String number;

  public EmployeeState(final String number, final int salary) {
    this(identityGenerator.nextLong(), number, salary);
  }

  public EmployeeState(final String id, final String number, final int salary) {
    super(id);
    this.number = number;
    this.salary = salary;
  }

  public EmployeeState(final String id) {
    this(id, null, 0);
  }

  EmployeeState() {
    super(identityGenerator.nextLong());
    this.number = "";
    this.salary = 0;
  }

  public EmployeeState with(final String number) {
    return new EmployeeState(this.persistenceId(), number, salary);
  }

  public EmployeeState with(final int salary) {
    return new EmployeeState(this.persistenceId(), number, salary);
  }

  @Override
  public int hashCode() {
    return 31 * number.hashCode() * salary;
  }

  @Override
  public boolean equals(final Object other) {
    if (other == null || other.getClass() != getClass()) {
      return false;
    } else if (this == other) {
      return true;
    }

    final EmployeeState otherPerson = (EmployeeState) other;

    return this.persistenceId() == otherPerson.persistenceId();
  }

  @Override
  public String toString() {
    return "EmployeeState[persistenceId=" + persistenceId() + " number=" + number + " salary=" + salary + "]";
  }

  @Override
  public int compareTo(final EmployeeState otherPerson) {
    return Long.compare(this.persistenceId(), otherPerson.persistenceId());
  }
}
```

To persist an instance of the `EmployeeEntity`'s `EmployeeState` to the database, use it's repository. Although we provide abstract bases of both `JournalRepository` and `StatefulRepository`, we can't do so for `ObjectRepository` due to the numerous different ways that Object-Relational Mapping can be implemented.

### Implementing `Sourced` Entities

Implementing a concrete entity that uses Event Sourcing requires that you extend one of the `SourcedEntity` base types, such as `EventSourcedEntity` or `CommandSourcedEntity`. First create a protocol in the same manner that would be used for a corresponding Reactive entity.

```java
public interface Product {
  static Product define(final String type, final String category, final String name, final String description, final long price) {
    return new ProductEntity(type, category, name, description, price);
  }

  void adjustPrice(final long price);
  void changeDescription(final String description);
  void rename(final String name);
}
```

Next implement the concrete entity that implements the `Product` protocol.

```java
import io.vlingo.xoom.turbo.scooter.model.sourced.EventSourcedEntity;

public class ProductEntity extends EventSourcedEntity implements Product {
  private String category;
  private String type;
  public String name;
  public String description;
  public long price;

  public ProductEntity(final String type, final String category, final String name, final String description, final long price) {
    apply(new ProductDefined(id(), type, category, name, description, price));
  }

  @Override
  public String id() {
    return streamName();
  }

  @Override
  public void adjustPrice(final long price) {
    apply(new ProductPriceAdjusted(id(), price));
  }

  @Override
  public void changeDescription(final String description) {
    apply(new ProductDescriptionChanged(id(), description));
  }

  @Override
  public void rename(final String name) {
    apply(new ProductRenamed(id(), name));
  }

  // INTERNAL USE ONLY: used by repository
  public ProductEntity(final List<Source<DomainEvent>> eventStream, final int streamVersion) {
    super(eventStream, streamVersion);
  }

  protected void whenProductDefined(final ProductDefined event) {
    this.name = event.name;
    this.description = event.description;
    this.price = event.price;
  }

  protected void whenProductDescriptionChanged(final ProductDescriptionChanged event) {
    this.description = event.description;
  }

  protected void whenProductPriceAdjusted(final ProductPriceAdjusted event) {
    this.price = event.price;
  }

  protected void whenProductRenamed(final ProductRenamed event) {
    this.name = event.name;
  }

  static {
    registerConsumer(Product.class, ProductDefined.class, Product::whenProductDefined);
    registerConsumer(Product.class, ProductDescriptionChanged.class, Product::whenProductDescriptionChanged);
    registerConsumer(Product.class, ProductPriceAdjusted.class, Product::whenProductPriceAdjusted);
    registerConsumer(Product.class, ProductRenamed.class, Product::whenProductRename);
  }
}
```

Note that this `ProductEntity` does not use an internal state type, although it could. There is an internal constructor that is to be used only by the repository, although it must be public since the implementations of `ProductEntity` and the repository are in two different packages. The `"when"` methods, which mutate the internal state of the entity as each event is applied, are registered in the static initializer and dispatched to by the base class just as they are with the corresponding Reactive entity types.

The following `JournalProductRepository` extends the Scooter `JournalRepository` and implements the `ProductRepository`.

```java
import io.vlingo.xoom.symbio.store.journal.Journal;
import io.vlingo.xoom.turbo.scooter.persistence.JournalRepository;

public class JournalProductRepository extends JournalRepository implements ProductRepository {
  private final EntryAdapterProvider entryAdapterProvider;
  private final Journal<String> journal;
  private final StreamReader<String> streamReader;

  @SuppressWarnings({ "rawtypes", "unchecked" })
  public JournalProductRepository(final Journal<String> journal) {
    this.journal = journal;
    this.streamReader = journal.streamReader("ProductStreams").await();
    this.entryAdapterProvider = PersistenceInitializer.instance().entryAdapterProvider;

    final EntryAdapter entryAdapter = PersistenceInitializer.instance().defaultEntryAdapter;

    entryAdapterProvider.registerAdapter(ProductDefined.class, entryAdapter);
    entryAdapterProvider.registerAdapter(ProductDescriptionChanged.class, entryAdapter);
    entryAdapterProvider.registerAdapter(ProductPriceAdjusted.class, entryAdapter);
    entryAdapterProvider.registerAdapter(ProductRenamed.class, entryAdapter);
  }

  @Override
  public Product productOf(final String productId) {
    final EntityStream<String> stream = streamReader.streamFor(productId).await();
    final List<Source<DomainEvent>> sources = entryAdapterProvider.asSources(stream.entries);
    return new ProductEntity(sources, stream.streamVersion);
  }

  @Override
  public void save(final Product product) {
    final AppendInterest interest = appendInterest();
    final ProductEntity entity = (ProductEntity) product;
    journal.appendAll(entity.id(), entity.nextVersion(), entity.applied().sources(), interest, null);
    await(interest);
  }
}
```

Note specifically the various uses of `await` in the repository implementation. This is to address the otherwise asynchronous nature of [XOOM Lattice](/xoom-lattice) and [XOOM Symbio](/xoom-symbio). See [`Completes::await()`](https://github.com/vlingo/vlingo-common/blob/8abd127d952498cffca6b1678d868cd4bffa454e/src/main/java/io/vlingo/common/Completes.java#L452) and [`JournalRepository::await(AppendInterest)`](https://github.com/vlingo/vlingo-xoom/blob/376597b5b6772c7add2c1173793076e35cc71a84/src/main/java/io/vlingo/xoom/scooter/persistence/JournalRepository.java#L43).

### Implementing a StatefulEntity

Implementing a concrete entity that uses key-value/state storage requires that you extend the `StatefulEntity` type. First create a protocol in the same manner that would be used for a corresponding Reactive entity.

```java
public static interface Person {
  static Person define(final Name name, final int age) {
    return new PersonEntity(new PersonState(name, age));
  }

  void changeName(final Name name);
  void increaseAge();
}
```

Next implement the concrete entity that implements the `Person` protocol.

```java
import io.vlingo.xoom.turbo.scooter.model.stateful.StatefulEntity;

public static class PersonEntity extends StatefulEntity<PersonState,DomainEvent> implements Person {
  private PersonState state;

  public PersonEntity(final PersonState state) {
    this.state = state;
  }

  @Override
  public void changeName(final Name name) {
    apply(state.withName(name));
  }

  @Override
  public void increaseAge() {
    apply(state.withAge(state.age + 1));
  }

  // StatefulEntity

  @Override
  public String id() {
    return state.id;
  }

  @Override
  public PersonState state() {
    return state;
  }

  @Override
  protected void state(final PersonState state) {
    this.state = state;
  }
}
```

The `PersonEntity` uses the `PersonState` type as the actual persistent object, and all mutations will be reflected in transitioning that type. Note that the `PersonEntity` does not emit domain events when it applies new state, although it is fully supported if the implementation uses events.

```java
public static class PersonState {
  public final String id;
  public final String name;
  public final int age;

  public PersonState(final String id, final String name, final int age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }

  public PersonState(final String id) {
    this(id, null, 0);
  }

  public PersonState copy() {
    return new PersonState(id, name, age);
  }

  public boolean hasState() {
    return id != null && name != null && age > 0;
  }

  public PersonState withName(final String name) {
    return new PersonState(this.id, name, this.age);
  }

  public PersonState withAge(final int age) {
    return new PersonState(this.id, this.name, age);
  }

  @Override
  public boolean equals(final Object other) {
    if (other == null || other.getClass() != this.getClass()) {
      return false;
    }
    final PersonState otherState = (PersonState) other;
    return this.id.equals(otherState.id);
  }

  @Override
  public String toString() {
    return "PersonState[id=" + id + " name=" + name + " age=" + age + "]";
  }
}
```

The following `PersonRepository` extends the Scooter `StatefulRepository`.

```java
import io.vlingo.xoom.symbio.store.state.StateStore;
import io.vlingo.xoom.turbo.scooter.persistence.StatefulRepository;

public class PersonRepository extends StatefulRepository {
  private final StateStore store;

  public PersonRepository(final StateStore store) {
    this.store = store;
  }

  public Person personOf(final String id) {
    final ReadInterest interest = readInterest();
    store.read(id, PersonState.class, interest);
    return await(interest);
  }

  public void save(final Person person) {
    final WriteInterest interest = writeInterest();
    final PersonEntity entity = (PersonEntity) person;
    final PersonState state = entity.state();
    store.write(state.id, state, entity.currentVersion(), interest);
    await(interest);
  }
}
```

Note specifically the uses of `await` in the repository implementation. This is to address the otherwise asynchronous nature of [XOOM Lattice](/xoom-lattice) and [XOOM Symbio](/xoom-symbio). See the source of[`StatefulRepository`](https://github.com/vlingo/vlingo-xoom/blob/master/src/main/java/io/vlingo/xoom/scooter/persistence/StatefulRepository.java) for uses of `await(ReadInterest)` and `await(WriteInterest)`. The `await(ReadInterest)` returns the result of the `StateStore::read()` once it has completed.

## Persistence

Use the `JournalRepository` abstract base class to implement repositories for `SourcedEntity` types that use Event Sourcing, Command Sourcing, or another type. You can see an implementation in the [previous section](/xoom-turbo/scooter#implementing-sourced-entities).

```java
import io.vlingo.xoom.symbio.store.journal.Journal;
import io.vlingo.xoom.turbo.scooter.persistence.JournalRepository;

public class JournalProductRepository extends JournalRepository implements ProductRepository {
  private final EntryAdapterProvider entryAdapterProvider;
  private final Journal<String> journal;
  private final StreamReader<String> streamReader;

  @SuppressWarnings({ "rawtypes", "unchecked" })
  public JournalProductRepository(final Journal<String> journal) {
    this.journal = journal;
    this.streamReader = journal.streamReader("ProductStreams").await();
    this.entryAdapterProvider = PersistenceInitializer.instance().entryAdapterProvider;
    ...
  }
  ...
}
```

Use the `StatefulRepository` abstract base class to implement repositories for `StatefulEntity` state types. You can see an implementation in the [previous section](/xoom-turbo/scooter#implementing-a-statefulentity).

```java
import io.vlingo.xoom.symbio.store.state.StateStore;
import io.vlingo.xoom.turbo.scooter.persistence.StatefulRepository;

public class PersonRepository extends StatefulRepository {
  private final StateStore store;

  public PersonRepository(final StateStore store) {
    this.store = store;
  }
  ...
}
```

Although we provide abstract bases of both `JournalRepository` and `StatefulRepository`, we can't do so for an `ObjectRepository` due to the numerous different ways that Object-Relational Mapping can be implemented. You may follow one of the styles exemplified in [*Implementing Domain-Driven Design*](https://kalele.io/books/)*.*

## Blocking Mailbox

If you consider asynchronous actor messaging to be daunting, why not trying synchronous actor messaging?

The tool provided is a specialized actor mailbox. You can read more about actors and the role of their mailboxes [here](/xoom-actors#how-do-actors-work) and [here](/architecture#message-driven-runtime). The XOOM Actors tooling supports any number of mailbox plugins. The particular one provided by Scooter is a blocking mailbox that requires the actor to handle the message before the sender receives control again.

```java
import io.vlingo.xoom.turbo.scooter.plugin.mailbox.blocking.BlockingMailbox;
```

This mailbox works by delivering a message to the target actor immediately rather than leaving the message for another thread to deliver. This allows you to get the feel of actor-based programming but without the unfamiliar nuances of asynchrony.

There is a potential problem with this. When you consider a request-response example, where the actor must send a message back to its sender. What would happen if the request handling actor and the response handling actor continued indefinitely sending each other messages rather than stopping after one? Correct, an ugly stack overflow would soon happen, or even re-entering an actor on the same thread and potentially modifying its state unexpectedly before the first message delivery has returned.

To prevent this the blocking mailbox does in fact implement a queue. It protects access to the queue using a compare-and-set operation. This limits the queue polling to only the first arriving enqueuing access. Think of the same thread that delivers to the request actor, next delivering a message to the response actor on the same thread. As described previously, this could cause a number of problems. So, what should be done?

```java
public class BlockingMailbox implements Mailbox {
  ...
  public void send(final Message message) {
    if (isClosed()) return;

    queue.add(message);

    if (isSuspended()) {
      return;
    }

    try {
      boolean deliver = true;

      while (deliver) {
        if (delivering.compareAndSet(false, true)) {
          while (deliverAll())
            ;
          delivering.set(false);
        }
        deliver = false;
      }
    } catch (Throwable t) {
      if (delivering.get()) {
        delivering.set(false);
      }
      throw new RuntimeException(t.getMessage(), t);
    }
  }
  ...
}
```

Consider the above `send(Message message)` method of the `BlockingMailbox`. The mailbox invocation that occurs first locks the mailbox queue, but without blocking another attempt to lock. The compare-and-set prevents blocking on any secondary deliveries. So a second, third, forth, etc., delivery on the same thread enqueues the message, and when it sees that access is already reserved, it simply returns. When the message deliveries (method invocations) unwind, the original access will see all additional messages enqueued and deliver them. This could go on for a long time without causing issues, as long as the stack is given the opportunity to unwind before the queue causes an out-of-memory condition.

We suggest that you not plan to use the `BlockingMailbox` for all future development. It is provided more as a learning tool, rather than a production worthy tool. Using it in production for most or all actors gives you no advantages over a normal blocking paradigm with direct method invocations. Instead, we suggest that you use the above blocking entity types since they take advantage of strengths of direct method invocations.


# Actors

Describes the XOOM platform Reactive foundation and demonstrates how it is used.

## **Actor Model Foundation**

In 1973, Dr. Carl Hewitt and his colleagues formulated the Actor Model. In recent years, the inventor of object orientation, Alan Kay, has stated that the Actor Model retained more of what he thought were the important object ideas. So, when you think of the Actor Model, think of objects done right.

![A Resource actor sending a command message to a Model Entity actor.](/files/-M9CQm0xaXGxpQmk9Rk6)

The XOOM Actors toolkit is an implementation of the Actor Model, and all primary platform components are built on our Actor Model implementation. Read on for detailed information on the use of XOOM Actors.

## What Are Actors?

XOOM Actors is an implementation of the Actor Model. The ideas behind the Actor Model are pretty simple, and these points show how XOOM Actors implement it.

1. The basic unit of computation is expressed through actors. Actors are basically objects, but their behaviors are requested by sending messages asynchronously rather than through directly invoking their methods. This enables all communication between actors to be performed through asynchronous messaging passing. Determined by a scheduler, each actor that has been sent a message will be given the opportunity to receive and process it, which also happens asynchronously.
2. Actors can create other actors. As Carl Hewitt is known to say, “One actor is no actors. Actors come in systems.” Thus, your applications should use not just some actors, but many actors. Understand that once you start down the road of asynchronous behaviors, you are all in. Just as you *don’t kind of* go swimming, because you are either completely wet, or you are not, you *don't kind of* use actors. If you try to fight the asynchrony, you will experience pain and software with very strange bugs.
3. Each actor can designate the behavior it will exhibit for the next message it receives. This is roughly the *State* pattern. Any actor using the XOOM Actors toolkit can dynamically *become* another kind of actor in preparation for handling its current state and any subsequent messages.
4. What is most unique about the XOOM Actors implementation is *type safety by design,* and the simplicity with which is it implemented and consumed. All that a programmer needs to understand is interfaces and implementation classes, and they get the asynchrony for free.
5. Most other actor implementations use a *receive* method or code block that takes *Object* (or *Any*) as a parameter. Thus, the *receive* needs to determine which messages to accept and which ones are not permitted at any given time; this may be especially necessary when the actor designates its next behavior (it *becomes* another type of actor). Also what is unique about XOOM Actors is that the current designated behavior can be based on a different interface that is implemented by the actor. In other words, any one actor can implement multiple interfaces and receive messages for any given interface when it chooses to.
6. Most modern actor model implementations use mailboxes to deliver messages. Each actor has a mailbox where messages are received into a FIFO queue, and each message is processed one at a time on an available thread. This is true for XOOM Actors, yet there are special kinds of mailboxes that have certain advantages (and possibly disadvantages).
7. You can tune your actor’s *world* and *stage* to support any number of threads, but it’s best to limit this number based on the available number of processor hyper-threaded cores, or a bit more. Fundamentally, you can’t run more threads simultaneously than there are available cores, e.g. `Runtime.getRuntime().availableProcessors()`.

Using objects in a typical fashion, such as with Java or C#, we have become accustomed, even addicted, to a blocking paradigm.

![A Client object invoking a method on a Server object, which blocks the Client.](/files/-M9CRQGKMEEkaRv8yOWQ)

Here a Client object invokes a method on a Server object. Understand that this is an in-process (in-VM) invocation, not a remote client and a remote server. The point is, when a method invocation occurs, the Client is blocked until the Server returns from the method invocation. In contrast, the Actor Model works differently.

![The Actor Model is message-driven and processes messages asynchronously.](/files/-M9H6GP5fgTaQMlKQk5u)

When the Sender actor wants another actor to provide a service, it sends that actor a message. The message is sent to the Receiver actor and handled asynchronously, but not until a thread is available. The Sender continues moving forward with its current activities, and when completed returns from its own message handling.

As previously stated, with the various Actor Model implementations (e.g. Erlang and Elixir), neither messages or the message receiver are strongly typed. Yet, with XOOM Actors type-safe messages are the fundamental building block, not an experimental afterthought. A strongly-typed Actor Model implementation is important at this time when type safety is in high demand and can provide much more reliable systems.

With its careful but simple design, XOOM Actors are a great foundation on which to build the other tools in the XOOM platform.

## How Do Actors Work?

Actors collaborate by sending messages, one actor to another. When there are hundreds, thousands, or millions of actors, there are many actors sending messages simultaneously. Still, any one actor can send only one message to one other actor at a time. Following that, the same actor can send a message to the same actor or a different actor. This fulfills [the first point of the following description of the actor message-receiving contract](https://en.wikipedia.org/wiki/Actor_model).

> An actor is a computational entity that, in response to a message it receives, can concurrently:
>
> * send a finite number of messages to other actors;
> * create a finite number of new actors;
> * designate the behavior to be used for the next message it receives.
>
> There is no assumed sequence to the above actions and they could be carried out in parallel.

Actors also must be able to fulfill the second and third points: actors can create child actors, and actors can prepare themselves for subsequent message receipt.

## Actors in Action

Now consider a brief tutorial on XOOM Actors. This tutorial takes you through preparing your build environment and also how to implement two actors that collaborate to accomplish a goal.

To get started, create your own playground project to work with. You can name this project `playground`. If you use Maven, place a dependency into your playground’s `pom.xml` file.

```markup
 ...
 <dependencies>
  <dependency>
   <groupId>io.vlingo.xoom</groupId>
   <artifactId>xoom-actors</artifactId>
   <version>x.y.z</version>
  </dependency>
 </dependencies>
 ...
```

If you prefer Gradle, insert the following into your `build.gradle`.

```groovy
dependencies {
    compile 'io.vlingo.xoom:xoom-actors:x.y.z'
}

repositories {
    jcenter()
}
```

The `x.y.z` is a semantic version number and reflects the version of xoom-actors JAR file that you depend on. This number may be something such as `1.8.0`. You will find the available versions, including the most recent version, available on one of the supported public repositories.

Additionally, add a JUnit dependency into your build script since the tutorial uses JUnit to run the actor collaboration.

```markup
 ...
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 ...
```

Or if using Gradle:

```groovy
dependencies {
    compile 'junit:junit:4.11'
}
```

Although there are a few different ways to configure the XOOM Actors runtime environment, we will skip that step here. It's easier to start with reasonable defaults instead. The configuration approaches are presented later.

Without delay, consider the really fun part—the programming. You are going to create a really basic Ping Pong game.

![The Pinger and Ponger send message to and receive messages from each other.](/files/-M9HLGOSkvs_8k4a95RN)

You need to create a few Java interfaces and classes. There’s a Java interface that acts as the type safe messaging protocol of the first actor that you will create. For now, create a `Pinger` interface with a single method definition, named `ping()`, which takes a `Ponger` as a parameter.

```java
package playground;

import io.vlingo.xoom.actors.Stoppable;

public interface Pinger extends Stoppable {
  void ping(final Ponger ponger);
}
```

Next create a `Ponger` interface the same way, but with a `pong()` method that takes a `Pinger` as a parameter.

```java
package playground;

import io.vlingo.xoom.actors.Stoppable;

public interface Ponger extends Stoppable {
  void pong(final Pinger pinger);
}
```

Now you have two protocols or two different actors. These define the type-safe behaviors that one or more actors will implement, and the means by which clients will interact with the actors. In case it’s not obvious, `Pinger` is a client of `Ponger`, and `Ponger` is a client of `Pinger`.

It’s time to create two simple actors. First create one to implement the `Pinger` protocol.

```java
package playground;

import io.vlingo.xoom.actors.Actor;

public class PingerActor extends Actor implements Pinger {
  private final Pinger self;

  public PingerActor() {
    self = selfAs(Pinger.class);
  }

  public void ping(final Ponger ponger) {
    ponger.pong(self);
  }
}
```

After that, create another actor to implement the `Ponger` protocol.

```java
package playground;

import io.vlingo.xoom.actors.Actor;

public class PongerActor extends Actor implements Ponger {
  private final Ponger self;

  public PongerActor() {
    self = selfAs(Ponger.class);
  }

  public void pong(final Pinger pinger) {
    pinger.ping(self);
  }
}
```

You now have two actors that collaborate to play ping pong. The problem is that these actors will play ping pong nonstop, forever, unless we do something to prevent that. Doing so demonstrates how actors can maintain their own state, just like typical objects.

```java
package playground;

import io.vlingo.xoom.actors.Actor;

public class PingerActor extends Actor implements Pinger {
  private int count;
  private final Pinger self;

  public PingerActor() {
    count = 0;
    self = selfAs(Pinger.class);
  }

  public void ping(final Ponger ponger) {
    if (++count >= 10) {
      self.stop();
      ponger.stop();
    } else {
      ponger.pong(self);
    }
  }
}
```

Looking back at the `Pinger` and `Ponger` interface definitions, you will notice that both of these protocols extend the `Stoppable` protocol. Thus, they can both be stopped by other actors that have a `Stoppable` reference to them. We use that capability from within `PingerActor` to cause both actors to stop when the `count` reaches `10`.

Note that in this case the actors are not required to implement their own `stop()` methods. That’s because the abstract base class, `Actor`, implements `stop()` for them. You could override `stop()` to find out when your actor is being stopped, but that’s not necessarily a good idea. What if you forgot to invoke the super’s `stop()`? That would make you think that your actor was going to stop, but the actor would never shut down because the `Actor` base class behavior would never be run. If you want to know when you are being stopped, you can override one of the four life cycle methods instead of `stop()`.

```java
package playground;

import io.vlingo.xoom.actors.Actor;

public class PingerActor extends Actor implements Pinger {
  private int count;
  private final Pinger self;

  public PingerActor() {
    count = 0;
    self = selfAs(Pinger.class);
  }

  public void ping(final Ponger ponger) {
    if (++count >= 10) {
      self.stop();
      ponger.stop();
    } else {
      ponger.pong(self);
    }
  }

  @Override
  protected void afterStop() {
    logger().log("Pinger " + address() + " just stopped!");
    super.afterStop();
  }
}
```

All five life cycle methods are:

* `beforeStart()`
* `afterStop()`
* `beforeRestart(final Throwable reason)`
* `afterRestart(final Throwable reason)`
* `beforeResume(final Throwable reason)`

These enable you to see when significant life cycle events occur with your actor. The restart life cycle methods are related to actor supervision. When your actor’s supervisor sees your actor failed with an `Exception`, it can take a number of actions. Your supervisor can tell your actor to resume, to stop, or to restart. If it tells your actor to resume, the `beforeResume()` is invoked. When it tells your actor to restart, the `beforeRestart()` is invoked first, and then the `afterRestart()` is invoked. Since your actor has failed, it may have been left in an invalid state. In such cases, these three life cycle methods give your actor the opportunity to clean up after the problem that caused the `Exception` and also reinitialize itself before reacting to its next available protocol message.

{% hint style="info" %}
The `Exception` recovery methods DO NOT cause the `Actor` instance to be completely discarded and recreated. Therefore, it is the responsibility of the `Actor` to set its state to a safe point before message processing resumes.
{% endhint %}

The above `afterStop()` method shows two additional perks of XOOM Actors. All actors have a personal address, which is available through your inherited `address()` method. Also, all actors have a `Logger` available via its `logger()` method. Any information that you log will be output asynchronously through a registered `Logger` actor, so your actor won't block while file output is performed.

Alright, we have two actors, but how do we bring the actors to life in the first place, and how do we get them to start collaborating in game play? Here’s how you start up the `World` for your actors to play in.

```java
package playground;

import org.junit.Test;

import io.vlingo.xoom.actors.Definition;
import io.vlingo.xoom.actors.World;

public class PlaygroundTest {

  @Test
  public void testPlayPingPong() {
    final World world = World.startWithDefaults("playground");
    final Pinger pinger = world.actorFor(Pinger.class, PingerActor.class);
    final Ponger ponger = world.actorFor(Ponger.class, PongerActor.class);

    pinger.ping(ponger);

    pauseThisThread();

    world.terminate();
  }
}
```

When this test is run, a `World` is created. The `World` is a major component of XOOM Actors. In a nutshell, a `World` is the primary container within which actors live and play. Generally you would create only one `World` per service instance. In DDD terms, a `World` is the root of a *Bounded Context.* (Don't worry about the use of `pauseThisThread()`; it is explained below.)

After the `World` is started, two actors are created, and a reference to their respective protocol is returned. Each actor is created by passing its protocol and the concrete actor type. You may also create actors by means of a `Definition`. The `Definition` indicates the class of the actor that implements the protocol, such as `PingerActor.class`, which implements the `Pinger.class` protocol. There are four ways to instantiate an actor by means of its constructor:

* Design the actor with a zero-parameter constructor, which is the case in the above example.
* Pass the implementation class type as the second parameter to `actorFor()` as seen above, and also pass each constructor parameter following the implementation class type. This has the advantage of making the parameters visible, but they are passed as *varargs* each of type `Object`, and are thus not type-safe.
* Create and pass a `Definition` object as the second parameter to `actorFor()`. The `Definition` contains the class of the actor implementation and a possibly one or more constructor parameters, or it can pass `Definition.NoParameters`. See the next code example for how to pass constructor parameters. This approach is also not type safe.
* All three of the above actor instantiation options use reflection to call the actor's constructor. Use of reflection can be avoided and at the same time also provide absolute type-safe constructor parameters. To accomplish this, implement a factory for your various actor types using the`ActorInstantiator`, a functional interface included in the `xoom-actors` SDK and runtime. Construct your specific `ActorInstantiator` type, pass any actor constructor parameters into the `ActorInstantiator` constructor. When the actor is ready to be created by the runtime, the `ActorInstantiator` method blah will be called. At that time call the specific actor's constructor when using `new`. (See example provided below.)

With these options available, consider the following (non-working) example of the `PingerActor` taking two parameters, a `String` and an `int`, using the `Definition` approach:

```java
    final Pinger pinger = world.actorFor(
            Pinger.class,
            Definition.has(
                    PingerActor.class,
                    Definition.parameters("Hey, yo!", 42),
                    "name-that-actor"));
```

The simplest way to create an actor with constructor parameters is by means of the following shorthand method, but with the downside that the parameters are not checked for type safety by the compiler but instead at runtime when matching parameter types to a specific constructor:

```java
final Pinger pinger = world.actorFor(Pinger.class, PingerActor.class, "Hey, yo!", 42);
```

The following example employs a type-safe `ActorInstantiator`, which does not require the use of reflection:

```java
public class PingerInstantiator implements ActorInstantiator<PingerActor> {
  private final String message;
  private final int value;

  public ProtocolInstantiator(final String message, final int value) {
    this.message = message;
    this.value = value;
  }

  @Override
  public ProtocolActor instantiate() {
    return new PingerActor(message, value);
  }

  @Override
  public Class<PingerActor> type() {
    return PingerActor.class;
  }
}
```

There are three ways to use the `PingerInstantiator`, each of which is demonstrated separately in the follow example:

```java
// Pass in a Definition
final PingerInstantiator instantiator = new PingerInstantiator("Hey, Yo!", 42);
final Pinger pinger = world.actorFor(Pinger.class, Definition.has(PingerActor.class, instantiator));


// Pass directly as an ActorInstantiator
final Pinger pinger = world.actorFor(Pinger.class, PingerActor.class, new PingerInstantiator("Hey, Yo!", 42));

// Use the FunctionalInterface for lazy instantiation
final Pinger pinger = world.actorFor(Pinger.class, () -> new PingerInstantiator("Hey, Yo!", 42));
```

Look over the XOOM Actors [source code repository](https://github.com/vlingo/xoom-actors) for the several different ways that an actor can be created, including with a specific parent, a non-default logger, and a specialized supervisor.

One additional point about the unit test is appropriate. As you probably noticed, a method named `pauseThisThread()` is used.

```java
  ...
  private void pauseThisThread() {
    try { Thread.sleep(100); } catch (Exception e) { }
  }
  ...
```

Some sort of coordination is necessary because the actors send and receive all protocol messages asynchronously. Recall that there will be a total of 10 pings. Since the messages are all delivered and reacted to asynchronously, there is no “automatic” way to know when all the messages, including the `stop()` for both actors, have been delivered.

{% hint style="danger" %}
Don't use `Thread.sleep()`in your tests or your production services.
{% endhint %}

Even so, this particular sleep approach is not correct, because on different machines a given sleep time may be insufficient for all messages to process. It's actually guess work to try to get this right. Additionally, if you configure a long-enough sleep time that will work for every possible machine and process load, it's going to make your tests slow on very fast machines and environments. *So, one reason for showing you this in the example is to emphasize that you should not use thread sleeps.*

The following shows how you can more conveniently test actors without using the thread sleep artifice. It uses the `io.vlingo.xoom.actors.testkit.TestUntil` component. This example also demonstrates how actors take constructor parameters. In the test method, create an instance of the `TestUntil` to pass to the `PingerActor` constructor.

```java
public class PlaygroundTest {

  @Test
  public void testPlayPingPong() {
    final World world = World.start("playground");
    final TestUntil until = TestUntil.happenings(1);
    final Pinger pinger = world.actorFor(Pinger.class, Definition.has(PingerActor.class, Definition.parameters(until)));
    final Ponger ponger = world.actorFor(Ponger.class, Definition.has(PongerActor.class, Definition.NoParameters));

    pinger.ping(ponger);

    until.completes();

    world.terminate();
  }
}
```

Then refactor `PingerActor` to take a `TestUntil` instance as a constructor parameter.&#x20;

{% hint style="info" %}
**Using the `Proxy` Protocol**

Note that the above test is provided with `Pinger` and `Ponger` instances. These are not direct references to the underlying `PingerActor` and `PongerActor` instances, but are instead proxies. Invoking a method on a proxy causes a message to be created and enqueued for the actor that backs the proxy.

Every such proxy implements a `Proxy` type. This can be used to access the `Address` of the actor using `address()`. In addition, all proxies supports working `equals()`, `hashCode()`, and `toString()` implementations.

Since the `Proxy` interface is not available by way of the `Pinger` protocol (or any other actor protocols), there is a way to obtain the Proxy instance:

`final Address address = Proxy.from(pinger).address();`

The `Proxy` type is available in the `io.vlingo.xoom.actors` package.
{% endhint %}

Additionally, the `PingerActor` must cause a `happened()` in its `afterStop()` method to signal to the test that the `Pinger` has stopped:

```java
public class PingerActor extends Actor implements Pinger {
  private int count;
  private final Pinger self;
  private final TestUntil until;

  public PingerActor(final TestUntil until) {
    this.until = until;
    this.count = 0;
    this.self = selfAs(Pinger.class);
  }
  ...
  @Override
  protected void afterStop() {
    logger().log("Pinger " + address() + " just stopped!");
    until.happened();
    super.afterStop();
  }
}
```

Before the `afterStop()` method causes the `until.happened()` the test method will block. As soon as the `until.happened()` causes its state to transition from `1` to `0`, the test will unblock and the `World` will terminate. This enables the test to complete.

{% hint style="warning" %}
Don't use `TestUntil` in code that will be used in production. Further, as is seen later in this chapter, you should actually use `AccessSafely` rather than `TestUntil`. It is not only thread safe, but also provides memory fences/gates around multi-threaded state modifications during tests.
{% endhint %}

Although *passing a test construct into a production-quality actor is poor design choice,* this example is only to show you that there are very reliable ways to test actors in an asynchronous messaging environment. Later you will see much better uses of `TestUntil` and other `io.vlingo.xoom.actors.testkit` tools.

In order to make the ping pong playground produce some output, create some log output in the `ping()` and `pong()` methods.

```java
  // in Pinger
  ...
  public void ping(final Ponger ponger) {
    ++count;
    logger().log("ping " + count);
    if (count >= 10) {
      self.stop();
      ponger.stop();
    } else {
      ponger.pong(self);
    }
  }
  ...

  // in Ponger
  public void pong(final Pinger pinger) {
    logger().log("pong");
    pinger.ping(self);
  }
  ...
```

When the test is run, you will see the following output.

```bash
vlingo/actors(test): ping 1
vlingo/actors(test): pong
vlingo/actors(test): ping 2
vlingo/actors(test): pong
vlingo/actors(test): ping 3
vlingo/actors(test): pong
vlingo/actors(test): ping 4
vlingo/actors(test): pong
vlingo/actors(test): ping 5
vlingo/actors(test): pong
vlingo/actors(test): ping 6
vlingo/actors(test): pong
vlingo/actors(test): ping 7
vlingo/actors(test): pong
vlingo/actors(test): ping 8
vlingo/actors(test): pong
vlingo/actors(test): ping 9
vlingo/actors(test): pong
vlingo/actors(test): ping 10
```

You can find an implementation of this tutorial code in the [xoom-examples repository](https://github.com/vlingo/xoom-examples).

Now that this tutorial has given you some of the most import knowledge about XOOM Actors, you are ready to take a deeper dive into more details about the other facilities provided by XOOM Actors.

## API

This section provides a how-to for the XOOM Actors toolkit API. The details are covered in sections. Some of these details are already demonstrated in the previous sections, including the tutorial.

{% hint style="info" %}
An integral component used to manage asynchronous behaviors provided by actors is the `Completes<T>` protocol with its backing implementation. Being cited in this chapter and others, it's best to understand how it works. To do so, refer to our discussion provided in the `Completes<T>` [documentation](/xoom-common#completes).
{% endhint %}

### Starting and Terminating the Actor Runtime

To start up the XOOM Actors runtime you start the `World` object as follows.

```java
final World world = World.startWithDefaults("my-world");
```

This starts a `World` with normal runtime defaults in which `Actor` instances are created and run. For many uses of XOOM Actors the defaults are the easiest and safest way to use the `Actor`runtime.

![The XOOM Actors World contains components that manage the reactive runtime.](/files/-M9H6mN_fDOdJsXTpsIx)

There are a few different ways to start a `World`. The following is a summary.

Use this API when you want to start a `World` by loading configurations from the file named `xoom-actors.properties`. The `name` is used to name the `World` instance.

```java
public static World start(final String name)
```

The following API is used when you want to start a `World` with your own name-value pairs using `java.util.Properties` defined in code. The details of the `xoom-actors.properties` file are discussed below.

```java
public static World start(final String name, final java.util.Properties properties)
```

A `World` can be started using fluent configuration.

```java
public static World start(final String name, final Configuration configuration)
```

The details of programatic `Configuration` are discussed below.

When you are preparing to shut down your application or service that is using the `World`, you should use the following to terminate the `Actor` runtime.

```java
world.terminate();
```

The `World::terminate()` method is currently a synchronous operation, but in the future will become asynchronous. When the `World` terminates asynchronously there will be a `Completes<T>` or callback construct to inform the client when the termination has completed.

#### Using the xoom-actors.properties File

The `Actor` runtime may be configured by means of a file that adheres to the `java.util.Properties` conventions. Each property is defined by a `name` followed by `=` and then a `value`. For the XOOM Actors toolkit the file must be named `xoom-actors.properties` and be located in the runtime `classpath`. The following shows how the standard `ConcurrentQueueMailbox` can be defined in this properties file.

```bash
plugin.name.queueMailbox = true
plugin.queueMailbox.classname =\
   io.vlingo.xoom.actors.plugin.mailbox.concurrentqueue.ConcurrentQueueMailboxPlugin
plugin.queueMailbox.defaultMailbox = true
plugin.queueMailbox.numberOfDispatchersFactor = 1.5
plugin.queueMailbox.dispatcherThrottlingCount = 1
```

When defining properties in a properties file, long lines may be continued by placing an escape character of `\` at the end of the line to be continued on the next line. To see example properties that can be used, you should review: [`xoom-actors/src/test/resources/xoom-actors.properties`](https://github.com/vlingo/xoom-actors/blob/master/src/test/resources/xoom-actors.properties)

Also the next subsection shows several configuration type objects and options.

#### Using Programmatic Configurations

As an alternative to using the file-based configuration, you can instead employ a configuration approach that provides a fluent API, an example of which follows.

```java
final Configuration configuration =
  Configuration
    .define()
    .with(PooledCompletesPluginConfiguration
      .define()
      .mailbox("queueMailbox")
      .poolSize(10))
    .with(SharedRingBufferMailboxPluginConfiguration
      .define()
      .ringSize(65535)
      .fixedBackoff(2)
      .dispatcherThrottlingCount(10))
    .with(ManyToOneConcurrentArrayQueuePluginConfiguration
      .define()
      .ringSize(65535)
      .fixedBackoff(2)
      .dispatcherThrottlingCount(10)
      .sendRetires(10))
    .with(ConcurrentQueueMailboxPluginConfiguration
      .define()
      .defaultMailbox()
      .numberOfDispatchersFactor(1.5f)
      .dispatcherThrottlingCount(10))
    .with(JDKLoggerPluginConfiguration
      .define()
      .defaultLogger()
      .name("vlingo/actors(test)")
      .handlerClass(DefaultHandler.class)
      .handlerName("vlingo")
      .handlerLevel("ALL"))
    .with(CommonSupervisorsPluginConfiguration
      .define()
      .supervisor("default", "pingSupervisor", Ping.class, PingSupervisorActor.class)
      .supervisor("default", "pongSupervisor", Pong.class, PongSupervisorActor.class))
    .with(DefaultSupervisorOverridePluginConfiguration
      .define()
      .supervisor("default", "overrideSupervisor", DefaultSupervisorOverride.class))
    .usingMainProxyGeneratedClassesPath("target/classes/")
    .usingMainProxyGeneratedSourcesPath("target/generated-sources/")
    .usingTestProxyGeneratedClassesPath("target/test-classes/")
    .usingTestProxyGeneratedSourcesPath("target/generated-test-sources/");
```

Follow the configuration definition it can be used to start the `World` instance.

```java
final World world = World.start("my-world", configuration);
```

#### World Miscellaneous Resources

In addition to the above facilities, a `World` provides the following. All concrete `Actor` instance may obtain both their `Stage` and their `World` instances as follows, which enables the `Actor` to reach specific facilities offered by each.

```java
// inside an actor
final Configuration configuration = stage().world().configuration();
```

You may require the use of the means to create unique `Actor` addresses or a way to produce an address from a primitive or `String` value. To do so, request it by means of the method `addressFactory()`.

```java
public AddressFactory addressFactory()
```

You may obtain the immutable `Configuration` of the `World` runtime. Even if you load your runtime properties from the `xoom-actors.properties` or your own `java.util.Properties` definition, all of your runtime configurations are placed in the `Configuration`.

```java
public Configuration configuration()
```

All messages sent to `Actor` instances that cannot be delivered for any reasons, such as the `Actor` instance has previously been stopped, are delivered to the special `Actor` know as `DeadLetters`. You may subscribe to receive `DeadLetters` messages.

```java
public DeadLetters deadLetters()
```

Use the following `DeadLetters` protocol method to subscribe to its received messages. Your listener Actor must implement the `DeadLettersListener` protocol.

```java
void registerListener(final DeadLettersListener listener)
```

If you want to obtain the default `Logger` that is provided to all `Actor` instances, use the following method.

```java
public Logger defaultLogger()
```

Every top-level application- or service-created `Actor` is a child of the default parent `Actor`.

```java
public Actor defaultParent()
```

Every `Actor` must be assigned to a overarching supervisor. The following provides a reference to the default supervisor of all newly created `Actor` instance.

```java
public Supervisor defaultSupervisor()
```

Although the default `Logger` is available through the `World` interface, there may also be a number of named `Logger` instances. If you use non-default `Logger` instances, they may be obtained via the following `World` facility. All `Logger` instances obtained through the standard XOOM Actors plugins are backed by actors, and are thus asynchronous by default.

```java
public Logger logger(final String name)
```

The `Logger` implementation is based on SLF4J. You may configure your `Logger` to your standards. The following is a simple example that outputs strictly to the console.

```markup
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
 
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
```

Another example logs to both the console and a file.

```markup
<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
```

There are many references available with far more details about the [SLF4J](https://logback.qos.ch/manual/configuration.html) facility. Note that one such configuration supports [asynchronous log appending](https://logback.qos.ch/manual/appenders.html#AsyncAppender). You may or may not find that this enhances the asynchronous logging that already exists through the logging actor.

The `Logger` protocol provides several facilities for logging application/service output and exceptions.

```java
void trace(String message)
void trace(String message, Object... args)
void trace(String message, final Throwable throwable)

void debug(String message)
void debug(String message, Object... args)
void debug(String message, final Throwable throwable)

void info(String message)
void info(String message, Object... args)
void info(String message, final Throwable throwable)
  
void warn(String message)
void warn(String message, Object... args)
void warn(String message, final Throwable throwable)

void error(String message)
void error(String message, Object... args)
void error(String message, final Throwable throwable)
```

The `World` interface provides some additional facilities, but ones that are useful only for plugins. Those are documented below.

### Creating Actors

Once you have started a `World` you are able to create `Actor` instance to run in it. As a reminder, there is nothing mysterious about actors. Actors are basically objects, but their behaviors are requested by sending messages asynchronously rather than through directly invoking their methods. The following shows you how to create an actor.

```java
final Simple simple = world.actorFor(Simple.class, SimpleActor.class);
```

In this example the `World` is used to create a new instance of the `SimpleActor` type. The `SimpleActor` type implements the protocol defined by the interface named `Simple`. Thus, actors provide protocol implementations, and they can implement multiple protocols.

In this example the SimpleActor takes no constructor parameters. If it did accept parameters then the parameters could be listed as follows.

```java
final Simple simple = world.actorFor(Simple.class, SimpleActor.class, p1, p2, p3);
```

The parameters must be listed in the order in which to constructor accepts them. In the above example the parameters are listed as `p1`, `p2`, and `p3`. These parameters could be of any type, and each parameter is required to follow the convention that the constructor contract requires.

When the `World` method `actorFor()` returns, the requesting client is given a reference to the protocol that provides asynchronous access to the `Actor`. This reference is used to send messages via methods on the protocol. The `Simple` protocol is defined as follows.

```java
public interface Simple {
  void simpleSay();
}
```

There is a single method named `simpleSay()`. Messages are sent asynchronously to the concrete `Actor` instance, which in the case of the above example is an instance of `SimpleActor`. This behavior is demonstrated by the following expression.

```java
simple.simpleSay();
```

The fundamental behavior of a method invocation on the protocol reference is to reify the method invocation to a message that is sent asynchronously to the `Actor`. The reification is accomplished by creating a `Function` that represents the method invocation and enqueuing the `Function` instance on to the `Actor`'s `Mailbox`. The `Function` will later be applied to the `Actor`instance when all previously enqueued messages have been processed and a thread becomes available to process the message at the front of the `Mailbox`. Thus, the method invocation is temporally decoupled from the sending side and the receiving side.

Creating an instance of a concrete `Actor` type might involve specifying its configuration, such as selecting a non-default mailbox type and setting a non-default `Actor` name. To do this, use the `Definition` type:

```java
Simple simple1 =
      world.actorFor(Simple.class,
                     Definition.has(
                           SimpleActor.class,
                           Definition.NoParameters,
                           "arrayQueueMailbox",
                           "simple-1"));
```

In the above example the `Definition` is used to pass the `SimpleActor` type that implements the `Simple` protocol. Note that this `SimpleActor` type requires no constructor parameters, as indicated by `Definition.NoParameters`. The two interesting `Definition.has()` arguments are `"arrayQueueMailbox"` and `"simple-1"`. As you likely determined already, the first of the two, `"arrayQueueMailbox"`, is the name of a non-default mailbox type to be used by this `SimpleActor` instance. The second is the name to be given to the `SimpleActor` instance.

There are several different predefined `Definition.has()` overrides. See the [Javadoc](https://javadoc.io/doc/io.vlingo.xoom/xoom-actors/latest/index.html) for the complete set.&#x20;

#### Actor Mailboxes

There are currently three mailbox types for use by actors.

|                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`queueMailbox`**      | A non-blocking unbounded mailbox based on the Java `ConcurrentLinkedQueue` implementation. This is the *default* mailbox, unless changed by the user. As the default mailbox it used by all actors unless the actor is specifically created using a different mailbox name. An unbounded mailbox can cause the VM an out-of-memory condition if the actor cannot process messages at least as fast as they are sent.             |
| **`arrayQueueMailbox`** | A very fast mailbox based on the Agrona project's non-blocking *many-to-one* concurrent array queue. The array queue is basically a ring buffer, which means that it can become full and cause incoming messages to be discarded, or at least rejected until space becomes available. Rejecting a message is signaled to the client by the `IllegalStateException`. Yet, this mailbox will not cause an out-of-memory condition. |
| **`ringMailbox`**       | Another fast mailbox based on a non-blocking ring buffer algorithm. The contract of this mailbox is like the other ring buffer implementation, `arrayQueueMailbox`, but internally is implemented with a different algorithm. However, this mailbox will never reject incoming messages, but this comes at the expense of possible slower enqueuing times. This mailbox will not cause an out-of-memory condition.               |

For any mailbox that can become full and cause some kind of contention or failure, it can be useful for the owning actor to be a router to some number of fan-out workers. One way to do that is with [XOOM Streams](https://docs.vlingo.io/xoom-streams) and another is with our actor [Routing](#routing-and-routers) tools.

See the [Plugins](#plugins) section for the behavior and configuration details of each mailbox type.

### A Stage for Actors

The `World` does not directly create an `Actor`. Instead, the `World` dispatches `actorFor()` requests to the default `Stage`. It is the `Stage` that provides the concrete implementation of `actorFor()`.

A `Stage` is the abstraction within which `Actor` instances are maintained. A `World` has at least one `Stage`, which is known as the default `Stage`. Its name is `"__defaultStage"`. If you need to query the instance of the default stage, you use the following `World` query:

```java
public class World {
  ...
  public Stage stage() {
    ...
  }
  ...
}
```

Every `Stage` supports two important behaviors, `actorFor()` and `actorOf()`. The `actorFor()` is a creational method, and there are several overloads supporting various parameter options. Using the method various implementations of the method `actorFor()` will create a new `Actor` instance and answer one or more protocols. Once you have a reference to a protocol you are able to send messages to the given `Actor` that implements the protocol(s).

The `actorOf()` method has a different purpose. Given an existing `Actor` that is contained within a given `Stage`, you may use `actorOf()` to find the existing `Actor` by passing the `Address` of the `Actor`. The `actorOf()` answers a `Completes<T>` because it is an asynchronous operation, answering the requested protocol eventually.

An `Actor` may obtain its containing `Stage` and its `World` as follows.

```java
// inside an actor
final Stage myStage = stage();
final World myWorld = myStage.world();
```

You may create additional `Stage` instances within the `World`, but the default `Stage` is automatically provided when a `World` starts. The `World` default `Stage` is responsible for holding the private root actor and the public root actor. These two instances act as default supervisors, which are responsible for protecting a `World` from catastrophic failures. Supervision is explained in detail below.

Since the `World` must create some default operational `Actor` instances when it is started, it may be best to segregate your application/service `Actor` instances into another `Stage`. It's simple to accomplish this. To obtain a reference to an existing `Stage` by an other name, or to obtain or a newly created `Stage` by name if non-existing, use one of the two following queries:

```java
public class World {
  ...
  public Stage stageNamed(final String name) {
     ...
  }

  public Stage stageNamed(final String name, final Class<? extends Stage> stageType, final AddressFactory addressFactory) {
    ...
  }
  ...
}
```

If the `Stage` instance with the given `name` does not yet exist, a new `Stage` with that name is created and returned.

We don't suggest creating several or many `Stage` instances. It's likely that the default `Stage` and one application/service `Stage` instance will be sufficient. Yet, we don't set a limit on the number of `Stage` instances in case more than two would be useful.

{% hint style="info" %}
Note that when using XOOM Lattice you may [create a distributed compute and data grid of actors](/xoom-lattice/grid).  The Lattice `Grid` type is an extension of the `Stage`.
{% endhint %}

#### Scheduler and the Scheduled Protocol

Every `Stage` has its own `Schedular`, which may be used to produce time-lapsed events that are sent to an `Actor`.

```java
// inside an actor
final DataPacket packet = new DataPacket(0);
stage().scheduler().schedule(selfAs(Scheduled.class), packet,  100, 1_000);
```

An `Actor` can schedule itself or another `Actor`, such as one or more of its children, for some timed event notification. In other words, it need not pass itself as the `Scheduled` instance.

{% hint style="info" %}
A concrete `Actor` scheduling itself for notifications must implement the `Scheduled` protocol in order for it to be scheduled to receiver interval signals.
{% endhint %}

The above example registers a repeating schedule that will begin within `100` milliseconds of the registration and will repeat every `1` second (`1_000` milliseconds). The `Actor` scheduling itself for notifications must implement the `Scheduled` protocol, and it passes an `Actor` enabled reference to that effect using the runtime method `selfAs()`. The `Actor` can associate some specific data with which it will be notified on each event, which in this example is the `DataPacket` instance `packet`. This `DataPacket` type is only used for the example, and would be replaced with your own type, or you can pass `null` if the data is unused.

Similarly you can schedule a single notification. The interval will not not be repeated as in the above example.

```java
// inside an actor
final DataPacket packet = new DataPacket(0);
stage().scheduler().scheduleOnce(selfAs(Scheduled.class), packet,  100, 1_000);
```

When registering a `Scheduled` object you are provided a `Cancellable` instance. You may use this instance to cancel one-time or repeating occurrences.

```java
this.cancellable = stage().scheduler().scheduleOnce(...);
...
cancellable.cancel();
```

The `Actor` receiving the timed event will be notified using the `intervalSignal()` method of the `Scheduled` protocol.

```java
public interface Scheduled {
  void intervalSignal(final Scheduled scheduled, final Object data);
}
```

It may be implemented something like the following.

```java
@Override
public void intervalSignal(final Scheduled scheduled, final Object data) {
  ((DataPacket) data).ifAccumulatedEnd(cancellable -> cancellable.cancel());
}
```

**Considering Scheduler Latency**\
When a `Scheduler` is instantiated it creates a thread pool of 1 thread to manage all scheduling for a single `Stage`. You can create a unique `Scheduler` that has its own thread pool in case the `Stage`'s `Scheduler` is already heavily used. Yet, note that if used as intended, the `Scheduled` interface registered with the `Scheduler` is generally implemented by an `Actor` (as explained above). Thus, in that case, the `Scheduler` thread is not used to run the `ScheduledTask` instances. That is, the `Scheduler` has a thread for tracking all `ScheduledTask` instances under its care.

From that perspective, it seems unlikely that much latency might be experienced on the `Scheduler` itself. There seem to be two areas of potential latency that are related to the actor receiving the timed interval messages:

1. The only latency over and above the `Scheduler` would be related to how many messages are already in the `Actor`'s mailbox before the `Scheduled#intervalSignal()` is delivered. The more messages in the mailbox, the more latency to the arrival of the message of concern, `intervalSignal()`.
2. Another factor to consider is whether the `Scheduled#intervalSignal()` messages arrive more rapidly than each previous one can be processed. In other words, are the full number of `intervalSignal()` messages stacking up in the actor's mailbox? If so, consider increasing the time between timer intervals, or finding a way to increase performance of the computing done while handling each message, or both. If the actor's message handling is blocking on I/O you might want to use XOOM Streams to introduce backpressure and a "work stealing" approach to requesting intervals. Additionally, you could employ the `Scheduler`'s `scheduleOnce()` service and reschedule for one interval each time the actor's processing ends.

Another way to solve latency overhead is by creating a different `Mailbox` type to increase the number of thread pools for a runtime. [You will find this discussion below under Plugins](#allocating-separate-actors-thread-pools).

#### Automatic Eviction of Seldom Used Actors

Sometimes in applications or microservices require a lot of actors to handle all required compute tasks. This is the case with whole applications or microservices that, for example, have a heavily used [domain model where entities are implemented as actors](/xoom-lattice/entity-cqrs). When this is the case it can be necessary to ensure that the memory heap of any given runtime process is not exhausted. When this is so, the solution runtime can use the `Stage`'s actor eviction service.

To use the eviction service with your solution, you may configure it as a plugin like other plugins. These details are [explained later in this chapter](#stage-directory-eviction-service).

### Implementing Multiple Protocols (Interfaces)

An `Actor` is not limited to implementing a single protocol or `interface`. It could have two or more. Consider again the `Scheduler` example (above). An Actor implementation that wants to schedule timed event signals will be more than a `Scheduled` type. Its primary purpose is to be another type of `Actor`, and to its clients that protocol type is the focus. Consider this example.

```java
public DocumentProcessorActor extends Actor
     implements DocumentProcessor, Scheduled {
  ...
}
```

Here the primary responsibility of the `Actor` is to be a `DocumentProcessor`. The fact that it is capable of being scheduled for timer signals is an internal concern only. The clients of this `Actor` will not know that it can be a `Scheduled`, only that it is a `DocumentProcessor`.&#x20;

```java
// creating a DocumentProcessor
final DocumentProcessor = world.actorFor(
      DocumentProcessor.class, DocumentProcessorActor.class, ...);
```

Still, the responsibility of being an effective `DocumentProcessor` requires it to schedule itself to receives timer signals. The `DocumentProcessorActor` may be registered with the `Scheduler` by passing a reference to itself as a `Scheduled`. You saw this in the above example, but to make it stand out here is another one that isolates the use of the essential `selfAs()`.

```java
// inside an actor
final Schedule scheduled = selfAs(Schedule.class);
final DataPacket packet = new DataPacket(0);
stage().scheduler().scheduleOnce(scheduled, packet,  100, 1_000);
```

All `Actor` types inherit the method `selfAs(Class<T>)` to request itself as an `Actor` that supplies the protocol represented by the generic parameter `T`. The Actor must implement the `T` protocol.

Note that you ***must never*** pass a reference to yourself using `this`. Passing `this`, for example to `scheduleOnce()`, will cause `intervalSignal()` notifications to be received as direct method invocations rather than as asynchronous messages. Even though you may think that this could be a good idea, it is definitely a very bad idea. You will eventually experience a race condition in your `Actor` where a message delivered asynchronously on one thread will collide by accessing data simultaneously with the `Scheduler` thread that makes the direct method invocations.

{% hint style="info" %}
You ***must never*** pass yourself using `this`. Always use the `Actor` inherited method`selfAs(SomeProtocol.class)` to comply with the proper use of the Actor Model.
{% endhint %}

An `Actor` may implement a number of protocols, such as when representing itself as protocols specifically supported by its children or other collaborators. This makes for loose coupling and least knowledge by design. Even so, care should be used to avoid creating an `Actor` that supports more protocols than is necessary to meet its primary responsibility.

### Returning Actor Message Outcomes

Actors may return values, but must do so by means of `Completes<T>`, where `T` is the type of the outcome. If your actor's message protocol that provides a return value answer does not return a `Completes<T>` value, then the platform runtime will reject the protocol.

The following is a valid protocol for returning a value.

```java
public interface TextToInteger {
  Completes<Integer> convertFrom(final String digits);
}
```

Your return value may be provided from inside your actor's message handling method as follows.

```java
public class TextToIntegerActor extends Actor implements TextToInteger {
  @Override
  public Completes<Integer> convertFrom(final String digits) {
    return completes().with(Integer.parseInt(digits));
  }
}
```

In some cases an actor is unable to determine a final outcome prior to returning from the message handling method. This is due to the actor depending on another actor requiring asynchronous message sending and an eventual outcome to be answered. Another protocol provides the definition of the `Calculator` behavior.

```java
public interface Calculator {
  Completes<Integer> calculate(final String digits, final int multiplier);
}
```

In such cases the `calculate()` method may use the `Actor` base class behavior `answerFrom()`. This manages the eventual outcome from another actor and and then carries out the final answer.

```java
public class CalculatorActor extends Actor implements Calculator {
  private TextToInteger textToInteger;

  @Override
  public void start() {
    textToInteger = childActorFor(TextToInteger.class, Definition.has(TextToIntegerActor.class, Definition.NoParameters));
  }

  @Override
  public Completes<Integer> calculate(final String digits, final int multiplier) {
    return answerFrom(textToInteger.convertFrom(digits).andThen(number -> number * multiplier));
  }
}
```

The `CalculatorActor` depends on the previous `TextToIntegerActor` to convert from a `String` to an `Integer` before the `CalculatorActor` can multiply that number by the given multiplier. Due to this asynchronous behavior, the `Actor` base class behavior `answerFrom()` is used to manage the asynchronous messaging and outcome, which is then used to calculate the answer, and provide that answer an eventual outcome to the original client.

### Actor Supervision

A recent account of cascading failure describes tens of thousands of nodes lost during a Kafka failure that caused a Kubernetes cluster to self destruct, taking out an entire infrastructure. Using supervision as bulkheads can save your system from catastrophic failure.&#x20;

The following diagram illustrates the contrast between how failure is handled in a reactive, Actor Model architecture, and in a typical blocking architecture. It also provides a good indication of why typical blocking architectures can fail catastrophically, and why reactive architectures tend not to.

![How cascading failure is prevented with reactive.](/files/-MAcSISDOVaChUWgJQe5)

When an actor throws an exception, or when some synchronous dependency in the actor's use throws an exception, and that exception is caught by the XOOM Actors message delivery component, the supervisor of this actor is informed. The supervisor is responsible for what happens to the actor, such as stopping it or resuming its processing, etc.

The default behavior of the system level supervisors is limited in that they decide what to do about the crashed actor based on static policies. An example might be, "if this actor has crashed 10 times in 5 seconds, I'm going to stop it; otherwise I'll just tell it to resume." Obviously creating your own supervisors provides superior customization, but the default system level supervisors protect again catastrophic failure when no specialized supervisors have been provided by the service/application team.

The Actor Model supports scoped supervision of `Actor` instances. When the `World` is created with default configuration, the following hierarchy of supervision is established.

```java
PrivateRootActor (literal)
  PublicRootActor (literal)
    ApplicationActor1 (example)
      ApplicationActor1_1 (example)
```

A concrete `Actor` that serves as a supervisor must implement the protocol defined by the `io.vlingo.xoom.actors.Supervisor`. Two of the standard supervisors know as the `PrivateRootActor` and the `PublicRootActor` implement the `io.vlingo.xoom.actors.Supervisor` protocol. Furthermore, if `ApplicationActor1` and `ApplicationActor1_1` are to serve as supervisors, they too must implement the `io.vlingo.xoom.actors.Supervisor` protocol.

The above example demonstrates that there is a base supervisor known as the `PrivateRootActor`. It is the ultimate supervisor that protects the `World` from catastrophic failure by serving as an impenetrable shield against lower-level failures. Just below the `PrivateRootActor` is the `PublicRootActor`. All top-level application/service `Actor` instances, such as `ApplicationActor1` in the above example, are supervised by the `PublicRootActor`. Any children of the `ApplicationActor1`, such as `ApplicationActor1_1` in the above example, are supervised by `ApplicationActor1`.

Thus, any newly created concrete `Actor` whose parent is known and implements the standard `Supervisor` protocol is the child's supervisor. If the parent is not known or the new `Actor` is top-level, then both its parent and its supervisor are assigned as the `PublicRootActor`.

#### Supervision Overrides

You may override the default supervisor arrangement using the `xoom-actors.properties` configuration.

```java
plugin.name.override_supervisor = true
plugin.override_supervisor.classname =
  io.vlingo.xoom.actors.plugin.supervision.DefaultSupervisorOverridePlugin
plugin.override_supervisor.types =\
  [stage=default name=overrideSupervisor
    supervisor=io.vlingo.xoom.actors.plugin.supervision.DefaultSupervisorOverride]
```

This will assign the default supervisor as the plugin `DefaultSupervisorOverride`, which is explained under the plugins section. This override may also be defined using fluent configuration.

```java
final Configuration configuration =
        Configuration
                .define()
                ...
                .with(DefaultSupervisorOverridePluginConfiguration
                        .define()
                        .supervisor("default", "overrideSupervisor",
                                    DefaultSupervisorOverride.class))
                ...
```

When an `Actor` throws an exception, the exception is caught by the runtime. When the exception is caught, the `Actor` is suspended, meaning that it is not permitted to process any messages until the exception has been handled. The exception will be handled by its supervisor when the exception is reified as a message and sent asynchronously to its supervisor. When received, the exception is interpreted and the supervisor's recovery strategy is employed. The supervisor strategy can specify the following actions.

* Resume operation of the `Actor` starting with its next message
* Restart the `Actor`
* Stop the `Actor`, which implies also stopping any of its children
* Escalate the recovery up another ancestor level

When the supervisor strategy is to restart, a restart is done only for a maximum number of restarts within a stipulated timeframe. In other words, the `Actor` may not be permitted to crash repeatedly over an extended period of time. To control restarts or leave them available continuously, the following stipulations may be used.

* If the current restart intensity count is within the specified intensity over the given period of time, restart the `Actor`.
* An example of intensity is `10` times within a period of `5` seconds, or `50` times over a period of `1` minute.
* You may specify a maximum intensity of an unlimited number of times over an infinite time period.

For examples see the following:

```java
io.vlingo.xoom.actors.PublicRootActor
io.vlingo.xoom.actors.SupervisionStrategy
io.vlingo.xoom.actors.DefaultSupervisor
io.vlingo.xoom.actors.DefaultSupervisorStrategy
```

The same overrides may be accomplished using the fluent configuration API.

```java
Configuration configuration =
    Configuration
      .define()
      .with(DefaultSupervisorOverridePluginConfiguration
          .define()
          .supervisor("default", "overrideSupervisor", DefaultSupervisorOverride.class));

```

#### Common Supervisors

There is also a means to provide a supervisor for a given protocol type. For example, the `Pinger` protocol can be assigned a common supervisor that will provide supervision for all instances of `Actor`s that implement the `Pinger`protocol. This can be configured from the `xoom-actors.properties` file. This example shows how to provide a common supervisor for the `Pinger` protocol and another for the `Ponger` protocol.

```
plugin.name.common_supervisors = true
plugin.common_supervisors.classname = io.vlingo.xoom.actors.plugin.supervision.CommonSupervisorsPlugin
plugin.common_supervisors.types =\
  [stage=default name=pingSupervisor protocol=io.vlingo.xoom.actors.supervision.Ping supervisor=io.vlingo.xoom.actors.supervision.PingSupervisorActor]\
  [stage=default name=pongSupervisor protocol=io.vlingo.xoom.actors.supervision.Pong supervisor=io.vlingo.xoom.actors.supervision.PongSupervisorActor]
```

Again, this configuration can be made from the programmatic fluent configuration API.

```java
Configuration configuration =
    Configuration
      .define()
      .with(CommonSupervisorsPluginConfiguration
          .define()
          .supervisor("default", "pingSupervisor", Ping.class, PingSupervisorActor.class)
          .supervisor("default", "pongSupervisor", Pong.class, PongSupervisorActor.class));
```

### Stowage

Actor message stowage is a means to temporarily pause message processing for a given actor, but without blocking the thread that initiates the pause. Stowage does this by using a secondary queue to stow all messages that are received until the actor is informed to un-stow messages. At the point of un-stowing, the messages that were stowed will be delivered to the actor before any newly queued messages and until the stowed messages are exhausted; but after messages of any of the `stowageOverrides` types (see below).

An actor can stow its messages by using the internal (protected) behavior `stowMessages()` and un-stow messages using `disperseStowedMessages()`. The Actor protected methods are as follows:

```java
  /**
   * Starts the process of dispersing any messages stowed for this {@code Actor}.
   */
  protected void disperseStowedMessages() {
    lifeCycle.environment.mailbox.resume(Mailbox.Paused);
  }

  /**
   * Starts the process of stowing messages for this {@code Actor}
   * and registers {@code stowageOverrides} as the protocols that
   * will trigger dispersal.
   * @param stowageOverrides the {@code Class<T>} array of protocols that will trigger dispersal
   */
  protected void stowMessages(final Class<?>... stowageOverrides) {
    lifeCycle.environment.mailbox.suspendExceptFor(Mailbox.Paused, stowageOverrides);
  }
```

Note that `stowMessages()` takes the *varargs* parameter `stowageOverrides`. This is an array of `Class` types that, when messages of any of those types are received, will automatically trigger the stowed message dispersal. That is, you enable the mailbox itself to react to a given kind of message that causes un-stowing to happen. When any message of any of the types in the `stowageOverrides` array is received, it is delivered ahead of any stowed messages. In other words, messages of types in the `stowageOverrides` array are treated as priority messages.

This is specifically used with [Lattice `Entity` types](/xoom-lattice/entity-cqrs#object-relational-mapping) that auto-persist applied state transition snapshots and/or events to [Symbio reactive storage.](/xoom-symbio)

### Plugins

The XOOM Actors foundation provides the following plugins.

#### `Completes<T>`

Some `Actor` protocols answer outcomes to one or more messages that they handle. Because messages are sent and received asynchronously, the sender will not block until the answered outcome is available. Thus, the contract must be asynchronous for a returned value from the`Actor` to the message-sending client. This contract is satisfied by means of the `Completes<T>` mechanism. The client sender of an outcome-answering `Actor` protocol message immediately receives a `Completes<T>` object. The client then registers a function with the `Completes<T>` object, and the registered function will be called when the answer becomes available. You may read more about the `Completes<T>` capabilities in the chapter [XOOM Common](/xoom-common).

Sometimes an asynchronous message outcome must be helped by some additional `Actor`-based plumbing. This is where the `CompletesEventually` plugin is used. This plugin is known as `"pooledCompletes"`, and as its name indicates, a pool of `Actor` instances is used to process possible high volumes of eventual outcomes.

You may configure this pool using the standard properties file as follows, or by using the fluent configuration API.

```java
plugin.name.pooledCompletes = true
plugin.pooledCompletes.classname =\
  io.vlingo.xoom.actors.plugin.completes.PooledCompletesPlugin
plugin.pooledCompletes.pool = 10
plugin.pooledCompletes.mailbox = queueMailbox
```

This configuration establishes `10` Actor instances that may be used to handle all eventual outcomes. Those `Actor` instances will use the `queueMailbox` as their mailbox type (see Mailbox plugin below).

#### Logging

The standard logging capabilities of the `io.vlingo.xoom.actors.Logger` protocol are provided by the logging plugin found in package `io.vlingo.xoom.actors.plugin.logger`. The `JDKLoggerPlugin` is the current default logger found under `io.vlingo.xoom.actors.plugin.logger.jdk`. There is also a "no op" logger that may be used for quicker testing, packaged under `io.vlingo.xoom.actors.plugin.logger.noop`.

The configurations for the JDK logger follow those available with `java.util.logging`. See the following class for configuration details.

```java
io.vlingo.xoom.actors.plugin.logging.jdk.JDKLoggerPlugin.JDKLoggerPluginConfiguration
```

#### Mailbox

There are currently three mailbox implementations provided as default plugins, each of which are described in the following content. Configuration examples can be found here.

```java
xoom-actors/src/test/resources/xoom-actors.properties
```

**`"queueMailbox"`**: A non-blocking unbounded mailbox based on the Java `ConcurrentLinkedQueue` implementation. This is the *default* mailbox, unless changed by the user. As the default mailbox it used by all actors unless the actor is specifically created using a different mailbox name.

Being an unbounded mailbox means that sending messages can result in and exception, specifically `OutOfMemoryException`, if any given `Actor` receives messages faster than it can process them. Note that this condition will likely require a significant amount of time as messages that can't be processed as quickly as they are queued slowly fill available (e.g. gigabytes of) memory.

Messages sent to an actor that uses this mailbox are ultimately delivered by means of a dispatcher. This `"queueMailbox"` dispatcher is based on a thread pool executor. You may set the maximum number of threads, or provide a factor (e.g. 0.5, 1.5, or 2.0) to multiply with the total number of processor--hyper thread--to determine the pool size. There are properties used for each option.

```java
plugin.queueMailbox.numberOfDispatchersFactor = 1.5
plugin.queueMailbox.numberOfDispatchers = 0
plugin.queueMailbox.dispatcherThrottlingCount = 1
```

The above `numberOfDispatchersFactor` example uses a factor of 1.5, which means that the pool of Java threads available for actors using this mailbox will be one-and-a-half times the number of hyper-threads on all cores on the CPU. For example, a 8-core CPU will have 16 total physical hyper-threads, which means that the pool will have 16 x 1.5 or 24 total Java threads.

To set a specific number of Java threads in the pool, set the `numberOfDispatchersFactor` to 0 and `numberOfDispatchers` to the exact desired number, such as 50. This would create exactly 50 Java threads in the pool.

{% hint style="info" %}
Having many more platform (e.g. Java/JVM) threads than there are physical hyper-threads is not necessarily an advantage. You should always measure rather than make assumptions that some thread-based configuration is better than the defaults or another set of values.
{% endhint %}

There is one additional, `dispatcherThrottlingCount`. This indicates the maximum number of messages that will be delivered to an actor using this mailbox on each single thread assignment. In other words, if this value is 10, then a single thread assignment to this mailbox could deliver up to 10 total messages before giving up the thread. The most fair configuration is 1, meaning that upon a single thread assignment to a mailbox there would be only 1 message delivered to the actor.

These values may be overridden in the default source code configuration as follows.

```java
final Configuration configuration =
        Configuration
          .define()
          .with(ConcurrentQueueMailboxPluginConfiguration
                  .define()
                  .defaultMailbox()
                  .numberOfDispatchersFactor(0)
                  .numberOfDispatchers(50)
                  .dispatcherThrottlingCount(5))
          ...

final World world = World.start("trading", configuration);
```

The following is the fully-qualified class name of the `"queueMailbox"`.

```java
io.vlingo.xoom.actors.plugin.mailbox.concurrentqueue.ConcurrentQueueMailbox
```

{% hint style="info" %}
Next, the current two additional mailbox types are described. Before describing those in detail, note that to use non-default mailboxes requires some additional definitions when creating an actor that uses one of them.
{% endhint %}

Assuming that the above `"queueMailbox"` is the default, each of the following two mailboxes (`"arrayQueueMailbox"` and `"ringMailbox"`) must be explicitly chosen when creating an actor that uses one of these. You can use the following code example to accomplish that, but of course provide the name of the mailbox for you specific choice:

```
final TradeRouter tradeRouter =
        world.actorFor(
                TradeRouter.class,
                Definition.has(
                    TradeRouterActor.class,
                    Definition.parameters(trade),
                    "arrayQueueMailbox",
                    "TradeRouter-1"));
```

**`"arrayQueueMailbox"`**: A very fast mailbox based on the Agrona project's non-blocking *many-to-one* concurrent array queue.

{% hint style="info" %}
Note that specifically this is a M:1 mailbox. This means that the mailbox can receive messages from many senders, but all messages are delivered to a single actor.

Further, the two M:1 mailbox types are not meant to be used with [Lattice `Entity` types](/xoom-lattice/entity-cqrs).  An `Entity` has a state that is persistent, and as such must use a non-blocking pause of message processing to confirm asynchronous persistence is successful. Mailboxes designed very high throughput and processing of messages should never be paused.

The non-blocking pauses are managed by [actor message stowage](#stowage). Although technically stowage could be supported for `"arrayQueueMailbox"` and `"ringMailbox"`, it is counter-intuitive to the fast mailbox implementations. Stowage would have to be implemented with an unbounded queue/list; effectively like `"queueMailbox"`. This would basically render the `"arrayQueueMailbox"` and `"ringMailbox"` with degraded performance for much of its lifetime.
{% endhint %}

There are a few available configurations.

```java
plugin.arrayQueueMailbox.size = 65535
plugin.arrayQueueMailbox.fixedBackoff = 2
plugin.arrayQueueMailbox.notifyOnSend = false
plugin.arrayQueueMailbox.dispatcherThrottlingCount = 1
plugin.arrayQueueMailbox.sendRetires = 10
```

The `size` property determines the total number of individual messages that can fit in the ring buffer at one time. The above shows a limit of 65535. Again note that there are not only 65535 message slots, but also 65535 pre-allocated, reusable message objects.

There is one dedicated thread assigned to the consumer/receiver actor side. Sometimes there will be no messages in the ring yet to be delivered. When this is the case we provide a `fixedBackoff` property to prevent the Java thread from spinning while waiting for the next message. The above configuration shows a fixed backoff of 2 milliseconds, which means that when there are no available messages to deliver the mailbox thread will sleep for 2 milliseconds. You may increase this value to increase the fixed backoff. You may also set this value to 0 to prevent any backoff; that is, the consumer thread will spin wait in a tight loop. This is the better option if you know that there will be a near constant high throughput of messages sent to the actor.

The `notifyOnSend` `boolean` property is used to potentially interrupt the dedicated mailbox thread if it is sleeping. If you are using a high value fixed backoff you may want to consider setting this to `true`. If you are using `fixedBackoff` of 0 then set `notifyOnSend` to `false`.

The `dispatcherThrottlingCount` is similar to that for other mailboxes. This indicates the maximum number of messages that will be delivered to an actor using this mailbox during a single dispatch. However, since this mailbox type uses a dedicated thread all that this amounts to is preventing an additional method invocation to have some maximum number of messages delivered rather than just one.

Due to the fact that this mailbox has a limited number of message elements to enqueue, there is a chance that the actor may not be able to process message delivery as fast as its ring buffer is filling. In such cases it is possible that a message could fail enqueuing. Thus, the `sendRetires` property indicates how many times the sender may attempt to enqueue a message before failing. Note that the margin for retries is a very limited time; only a single for-loop iteration, meaning that even 10 retries is a very small window for the consuming actor to empty one element for the currently delivering message to enqueue. This also doesn't consider that multiple message producers/senders may be simultaneously contending for emptying elements. If the enqueuing fails, the client will be signaled by an `IllegalStateException`.

{% hint style="info" %}
The trick is that the actor really must empty ring buffer slots faster than senders can send. Enlarging the ring buffer by configuration will only prolong the point where a slow actor reaches its saturation point. It can be useful for such an actor to be a router to some number of fan-out workers. One way to do that is with [XOOM Streams](https://docs.vlingo.io/xoom-streams) and another is with our actor [Routing](#routing-and-routers) tools.
{% endhint %}

You may use programmatic configuration for the `"arrayQueueMailbox"`.

```java
final Configuration configuration =
        Configuration
          .define()
	        .with(ManyToOneConcurrentArrayQueuePluginConfiguration
	                .define()
	                .ringSize(65535)
	                .fixedBackoff(0)
	                .notifyOnSend(false)
	                .dispatcherThrottlingCount(10)
	                .sendRetires(10))
          ...

final World world = World.start("trading", configuration);
```

The following is the fully-qualified class name of the `"arrayQueueMailbox"`.

```java
io.vlingo.xoom.actors.plugin.mailbox.agronampscarrayqueue.ManyToOneConcurrentArrayQueueMailbox
```

As previously described, this mailbox uses a MPSC data structure, meaning that there may be multiple senders (producers) but only a single receiver (consumer) of the messages. Any number of actors can individually be assigned its own instance of this mailbox.

**`"ringMailbox"`**: A fast mailbox based on a non-blocking ring buffer algorithm.

Senders may contend to enqueue new message by means of a CAS (compare and set) spin lock. This is slower than the `"arrayQueueMailbox"` but faster than the `"queueMailbox"`. The primary benefit is that this mailbox will not fail enqueuing to a full ring buffer, but this comes at the expense of possible slower enqueuing times while the actor empties enough slots for all currently sending client contenders.

{% hint style="info" %}
The trick is that the actor really must empty ring buffer slots faster than senders can send. Enlarging the ring buffer by configuration will only prolong the point where a slow actor reaches its saturation point. It can be useful for such an actor to be a router to some number of fan-out workers. One way to do that is with [XOOM Streams](https://docs.vlingo.io/xoom-streams) and an other is with our actor [Routing](#routing-and-routers) tools.
{% endhint %}

```java
plugin.ringMailbox.size = 65535
plugin.ringMailbox.fixedBackoff = 2
plugin.ringMailbox.notifyOnSend = false
plugin.ringMailbox.dispatcherThrottlingCount = 1
```

The configuration properties are nearly the same as for the `"arrayQueueMailbox"`,  but with a few differences. For example, there is no need for a `sendRetires` property because an indefinite CAS (compare and set) spin lock is used for retries. Also setting `fixedBackoff` to 0 has a different affect in the case of this mailbox.

The `size` property determines the total number of individual messages that can fit in the ring buffer at one time. The above shows a limit of 65535. Again note that there are not only 65535 message slots, but also 65535 pre-allocated, reusable message objects.

There is one dedicated thread assigned to the consumer/receiver actor side. Sometimes there will be no messages in the ring yet to be delivered. When this is the case we provide a `fixedBackoff` property to prevent the Java thread from spinning while waiting for the next message. The above configuration shows a fixed backoff of 2 milliseconds, which means that when there are no available messages to deliver the mailbox thread will sleep for 2 milliseconds. You may increase this value to increase the fixed backoff. You may also set this value to 0 in order to request capped exponential backoff. Using this backoff approach will double the current backoff in milliseconds until a maximum cap value is reached. The current range is 1 to 4096 milliseconds.

The boolean `notifyOnSend` property is used to potentially interrupt the dedicated mailbox thread if it is sleeping. If you are using a high value fixed backoff or the capped exponential backoff you should set this the `true`.

The `dispatcherThrottlingCount` is similar to that for other mailboxes. This indicates the maximum number of messages that will be delivered to an actor using this mailbox during a single dispatch. However, since this mailbox type uses a dedicated thread all that this amounts to is preventing an additional method invocation to have some maximum number of messages delivered rather than just one.

You may use programmatic configuration for the `"ringMailbox"`.

```java
final Configuration configuration =
        Configuration
          .define()
          .with(SharedRingBufferMailboxPluginConfiguration
                  .define()
                  .ringSize(65535)
                  .fixedBackoff(0)
                  .notifyOnSend(true)
                  .dispatcherThrottlingCount(10))
          ...

final World world = World.start("trading", configuration);
```

The following is the fully-qualified class name of the `"ringMailbox"`.

```java
io.vlingo.xoom.actors.plugin.mailbox.sharedringbuffer.SharedRingBufferMailbox
```

#### Allocating Separate Actors Thread Pools

Closely connected with actor mailboxes is the potential need to use multiple thread queues to process different kinds of messages, such as those the require longer to process than most, and that must potentially block such as for I/O to complete. Although there are techniques that can be used to avoid these situations from happening, in some cases it is impractical to do so. In other cases it is simply not possible.

Basically every mailbox type configured as a plugin has its own thread pool. Thus, it is possible to even use the same kind of mailbox but with different configuration names, to force separate thread pools to be created.

{% hint style="info" %}
Note that in the following examples you will note some material duplicated from above, but it is used here for different purposes.
{% endhint %}

In the following example, the `xoom-actors.properties` is used to explain. Of course you may set up all the configuration programmatically, but here the properties file is used for simplicity:

```
plugin.name.queueMailbox = true
plugin.queueMailbox.classname = io.vlingo.xoom.actors.plugin.mailbox.concurrentqueue.ConcurrentQueueMailboxPlugin
plugin.queueMailbox.defaultMailbox = true
plugin.queueMailbox.numberOfDispatchersFactor = 1.5
plugin.queueMailbox.numberOfDispatchers = 0
plugin.queueMailbox.dispatcherThrottlingCount = 1

plugin.name.lowLatencyQueueMailbox = true
plugin.lowLatencyQueueMailbox.classname = io.vlingo.xoom.actors.plugin.mailbox.concurrentqueue.ConcurrentQueueMailboxPlugin
plugin.lowLatencyQueueMailbox.defaultMailbox = false
plugin.lowLatencyQueueMailbox.numberOfDispatchersFactor = 0.5
plugin.lowLatencyQueueMailbox.numberOfDispatchers = 0
plugin.lowLatencyQueueMailbox.dispatcherThrottlingCount = 1
```

As seen above, these two mailbox types are the same implementation, but cause the use of different thread pools. The standard and default `queueMailbox` is allocated with 1.5 times the Java threads as there are physical hyper-threads (not cores, but what Java refers to as processors). If there are 4 cores and 8 physical hyper-threads, this mailbox thread pool will have 12 Java threads.

The second mailbox type is `lowLatencyQueueMailbox`, which uses the same Mailbox implementation of `ConcurrentQueueMailboxPlugin` as `queueMailbox` uses. Even so, `lowLatencyQueueMailbox` is configured to have only 0.5 times the hyper-threads; if there are 4 cores and 8 hyper-threads, its thread pool will have 4 Java threads. Of course, having a total of 2x the number of Java threads as hyper-threads might stretch things a bit. Yet, we have found that Java can deal with perhaps a few hundred more Java threads than actual hyper-threads. Still, your actual results may vary. It is always most responsible to measure in your own environment.

{% hint style="info" %}
To measure the throughput of one or more mailbox types, you may use as an example a benchmark that we have made public. It is the [ArrayQueueBenchmark](https://github.com/vlingo/xoom-examples/blob/master/xoom-benchmarks/src/main/java/io/vlingo/xoom/examples/benchmark/actors/mailbox/arrayqueue/ArrayQueueBenchmark.java).

Note that the next mailbox type example explains this very mailbox type.
{% endhint %}

Note also that you can do the following, for example, to explicitly set the number of threads used by a given mailbox type:

```
plugin.lowLatencyQueueMailbox.numberOfDispatchersFactor = 0
plugin.lowLatencyQueueMailbox.numberOfDispatchers = 20
```

Even more naturally, you can use a very low-latency mailbox type that far outperforms the `ConcurrentQueueMailboxPlugin` by something like 3:1 or 4:1 (18-20 million messages per second). This is the mailbox type for which the above mentioned `ArrayQueueBenchmark` is written against.

```
plugin.name.arrayQueueMailbox = true
plugin.arrayQueueMailbox.classname = io.vlingo.xoom.actors.plugin.mailbox.agronampscarrayqueue.ManyToOneConcurrentArrayQueuePlugin
plugin.arrayQueueMailbox.defaultMailbox = false
plugin.arrayQueueMailbox.size = 65535
# 0 = exponential back off; >0 = fixed back off
plugin.arrayQueueMailbox.fixedBackoff = 2
plugin.arrayQueueMailbox.notifyOnSend = false
plugin.arrayQueueMailbox.dispatcherThrottlingCount = 1
plugin.arrayQueueMailbox.sendRetires = 10
```

This `arrayQueueMailbox` is single threaded because it dispatches to only one actor, but multiple producer actors may send messages to the actor that owns it.

We suggest using a variety of approaches to find the one(s) that work best for your domain.

#### Supervision

Supervision alternatives may be provided as plugins. The two possible types of extended supervision are as follows.

1. Name `"override_supervisor"`: Registering this plugin enables an override for the standard default supervisor provided by `PublicRootActor`.
2. Name `"common_supervisors"`: Registering this plugin enables any number of different supervisors used to protect against crashed actors of specific protocol types. In other words, you may register a supervisor that will be used to handle exceptions of all actors that implement a specific protocol, and are handling a message for that protocol when the exception is thrown.

The following shows configuration examples for these two kinds of override supervisors found in the properties file.

```java
xoom-actors/src/main/resources/xoom-actors.properties
```

```java
plugin.name.override_supervisor = true
plugin.override_supervisor.classname =\
  io.vlingo.xoom.actors.plugin.supervision.DefaultSupervisorOverridePlugin
plugin.override_supervisor.types =\
  [stage=default name=overrideSupervisor \
   supervisor=io.vlingo.xoom.actors.plugin.supervision.DefaultSupervisorOverride]

plugin.name.common_supervisors = true
plugin.common_supervisors.classname =\
  io.vlingo.xoom.actors.plugin.supervision.CommonSupervisorsPlugin plugin.common_supervisors.types =\
  [stage=default name=pingSupervisor protocol=io.vlingo.xoom.actors.supervision.Ping \
   supervisor=io.vlingo.xoom.actors.supervision.PingSupervisorActor] \
  [stage=default name=pongSupervisor protocol=io.vlingo.xoom.actors.supervision.Pong \
   supervisor=io.vlingo.xoom.actors.supervision.PongSupervisorActor]
```

#### Stage Directory Eviction Service

To configure the eviction service for `Stage` instances of an application or microservice, use the following properties. These reflect the default values:

```
plugin.name.directoryEviction = true
plugin.directoryEviction.classname = io.vlingo.xoom.actors.plugin.eviction.DirectoryEvictionPlugin
plugin.directoryEviction.excludedStageNames=__defaultStage
plugin.directoryEviction.enabled = false
plugin.directoryEviction.lruProbeInterval = 40000
plugin.directoryEviction.lruThreshold = 120000
plugin.directoryEviction.fullRatioHighMark = 0.8
```

This configuration indicates that the standard eviction service plugin will be used, which is `DirectoryEvictionPlugin`. The following properties have specific meaning:

1. The `plugin.directoryEviction.excludedStageNames` property offers a comma separated list of names of `Stage` instances that are not included in eviction services. The default `Stage` named `__defaultStage` is never included in eviction services. The default `Stage` should be safe for relatively low-traffic, quiet actors, such as supervisors, to exist for the life of the service or application and be used only when necessary, which is perhaps seldom. If your Stage name is not listed in this property, it is a candidate for eviction services, but also depends on the value of the following property.
2. The `plugin.directoryEviction.enabled` property indicates whether the eviction service is enabled for all `Stage` instances other than those listed by name in the previous property, where `false` means disabled by default and `true` means enabled by default. It might seem counter intuitive that the suggested default is `false`, or disabled. Most heap pressure will come by way of a growing number of specific application or microservice actors. For example, consider the large number of potential behavioral and data-only entities that could be cached in the [XOOM Lattice distributed grid](/xoom-lattice/grid). Those actors that have gone without receiving a message for the longest are considered *least recently used (LRU).* When heap memory is reaching high pressure (memory is reaching a "highwater mark") then the actors that are least recently used must be detected and stopped, freeing the memory that they consume at runtime. By default, all `Grid` instances, which are `Stage` extenders, will be managed by eviction services; that is, unless its name is listed in the above `excludedStageNames` property.
3. The `plugin.directoryEviction.lruProbeInterval` property is the time interval between probes for heap pressure. That is, every interval of this value a scheduler event will fire to cause the heap memory to be probed for a threshold or highwater mark. If the highwater mark is detected, all actors that have reached the LRU threshold will be evicted, as long as they don't currently have any messages waiting for delivery. The default interval is 40 seconds.
4. The `plugin.directoryEviction.lruThreshold` property is the length of time considered as the actor LRU threshold, meaning that an actor must be inactive for this time threshold before it is considered for eviction. The default is 2 minutes. Lower this value if heap pressure tends to stay high. Likely two minutes is a low enough interval for solutions that have minimal or average heap pressure. If the solutions tends to require user think time, this timeframe might require increase to reflect the typical user-experience.
5. The `plugin.directoryEviction.fullRatioHighMark` property is the level of heap pressure highwater mark that is to be experienced before checking for least recently used actors for eviction. Decrease this value if your heap tends to grow rapidly. The default value is 0.8 or 80% of total maximum heap available. Likely this value would be adjusted with either or both timeframe properties.

To reiterate, for an actor to qualify for eviction, the actor would be least recently used for the `lruThreshold` *and its mailbox must also be empty.* That is, the actor will not be evicted if it is just at the cusp of handling a new message. This favors  consistency of delivery over memory efficiency.

### Actor Runtime and Life Cycle

Every `Actor` has a life cycle. The `Actor` is first created and begins life. The `Actor` may receive and process a number of messages. After some time, the `Actor` may have reached the extent of its usefulness. At that point some component, possibly another `Actor`,  will request that it be stopped. At that time the `Stage` containing the `Actor` instance will remove it from its internal directory, and stop it.

#### Common Protocols

The following protocols are available to `Actor` instances to help manage its life cycle.

1. Protocol `Startable`: All concrete `Actor` types support this protocol. When the `Actor` instance is first being started, it receives a `start()` message. If the concrete `Actor` wants to react to this message it must override the default behavior, which does nothing.
2. Protocol `Stoppable`: All concrete `Actor` types support this protocol. When the `Actor` instance is first being stopped, it receives a `stop()` message. Unlike with the `Startable` protocol, the base `Actor` does provide specific critical behavior for its `stop()` message. Therefore, if the concrete `Actor` wishes to react to this message by overriding to default, it must ensure that the base implementation is invoked by using `super.stop()`. If your `Actor` override attempts to use certain facilities, such as children, the outcome is unpredictable. Due to this somewhat finicky behavior, it may be best for your Actor to instead override the `afterStop()` life cycle message handler.
3. Protocol `Scheduled`: Concrete `Actor` types by default do not support this protocol, and it must be implemented when using the `Scheduler` to receive time-based events.

#### Actor Life Cycle Messages

The Actor abstract base class provides five life cycle message handlers:

* `beforeStart()`
* `afterStop()`
* `beforeResume(final Throwable reason)`
* `beforeRestart(final Throwable reason)`
* `afterRestart(final Throwable reason)`

These enable you to see when significant life cycle events occur with your actor.

The `beforeStart()` message is sent and handled before each `Actor` is fully started. The default behavior does nothing. If you wish to handle this message in your concrete `Actor` you must override it.

The `afterStop()` message is sent and handled after each Actor is fully stopped. The default behavior does nothing. If you wish to handle this message in your concrete `Actor` you must override it.

The restart life cycle methods are related to actor supervision. When your actor’s supervisor sees your actor failed with an `Exception`, it can take a number of actions. Your supervisor can tell your actor to resume, to stop, or to restart. If it tells your actor to resume, the `beforeResume()` is invoked. When it tells your actor to restart, the `beforeRestart()` is invoked first, and then the `afterRestart()` is invoked.

Since your actor has failed, it may have been left in an invalid state. In such cases, these life cycle methods give your actor the opportunity to clean up after the problem that caused the `Exception` and also reinitialize itself before reacting to its next available protocol message.

{% hint style="info" %}
The `Exception` recovery methods DO NOT cause the `Actor` instance to be completely discarded and recreated. Therefore, it is the responsibility of the `Actor` to set its state to a safe point before message processing resumes.
{% endhint %}

Since all actors have a `Logger` available via its `logger()` method, any information that you log due to a life cycle message will be output asynchronously through a registered `Logger`. Your `Actor` won't block while output is performed.

#### Becoming Other Characters

One of the primary capabilities of an `Actor` is to prepare itself to receive and handle its next message. Since the XOOM Actors foundation fully supports the *Actor Model* of computation, we enable you to morph any given `Actor` to the protocol that suites its current state. Thus, an Actor is a state machine and when it reaches any given state its behavior may change to support the specific state.

Changing characters dynamically is managed by the `io.vlingo.xoom.actors.Characters` mechanism. This test demonstrates how: `io.vlingo.xoom.actors.CharactersTest`

### Testing Actors

Testing asynchronous components can be challenging. Yet, the XOOM Actors foundation makes it quite simple to manage. There are a few components that help.

1. Component `TestWorld`: This component wraps the standard `World` object with test capabilities. It supports all of the standard `World` facilities, but in a specialized way that assists in testing. A `TestWorld` may be started in exactly the same ways as a `World`. Creating an `Actor` through the `TestWorld` actually creates a `TestActor<T>`.
2. Component `TestActor<T>`: This component is a thin wrapper around the `T` typed concrete `Actor` instance. There are three ways to access the `Actor` to send it a message: (a) Using its `T` typed protocol, but via a synchronous mailbox; messages are sent and received synchronously. (b) By using the `Actor` instance directly per the default protocol, enabling direct method invocations. (c) By dynamically casting the `Actor` instance to another one of its supported protocols, and then directly invoking a method (like b, but using a non-default protocol).
3. Component `TestState`: Every `Actor` implements the `TestStateView` protocol, enabling tests to request data of the internal state of the `Actor`. Using method `viewTestState()` a test can acquire the `TestState`of the `Actor`. A `TestState` is a set of key-value pairs, providing internal state data that a given concrete `Actor` is willing to share with a test in order for expectations to be asserted.
4. Component `TestUntil`: This component is backed by a Java `CountDownLatch`, enabling a test to wait on an expected number of happenings in a tested unit. A `TestUntil` is instantiated by a test to a predetermined number of happenings, such as three. The test invokes `until.completes()`, which blocks until the number of happenings occurs. The `TestUntil` instance is shared with a unit under test, and each time that an expected happening takes place, the `TestUntil` is notified using its `happened()` protocol. Each `happened()` notification causes the internal atomic counter to decrement. When the expected number of occurrences has happened, the `CountDownLatch` reaches zero, and the client unit test side unblocks, allowing the test to complete. This is intended for the most basic tests where data modifications by multiple threads will not cause test issues due to Java memory model unsynchronized updates. See `AccessSafely` next.
5. Component `AccessSafely`: This component uses `TestUntil` to count down expected steps, but also adds the additional workings to ensure that your test thread sees the same data updates that your actor thread produces. The modern CPU (cores, caching, predictive execution, etc.) are very sophisticated in executing code, but can also produce problems in viewing the same data across different threads. Depending on the design of the language runtime memory model, such as with Java, the data may be synchronized between threads only when certain language facilities are used. When you use `AccessSafely` to manage the thread-data interplay, you will be able to see data consistently across threads.

{% hint style="info" %}
We highly recommend using [`AccessSafely`](/xoom-actors#thread-safe-data-access) rather than making direct use of `TestUntil`.
{% endhint %}

You can see these facilities used throughout the XOOM Actors tests. One place to see the test facilities is to view its own tests: `io.vlingo.xoom.actors.testkit.TestkitTest`

All actors created directly through the `TestWorld` are assigned a mailbox type of `TestMailbox`. The `TestMailbox` does not queue messages, but performs immediate, synchronous delivery. This is done with the purpose of instantly testing the impact of each received message on the receiving actor. Such a test does not have to wait for asynchronous message delivery, making it much simpler to see the resulting message-drive state transition on the receiving actor, for example. When testing actors created through the conventional `World`, the test must employ a mechanism such as `AccessSafely` to eventually see and assert against the expected outcomes. It is not always convenient to mock a protocol interface that is backed by a `AccessSafely` instance, making an actor created through the `TestWorld` and possessing a `TestMailbox` an essential tool.

Yet, you must be careful when using an actor created by the `TestWorld` because such actors don't have asynchronous semantics. If you use several such actors together, it is almost certain that you will experience race conditions. As with all software tools, `TestWorld` and actors created through it, come with tradeoffs. Use the tools with this knowledge. Note that inside every `TestWorld` is a normal `World` that you can query.

```java
World world = testWorld.world();
```

This enables the creation of both `TestActor<T>` and conventional actor instances.

#### Thread-Safe Data Access

There is a specific `io.vlingo.xoom.actors.testkit` tool for maintaining thread-safety of data shared between tests and the XOOM Actors platform components. The tools is named `io.vlingo.xoom.actors.testkit.AccessSafely` and provides multi-threaded access for both the test thread and the actors being run by the test.

It should be understood that multi-threading is hard to get right, and working with Java on modern CPUs can make it even more complex. Modern CPUs are not only multi-core, but also have performance optimizations that perform what may seem to be counter intuitive operations. One such operations is executing code out of sequence from the actual implementation seen in source code. Thus, even when using `AccessSafely` to protect access to data until it has been written to by an actor running on a separate thread, if the visible/logical program code is not run in the expected order, other threads can see unexpected values.

```java
atomicValue.set(1);
until.completed();
```

In this very simple example, what would happen if the CPU decided that it would be more performant to execute the second statement first, and the first statement second? Impossible? Consider these statements in the Wikipedia article on the Java Memory Model.

> The major caveat of this is that as-if-serial semantics do not prevent different threads from having different views of the data.... The basic rules imply that individual actions can be reordered, as long as the as-if-serial semantics of the thread are not violated.

What would happen is the test thread that is blocking on the `TestUntil` completion would unblock and attempt to read the `atomicValue`. If the other thread has not yet written `1` to the `atomicValue`, the test thread will see the wrong value and its assertion will fail. When you review the code you will insist that it is impossible for the `atomicValue` to remain unchanged if the `TestUntil` completed, and yet due to the CPU architecture you would be wrong.

Next, consider a related and critical point from the same Java Memory Model article.

> Actions that imply communication between threads, such as the acquisition or release of a lock, ensure that actions that happen prior to them are seen by other threads that see their effects. For example, everything that happens before the release of a lock will be seen to be ordered before and visible to everything that happens after a subsequent acquisition of that same lock.

The `AccessSafely` testkit component helps you avoid such problems and solve them using the aforementioned techniques, relieving you from the burden of writing complex test code.

To use this tool, first create a component to be used under the control of the test, such as a mock object, such as one passed to an actor. The mock would resemble the expected asynchronous argument, but is not an asynchronous implementation. One such example is creating a mock implementor of `PersistResultInterest`, such as is done in XOOM Symbio with `MockPersistResultInterest`. Please see the tests that use the mocks. The following is a snippet from one part of the mock.

Inside the `MockPersistResultInterest` you set up some writers for the inside to write with, and readers for the test to read with.

```java
public AccessSafely afterCompleting(final int times) {
  access = AccessSafely
    .afterCompleting(times)
    .writingWith("add", (value) -> persistentObjects.add((int) value))
    .writingWith("addAll", (values) -> persistentObjects.addAll((List) values)) 
    .readingWith("object", (index) -> persistentObjects.get((int) index))
    .readingWith("size", () -> persistentObjects.size());
  return access;
}
```

This creates a new `AccessSafely` for some number of write occurrences followed by the registration of properties with write and read access. The property names are provided as `String` values. The actual writers and readers are lambdas.

The `times` of predetermined actions is backed by `TestUntil` inside (see above). When you first `readFrom("some-property")` you will block until those actions have been completed, at which time you will get the return value of the property that you asked for. In the above example there are four properties including `"size"` and `"object"`. When the test client uses `readFrom("size")` it may block, but the second one `readFrom("object", 0)` doesn't, because both are protected by the same `TestUntil` created with `afterCompleting(1)`.

To create properties, register both writers and readers. The writers are all `java.util.function.Consumer<T>` expressions. The readers may be simple `java.util.function.Supplier<T>` expressions or `java.util.function.Function<T,R>` expressions. The properties are now available on both sides of the test.

Again inside the `MockPersistResultInterest` create the code that handles writing to properties when it receives a notification of some persistence results. It uses a property writer to set the value atomically and inside a lock. You don't have to know the details of the implementation inside `AccessSafely`, only that thread-safe property access is handled for you.

```java
public void persistResultedIn(
    final Outcome outcome,
    final Object persistentObject,
    final int possible,
    final int actual,
    final Object object) {
  if (actual == 1) {
    access.writeUsing("add", persistentObject);
  } else if (actual > 1) {
    access.writeUsing("addAll", persistentObject);
  } else {
    throw new IllegalArgumentException(...);
  }
}
```

This ensures that a barrier/fence is placed around each data property so each property can be both written to and read from in a thread-safe manner. Here is a code snippet from the test that reads the properties to assert on its expectations.

```java
public void testThatObjectPersistsQuerys() {
  final AccessSafely persistAllAccess = persistInterest.afterCompleting(1);
  final Person person = new Person("Tom Jones", 85);
  objectStore.persist(person, persistInterest);
  final int persistSize = persistAllAccess.readFrom("size");
  assertEquals(1, persistSize);
  assertEquals(person, persistAllAccess.readFrom("object", 0));
  ...
}
```

This simple tool will prevent what may appear to be impossible data values as test outcomes.

### Routing and Routers

Routers offer a way to deliver a message to one or more other actors, according to a specified routing strategy. They allow you to decouple the source of a message from its destination and they function as a branching mechanism in the message channel between actors. Routers can be used to control and improve message throughput for a particular message protocol, to distribute workload among a pool of actors in a desirable way, or even both.

Based on it's routing strategy, a router will compute a "routing" which consists of an ordered list of one or more actors, referred to as "routees", to which a message will be dispatched for processing. The router may consider any state, including the message itself, in computing the routing.

#### Router Responsibilities

Routers have four main responsibilities:

1. Maintain the list of actors that are currently subscribed as routees
2. Support the subscribing and unsubscribing of routees
3. Computing a routing for a given message according to some routing logic
4. Dispatch messages to the actors who were selected to be members of the routing

#### Type Safety

Routers and routees are actors and, like all actors in vlingo, are type safe. Each will implement one or more messaging protocols (i.e., Java interfaces). A router and its routees must implement the same messaging protocol, though each may also implement other protocols that are not shared.

The `io.vlingo.xoom.actors.Router` and its abstract subclasses are generic types whose type parameter `<P>` is the Java interface representing the message protocol implemented by the router and its routees:

```java
public abstract class Router<P> extends Actor
```

#### Provided Routers

XOOM Actors provides several kinds of routers out-of-the-box that are mainly distinguished by the routing strategy they employ:

* `io.vlingo.xoom.actors.BroadcastRouter` - dispatches every message to every routee
* `io.vlingo.xoom.actors.ContentBasedRouter` - considers the content of the message in choosing which routee to dispatch the message to
* `io.vlingo.xoom.actors.RandomRouter` - dispatches each message to a random one of the routees
* `io.vlingo.xoom.actors.RoundRobinRouter` - dispatches each message to the next routee, in turn
* `io.vlingo.xoom.actors.SmallestMailboxRouter` - dispatches each message to the routee with the least number of messages in its mailbox at the time

Each of these routers is provided as an abstract class that extends `io.vlingo.xoom.actors.Router` (which extends `io.vlingo.xoom.actors.Actor`).

It is possible, of course, to implement your own new kind of router by directly extending `io.vlingo.xoom.actors.Router`.

#### Routee Subscription

Routees must be subscribed to a router before they can be dispatched any messages. There are two approaches for subscribing routees:

* Automatically during router initialization
* Explicitly after router initialization

Automatic routee subscription is accomplished by passing a `io.vlingo.xoom.actors.RouterSpecification` with a non-zero initial pool size to your router's constructor. For more information , see the *Creating a Router: Construction and Routee Pool Initialization* section below.

Explicit routee subscription requires the router to expose the subscription (and unsubscription) protocol as a public method(s). Since all the routees must comply with the messaging protocol, create an interface providing the type safe subscription protocol, for example:

```java
public interface InvoiceSubmitterSubscription {
  void subscribe(InvoiceSubmitter submitter);
  void unsubscribe(InvoiceSubmitter submitter);
}
```

&#x20;The router then needs to implement this interface, self-delegating to the protected `subscribe(Routee)` and `unsubscribe(Routee)` methods defined in the `io.vlingo.xoom.actors.Router` superclass:

```java
public class InvoiceSubmissionRouter extends ..... impements InvoiceSubmitterSubscription, ...{

  public void subscribe(InvoiceSubmitter submitter) {
    subscribe(Routee.of(submitter));
  }
  
  public void unsubscribe(InvoiceSubmitter submitter) {
    unsubscribe(Routee.of(submitter));
  }
}
```

#### Route Computation

The `io.vlingo.xoom.actors.Router` class provides a set of route computation methods:

```java
<T1> Routing<P> routingFor(final T1 routable1)
<T1, T2> Routing<P> routingFor(final T1 routable1, final T2 routable2)
<T1, T2, T3> Routing<P> routingFor(final T1 routable1, final T2 routable2, final T3 routable3)
<T1, T2, T3, T4> Routing<P> routingFor(final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4)
```

Most types of routers do not base routing decisions on the message being routed because their routing logic is more mechanical (e.g., round robin) or is based on the state of the routees (e.g., smallest mailbox).

For this reason, the default implementation of the above four route computation methods simply self-delegates to the method:

```java
protected abstract Routing<P> computeRouting();
```

You will find that each subclass of `io.vlingo.xoom.actors.Router` will provide a concrete implementation of this method that encodes its particular routing strategy logic.

The exception is `io.vlingo.xoom.actors.ContentBasedRouter` for which, by definition, the routing logic depends on the specific message being routed. For this reason, `ContentBasedRouter` implements `computeRouting()` to throw `java.lang.UnsupportedOperationException`. Instead, you will need to override one of the `routingFor()` methods listed above and encode your routing logic there.

#### Router Message Dispatching

As noted previously, one of the responsibilities of routers is to dispatch messages to the actors that were selected as routees. The abstract class `io.vlingo.xoom.actors.Router` provides two sets of message dispatching protocol:

* Command dispatching
* Query dispatching

The **command dispatching** protocol is used to dispatch messages that may have arguments but *do not* have a return value, for example `void submitInvoice(Invoice)`:

```java
<T1> void dispatchCommand(final BiConsumer<P, T1> action, final T1 routable1)
<T1, T2> void dispatchCommand(final TriConsumer<P, T1, T2> action, final T1 routable1, final T2 routable2)
<T1, T2, T3> void dispatchCommand(final QuadConsumer<P, T1, T2, T3> action, final T1 routable1, final T2 routable2, final T3 routable3)
<T1, T2, T3, T4> void dispatchCommand(final PentaConsumer<P, T1, T2, T3, T4> action, final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4)
```

The command dispatching methods take a Consumer (function) as the first argument, and then from 1 to 4 objects that will be the arguments to the Consumer function. These objects map to the arguments of the messaging protocol method.

The **query dispatching** protocol is used to dispatch messages that may have arguments and *do* return a value, for example `Price computePrice(ProductID, CustomerID)`:

```java
<T1, R extends Completes<?>> R dispatchQuery(final BiFunction<P, T1, R> query, final T1 routable1)
<T1, T2, R extends Completes<?>> R dispatchQuery(final TriFunction<P, T1, T2, R> query, final T1 routable1, final T2 routable2)
<T1, T2, T3, R extends Completes<?>> R dispatchQuery(final QuadFunction<P, T1, T2, T3, R> query, final T1 routable1, final T2 routable2, final T3 routable3)
<T1, T2, T3, T4, R extends Completes<?>> R dispatchQuery(final PentaFunction<P, T1, T2, T3, T4, R> query, final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4)
```

The query dispatching methods take a Function as the first argument, and then from 1 to 4 objects that will be the arguments to the Function. These objects map to the arguments of the messaging protocol method.

#### Implementing a Router in Your Application

Implementing a router in your application is straight forward. You'll need to:

* Create the message protocol that your router and routees will support as a Java interface
* Create your routee actor
* Create your router actor by extending one of the abstract subclasses of `io.vlingo.xoom.actors.Router`

*Create the Message Protocol*

As an example, let's say you are implementing an invoice submission process and there are several ERP systems to which any given invoice might need to be submitted. Your router will route each Invoice to one of several `InvoiceSubmitter` actors, each of which represents a particular ERP system. The selected routing will likely depend on information in the Invoice itself (e.g., customer ID).

To support this scenario, you might design the following protocol:

```java
public interface InvoiceSubmitter {
  void submitInvoice(Invoice invoice);
}
```

*Create the Routee Actor(s)*

Now that you have the `InvoiceSubmitter` protocol defined, you can create the actor(s) to which your router will route messages. These actors will be the ones actually doing the work, in our case submitting an Invoice to a specific ERP system.

Let's assume ERP systems in your company are named after Greek mythological gods, such as Apollo and Atlas, and that for various reasons you decide to create a different actor per ERP system.

Here is the rough definition of the actor for the Apollo ERP invoice submission:

```java
public class ApolloInvoiceSubmitter extends Actor implements InvoiceSubmitter {
  public void submitInvoice(Invoice invoice) {
    //do some work here
  }
}
```

Your actor for Atlas and other ERPs would have a similar structure but different logic in their `submitInvoice` methods.

*Create a Router: Extending a Built-in Router*

As noted above, XOOM Actors provides a number of built-in implementations of `io.vlingo.xoom.actors.Router` that you can extend.

In the example, the routing will be *content-based*, because the router will use information from the message itself (e.g., the customer ID of the Invoice) to select which ERP-specific routee to dispatch the message to. Thus, t will extend `io.vlingo.xoom.actors.ContentBasedRouter`:

```java
public class InvoiceSubmissionRouter
extends ContentBasedRouter<InvoiceSubmitter>
implements InvoiceSubmitter {
  ...
}
```

*Creating a Router: Construction and Routee Pool Initialization*

The `io.vlingo.xoom.actors.Router` class requires that a `io.vlingo.xoom.actors.RouterSpecification` be provided as a constructor argument and offers subclasses an opportunity to get involved in the initialization of the routee pool:

```java
  public Router(final RouterSpecification<P> specification) {
    this.routees = new ArrayList<Routee<P>>();
    initRoutees(specification);
  }
```

By default, the information in the `RouterSpecification` will be used to create an initial (possibly empty) pool of routee actors as child actors of the router actor. Subclasses may customize that behavior by overriding `initRoutees(RouterSpecification)`.

Often, your concrete router class can make these decisions for itself by implementing a constructor that supplies them. For example:

```java
public OrderRouterActor(final int poolSize) {
  super(
    new RouterSpecification(
      poolSize,
      Definition.has(OrderRouterWorker.class, Definition.NoParameters()),
      OrderRouter.class)
  );
}
```

*Creating a Router: Routing Logic*

In the [Route Computation](/xoom-actors#route-computation) section above, we learned that subclasses of `io.vlingo.xoom.actors.ContentBasedRouter` need to override one of the `routingFor()` methods inherited from `io.vlingo.xoom.actors.Router` and implement the routing logic there. The `routingFor()` method variants provide access to the message arguments so that the router can inspect that information as part of its routing logic.

In our example, the message protocol `void submitInvoice(Invoice invoice)` has a single argument, so we can override the single-argument `routingFor()` method:

```java
  @override
  protected <T1> Routing<P> routingFor(final T1 routable1) {
    Invoice invoice = (Invoice) routable1;
    InvoiceSubmitter submitter = selectERPInvoiceSubmitter(invoice.customerID);
    return Routing.with(submitter);
  }

  private InvoiceSubmitter selectERPInvoiceSubmitter(CustomerID customerID) {
    //select one of the subscribed InvoiceSubmitter actors based on CustomerID
  }
```

Note that both `InvoiceSubmissionRouter` and `ERPInvoiceSubmitter` implement the `InvoiceSubmitter` interface, thereby establishing the type safe messaging protocol that they share, which allows the router to forward messages to the routees in a type safe way.

*Creating a Router: Dispatching*

Implementing dispatching logic requires implementing the message protocol and calling one of the methods discussed in the [Router Message Dispatching](/xoom-actors#router-message-dispatching) section above.

The `InvoiceSubmitter` protocol declares the one-argument command method `void submitInvoice(Invoice)`, so we we need to provide an implementation that calls the `dispatchCommand` method inherited from `io.vlingo.xoom.actors.Router` that accommodates one argument:

```java
protected <T1> void dispatchCommand(final BiConsumer<P, T1> action, final T1 routable1)
```

Notice that the first argument to each `dispatchCommand` (and `dispatchQuery`) method is a function. XOOM Actors supplies variants of these dispatching methods for 1 to 4 arity functions. Any lambda expression matching the signature of the dispatching method can be passed.

Here, then, is the dispatching logic of our `InvoiceSubmissionRouter`:

```java
   @Override
    public void submitInvoice(final Invoice invoice) {
      dispatchCommand(InvoiceSubmitter::submitInvoice, invoice);
    }
```

In the implementation above, we take advantage of the fact that Java method references are shorthand for lambda expressions that call the same method - in this case the `void submitInvoice(Invoice)` method of `InvoiceSubmitter`.

*Creating a Router: Subscribing Routees*

As noted in the "*Creating a Router: Construction and Routee Pool Initialization*" section above, one easy way of subscribing routees is to pass a `RouterSpecification` with a non-zero initial pool size to your router's constructor. The actor `Definition` in the `RouterSpecification` will be used by your router to create and subscribe a number of child actors that implement your routing message protocol. This approach works well when the routees can all be instances of the same class.

Sometimes, such as in our invoice submission example, the routees need to be instances of different classes that all implement the same message protocol. In our example, the `InvoiceSubmitter` actors for the Apollo and Atlas ERPs were implemented as different classes. In such cases, actors need to be explicitly subscribed to the router. This requires the router to provide public un/subscription protocol, as described in the [Routee Subscription](/xoom-actors#routee-subscription) section above.


# HTTP (REST and RPC)

The embeddable HTTP server for Reactive REST backed by XOOM Actors and XOOM Wire.

## Reactive REST

The XOOM HTTP component supports reactive, scalable, and resilient HTTP servers and REST services running as a small, fast, embedded serve&#x72;*.* Thus, this component does not run standalone, but is meant to provide very lightweight and high-performing HTTP support within a application- or microservice-based runtime, such as a Bounded Context. The server supports REST and RPC dispatching to implementations of fluent APIs.

{% hint style="info" %}
It is common for developers to think of REST over HTTP in terms of CRUD because the primary methods provided by the protocol are: POST, GET, PUT, and DELETE. If taken at face value, these verbs are CRUD through and through. Yet, almost no one uses the methods to map directly from browser to a database. Most contemporary applications instead map the HTTP methods to procedures (i.e. a method on a Java or C# class) within the application. Those procedures are responsible for adapting path parameters, headers, and the request body to a form that can be consumed by the inner application components.

The procedure to which the HTTP request is mapped need not represent a CRUD operation at all. When you consider that POST, GET, PUT, DELETE, and others such as PATCH, are *message categories that map to procedures,* not only ways to perform CRUD operations on data, it makes for a lot more flexibility in how HTTP can be used.

For example, a POST method would always be used with the intention to *create* some entity resource, such as a product; that is, POST is in the procedure category of creation. Yet, there is no reason for the procedure to which that HTTP request is mapped to be named `postProduct()` or even the "obvious" `createProduct()`. Instead, the procedure could be named something more in line with the language spoken by the business, such a `catalogProduct()`. Here *catalog* is used as a verb; that is, our company is not in the business of creating new products. The products come to the company already created by a manufacturer. Our company *sells products through catalogs.* For us, products need to be *cataloged* (verb) for them to be accessible for purchase through a *catalog* (noun). With that in mind, *establishing a new kind of catalog for a kind of product* might be thought of as *defining a catalog.* Thus, the procedure would be named `defineCatalog()`.

Given this line of reasoning, the ways that HTTP methods are mapped are virtually unlimited, and all the while still honoring the REST way of doing things. The older SOAP protocol used to implement RPC-based APIs, was known to those who could cut through the jargon as "XML over HTTP." Thus, if XML over HTTP can be used to implement RPC, certainly it stands to reason that JSON over HTTP could be used in the same way.

The following sections demonstrate the flexibility of using HTTP as a means to support far more than CRUD. Avoid pedantic opinions that limit creativity. Such opinions are generally held by those who think only in terms of technology and expect the business to speak their language, which is composed mostly of CRUD and collection-oriented (add, insert, remove) terminology.
{% endhint %}

Consider the overall architecture of our HTTP server. It is highly Reactive by employing actors at every major operational junction.

![A request is received and processed asynchronously from beginning through to response.](/files/-MBl4cnJOQagCAIlDdn2)

REST over HTTP is quite commonly employed to support user interfaces, service integrations, and even distribution of event streams. Of course, we don't suggest that your services should be primarily REST-based, we provide our HTTP server for when REST it is useful. Even RPC can be supported. See the above information box. Since REST over HTTP is the most common contemporary use case, the documentation mostly refers to REST rather than RPC, but everything herein is equally applicable to RPC using the style discussed in the above information box.

### Use With Domain-Driven Design Context Mapping Patterns

With any use of the XOOM HTTP server, which might be with a REST flavor as more so as RPC, the use of a few Domain-Driven Design patterns are common. Among the *Context Mapping* patterns, the *Open-Host Service* and *Published Language* patterns naturally support these API styles. The *Open-Host Service* is the well defined API that is open for public use, with the possible requirement of client credentials. The *Published Language* is the REST resources or RPC response values that are provided.

## Overview

Our HTTP component can help you create REST-based services rapidly and with great simplicity. One glance at the REST request mappings to Java objects is all it takes to understand this. The following demonstrates both file-based and code-based fluent request handler mappings.

```java
action.user.register.method = POST
action.user.register.uri = /users
action.user.register.to = register(body:sample.user.UserData userData)

action.user.contact.method = PATCH
action.user.contact.uri = /users/{userId}/contact
action.user.contact.to = changeContact(String userId, body:sample.user.ContactData contactData)
```

The above declarations are made in the `vlingo-http.properties` file. The following is the resource handler implementation to match it.

```java
public class UserResource extends ResourceHandler {
  public void register(final UserData userData) {
    final User user =
            User.from(
                    Name.from(userData.nameData.given, userData.nameData.family),
                    Contact.from(userData.contactData.emailAddress, userData.contactData.telephoneNumber));

    repository.save(user);
    
    completes().with(Response.of(Created, headers(of(Location, userLocation(user.id))), serialized(UserData.from(user))));
  }

  public void changeContact(final String userId, final ContactData contactData) {
    final User user = repository.userOf(userId);
    if (user.doesNotExist()) {
      completes().with(Response.of(NotFound, userLocation(userId)));
      return;
    }
   
    final User changedUser = user.withContact(new Contact(contactData.emailAddress, contactData.telephoneNumber));
    
    repository.save(changedUser);
   
    completes().with(Response.of(Ok, serialized(UserData.from(changedUser))));
  }
}
```

By means of the `ResourceHandler` base class, there are several Request parts available: URI, headers, body, and any query parameters. You may also access the default `ContentType`, which may be overridden. See the following `queryUsers()` handler method.

```java
  public Completes<Response> queryUsers() {
    final String page = context().request().queryParameters().valuesOf("page");
    final String contentType = context().contentType();
    ...
  }
```

The above is from file-based request/response resource mappings defined in the properties file`vlingo-http.properties`. Yet, our versatile API also supports fluent mappings in source code.

```java
public class UserResource {
  ...
  public Resource<?> routes() {
    return resource("User Resource",
      post("/users")
        .body(UserData.class)
        .handle(this::register),
      patch("/users/{userId}/contact")
        .param(String.class)
        .body(ContactData.class)
        .handle(this::changeContact));
  }
}
```

In the above example only the `routes()` is shown, and would replace the file-based route mappings previously shown. Also note in this example, when using the fluent routes API your resource class should not extend `ResourceHandler`. Although you may do so, at time of execution its state will be hollow because the runtime does not support `ResourceHandler`. Instead, to get similar base class state and behavior with dynamic resources created with the fluent API, use the optional `DynamicResourceHandler`.

```java
public class UserResource extends DynamicResourceHandler {
  private static final AtomicInteger nextId = new AtomicInteger(0);
  private final int id;
  
  public UserResource(final Stage stage) {
    super(stage);
    
    this.id = nextId.incrementAndGet();
    
    logger().info("UserResource: Pooled instance created: " + this.id);
  }
  
  public Completes<Response> register(final UserData data) {
    final String userType = context().request().queryParameters().valuesOf("userType");
    final String contentType = context().contentType();
    ...
  }
  
  ...
  @Override
  public Resource<?> routes() {
    logger().info("UserResource: wiring resources for: " + this.id);
    
    return resource("User Resource", this,
      post("/users")
        .body(UserData.class)
        .handle(this::register),
      patch("/users/{userId}/contact")
        .param(String.class)
        .body(ContactData.class)
        .handle(this::changeContact));
  }
}
```

By extending `DynamicResourceHandler` your resource may use the `Stage` managing this resource, the `Logger` and `Scheduler` of that `Stage`, and the `Context` with the current `Request`. The `Request` provides various request parts such as the URI, headers, body, and any query parameters. You may also access the default `ContentType`, which may be overridden. See the `register(UserData)` handler method for an example accessing the query parameters and `ContentType`.

{% hint style="info" %}
Query parameters may be mapped more naturally using the fluent API as seen [below](https://docs.vlingo.io/vlingo-http#query-parameters).
{% endhint %}

The concrete resource handler must provide a `Stage` to the `DynamicResourceHandler` constructor. It is assumed that the concrete resource handler's constructor will take at least the `Stage` as a parameter. The `DynamicResourceHandler` declares the `routes()` method abstract, so it must be overridden in the concrete extender. As you can see above, `routes()` returns `resource()`with an optional parameter of the `DynamicResourceHandler` as the`this` object, which is to be given the current request `Context` before each handler invocation.

In the following sections you will learn how to quickly set up and start your server with resources handlers.

## Setting Up the Server

If you will use the file-based configuration you must create `vlingo-http.properties`. Otherwise you will write source code to define the server configuration. First the file-based configuration is explained, and then the source code and fluent API approach.

### File-Based Configuration

Create the file `vlingo-http.properties` and place it into the project directory hierarchy used for resources. For Maven that would be `src/main/resources` for production and if you are defining the properties for test, it would be `src/test/resources`. In this file create the following properties. Your values may differ.

```java
#=====================================
# server
#=====================================

server.http.port = 8080
server.dispatcher.pool = 10
server.buffer.pool.size = 100
server.message.buffer.size = 65535
server.probe.interval = 10
server.probe.timeout = 2
server.processor.pool.size = 10
server.request.missing.content.timeout = 100

#=====================================
# generated resource dispatchers
#=====================================

resource.dispatcher.generated.sources.main = target/generated-sources/
resource.dispatcher.generated.sources.test = target/generated-test-sources/
resource.dispatcher.generated.classes.main = target/classes/
resource.dispatcher.generated.classes.test = target/test-classes/
```

This is the basic minimum configuration necessary to start the server. There are other properties that you will learn about later. The following summarizes these properties.

1. **`server.http.port`**: the socket port to be used by the server, which here is 8080.
2. **`server.dispatcher.pool`**: the server uses a pool of actors to dispatch incoming requests asynchronous. Here the dispatcher pool size is 10.
3. **`server.buffer.pool.size`**: used by the server to create a pool of reusable ByteBuffer instances to use for incoming requests and outgoing resources. There will be at least 100 buffers in this pool. Yet, the elastic pool design enables it to grow dynamically under heavy load and contract back down to 100 buffers as load diminishes.
4. **`server.message.buffer.size`**: used by the server when creating the buffer pool to allocate each buffer with this many bytes. Here the buffers will each be 65,535 bytes. (a) This does not limit the overall size of a given incoming message because these may be read in chunks and span multiple buffers. (b) This also does not limit the size of outgoing responses because a non-pooled buffer will be temporarily allocated to send payloads larger than this maximum. Serving larger responses should be the exception rather than common, otherwise performance will suffer. If a common occurrence consider setting this buffer limit to the largest common payload size.
5. **`server.probe.interval`**: determines the number of milliseconds between each socket channel probe to receive new connections and requests, and to send new responses. Be careful with this value as various O/S and JDKs deal differently with intervals, possibly being too fast to too slow.
6. **`server.probe.timeout`**: the amount of time in milliseconds that the socket channel probe will wait for new connections and requests, and to check for writable status used for sending responses. Be careful with this value as when there are no new requests, it causes the actor's thread to block inside the socket channel probe until this timeout is reached.
7. **`server.processor.pool.size`**: used by the server to size the pool of socket channel processors. Here the processor pool size is 10. There will be 10 total actors created and used in round-robin order as new connections are accepted, which will each read from and write to every newly accepted client socket channel connection.
8. **`server.request.missing.content.timeout`**: as previously indicated, very large incoming request messages of byte length greater than `server.message.buffer.size` will require spanning two or more total buffers. This value indicates how long the incomplete message will be retained in the server before it is considered a bad request (missing bytes). This example indicates that such an incomplete request may be retained for a maximum of 100 milliseconds in anticipation of remaining bytes being received.
9. **`resource.dispatcher.generated.sources.???`**: These four properties define where generated source code is to be saved as Java source files and where class files are save after dynamic compilation. This example uses the Maven target layout and defines both main and test areas.

In addition to this, it only makes sense to include the description of at least one resource handler (a.k.a. endpoint or controller).

```java
#=====================================
# user resources
#=====================================

resource.name.user = [register, contact, name, queryUser, queryUsers, queryUserError]

resource.user.handler = io.vlingo.xoom.http.sample.user.UserResource
resource.user.pool = 10
resource.user.disallowPathParametersWithSlash = true

action.user.register.method = POST
action.user.register.uri = /users
action.user.register.to = register(body:io.vlingo.xoom.http.sample.user.UserData userData)

action.user.contact.method = PATCH
action.user.contact.uri = /users/{userId}/contact
action.user.contact.to = changeContact(String userId, body:io.vlingo.xoom.http.sample.user.ContactData contactData)

action.user.name.method = PATCH
action.user.name.uri = /users/{userId}/name
action.user.name.to = changeName(String userId, body:io.vlingo.xoom.http.sample.user.NameData nameData)

action.user.queryUser.method = GET
action.user.queryUser.uri = /users/{userId}
action.user.queryUser.to = queryUser(String userId)

action.user.queryUsers.method = GET
action.user.queryUsers.uri = /users
action.user.queryUsers.to = queryUsers()

action.user.queryUserError.method = GET
action.user.queryUserError.uri = /user/{userId}/error
action.user.queryUserError.to = queryUserError(String userId)
```

This is a more complete resource routing definition. The properties are summarized next.

1. **`resource.name.{name}`**: The first property of any resource handler is the name, which above is `resource.name.user`. This says, here is a resource named `user`.  The property's value is an array of method names that are used as individual route request handlers. Each of these names must have a corresponding set of `action.{name}...` properties, which are documented in a following numbered descriptions. If you do not list a name in this array for every route request handler, the corresponding handler action definition will not be found for the missing name.
2. All properties associated with the named resource are in the form *`resource.name.property`*, such as `resource.user.handler`.
3. **`resource.{name}.handler`**: the fully-qualified class name of the concrete `ResourceHandler` extender. The server will dispatch to actions matching the URI patterns to the methods in this `ResourceHandler`. The above example references the `UserResource`, but along with it's package name.
4. **`resource.{name}.pool`**: used to create a pool of actors for `ResourceHandler` instances of the type defined by the `resource.{name}.handler` property. Individual requests are handled in a round-robin fashion. In this example the `resource.user.pool` defines a pool size of 10. Note that this pool is created for each `server.dispatcher.pool`, meaning that there will be a total of `server.dispatcher.pool` \* `resource.name.pool` actors to handle requests to this named resource.
5. **`resource.{name}.disallowPathParametersWithSlash`**: deprecated and must always be `true`.  Above is for the resource named `user`, as in `resource.user.disallow...`
6. **`action.{name}.{endpoint}.method`**: used to define the HTTP method to be used to make a matching request to the given URI. Here `{name}` and `{endpoint}` are placeholders for the actual names. In the first example above `{name}` is `user` and the `{endpoint}` method is `register`. Note that this property's value may be one of: `POST`, `GET`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `TRACE`, `OPTIONS`, or `CONNECT`.
7. **`action.{name}.{endpoint}.uri`**: used to define the URI that will map to the given endpoint. Here `{name}` and `{endpoint}` are placeholders for the actual names. In the first example above `{name}` is `user` and the `{endpoint}` method is `register`. Path parameters, if any, are surrounded by curly braces, such as in `/users/{userId}/contact`, where the parameter name is `userId`. In the actual URI, userId must be replaced with some sort of identity, such as may be mapped to a `String` value.
8. **`action.{name}.{endpoint}.to`**: used to define the method name and signature to which this route mapping will dispatch to on the given `resource.{name}.handler` class instance. Here `{name}` and `{endpoint}` are placeholders for the actual names. In the first example above `{name}` is `user` and the `{endpoint}` method is `register`. When the HTTP method is `POST` and the URI is `/users` then the match will route to the given Java method, such as `register(UserData userData)`. In the above example the `body:` keyword indicates that the `UserData` will be found in the request body. Depending on the content type, which is by default JSON, the body will be automatically deserialized into an instance of the given type, such as `UserData`. Note that when the URI contains one or more path parameters, the `{paramName}` will be mapped to the matching Java method parameter with the same name, and automatically deserialized into the given Java parameter type. In the above example the `/users/{userId}/contact` maps to the Java method parameter `String userId`.

When using the file-based configuration there is no limit to the number of path parameters. However, the greater the number of parameters the more complex the Java method will be to create and maintain.

It is quite simple to start a server from file-based configuration.

```java
final World world = World.startWithDefaults("server");

final Server server = Server.startWith(world.stage());
```

Using the above examples, this `Server` is started on port 8080 and has a single resource handler, `UserResource`. The remaining properties are applied to the server as previously explained.

{% hint style="info" %}
The `ResourceHandler` and `DynamicResourceHandler` base classes provide access to several request parts, such as headers, query parameters, and other environmental objects.
{% endhint %}

#### Provided By `ResourceHandler` and `DynamicResourceHandler`:

| **Type Accessor**           | **Description**                                                                                                                                                                                                                                                                                    |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Context context()`         | <p>The <code>Context</code> type provides numerous details. This contains the <code>Request</code>, which in turn contains <code>Method</code>, <code>URL</code>, <code>Version</code>, <code>Headers</code>, and <code>Body</code>. This gives you access to all parts of the request.</p><p></p> |
| `ContentType contentType()` | The details about the content type of the request. (only on `ResourceHandler`)                                                                                                                                                                                                                     |
| `Logger logger()`           | The means to log debug, error, and informational messages.                                                                                                                                                                                                                                         |
| `Scheduler scheduler()`     | Use to manage the scheduling of future tasks.                                                                                                                                                                                                                                                      |
| `Stage stage()`             | The `Stage` of this request.                                                                                                                                                                                                                                                                       |

### Source Code Configuration

The following provides a very simple example of source code configuration along with the XOOM HTTP fluent route mapping API. This provides the minimum code to create an endpoint that responds with `"Hello, World!"`. Both Java and Kotlin examples are available. The tutorial descriptions refer to the Java code.

Create a new project with your favorite editor/IDE and create a `Bootstrap` class with the following content.

{% tabs %}
{% tab title="Java" %}
{% code title="Bootstrap.java" %}

```java
import io.vlingo.xoom.actors.World;
import io.vlingo.xoom.common.Completes;
import io.vlingo.xoom.http.Response;
import io.vlingo.xoom.http.resource.Configuration.Sizing;
import io.vlingo.xoom.http.resource.Configuration.Timing;
import io.vlingo.xoom.http.resource.Resource;
import io.vlingo.xoom.http.resource.Resources;
import io.vlingo.xoom.http.resource.Server;

import static io.vlingo.xoom.http.resource.ResourceBuilder.get;
import static io.vlingo.xoom.http.resource.ResourceBuilder.resource;

public class Bootstrap {
  private final static int PORT = 8080;
  private static Bootstrap instance;
    
  public final Server server;
  public final World world;

  private Bootstrap() {
    this.world = World.startWithDefaults("hello world example java");

    final Resources resources = Resources.are(helloWorldResource());

    this.server =
            Server.startWith(
                world.stage(),
                resources,
                PORT,
                Sizing.define(),
                Timing.define());
    }

    private Resource helloWorldResource() {
      return resource("Hello World",
        get("/helloworld")
          .handle(() -> withSuccess(of(Ok, "Hello, World!")))
        );
    }

    public static final Bootstrap instance() {
      if (instance == null) {
        instance = new Bootstrap();
      }
      return instance;
    }

    public static void main(final String[] args) throws Exception {
        System.out.println("=========================================");
        System.out.println("service: started at http://localhost:" + Bootstrap.PORT);
        System.out.println("try: curl http://localhost:" + Bootstrap.PORT + "/helloworld");
        System.out.println("=========================================");
        Bootstrap.instance();
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="Bootstrap.kt" %}

```kotlin
import io.vlingo.actors.World
import io.vlingo.common.Completes.withSuccess
import io.vlingo.http.Response.of
import io.vlingo.http.Response.Status.Ok
import io.vlingo.http.resource.Configuration.Sizing
import io.vlingo.http.resource.Configuration.Timing
import io.vlingo.http.resource.Resource
import io.vlingo.http.resource.ResourceBuilder.get
import io.vlingo.http.resource.ResourceBuilder.resource
import io.vlingo.http.resource.Resources
import io.vlingo.http.resource.Server

class Bootstrap {
    private val world = World.startWithDefaults("hello world example kotlin")
    private val server: Server

    init {
        val resources = Resources.are(helloWorldResource())

        server = Server.startWith(world.stage(), 
                                  resources, 
                                  PORT, 
                                  Sizing.define(), 
                                  Timing.define())
    }

    private fun helloWorldResource(): Resource<*> {
        return resource("hello world resource",
                        get("/helloworld")
                            .handle { withSuccess(of(Ok, "Hello World")) })
    }

    companion object {
        const val PORT = 8080
    }
}

fun main(args: Array<String>) {
    println("=========================================")
    println("service: started at http://localhost:" + Bootstrap.PORT)
    println("check out http://localhost:" + Bootstrap.PORT + "/helloworld")
    println("=========================================")
    Bootstrap()
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Compile and run the server by means of the Java `main()` method. Check the results by running the following command-line.

```bash
> curl http://localhost:8080/helloworld
```

The `curl` command should print the following text into the terminal window: `Hello, World!`

{% hint style="info" %}
The `Server` logs informational output by means of the `World` standard `Logger` configuration.
{% endhint %}

The `Resources`(23) is the set of HTTP endpoints, which in this case is only one. The `Server` instance (25) is where the `Resources` are held and used to match and dispatch on requests. To start a `Server` you simply provide a `Stage` and the `Resources`. When created, the `Server` starts listening on port 8080 for HTTP requests.

`Sizing` (30) is the configuration parameter with the *processor pool size, dispatcher pool size, max buffer pool size,* and *max message size*. `Timing` (31) is the configuration with the *probe interval* and *timeout* parameters. For now, we use the default configuration.

{% hint style="warning" %}
The next sections use the previous code as starting point.
{% endhint %}

### Configuring Special Features

There are some additional features available through configuration: static file resources, server-sent events, and feed resources.

#### Static File Resources

Static file resources are ordinary content in disk files, such as HTML, images, and video. To serve static file resources use the `vlingo-http.properties` file-based configuration.

```
#=====================================
# static file resources
#=====================================

static.files.resource.pool = 5
static.files.resource.root = /siteroot/content
static.files.resource.subpaths = [/, /css, /js, /views]
```

This configuration auto-creates `io.vlingo.xoom.http.resource.StaticFilesResource` that serves files from the resource root `/siteroot/content` directory structure. Any request URI that begins with the `static.files.resource.subpaths` list will be served.

| Virtual URI     | Physical URI                     |
| --------------- | -------------------------------- |
| `/{file}`       | `/siteroot/content/{file}`       |
| `/css/{file}`   | `/siteroot/content/css/{file}`   |
| `/js/{file}`    | `/siteroot/content/js/{file}`    |
| `/views/{file}` | `/siteroot/content/views/{file}` |

#### Server-Sent Events (SSE)

You may create a pre-packaged SSE resource using the following configuration.

```
#=====================================
# server-sent events
#=====================================

sse.stream.name.all = /eventstreams/all
sse.stream.all.feed.class = io.vlingo.xoom.http.sample.user.AllSseFeedActor
sse.stream.all.feed.payload = 50
sse.stream.all.feed.interval = 1000
sse.stream.all.feed.default.id = -1
sse.stream.all.pool = 10
```

This enables clients to register for a long-lasting stream of events from the server. The URI used by clients is the value of `sse.stream.name.{name}`. In the above example the name is `all` and the URL is `/eventstreams/all`.

The `sse.stream.all.feed.class` is provided by the custom service/application, and in this case is `io.vlingo.xoom.http.sample.user.AllSseFeedActor`. The fully-qualified class name must be given. There may be up to 50 events in a single feed (one send to a client) with an interval of 1,000 milliseconds between feeds. If the client does not provide an id for the starting event, the `default.id` is used. In this case it is -1. There will be 10 total feed instances created in the pool.

A client makes a request to subscribe, such as the following.

```java
Client client = Client.using(Configuration.defaultedKeepAliveExceptFor(...), ...);

Request subscribe =
    Request
        .method(Method.GET)
        .uri("/eventstreams/all")
        .and(RequestHeader.host("StreamsRUs.co"))
        .and(RequestHeader.accept("text/event-stream;charset=utf-8"));

client
    .requestWith(subscribe)
    .andThenConsume(response -> {
        switch (response.status) {
        case Ok:
          processEvents(response);
          break;
        default:
          logger().error("Unexpected: " + response.status);
          break;
        }
    })
    .repeat();
```

In the above example the asynchronous `io.vlingo.xoom.http.resource.Client` will continue to receive responses as feeds occur because it is configured for *keep-alive* mode and tells the `Completes<Response>` to `repeat()` after every feed is received.

The following is a skeleton of class `AllSseFeedActor`.

```java
public class AllSseFeedActor extends Actor implements SseFeed {

  public AllSseFeedActor(final String streamName, final int feedPayload, final String feedDefaultId) {
    ...
  }

  @Override
  public void to(final Collection<SseSubscriber> subscribers) {
    ...
  }
}
```

In the above example the custom feed actor is class `AllSseFeedActor`, which must extend `Actor` and implement `io.vlingo.xoom.http.resource.sse.SseFeed`. See the `io.vlingo.xoom.http.resource.sse.SseStreamResource` that manages the feed generation process, using the custom `SseFeed` actor when needed.

The feed must follow the [SSE standard definition](https://www.w3.org/TR/eventsource/). The following is one example, but not the only possibility.

```java
event: SecurityTokenIssued
data: {"username": "jclifford", "token": "je;se9727anndnds!@"}

event: SecurityTokenIssued
data: {"username": "l.mary", "token": "l9928**)^^322nand$"}

event: SecurityTokenIssued
data: {"username": "camerontyrone", "token": "pdpjehrhfks'//&dh+a"}
```

There is a complete example in the [`xoom-http-frontservice`](https://github.com/vlingo/xoom-examples/tree/master/xoom-http-frontservice) and [`xoom-http-backservice`](https://github.com/vlingo/xoom-examples/tree/master/xoom-http-backservice) in the Github repository [vlingo/xoom-examples](https://github.com/vlingo/xoom-examples).

#### Feed Resources

There is another kind of feed resource, one that is not a SSE stream, but has similar characteristics. It is a stream of any kind and defines its own response body payload. You might think of such as Atom feeds, or similar.

```
#=====================================
# feed resources
#=====================================

feed.resource.name.events = /feeds/events
feed.resource.events.producer.class = io.vlingo.xoom.http.resource.feed.EventsFeedProducerActor
feed.resource.events.elements = 20
feed.resource.events.pool = 10
```

The feed has a name, in this case `feed.resource.name.events`, which is the URI `/feeds/events`. Clients may request a feed region by providing an id. The `...elements` property indicates the maximum number of 20 elements may be in a given feed. There will be 10 total feed instances created in the pool.

```java
public class EventsFeedProducerActor extends Actor implements FeedProducer {
  ...
  @Override
  public void produceFeedFor(final FeedProductRequest request) {
    ...
  }
}
```

In the above example the custom feed actor is class `EventsFeedProducerActor`, which must extend `Actor` and implement `io.vlingo.xoom.http.resource.feed.FeedProducer`. The format of the feed itself is not standardized, but may be JSON, XML, or otherwise follow the Atom standard. The `EventsFeedProducerActor` itself may be backed by the XOOM Lattice exchange feed type, which may stream from a XOOM Symbio `Journal`, or any kind of `EntryReader` for the storage types `ObjectStore` and `StateStore`.

```java
package io.vlingo.xoom.lattice.exchange.feed.Feed;

import io.vlingo.xoom.actors.Actor;
import io.vlingo.xoom.actors.Stage;
import io.vlingo.xoom.symbio.Entry;
import io.vlingo.xoom.symbio.Source;
import io.vlingo.xoom.symbio.store.EntryReader;

/**
 * Provides support utilities for {@code Feed} and related types.
 * Every {@code Feed} has an {@code exchangeName}.
 */
public interface Feed {
  /** The default number of messages per feed. */
  static final int DefaultMessagesPerFeedItem = 20;

  /**
   * Answer a new {@code Feed} with the given properties.
   * @param stage the Stage used to create my Feeder
   * @param exchangeName the String name of my exchange
   * @param feederType the Actor type of my Feeder
   * @param entryReaderType the EntryReader that my Feeder uses
   * @return Feed
   */
  static Feed defaultFeedWith(final Stage stage, final String exchangeName, final Class<? extends Actor> feederType, final EntryReader<?> entryReaderType) {
    return new DefaultFeed(stage, exchangeName, feederType, entryReaderType);
  }

  ...
}
```

The above `DefaultFeed` is a factory for actor-based `Feeder` types. Invoking the `Feed::feeder()` will return a new actor-based `Feeder` of `feederType` with the given `entryReaderType`.

There is a default `Feeder` , the `TextEntryReaderFeeder`, that can consume text entries from any XOOM Symbio `EntryReader` implementation and produce simple feeds.

```java
package io.vlingo.xoom.lattice.exchange.feed;

import java.util.ArrayList;
import java.util.List;

import io.vlingo.xoom.actors.Actor;
import io.vlingo.xoom.symbio.BaseEntry.TextEntry;
import io.vlingo.xoom.symbio.store.EntryReader;

/**
 * The {@code Feeder} serving {@code TextEntry} instances.
 */
public class TextEntryReaderFeeder extends Actor implements Feeder {
  private final EntryReader<TextEntry> entryReader;
  private final Feed feed;

  /**
   * Construct my default state.
   * @param feed the Feed that I serve
   * @param entryReader the {@code EntryReader<TextEntry>} from which content is read
   */
  public TextEntryReaderFeeder(final Feed feed, final EntryReader<TextEntry> entryReader) {
    this.feed = feed;
    this.entryReader = entryReader;
  }

  /**
   * @see io.vlingo.xoom.lattice.exchange.feed.Feeder#feedItemTo(io.vlingo.lattice.exchange.feed.FeedItemId, io.vlingo.lattice.exchange.feed.FeedConsumer)
   */
  @Override
  public void feedItemTo(final FeedItemId feedItemId, final FeedConsumer feedInterest) {
    final long feedId = feedItemId.toLong();
    final long id = (feedId - 1L) * feed.messagesPerFeedItem() + 1;

    entryReader
      .readNext(String.valueOf(id), feed.messagesPerFeedItem())
      .andThen(entries -> {
        feedInterest.consumeFeedItem(toFeedItem(feedItemId, entries));
        return entries;
      });
  }

  /**
   * Answer a new {@code FeedItem} from converted {@code entries}.
   * @param feedItemId the FeedItemId of the current item
   * @param entries the List<TextEntry> to convert
   * @return FeedItem
   */
  private FeedItem toFeedItem(final FeedItemId feedItemId, final List<TextEntry> entries) {
    final List<FeedMessage> messages = new ArrayList<>(entries.size());
    for (final TextEntry entry : entries) {
      final FeedMessageBody body = FeedMessageBody.with(entry.entryData());
      final FeedMessage message = FeedMessage.with(entry.id(), body, entry.typeName(), entry.typeVersion());
      messages.add(message);
    }

    if (feed.messagesPerFeedItem() == entries.size()) {
      return FeedItem.archivedFeedItemWith(feedItemId, feedItemId.next(), feedItemId.previous(), messages);
    } else {
      return FeedItem.currentFeedWith(feedItemId, feedItemId.previous(), messages);
    }
  }
}
```

It should be clear how you can stitch together a number of feeds to provide HTTP feeds of event streams: `Response <- http-Feed <- lattice-Feed <- symbio-EntryReader`

### Request and Response Filters

You can register filters with the `Server` for both requests and responses. The following is an example of how to start the Server with any number and type of filters:

```java
Filters filters =
    Filters.are(
        Arrays.asList(new DateRequestFilter()),
        Arrays.asList(new DateResponseFilter()));

Server server =
    Server.startWith(
        world.stage(),
        resources,
        filters,
        PORT,
        Sizing.define(),
        Timing.define());
```

The following is an example of a `RequestFilter` that is used to ensure that every request has a `Date` header:

```java
public class DateHeaderFilter extends RequestFilter {
  @Override
  public Tuple2<Request, Boolean> filter(final Request request) {
    if (request.headerValueOr(RequestHeader.Date, null) == null) {
      request.header(RequestHeader.Date, Instant.now().toString());
    }
    return Tuple2.from(request, true);
  }
}
```

The return type of `Tuple2<Request, Boolean>` provides both the `Request` results of the filter and a `Boolean` to indicate whether the filter chain should continue (`true`) or short circuit (`false`).

The following `ResponseFilter` does the same as the previous, but for responses:

```java
public class DateHeaderFilter extends ResponseFilter {
  @Override
  public Tuple2<Request, Boolean> filter(final Response response) {
    if (response.headerValueOr(ResponseHeader.Date, null) == null) {
      response.header(ResponseHeader.Date, Instant.now().toString());
    }
    return Tuple2.from(response, true);
  }
}
```

The return type is the same as for the `RequestFilter` and has the same meaning.

There is a special `ResponseFilter` that supports CORS request-response from cross-origin clients:

```java
final CORSResponseFilter filter = new CORSResponseFilter();

final List<ResponseHeader> headers =
        Arrays.asList(
                ResponseHeader.of(ResponseHeader.AccessControlAllowOrigin, "*"),
                ResponseHeader.of(ResponseHeader.AccessControlAllowHeaders, "Content-Type, Content-Length"),
                ResponseHeader.of(ResponseHeader.AccessControlAllowMethods, "POST,GET"));

filter.originHeadersFor(headerAcceptOriginAny, headers);

final Filters filters = Filters.are(Filters.noRequestFilters(), Arrays.asList(filter));

Server server =
    Server.startWith(
                world.stage(),
                resources,
                filters,
                PORT,
                Sizing.define(),
                Timing.define());
```

Register the kinds of access control headers that are supported by the receiving application. There must always be an `Access-Control-Allow-Origin` header, which is used to match that sent by the client agent. The matching string may be `"*"` for any origin or some well-know URI of a acceptable application. Other headers are as follows, and each has a corresponding constant in class `ResponseHeader`:

| Header                             | Constant in Class `ResponseHeader` |
| ---------------------------------- | ---------------------------------- |
| `Access-Control-Allow-Origin`      | `AccessControlAllowOrigin`         |
| `Access-Control-Allow-Credentials` | `AccessControlAllowCredentials`    |
| `Access-Control-Expose-Headers`    | `AccessControlExposeHeaders`       |
| `Access-Control-Max-Age`           | `AccessControlMaxAge`              |
| `Access-Control-Allow-Methods`     | `AccessControlAllowMethods`        |
| `Access-Control-Allow-Headers`     | `AccessControlAllowHeaders`        |

## Reactive Client

As noted earlier, XOOM HTTP provides a special `Client` used for making HTTP requests and reacting to responses as they happen. Being reactive, this `Client` is a non-blocking tool. The above example showed how to use a reactive pipeline to both request and reactive to the eventual response. Here is a similar example that could be used for `GET` requests and responses:

```java
import io.vlingo.xoom.http.resource.Client;
...
  Catalog catalog = Catalog.of(CatalogType.SummerOffers);
  Client client = Client.using(configuration, clientConsumerType, poolSize);

  client
    .requestWith(
        Request
          .method(Method.GET)
          .uri("/offers/summer-4528")
          .and(RequestHeader.host("chocolaterocks.io"))
          .and(RequestHeader.accept("application/json")))
    .andThenConsume(response -> {
        switch (response.status) {
        case Ok:
          catalog.offer(offerFrom(response));
          break;
        default:
          logger().error("Unexpected: " + response.status);
          break;
        }
      })
      .close();
    ...
```

Assume that the `catalog` object is backed by an actor. In this example the `close()` occurs just after the `offer()` message is sent to the `catalog`. The `Client` could have remained open if it was configured for keep-alive mode, and if it had used `repeat()` as the final pipeline expression (demonstrated [previously](#server-sent-events-sse)).

The `Client` provides a factory with the means to configure the resulting `Client` object along with one of three client types by means of the `ClientConsumerType`.

The `Configuration` has a number of factories that arrange for defaults to be set, and one that accepts all possible configuration parameters:

| Factory                                                                                                                                                                                                                                                                                                                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p><code>defaultedExceptFor(</code><br>  <code>Stage,</code><br>  <code>ResponseConsumer)</code></p>                                                                                                                                                                                                                                      | <p>The <code>Stage</code> is used to access standard platform resources, such as the <code>Scheduler</code>. The <code>ResponseConsumer</code> provides the the actor-backed protocol for the "consumer of unknown responses."<br><br>The remaining attributes will use defaults, which means keep-alive is <code>false</code>.<br><br>The remaining attributes will use defaults, which means keep-alive is <code>false</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| <p><code>defaultedExceptFor(</code></p><p>  <code>Stage</code></p><p>  <code>Address,</code></p><p>  <code>ResponseConsumer)</code></p>                                                                                                                                                                                                   | <p>The same as above, but with the <code>Address</code> of the host server (host name and port).<br><br>The remaining attributes will use defaults, which means keep-alive is <code>false</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <p><code>defaultedExceptFor(</code></p><p>  <code>Stage</code></p><p>  <code>Address,</code></p><p>  <code>ResponseConsumer,</code></p><p>  <code>int writeBufferSize,</code></p><p>  <code>int readBufferSize)</code></p>                                                                                                                | <p>The same as above, but provides the size (length) of write and read <code>ByteBuffer</code> instances, respectively, created to be used by the channel. The default for both is 10,240 bytes.<br><br>The remaining attributes will use defaults, which means keep-alive is <code>false</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <p><code>defaultedKeepAliveExceptFor(</code></p><p>  <code>Stage</code></p><p>  <code>Address,</code></p><p>  <code>ResponseConsumer)</code></p>                                                                                                                                                                                          | <p>The same as above, but requests that the the connection channel be kept alive (keep-alive is <code>true</code>) until it is explicitly closed by the caller.<br><br>When keep-alive is used, it is possible and practical to reuse <code>Completes\<Response></code> that is the return value of <code>Client</code> <code>requestWith(...)</code>. To accomplish this, use the repeat() as the final expression of the completes pipeline.<br><br>The remaining attributes will use defaults.</p>                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <p><code>has(</code></p><p>  <code>Stage</code></p><p>  <code>Address,</code></p><p>  <code>ResponseConsumer,</code></p><p>  <code>boolean keepAlive,</code></p><p>  <code>long probeInterval,</code></p><p>  <code>int writeBufferSize,</code></p><p>  <code>int readBufferPoolSize,</code></p><p>  <code>int readBufferSize)</code></p> | <p>Creates the <code>Configuration</code> with all explicit parameters for full attribute setting. All of the parameters are explain above except for <code>probeInterval</code> and <code>readBufferPoolSize.</code> </p><p></p><p>The <code>probeInterval</code> is the frequency in milliseconds that the channel is read. We recommend that you use the default of <code>10</code>. You can experiment with different intervals, but if problems occur it is probably too frequent or too seldom.<br><br>The <code>readBufferPoolSize</code> is the number of read <code>ByteBuffer</code> instances allocated in a pool, with each used to read different channels asynchronously. The default is <code>10</code>. If the number of pooled buffers are exhausted, the pool will automatically grow to handle a greater number of simultaneous requests. Any extra temporary buffers are discarded as load diminishes.</p> |

The `ClientConsumerType` is an `enum` that enables the following dispatcher types:

| Type            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Correlating`   | <p>Used to create a <code>Client</code> that interacts with the HTTP server using the extended header <code>X-Correlation-ID</code>. Each request is sent with a unique identity (UUID) header value and the server is expected to include the same header and value in its response. The unique identity can be provided as a pre-set <code>X-Correlation-ID</code> header by the <code>using(...)</code> caller, or the header will be created by the internal requester.</p><p></p><p>When used, it is often advantageous that the <code>Client</code> be created with the <em>keep-alive</em> configuration. Keep-alive mode ensures that the underlying connection remains open and is thus reusable for many request-response pairs. Even so, a keep-alive <code>Client</code> is not required.</p><p></p><p>When the response is received and parsed, it is provided through the platform standard <code>Completes\<Response></code> object.</p> |
| `LoadBalancing` | <p>Used to create a <code>Client</code> that makes requests using a load-balanced dispatch across some number of channel actors.<br><br>The <code>Client.using()</code> parameter <code>poolSize</code> is used to create the number of round-robin dispatchers. The load-balancing is based on the dispatcher with the least number of requests currently in its mailbox.</p><p><br>When the response is received and parsed, it is provided through the platform standard <code>Completes\<Response></code> that is the return value when calling the <code>Client</code> <code>requestWith()</code>.</p>                                                                                                                                                                                                                                                                                                                                             |
| `RoundRobin`    | <p>Used to create a <code>Client</code> that makes requests using a round-robin dispatch across some number of channel actors.<br><br>The <code>Client.using()</code> parameter <code>poolSize</code> is used to create the number of round-robin dispatchers.<br><br>When the response is received and parsed, it is provided through the platform standard <code>Completes\<Response></code> that is the return value when calling the <code>Client</code> <code>requestWith()</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

Determine which kind of `Client` to create for various request-response situations.

## Defining Dynamic Resources

XOOM HTTP provides a fluent API to define HTTP endpoints and corresponding Java handler methods. These kinds of resources are different than those loaded from the file `vlingo-http.properties`. You had a brief introduction to the handler methods at the outset of this chapter. Here you will see them in more detail.

The following is the `ResourceBuilder` used to fluently create route mappings.

```java
ResourceBuilder.resource(final String name, final RequestHandler... requestHandlers) 
```

You give the `Resource` a name and a varargs list of `RequestHandler` definitions. This method returns a `Resource`. The `Server` needs a set of `Resource` instances to match and route HTTP requests to handlers that respond. Each of the RequestHandler instances are mapped by means of declaring HTTP methods, as next discussed.

### HTTP Methods

The fluent API supports the following HTTP methods.

* `ResourceBuilder.post(final String uri)`
* `ResourceBuilder.get(final String uri)`&#x20;
* `ResourceBuilder.put(final String uri)`
* `ResourceBuilder.patch(final String uri)`
* `ResourceBuilder.delete(final String uri)`
* `ResourceBuilder.head(final String uri)`
* `ResourceBuilder.options(final String uri)`
* `ResourceBuilder.trace(final String uri)`
* `ResourceBuilder.connect(final String uri)`

All of the above methods answer a new resource handler instance, whether or not it extends the base class `DynamicRequestHandler`. We recommend using static imports for the most fluent use of the API.

```java
import static io.vlingo.xoom.common.serialization.JsonSerialization.serialized;
import static io.vlingo.xoom.http.Response.Status.Created;
import static io.vlingo.xoom.http.Response.Status.NotFound;
import static io.vlingo.xoom.http.Response.Status.Ok;
import static io.vlingo.xoom.http.ResponseHeader.Location;
import static io.vlingo.xoom.http.ResponseHeader.headers;
import static io.vlingo.xoom.http.ResponseHeader.of;
import static io.vlingo.xoom.http.resource.ResourceBuilder.get;
import static io.vlingo.xoom.http.resource.ResourceBuilder.patch;
import static io.vlingo.xoom.http.resource.ResourceBuilder.post;
import static io.vlingo.xoom.http.resource.ResourceBuilder.resource;
```

The above shows other common static imports besides those needed for fluent resource wiring.

### Request Handler

The request handler enforces type safety on the handler function method definition through the declaration of expected parameters. There are several mapping options, so consider each.

#### Path Parameters

Map path parameters by identifying them in the URI as a `{variable}` and then indicate the type in the `path()` method to be used by your handler.

{% tabs %}
{% tab title="Java" %}

```java
get("/user/{userId}")
    .path(String.class)
    .handler((userId) -> /* */);
```

{% endtab %}

{% tab title="Kotlin" %}

{% endtab %}
{% endtabs %}

Here the `userId` will be mapped to a `String` because the method `path(String.class)` specifies that type. You can specify parameter mappings to any of the following types.

* `String`
* `Long`
* `Integer`
* `Float`
* `Double`
* `Boolean`
* `Short`
* `Character`

{% hint style="danger" %}
The `path()` method must be used before any other route mapping method, otherwise an exception will be thrown when the `Server` starts.
{% endhint %}

{% hint style="warning" %}
When using `path()` be sure you have the same path variable in the URI between brackets `{<variable>}`  as the `path()` methods reference.
{% endhint %}

#### Body Parameter

The `body()` method maps the HTTP body into the type you specify.

{% tabs %}
{% tab title="Java" %}

```java
post("/user")
    .body(NameData.class)
    .handler((nameData) -> /* */);
```

{% endtab %}

{% tab title="Kotlin" %}

```java
```

{% endtab %}
{% endtabs %}

#### Query Parameters

You may use query parameters in the expected way. For example, page=5 is a query parameter in this curl command.

```bash
> curl http://localhost:8080/user?page=5
```

You may map this specific query parameter fluently in three different ways.

{% tabs %}
{% tab title="Java" %}

```java
get("/user")
    .query("page")
    .handler((page) -> /* */);

get("/user")
    .query("page", Integer.class)
    .handler((page) -> /* */);

get("/user")
    .query("page", Integer.class, 0 /* default value */)
    .handler((page) -> /* */);
```

{% endtab %}

{% tab title="Kotlin" %}

```java
get("/user")
    .query("page")
    .handler((page) -> /* */);
```

{% endtab %}
{% endtabs %}

By default, the type of all query parameters is `String`. When the query parameter isn't present, the value is `null`. It's good practice to always specify a default value for query parameters to avoid unexpected behavior.

#### Request Headers

You may access request headers as expected.

{% tabs %}
{% tab title="Java" %}

```java
get("/user")
    .header("Location")
    .handler((location) -> /* */);
```

{% endtab %}

{% tab title="Kotlin" %}

{% endtab %}
{% endtabs %}

#### Combining Them All

The following is an example showing all of the above parameter options.

{% tabs %}
{% tab title="Java" %}

```java
post("/user/{userId}")
    .param(String.class)
    .body(UserData.class)
    .header("Location")
    .handler((userId, userData, location) -> {
        // Perform some action
        return Completes.withSuccess(Response.of(Ok, serialized(userData)));
    });
```

{% endtab %}

{% tab title="Kotlin" %}

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The order of the parameters matters. Try changing the order of body and header. You will see that the type of the `userData` parameter becomes a header type and `location` now has the `UserData` type.
{% endhint %}

Check the [`xoom-http-frontservice`](https://github.com/vlingo/xoom-examples/tree/master/xoom-http-frontservice) for a more complete working example.

## Content Negotiation

To support media/content negotiation request handlers use the `ObjectResponse<?>` return type. The `?` is replaced with your actual representation data type, such as `PersonData` or `EmployeeData`, or whatever; the type that is represented to clients.

The `from(...)` method enables building an `ObjectResponse` with a response status, headers, and a concrete represented content type. This response is serialized according to the accept headers of the request via the `MediaTypeMapper`, or `JSON` if a given `MediaTypeMapper` is not supplied. If there is no match on the specific media type, the client receives the appropriate HTTP status code.

Once serialized by the supplied `MediaTypeMapper` , the final `Response` is generated and the appropriate `Content-Type` header is automatically inserted into the `Response`, along with any other headers provided by the handler method. The following is a basic example of how to create a handler that returns `MyType` as the `ObjectResponse` type.

```java
// GET /resources/mytype
ObjectResponse<MyType> provideMyType() {
  return ObjectResponse.from(Status.ok, new MyType("some value"));
}
```

The previous `Mapper` type has been deprecated, which affects places where the existing `Mapper` is being used as an input parameter to the `RequestHandler` methods. The older `Mapper` is undesirable because it ignores the accept header and may create confusion—the deprecation note speaks to that.

## Resource Handler Methods

There are a few things to keep in mind when designing a request handler method on a resource.

Resource methods must return one of two types. It may be `Completes<Response>` or `Completes<ObjectResponse>`. The use of the `Completes<?>` enables the server to operate asynchronously by postponing responses until all necessary processing has completed.

If there are a number of asynchronous steps required to carry out a request to the ultimate response, the steps should be managed through a `Completes` pipeline.

```java
public class UserResource {
  private final AddressFactory addressFactory;
  private final Stage stage;

  public UserResource(final World world) {
    this.addressFactory = world.addressFactory();
    this.stage = world.stage();
  }
  ...
  public Completes<Response> changeContact(final String userId, final ContactData contactData) {
    return stage.actorOf(User.class, addressFactory.from(userId))
      .andThenTo(user -> user.withContact(new Contact(contactData.emailAddress, contactData.telephoneNumber)))
      .andThenTo(userState -> Completes.withSuccess(Response.of(Ok, serialized(UserData.from(userState)))))
      .otherwise(noUser -> Response.of(NotFound, userLocation(userId)));
  }
  ...
  public Resource<?> routes() {
    return resource("User Resource",
      ...
      patch("/users/{userId}/contact")
        .param(String.class)
        .body(ContactData.class)
        .handle(this::changeContact),
      ...
      );
  }
}
```

Recall that `andThenTo()` is used to send an asynchronous message to an actor with an eventual outcome via `Completes`, and `otherwise()` handles an error outcome, while exceptions are handled by `recoverFrom()`. If you must simply map the outcome value to a new value and possibly a new type, you need only use `andThen()`. You can read more details about `Completes<T>` [here](/xoom-common#completes).

Due to the fact that any given handler instance will be reused many times, handler methods must be side-effect free. That is, they must not mutate the state of the handler instance. In the above example you can see that all `UserResource` state is final and the `changeContact()` method is side-effect free. Handler methods are themselves pure functions, but do not require components that they use to be pure functions. In other words, the `User` domain object actor may be mutable.

## Known Limitations

We know of a few limitations.

* Using the fluent API, we currently support up to six handler function arguments. If you need more than six, please open an issue [here](https://github.com/vlingo/vlingo-http/issues).
* ~~There is currently a~~ [~~problem~~](https://github.com/vlingo/vlingo-wire/issues/28) ~~with some Linux servers and the JDK implementation of non-blocking socket channel reads.~~ (Was fixed.)

Would you like to contribute to XOOM HTTP? See the [vlingo/xoom-http](https://github.com/vlingo/xoom-http) repository and review any outstanding issues. We are happy to help you with the simple on-boarding steps.


# Lattice

The VLINGO XOOM platform toolset providing compute grid, actor caching, object spaces, cross-node cluster messaging, publish-subscribe, CQRS, and Event Sourcing support.

## Feature Overview

The XOOM Lattice component provides tooling for reactive Domain-Driven Design projects that are highly concurrent. The tools of the component include compute grid, actor caching, spaces, cross-node cluster messaging, publish-subscribe, CQRS, and Event Sourcing support.

| Feature                                                                       | Description                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [CQRS](/xoom-lattice/cqrs)                                                    | Understanding the Command-Query Responsibility Segregation pattern.                                                                                                                                                                                                                                                                     |
| [Object, Stateful, and Sourced Entities with CQRS](/xoom-lattice/entity-cqrs) | <p>Supports three styles of persistence, including Object, Stateful, and Sourced.</p><p></p><p>Command-Query Responsibility Segregation uses two models per Bounded Context (application or service), the Command Model and the Query Model, otherwise known as the Read Model and the Write Model, respectively.</p>                   |
| [Grid](/xoom-lattice/grid)                                                    | Provides an API for distributed computations and data processing across multiple nodes in a cluster. Supports distributed parallel processing by sending computational execution requests to actors on any node in a cluster with the potential to receive results in return.                                                           |
| [Exchange](/xoom-lattice/exchange)                                            | Provides an abstraction over Publish-Subscribe messaging exchanges or topics. This is a means to publish messages to exchanges/topics inside or outside your current application/service, and to subscribe to such messages. Provides translators from internal to external message types, and from external to internal message types. |
| [Processes](/xoom-lattice/processes)                                          | Long-running processes that manage complex, coarse-grained, business transactions, must be managed through every step until completion. These tools assist in managing such processes whether by means of object persistence, stateful command models, or sourced with commands.                                                        |
| [Projections](https://docs.vlingo.io/vlingo-lattice/projections)              | How to project state, Domain Events, and other Source types into a CQRS Query Model.                                                                                                                                                                                                                                                    |
| [Routers](/xoom-lattice/routers)                                              | Use message-driven command routing to handlers that are responsible for modifying the domain model, which may be segregated as a Command Model.                                                                                                                                                                                         |

## Types

The following types are defined in the XOOM Lattice component and commonly used with domain-driven designed services.

| Type                    | Descriptio                                                                                                                                                                               |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DomainEvent`           | A abstract type used to model a record of fact about an important business occurrence in the domain model                                                                                |
| `IdentifiedDomainEvent` | A abstract type used to model a record of fact about an important business occurrence in the domain model and that has an identity associated with it, which can be used for correlation |
| `EventSourced`          | An abstract type used to create an Event Sourced entity that is backed by a persistent Journal                                                                                           |
| `Command`               | An abstract type used to model a record of an imperative directive to carry out a business operation                                                                                     |
| `CommandSourced`        | An abstract type used to create an Command Sourced entity                                                                                                                                |
| `ObjectEntity`          | An abstract type used to model an entity that is backed by object-relational persistence                                                                                                 |
| `StatefulEntity`        | An abstract type used to model an entity that is backed by Key-Value persistence                                                                                                         |
| `Process`               | An interface implemented by a component that orchestrates the steps necessary to complete a composite task                                                                               |
| `Projection`            | An interface implemented by a component that serves to project Command Model state onto the Query Model                                                                                  |
| `Projectable`           | An interface used to abstract the Command Model data projected onto the Query Model                                                                                                      |
| `Exchange`              | An abstraction over Publish-Subscribe messaging exchanges and topics                                                                                                                     |
| `CommandRouter`         | A means of asynchronous message-driven command routing to handlers that are responsible for modifying the domain model                                                                   |

These types are discussed in detail throughout the subsections of this chapter.


# CQRS

Understanding Command-Query Responsibility Segregation

Software developers commonly face a design challenge because of the way users view data.  The data of effective user interface views tends to be in quantities, shapes, and sizes that are different from the way users modify data. Using a traditional domain model that provides both mutation and query operations together results in the following problems, because the data users view cannot be retrieved as optimally as is generally possible for mutation.

![](/files/-MLv5B0PVyH7a0Zzr49M)

The system state that the user wants to view tends to be rich and cuts across at least several logical entity/aggregate types. The state that the user wants to mutate tends to be concentrated on one one aggregates or a few entities. The strengths of CQRS are in enabling developers to design for state mutation separately from state queries. The state mutation operations are optimized for creates and updates. The operations and data used for querying are optimized for how the user tends to view the system state. Both of these sets of operations and states can be designed and scaled separately. In brief, the stated software design challenges can be addressed and related problems overcome with the use of CQRS.

## CQRS and Architecture

One of the primary misunderstandings even among those who claim to know CQRS well, is thinking that CQRS is a system-level or top-level architecture, as in an architectural style. It’s possible that some think this simply because they don’t understand what constitutes a top-level architecture, or architectural style. An architectural style describes the pattern that is followed by an entire application or service, and not just some small portion of the the overall application or service. For example, there are Layers architecture and Ports and Adapters architecture.

Ports and Adapters is an architecture that has an impact on the way an application or service as a whole works. When the Ports and Adapters architecture is used, everything within the application or service reflects some well-defined part of the definition of Ports and Adapters. Although Ports and Adapters highlights the adapters for incoming stimulus, the architecture also defines the inside with the application interfaces. Additionally, the application inside may be further divided into application services and a domain model.

![](/files/-MLv7j95ouWwQekQcAWz)

CQRS is not intended to be and architectural style since it doesn’t by definition have an impact on the overall application or service. Instead, CQRS is an architecture pattern; one that has some substantial influence on the inner workings of the application or service, but not every part of it. With that in mind, consider what CQRS actually means.

## Meaning

The CQRS architecture pattern is based on the CQS software principle defined by Bertrand Meyer, creator of the Eiffel programming language. To understand CQRS it helps to first understand CQS. It’s fitting then to provide a few definitions.

CQS, or Command-Query Separation states that a software interface abstraction is designed with two types of methods. One method type is known as a Command method, and the other method type is known as a Query method. A Command method modifies or mutates the state underneath the interface, but does not answer any portion of that state. A Query method answers the current state beneath the interface, but must not modify that state before answering it. In particular note that CQS mandates the definition of the methods of a single interface abstraction. In the literature CQS is not considered a pattern, but a principle. I don’t want to split hairs over this, because you might argue that CQS is a design pattern, but it’s difficult to find official definitions to support that argument.

```java
package com.ecommrus.catalog.model;

public interface Product {
  void changeSku(final SKU sku);
  SKU querySku();
  void rename(final String name);
  String queryName();
  void summarize(final String summary);
  String querySummary();
  void describe(final String description);
  String queryDescription();
  ...
}
```

Although there is more detail to the `Product` interface, what is shown is enough to make the essential point about CQRS. This interface combines both commands and queries. The `changeSku()` and `rename()` are command methods, which are used to modify the `sku` and `name`, respectively. The `querySku()` and `queryName()` are used to read the current state of the Product `sku` and `name`, respectively.

This seems to be designed appropriately. The problem is that when the user needs to view the `Product` they also need to view the `Pricing`, `Availability`, `SimilarProducts`, `ProductReviews`, and possibly other information that is loosely associated with a given `Product`. Considering that there is a minimum of five objects that must be retrieved for that user view, it will certainly be quite difficult and inefficient to query each piece of data separately.

With motivations to optimize for the above use case, we decide to design our Command Model and our Query Model separately. Thus, the `Product` in the Command Model is refactored as follows, with command operations only.

CQRS, or **Command-Query Responsibility Segregation**, is similar to CQS because it focuses on separating Command methods and Query methods, but it does so to an even greater degree. This is a good time to highlight the terms responsibility and segregation. The term responsibility conveys the idea that Commands are not only a type of method, but a type of software responsibility. The same goes for Queries. The term segregation emphasizes that the two responsibilities, Commands and Queries, are segregated from each other using separate interfaces. Thus, where there is one `Product` interface in the above example, there are now two interfaces.

To optimize for the above use case, we decide to design the Command Model and the Query Model separately. Thus, the `Product` in the Command Model is refactored as follows, with command operations only.

```java
package com.ecommrus.catalog.command;

public interface Product {
  void changeSku(final SKU sku);
  void rename(final String name);
  void summarize(final String summary);
  void describe(final String description);
  ...
}
```

The Query Model is even in a separate module/package.

```java
package com.ecommrus.catalog.query;

public class ProductQueries {
  Collection<ProductData> queryAll();
  ProductData queryProductOf(final SKU sku);
}

public class ProductData {
  public final String sku;
  public final String name;
  public final String summary;
  public final String description;
  ...
  public final AvailabilityData availability;
  public final PricingData pricing;
  public final ProductReviewsData productReviews;
  public final SimilarProductsData similarProducts;
}
```

It seems important to note that the above segregated interfaces emphasize why CQRS is not an architectural style, but an architecture pattern. Since `Product` is likely not the only business concept in the application or service, there could be several other business model concepts defined. These are concepts that are more closely associated with the interior of the application or service, generally know as the domain model.

It's not an oversimplification to say that CQRS is just that simple.

## Command Model and Query Model

Considering a traditional domain model, there is just one model that defines the application’s or service’s state. Defining our business concepts using the CQS principle, there is still just one root object constituting a `Product`.

When using CQRS it is typical to use not one, but two, models, those being a Command Model and a Query Model. This is part of the segregation, but in addition to the interfaces there are the software models of the segregated states. There are the segregated states used by the Commands, and segregated states used by the Queries. This is at least a logically segregation because there is nothing to prevent the implementation from persisting the Command states and Query states together. Still, it is easier to reason about two state models rather than one.

When methods on the `Product` interface are executed, the Command Model state is mutated. When methods on the `ProductQueries` interface are executed, the Query Model state is queried. That makes sense, except for how the Query Model state comes about. That is illustrated by the following diagram.

![](/files/-MLvCn8FR3OXjMbWLboq)

The [Query Model is built up by projecting on to it](/xoom-lattice/projections) the changes made to the Command Model. As the user submits Command operations, the outcome of the Command Model mutations are used by software components to projection appropriate updates onto the Query Model. The user views the system state by way of the use-case-optimized Query Model.

In the above diagram, the Command Model mutations are captured by Domain Events, which are also used to project updates onto the Query Model. It is not necessary to use Domain Events for this. The entire state of a Command Model object that is mutated may be projected instead. If this approach is used, it’s helpful to indicate to the projection components what the actual Command operation was that caused the state to mutate. This enables the projection components to have both a rich set of data to project, but with full knowledge of the actual state that changed.


# Object, Stateful, and Sourced Entities With CQRS

Understanding reactive Object, Stateful, Sourced, and CQRS actor-based persistence.

[*Command-Query Responsibility Segregation*](/xoom-lattice/cqrs) uses two models per Bounded Context (application or service). These are the *Command Model* and the *Query Model,* otherwise known as the *Read Model* and the *Write Model,* respectively.

{% hint style="info" %}
The *Command Model* is often referred to as the "Write Model" and the *Query Model* as the "Read Model." These AKAs are quite inaccurate because you actually read from and write to both models. We prefer the names *Command Model* and *Query Model* because these names adhere to the pattern name, CQRS, and express the purpose of each of the two models.
{% endhint %}

The XOOM Lattice tools support three styles of persistence, including object, flat state, and sourced. The object style of persistence is more commonly known as Object-Relational Mapping (ORM), although a very low-impact mapping approach is also provided. The flat state style uses a Key-Value persistence, which is often suitable for both the CQRS Command Model and Query Model. The sourced style provides the persistence of a series of facts, known as Domain Events, that when applied or folded into a single object, combine to form a state. This is know as Event Sourcing, but may also be used with Commands to support Command Sourcing, and even other sources such as [process messages](/xoom-lattice/processes).

## Understanding Entity Actor Lifecycles

Let's start out by contrasting the lifecycles of Plain Old Java Objects (POJOs) with Actor-based entities.

In a typical object-based application or service that uses POJOs, the lifecycle of entities is different from that of actor-based entities. Here we can assume that Entity and Aggregate as defined within Domain-Driven Design are interchangeable; that is, what follows deals with both concepts.

### POJO Lifecycles

The following describes the typical lifecycle of a POJO Entity:

* Non-existing Entity states are newly constructed and then persisted to storage
* Preexisting Entity states are reconstituted from storage, modified, and then persisted back to the same storage (updated).
* Across a single JVM or a multi-JVM cluster, there may be any number of duplicated Entity instances. This implies that any of the duplicate instances may simultaneously have different operations performed by different users. In such cases the database must provide optimistic concurrency and detect concurrency violations via state versions.
* The object reference is released after Entity persistence and the instance garbage collected.

### Actor-Entity Lifecycles

The following describes the typical lifecycle of an actor-based Entity.

![Lattice model entity types and respective storage interfaces.](/files/-M9C7jMJgrTgeL4iE6A-)

Note that this applies across various types of Entities supported by XOOM Lattice, including `Sourced<T>`, `StatefulEntity<T>`, and `ObjectEntity<T>`:

* Non-existing states are newly persisted, and the guaranteed persistent state is then set back onto the actor state.
* Preexisting states are possibly already in memory; if not in memory, states are reconstituted from storage; proposed changes are then persisted back to the same storage; following persistence, the state is then set back onto the actor state.
* Across a single JVM or a multi-JVM cluster, there is one uniquely identified Entity instance, and all requests for creation/modification will be focused on that single instance, wherever it may be.
* The actor is retained in memory until memory constraints call for some actors to be evicted. A least-recently-used algorithm determines which specific actor instances must be evicted, and those actors are stopped. The evictions make room for other currently "hot" actors.

### Commands, Domain Events, and Identified Domain Events

Lattice defines abstract base types: `Command`, `DomainEvent`, `IdentifiedDomainEvent`. These provide for modeling specific types as follows:

| Type                    | Description                                                                                                                                                                              |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Command`               | An abstract type used to model the imperative intent directive to carry out a business operation. Alternatively a command can be a method declaration rather than an object/record       |
| `DomainEvent`           | A abstract type used to model a record of fact about an important business occurrence in the domain model                                                                                |
| `IdentifiedDomainEvent` | A abstract type used to model a record of fact about an important business occurrence in the domain model and that has an identity associated with it, which can be used for correlation |

These types, and especially `DomainEvent` and `IdentifiedDomainEvent` will be extended in order to create concrete types used in each domain model. In the examples that follow two domain events are used, `CartCreated` and `ProductPlacedInCart`. These could be modeled as either `DomainEvent`, or `IdentifiedDomainEvent` if there is a need to correlate multiple domain events to a kind of long-running process, also known as a Saga.

### Entity Construction Details

Regarding the creation of the various Entity types, including `Sourced`,`EventSourced`, and `CommandSourced`, there are design decisions that determine some minor constraints.

In the following discussions we refer to `apply()` methods. These are provided by the aforementioned Entity abstract types: `StatefulEntity`, `ObjectEntity`, `Sourced`,`EventSourced`, `CommandSourced`, etc. These methods are responsible for managing the atomic persistence of Entity state and `Source<T>` instances, such as concrete extensions of `DomainEvent`. These are also responsible for setting the guaranteed persistent state back onto the Entity. These `apply()` methods are explained in more detail below, but you must be aware of their existence here.

Generally speaking, it is very difficult to support the use of `apply()` methods from inside Entity constructors. Thus, we do not currently support using an `apply()` method from a Entity constructor. Next it is explained why this is the case. A `Product` protocol is used as the concrete Entity type and `EventSourced` as the abstract base Entity, although it could be any of the abstract base types.

1. All Entity abstract base types provide constructors that take either zero parameters or one parameter, that being the Entity unique identity.
2. If the zero-argument constructor is used, the actor's address is used as the unique identity. This works out especially well for [Grid-based actors](/xoom-lattice/grid) because the address is based on a universally unique identity (our recommended approach).
3. The `Product` constructor may take one or more parameters used for identity, but the abstract base constructor accepts only zero or a single parameter, but only one identity may be passed to the base constructor. When supplying the constructor with multiple identity parts, these can be turned into a single composite identity using the `streamNameFrom(...)` of `Sourced<T>` (e.g. `EventSourced`, `CommandSourced`, and `Process`) and the `idFrom(...)` for `StatefulEntity` and `ObjectEntity`.
4. &#x20;After the Entity constructor has completed, the actor will receive it's first message, known as `start()`. It is when handling this `start()` message that the abstract base Entity attempts to restore its state from persistence. If persistent state is not available, the Entity has its initial default state. If persistent state is available, the Entity is initialized with it. For `Sourced<T>` entities the initial state will be applied using one or more sources, such as `DomainEvent` types, in its stream. This emphasizes that if the concrete Entity type overrides the `start()` message, it must ensure that the base `start()` is always handled with `super.start()`. Also the concrete Entity type must assume that the initial state in not available until after the base `start()` handler is run. In fact, the concrete Entity type will never see a recovered initial state because the base `start()` handles recovery using asynchronous messaging to and from the storage actor.

Consider also that any constructor is not a good expression of behavior for the Ubiquitous Language. Even when designing with POJOs it's generally desirable to hide the constructor behind an expressive Factory Method, such as:

```java
Product product = Product.receiveInto(warehouse);
```

Look at the `vlingo-iddd-collaboration` example to [see examples](https://github.com/vlingo/vlingo-examples/blob/8fbc432545555641efab01d790183c6580a985c9/vlingo-iddd-collaboration/src/main/java/com/saasovation/collaboration/model/forum/Forum.java#L24) of how this may be accomplish in the `Forum` protocol Factory Method. Additionally, `ForumEntity` starts a new `Discussion` in its  `discussFor()` [message handler](https://github.com/vlingo/vlingo-examples/blob/8fbc432545555641efab01d790183c6580a985c9/vlingo-iddd-collaboration/src/main/java/com/saasovation/collaboration/model/forum/ForumEntity.java#L57). Likewise, the `DiscussionEntity` creates a new `Post` in its `postFor()` [message handler](https://github.com/vlingo/vlingo-examples/blob/8fbc432545555641efab01d790183c6580a985c9/vlingo-iddd-collaboration/src/main/java/com/saasovation/collaboration/model/forum/DiscussionEntity.java#L39).

## Entity Storage Mechanisms

The following explains the storage options available for each Entity type: `ObjectEntity`, `StatefulEntity`, as well as `EventSourced` and `CommandSourced`.

{% hint style="info" %}
Note that when an Entity's applied state and/or events are persisted, [actor message stowage](/xoom-actors#stowage) is used for non-blocking operational pauses until the persistence success or failure is confirmed.
{% endhint %}

### Object-Relational Mapping

An `ObjectEntity` concrete extension is stored using Object-Relational Mapping (ORM). There is already much literature available on ORM so we won't spend much time explaining it here. The basic idea is that a software object may be mapped into the row of a relational database table. Each of the object's attributes are mapped to a column in that row. There are, of course, more elaborate mapping relationships that can be employed, such as for one-to-many, many-to-one, and many-to-many object compositions. Yet, the mappings still come down to tables, rows, and columns holding object state.

The [XOOM Symbio](/xoom-symbio) components provide various JDBC implementations for ORM using the `ObjectStore`, including Java Persistence Architecture (JPA). The JPA options include EclipseLink, OpenJPA, and Hibernate. Another JDBC implementation of XOOM Symbio supports Jdbi, which is a very lightweight toolkit for mapping objects. As long as your entity designs are small, using Jdbi may be all you need and will be a welcome alternative to JPA and other traditional ORM tools.

The following table shows the databases current supporting ORM.

| Database           | Use        |
| ------------------ | ---------- |
| Apache Geode       | Production |
| HSQLDB (in-memory) | Testing    |
| In-Memory          | Testing    |
| MariaDB            | Production |
| MySQL              | Production |
| PostgreSQL         | Production |
| YugaByte           | Production |

Below you will see [how to use Object-Relational Mapping in your entities](/xoom-lattice/entity-cqrs#objectentity-example).

### Stateful

A `StatefulEntity` concrete extension is stored using a key-value database. The [XOOM Symbio](/xoom-symbio#what-is-symbio) components provide simple key-value persistence that works over several different database products. The storage type is know as the `StateStore`. In addition to all supported relational (JDBC) databases, there is also support for Amazon DynamoDB and Apache Geode.

| Database           | Use        |
| ------------------ | ---------- |
| DynamoDB           | Production |
| Apache Geode       | Production |
| HSQLDB (in-memory) | Testing    |
| In-Memory          | Testing    |
| MariaDB            | Production |
| MySQL              | Production |
| PostgreSQL         | Production |
| YugaByte           | Production |

Below you will see [how to use stateful entities](/xoom-lattice/entity-cqrs#statefulentity-example).

### Sourced

The states of `EventSourced` and `CommandSourced` entities are not stored as whole objects. Instead, every such entity maintains a stream of records, each representing a partial state. The individual records of partial state are stored in a `Journal`, and collectively combine to create its state. The word "source" conveys the idea of an official origin, which in this case is a record of partial state. The record may be a fact, such as is captured by a `DomainEvent`. The record may instead be an imperative directive to carry out an operations, known as a `Command`. Persisting one or more `DomainEvent` instances to represent an aggregate's state is known as Event Sourcing. A similar approach in save the `Command` states, such as is generally the case with a [Process](/xoom-lattice/processes) (Manager), is known as Command Sourcing.

![](/files/-MLvKxLKjkqRIVFjyoDx)

A sourced entity is one that owns an ordered collection of records that each indicate a discreet change that was made to the state of that entity. This ordered collection may be likened to an accounting ledger, with one row per change to an account. The changes in a ledger are either debits or credits to the account. Starting from a balance of zero, a credit must be added to the ledger to provide the first available funds. From there the next entry may be another credit, or a debit. Over time there are a number of entries which can be used to derive the account's balance. Starting from the first entry in the ledger, add credits and subtract debits in the order in which they occurred. After applying the addition or subtraction of the last entry in the ledger you know the account's balance.

Now consider that you have a similar ledger, but made up of a sequence of `DomainEvent` instances. Starting with the first `DomainEvent` apply its attributes to the state of the entity that owns the `DomainEvent`. Do the same for every subsequent `DomainEvent` until there are no more. At the end you know the current state of the entity.

The sequence in which the discreet records were produced is strictly maintained because both the records and the order in which they occurred are required to reproduce the accurate and valid state of the entity.

Continuing with the above e-commerce example, the following may be the ordered collection of events for a shopping cart.

| Index | Event Type                                         |
| ----- | -------------------------------------------------- |
| 1     | `com.ecommrus.model.cart.CartCreated`              |
| 2     | `com.ecommrus.model.cart.ProductPlacedInCart`      |
| 3     | `com.ecommrus.model.cart.ProductQuantityIncreased` |
| 4     | `com.ecommrus.model.cart.ProductPlacedInCart`      |
| 5     | `com.ecommrus.model.cart.ProductRemovedFromCart`   |

The *Index* column indicates the order in which the event occurred on the given `Cart` entity. The *Event Type* column contains the name of the `DomainEvent` that occurred in the given order. Note that this table does not show the event data along side the type; the actual `Journal` would include the data. Here's what the events indicate.

1. The shopping cart was created on behalf of a user.
2. The user placed a given product into the cart.
3. The user increased the quantity that they require for the product from #2.
4. The user placed an additional product into the cart.
5. The user removed one of their two products from the cart. To know which of the two products was removed, the data of the event must be examined for the product id.

As noted previously the sequence of records may be specializations of `DomainEvent` and `Command`, but are more commonly of type `DomainEvent`. Thus, an entity that is sourced by a sequence of `DomainEvent` instances is Event Sourced. Assuming that the sequence of entries in the collection are DomainEvent types, this collection is known as the entity's *event stream.*

Each entity's event stream is persisted into a `Journal`. This `Journal` is responsible for maintaining two kinds of streams. One kind of stream is the individual stream of each entity. If you have 1 million Event Sourced entity instances in your Bounded Context then the `Journal` will have 1 million individual streams. The second kind of stream is the totally ordered entries of all entities in the entire Bounded Context. That is, as each entity appends new entries into its own stream, those entries are also indexed in a totally ordered stream of all entries. Thus, if each entity has an average of five entries in its individual stream, the totally ordered stream of all entries is 5 million total.

The `Journal` is append only. Once an entry has been appended it may not be (physically) deleted/removed. Further, every discreet entry is immutable.

The following table shows the databases current supporting `Journal`.

| Database           | Use          |
| ------------------ | ------------ |
| FoundationDB       | Experimental |
| HSQLDB (in-memory) | Testing      |
| In-Memory          | Testing      |
| MariaDB            | Production   |
| MySQL              | Production   |
| PostgreSQL         | Production   |
| YugaByte           | Experimental |

Below you will see [how to use event sourced and command sourced entities](/xoom-lattice/entity-cqrs#eventsourced).

## Entity Types

`ObjectEntity`, `StatefulEntity`, and `EventSourced` are abstract base classes used in developing DDD models. The `ObjectEntity` supports various forms of relational database mapping, including ORM as in JPA and Hibernate, and Jdbi (a very thin wrapper around JDBC that maps with less pain). You can read more about those [above](/xoom-lattice/entity-cqrs#object-relational-mapping) and [here](/xoom-symbio/object-storage). The `StatefulEntity` doesn't provide mapping, only a key-value store with the aggregate state as a CLOB/BLOB value. This enables using many different kinds of NoSql storage. The `EventSourced` supports Event Sourcing. Consider this simple usage example.

{% hint style="info" %}
Note that when an Entity's applied state and/or events are persisted, [actor message stowage](/xoom-actors#stowage) is used for non-blocking operational pauses until the persistence success or failure is confirmed.
{% endhint %}

### `ObjectEntity` Example

An actor that serves as a domain model entity may be designed extending the `ObjectEntity` type. The `ObjectEntity` should implement a protocol that defines the behavior available through message sending and delivery. Its state is stored in an `ObjectStore`.

![CartEntity is an ObjectEntity extender, which means its state is OR mapped.](/files/-M9C96ivE0uK1Yadab0R)

Here is a `CartEntity` that extends `ObjectEntity` and implements the `Cart` protocol.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends ObjectEntity implements Cart {
  private CartState cartState;
  ...
  
  public CartEntity(String cartId, String userId) {
    super(idFrom(":", cartId, userId));
    
    this.cartState = CartState.initial(cartId, userId);
  }
}
```

An `ObjectEntity` should receive its unique identity by means of its constructor, making the identity available during its initialization. If the entity is preexisting, the identity is used during actor startup to reconstitute its state from the `ObjectStore`.

The following shows how a command message is handled and the state and event is persisted using a `ObjectStore` via the `ObjectEntity`.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends ObjectEntity implements Cart {
  private CartState cartState;
  ...
  
  public void placeProductInCart(Product product) {
    val productPlacedInCart =
      ProductPlacedInCart.with(product.sku, product.description, product.price);

    apply(cartState.withSelected(product), productPlacedInCart);
  }
  
  ...
}
```

The `ObjectEntity` provides a means to `apply()` a new state and concrete `DomainEvent` instances. In the above example a new `CartState` instance and a `ProductPlacedInCart` are applied together. The `apply()` causes four processing steps.

1. The `CartEntity` message processing is temporarily suspended until the following step 2 and step 3 are completed.
2. The new `CartState` and the `ProductPlacedInCart` event are asynchronously and atomically persisted to the backing `ObjectStore`.
3. The persistence is confirmed. At that time the overridden `stateObject(CartState)` method is called to replace the current `cartState` with the new value. You can see this overridden method in the below code snippet displaying the overridden protected methods.
4. The `CartEntity` message processing is restored, allowing subsequent messages, such as commands, to be handled.

{% hint style="info" %}
The `ObjectEntity` concrete type may not process its next messages until the current state transition and any events are fully applied. The same entity's state must not transition until the new state's persistence is confirmed.

The above steps 1-4 are processed asynchronously; that is, the entity does not block a thread while these steps are carried out.
{% endhint %}

In the following case the command message handler is augmented to answer an eventually available, guaranteed stored state of the entity. The message handler method would need to change as follows.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends ObjectEntity implements Cart {
  private CartState cartState;
  ...
  
  public Completes<CartState> placeProductInCart(Product product) {
    val productPlacedInCart =
      ProductPlacedInCart.with(product.sku, product.description, product.price);

    return apply(
        cartState.withSelected(product),
        productPlacedInCart,
        () -> cartState);
  }
  
  ...
}
```

In the above example, notice that the protocol has been changed to support a `Completes<T>` return value, specifically `Completes<CartState>`. The `Completes<T>` protocol is [explained here](/xoom-common#completes). The `apply(...)` method now provides a return value, and it also takes a parameter to supply the final `cartState` value as the contents of the `Completes<CartState>`. The `apply()` causes five processing steps.

1. The `CartEntity` message processing is temporarily suspended until steps 2 and 3 are completed.
2. The new `CartState` and the `ProductPlacedInCart` event are asynchronously and atomically persisted to the backing `ObjectStore`.
3. When the persistence is confirmed, the overridden `stateObject(CartState)` method is called to replace the current `cartState` with the new value. You can see this overridden method in the below code snippet displaying the overridden protected methods.
4. The `CartEntity` message processing is restored, allowing subsequent messages, such as commands, to be handled.
5. The newly stored `cartState` instance that was replaced by the `stateObject()` method (next example) is used to complete the `Completes<CartState>` outcome value.

Every concrete `ObjectEntity` must override a few methods.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends ObjectEntity implements Cart {
  private CartState cartState;
  
  ...

  @Override
  protected CartState stateObject() {
    return cartState;
  }

  @Override
  protected void stateObject(final CartState stateObject) {
    this.cartState = stateObject;
  }

  @Override
  protected Class<CartState> stateObjectType() {
    return CartState.class;
  }
  
  @Override
  protected <C> Tuple2<CartState,List<Source<DomainEvent>>> whenNewState() {
    // answer a Tuple2 if the context is an intial state; otherwise null
    if (cartState.isInitial()) {
      return Tuple2.of(cartState, Arrays.asList(new CartCreated(...)));
    }
    return null;
  }
}
```

These methods support the `ObjectEntity` abstract base in interacting with the `ObjectStore` in behalf of the concrete `CartEntity`.&#x20;

* The `stateObject()` answers the `CartEntity` current `CartState` value.
* The `stateObject(CartState)` provides a new state to replace the previous state. This is called following the restoration of the `CartState` from persistence when the `CartEntity` is being (re)started from an existing state, and following the persistence of a new state and zero or more events.
* The `stateObjectType()` answers the Class\<T> of the specific entity, which in this case is `CartState.class`.
* The `whenNewState()` is an optional override if it is desired to provide an initial state to be persisted only when the Entity has been newly created. In this example, when the `cartState` is considered initial, the `whenNewState()` answers a `Tuple2` of a `CartState` and a `List<Source<DomainEvent>>`. If the `cartState` has already transitioned past its initial state, answer `null` and state restoration from the `ObjectStore` is attempted instead.

Read the [API documentation](https://javadoc.io/doc/io.vlingo/vlingo-lattice/latest/io/vlingo/lattice/model/object/ObjectEntity.html) for more details.

#### `ObjectTypeRegistry`

In order to introduce your concrete entity types to the underlying `ObjectStore` persistence mechanism that is used by the `ObjectEntity` abstract base, you must register each one with the `ObjectTypeRegistry`.

```java
import io.vlingo.xoom.lattice.model.object.ObjectTypeRegistry;
import io.vlingo.xoom.symbio.store.object.StateObjectMapper;

ObjectTypeRegistry registry = new ObjectTypeRegistry(world);

StateObjectMapper cartStateMapper =
        StateObjectMapper.with(
          CartState.class,
          JdbiPersistMapper.with(
            insertQuery,
            updateQuery,
            SqlStatement::bindFields),
          new CartStateMapper());

String cartQuery = "SELECT FROM TBL_CARTS ...";

Info<Cart> cartInfo =
        new Info(
          objectStore,
          CartState.class,
          "Cart-Database",
          MapQueryExpression.using(
            Cart.class,
            cartQuery,
            MapQueryExpression.map("cartId", "")),
          cartStateMapper);

registry.register(cartInfo);
```

The above code registers a mapper for the `Cart` and `CartState` using a Jdbi mapping.

1. The `ObjectTypeRegistry` is created within the `World` that is used by the service.
2. The `StateObjectMapper` is created for the `CartState`.
3. An `ObjectTypeRegistry.Info` instance is created, which holds the components necessary to persist and query a `CartState` via the `Cart` implementor `CartEntity`. The `Info` holds: (a) the `ObjectStore` that persists `CartState`,  (b) the type that is persisted, in this case`CartState.class`, (c) an identifying name given to the store, (d) a `QueryExpression`, in this case a `MapQueryExpression`, that uses the `cartQuery` that takes as a parameter `cartId`, and (e) the previously created `StateObjectMapper` for `CartState` instances.
4. The `ObjectTypeRegistry` is then used to register the `Info<Cart>`, enabling these to be supportable by the XOOM Lattice `ObjectEntity`.

You must register such an `ObjectTypeRegistry.Info` for every model type and state type, as was done above for `Cart` and `CartState`, respectively.

### `StatefulEntity` Example

An actor that serves as a domain model entity may be designed extending the `StatefulEntity` type. The `StatefulEntity` should implement a protocol that defines the behavior available through message sending and delivery.

![CartEntity is an StatefulEntity extender, meaning its state is stored as a key-value/document.](/files/-M9C9xUTeK-tcUPYCu-Y)

Here is a `CartEntity` that extends `StatefulEntity` and implements the `Cart` protocol.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends StatefulEntity implements Cart {
  private CartState cartState;
  ...
  
  public CartEntity(String cartId, String userId) {
    super(":", cartId, userId);
    
    this.cartState = CartState.initial(cartId, userId);
  }
}
```

A `StatefulEntity` should receive its unique identity by means of its constructor, making the identity available during its initialization. If the entity is preexisting, the identity is used during actor startup to reconstitute its state from the `StateStore`.

The following shows how a command is handled by a `StatefulEntity` to persist the new state and any events using the underlying `StateStore`. Notice that the interface for applying the state and event are identical to the `ObjectEntity` interface.

```java
import io.vlingo.xoom.lattice.model.stateful.StatefulEntity;

public class CartEntity extends StatefulEntity implements Cart {
  private CartState cartState;
  ...
  
  public void placeProductInCart(Product product) {
    val productPlacedInCart =
      ProductPlacedInCart.with(product.sku, product.description, product.price);

    apply(cartState.withSelected(product), productPlacedInCart);
  }
  
  ...
}
```

The `StatefulEntity` provides a means to `apply()` a new state and concrete `DomainEvent` instances. In the above example a new `CartState` instance and a `ProductPlacedInCart` are applied together. The `apply()` causes four processing steps.

1. The `CartEntity` message processing is temporarily suspended until steps 2 and 3 are completed.
2. The new `CartState` and the `ProductPlacedInCart` event are asynchronously and atomically persisted to the backing `StateStore`.
3. When the persistence is confirmed, the overridden `state(CartState)` method is called to replace the current `cartState` with the new value. You can see this overridden method in the following code snippet.
4. The `CartEntity` message processing is restored, allowing subsequent messages, such as commands, to be handled.

{% hint style="info" %}
The `StatefulEntity` concrete type may not process its next messages until the current state transition and any events are fully applied. The same entity's stated must not transition until the new state's persistence is confirmed.

The above steps 1-4 are processed asynchronously; that is, the entity does not block a thread while these steps are carried out.
{% endhint %}

In the following case the command message handler is augmented to answer an eventually available, guaranteed stored state of the entity. The message handler method would need to change as follows.

```java
import io.vlingo.xoom.lattice.model.stateful.StatefulEntity;

public class CartEntity extends StatefulEntity implements Cart {
  private CartState cartState;
  ...
  
  public Completes<CartState> placeProductInCart(Product product) {
    val productPlacedInCart =
      ProductPlacedInCart.with(product.sku, product.description, product.price);

    return apply(
        cartState.withSelected(product),
        productPlacedInCart,
        () -> cartState);
  }
  
  ...
}
```

In the above example, notice that the protocol has be changed to support a `Completes<T>` return value, specifically `Completes<CartState>`. The `Completes<T>` protocol is [explained here](/xoom-common#completes). The `apply(...)` method now provides a return value, and it also takes a parameter to supply the final `cartState` value as the contents of the `Completes<CartState>`. The `apply()` causes five processing steps.

1. The `CartEntity` message processing is temporarily suspended until steps 2 and 3 are completed.
2. The new `CartState` and the `ProductPlacedInCart` event are asynchronously and atomically persisted to the backing `ObjectStore`.
3. When the persistence is confirmed, the overridden `stateObject(CartState)` method is called to replace the current `cartState` with the new value. You can see this overridden method in the below code snippet displaying the overridden protected methods.
4. The `CartEntity` message processing is restored, allowing subsequent messages, such as commands, to be handled.
5. The newly stored `cartState` instance that was replaced by the `stateObject()` method (next example) is used to complete the `Completes<CartState>` outcome value.

Every concrete `StatefulEntity` must override a few methods.

```java
import io.vlingo.xoom.lattice.model.DomainEvent;
import io.vlingo.xoom.lattice.model.stateful.StatefulEntity;

public class CartEntity extends StatefulEntity implements Cart {
  private CartState cartState;
  ...
  
  @Override
  protected void state(final CartState state) {
    this.cartState = state;
  }

  @Override
  protected Class<CartState> stateType() {
    return CartState.class;
  }

  @Override
  protected <C> Tuple3<CartState,List<Source<DomainEvent>>> whenNewState() {
    // answer a Tuple2 if the context is an intial state; otherwise null
    if (cartState.isInitial()) {
      return Tuple3.of(cartState, Arrays.asList(new CartCreated(...)), "created");
    }
    return null;
  }
}
```

These methods support the `StatefulEntity` abstract base in interacting with the `StateStore` in behalf of the concrete `CartEntity`.

* The `id()` answers the `String` unique identity of the `CartEntity`.
* The `state(CartState)` provides a new state to replace the previous state. This is called following the restoration of the `CartState` from persistence when the `CartEntity` is being (re)started from an existing state, and following the persistence of a new state and zero or more events.
* The `stateType()` answers the concrete state type, such as the `Class<CartState>`.
* The `whenNewState()` is an optional override if it is desired to provide an initial state to be persisted, but only when the Entity has been newly created. The `whenNewState()` is called each time the `CartEntity` actor is started. On the initial start just following the first ever construction of the entity, this method offers the opportunity to provide the initial state to be applied. The offer may be ignored by not overriding this method, as the default answers `null`. If this method is called at any other time other than the first ever construction of the entity, it must answer `null`. In this example, when the `cartState` is considered initial, the `whenNewState()` answers a `Tuple3` of a `CartState`, a `List<Source<DomainEvent>>`, and the `"created"` operation which caused it. If the `cartState` has already transitioned past its initial state, answer `null` and state restoration from the `ObjectStore` is attempted instead.

Read the [API documentation](https://javadoc.io/doc/io.vlingo/vlingo-lattice/latest/io/vlingo/lattice/model/stateful/StatefulEntity.html) for more details.

#### `StatefulTypeRegistry`

In order to introduce your concrete entity types to the underlying `StateStore` persistence mechanism that is used by the `StatefulEntity` abstract base, you must register each one with the `StatefulTypeRegistry`.

```java
import io.vlingo.xoom.lattice.model.stateful.StatefulTypeRegistry;
import io.vlingo.xoom.symbio.store.state.dynamodb.DynamoDBStateActor;
import io.vlingo.xoom.symbio.store.state.StateStore;

StateStore store = world.actorFor(StateStore.class, DynamoDBStateActor.class, dispatcher);

registry = new StatefulTypeRegistry(world);

registry.register(new Info<>(store, CartState.class, CartState.class.getSimpleName()));
```

You must register such an `StateTypeRegistry.Info` for every state type, as was done above for `CartState`.

### `EventSourced` Example <a href="#eventsourced" id="eventsourced"></a>

An actor that serves as a domain model entity may be designed as an extension to the `EventSourced` type. The `EventSourced` should implement a protocol that defines the behavior available through message sending and delivery.

![CartEntity is an EventSource extender, meaning its events are stored as a stream in a journal.](/files/-M9CA_9cK_iaWgwsQaH9)

Here is a `CartEntity` that extends `EventSourced` and implements the `Cart` protocol.

```java
import io.vlingo.xoom.lattice.model.object.ObjectEntity;

public class CartEntity extends EventSourced implements Cart {
  private CartState cartState;
  ...
  
  public CartEntity(String cartId, String userId) {
    super(); // use the actor address as unique identity
    
    this.cartState = CartState.initial(cartId, userId);
  }
}
```

An `EventSourced` may receive its unique identity by means of its constructor, or it may provide no identity, in which case the actor's address will be used. Either way, this makes the identity available during the entity's initialization. If the entity is preexisting, the identity is used during actor startup to reconstitute its state from the `Journal`.

The following shows how a command is handled by an `EventSourced` to persist events using the underlying `Journal`. Notice that the interface for applying the event(s) is different from the `ObjectEntity` and `StatefulEntity`.

```java
import io.vlingo.xoom.lattice.model.sourcing.EventSourced;

public class CartEntity extends EventSourced implements Cart {
  private CartState cartState;
  ...
  
  public void placeProductInCart(Product product) {
    val productPlacedInCart =
      ProductPlacedInCart.with(product.sku, product.description, product.price);

    apply(productPlacedInCart);
  }
  
  ...
}
```

In the case of `EventSourced` the state is not automatically persisted because it is not generally needed. The events themselves represent the state of the cart, as [explained above](/xoom-lattice/entity-cqrs#sourced). You'll next see how the state is persisted if the conditions exist to justify that.

The unique identity of the entity is set in the base constructor in the `streamName` immutable variable.

```java
protected final String streamName;
```

In the case of `Sourced<T>` entities, such as `EventSourced`, the implementor will be asked if they would like to include a snapshot of the state at any given point of `apply()`.  The concrete `EventSourced`, in this case `CartEntity`, may do so using the following override.

```java
  @Override
  protected CartSate snapshot() {
    return cartState;
  }
```

Notice, however, that this example unconditionally provides the `CartState` instance as a snapshot in all cases. This is generally not desirable because it is probably not necessary. In fact snapshots are generally only useful when a given entity may have many, many events associated with it. In such cases it is best to use a heuristic metric to determine when a snapshot is necessary, where the metric is based on some point where the performance of entity reconstitution starts to degrade with many events.

For example, say that you have an entity that could have thousands of items in it. This might be a large order being populated with a many products from a warehouse. To solve the overhead of loading all events from the `Journal`, you may decide to take a snapshot at every 250th event.

```java
  @Override
  protected OrderState snapshot() {
    return currentVersion() % 250 == 0 state : null;
  }
```

The `currentVersion()` provides a 1-based version or sequence number of the next event to be appended to the `Journal`; that is, the first of potentially multiple events currently being applied. In the above example the snapshot of the `OrderState` will only be provided every 250th event. Otherwise `null` is answered to prevent a snapshot from being persisted along with the event(s).

{% hint style="info" %}
If any given command message handler produces multiple events, it is possible for the above calculation to be inexact.
{% endhint %}

If using snapshots, the following method must be overridden in order to apply the most recent snapshot to the entity's state when the entity is being reconstituted.

```java
  ...
  
  protected <OrderState> void restoreSnapshot(final OrderState snapshot, final int currentVersion) {
    this.state = snapshot;
  }
  
  ...
```

Another useful tool is `asList()`, which places multiple events into a `List<DomainEvent>` that may be passed to the respective `apply()` methods. For example, it's possible that a shopping cart is created by the user selecting the currently viewed product into a new cart.

```java
public void createCartWithFirstProduct(...) {
  apply(asList(new CartCreated(...), new ProductPlacedInCart(...)));
}
```

The `EventSourced` provides a means to `apply()` one or more concrete `DomainEvent` instances. In the above example a new `CartCreated` and `ProductPlacedInCart` are applied together. The `apply()` causes five processing steps.

1. The `CartEntity` message processing is temporarily suspended until steps 2 and 3 are completed.
2. The `snapshot()` is used to determine whether or not a snapshot instance should be persisted with the events. If not, the `snapshot()` will answer `null`. The default is to never provide snapshots.
3. The new `CartCreated` and `ProductPlacedInCart` events are asynchronously and atomically appended to the backing `Journal`.
4. When the persistence is confirmed, a registered event-specific method is called, once for each applied event, to transition the current `cartState` with based on the new event value. You can see examples in the below code snippet.
5. The `CartEntity` message processing is restored, allowing subsequent messages, such as commands, to be handled.

{% hint style="info" %}
The `EventSourced` concrete type may not process its next messages until the events are fully applied. The same entity's stated must not transition until the state's storage is confirmed.

The above steps 3 and 4 are processed asynchronously; that is, the entity does not block a thread while these steps are carried out.
{% endhint %}

Every concrete `EventSourced` must register an event-specific method transition from the current state to a new state for each newly applied event.

```java
import io.vlingo.xoom.lattice.model.sourcing.EventSourced;

public class CartEntity extends EventSourced implements Cart {
  private CartState cartState;
  ...

  static {
    registerConsumer(CartEntity.class, CartCreated.class, CartEntity::applyCartCreated);

    registerConsumer(CartEntity.class, ProductPlacedInCart.class, CartEntity::applyProductPlacedInCart);

    ...
  }

  private void applyCartCreated(CartCreated event) {
    cartState = CartState.initial(event.cartId, event.userId);
  }

  private void applyProductPlacedInCart(ProductPlacedInCart event) {
    Product product = new Product(event.productId, event.quantity, event.price);
    cartState = cartState.withProduct(product);
  }
  
  ...
}
```

Following the confirmation of the `CartCreated` event being stored, the `EventSourced` base class calls `applyCartCreated()` with the `CartCreated` instance. This gives the `CartEntity` the opportunity to transition the `CartState` to the new value, which in this case is its initial value.

Following the confirmation of the `ProductPlacedInCart` event being stored, the `EventSourced` base class calls `applyProductPlacedInCart()` with the new `ProductPlacedInCart` instance. This gives the `CartEntity` the opportunity to transition the `CartState` to the new value to include the newly placed product.

Read the [API documentation](https://javadoc.io/doc/io.vlingo/vlingo-lattice/latest/io/vlingo/lattice/model/sourcing/Sourced.html) for more details on all possible overrides. Note that all of the above applies also to the `CommandSourced`, with the same [API documentation](https://javadoc.io/doc/io.vlingo/vlingo-lattice/latest/io/vlingo/lattice/model/sourcing/EventSourced.html).

#### `SourcedTypeRegistry`

In order to introduce your concrete entity types to the underlying `Journal` persistence mechanism that is used by the `EventSourced` abstract base, you must register each one with the `SourcedTypeRegistry`.

```java
import io.vlingo.xoom.lattice.model.sourcing.SourcedTypeRegistry.Info;
import io.vlingo.xoom.symbio.store.common.jdbc.Configuration;
import io.vlingo.xoom.symbio.store.journal.Journal;

...

journal = world.actorFor(Journal.class, JDBCJournalActor.class, configuration);

registry = new SourcedTypeRegistry(world);

Info info = new Info(journal, CartEntity.class, CartEntity.class.getSimpleName());

registry.register(info);
```

You must register such an `SourcedTypeRegistry.Info` for every state type, as was done above for `CartState`.

### Summary

In all cases, the new state and/or events are persisted asynchronously and safely replaced on the entity instance when reconstituted. The `apply()` handles all that for you, but without involving the aggregate designer in persistence, and minus technical naming. There are no race conditions or conflicting operation results, or failed persistence due to a database consistency violation.

## Modeling State

In all of the above entity examples there is a single state object held by each of the entity types, the `CartState` type. This approach has several advantages.

* There is only one variable to manage for all state, including one or more identities and all state that may transition over time.
* Less state objects to manage requires less ongoing cognition.
* The state is immutable, which makes the state simpler to maintain and reason about.
* The state has a side-effect-free, intention-revealing interface, resulting in states transitioning by being fully replaced.
* The state transitions one operation at a time, with each transition clearly focused on a single reason for replacement.

Such a state object may be designed as follows.

```java
public final class CartState {
  public final String cartId;
  public final List<Product> products;
  public final String userId;

  public static CartState initial(String cartId, String userId) {
    new CartState(cartId, userId);
  }

  public CartState withProduct(Product product) {
    new CartState(cartId, userId, place(product));
  }

  private CartState(String cartId, String userId) {
    this(cartId, userId, new ArrayList<>(0));
  }

  private CartState(String cartId, String userId, List<Product> products) {
    this.cartId = cartId;
    this.userId = userId;
    this.products = products;
  }

  private List<Product> place(Product product) {
    List<Product> products = new ArrayList(products);
    products.add(product);
    return Collections.unmodifiableList(products);
  }
}
```

Note that the instance variables are all declared `public final`, making accessor methods unnecessary because clients may directly access the immutable variables. A functional style of programming is employed, which is named referential transparency. That is, the value outcome of a function may be replaced by the value itself. The benefit is the reduction of the cognitive overhead of the interface. Yet, this means that you must take care to design naturally mutable objects, such as `List<Product>`, as immutable. The above example employs `Collections.unmodifiableList()` to make the `products` immutable so that client access may not directly change the list without the `CartState` knowledge.

You may easily add support for other concepts in the state type, such as collections of `Coupon` or `DiscountCode` instances, depending on you Ubiquitous Language. All such additions would focus on only the changes necessary to support the `CartEntity` commands.

## Querying a StateStore

XOOM Lattice provides a specialized query component for querying a `StateStore` asynchronously. It is the abstract base class `StateStoreQueryActor`.

```java
import io.vlingo.xoom.lattice.query.StateStoreQueryActor;

public class ProductQueriesActor extends StateStoreQueryActor implements ProductQueries {
  public ProductQueriesActor(final StateStore stateStore) {
    super(stateStore);
  }
  
  // implement ProductQueries
  
  public Completes<ProductCategoryView> productCategoryOf(final String category) {
    return queryStateFor(category, ProductCategoryView.class);
  }

  public Completes<ProductView> productOf(final String productId) {
    return queryStateFor(productId, ProductView.class);
  }
}
```

Use the `StateStoreQueryActor` to quickly implement queries of various kinds on the `StateStore` .

## `StateAdapter` and `StateAdapterProvider`

All store types, `ObjectStore`, `StateStore`, and `Journal`, serialize state objects to `State<T>` instances. Some stores must serialize state objects in order to persist them, while others do not. In the case of `StateStore` and `Journal`, the states are indeed serialized for the sake of persistence. On the other hand, the `ObjectStore` will always map state to a row and columns, and thus does not use a serialized `State<T>` to persist. Even so, `ObjectStore` will still always serialize the state to a `State<T>` for the purpose of post persistence processing. Therefore, every state type must use a `StateAdapter`.

```java
import io.vlingo.xoom.common.serialization.JsonSerialization;
import io.vlingo.xoom.symbio.BaseEntry.TextEntry;
import io.vlingo.xoom.symbio.StateAdapter;
import io.vlingo.xoom.symbio.Metadata;

public class CartStateAdapter implements StateAdapter<CartState, TextState> {
  @Override
  public int typeVersion() {
    return 1;
  }

  @Override
  public CartState fromRawState(final TextState raw) {
    return JsonSerialization.deserialized(raw.data, CartState.class);
  }

  @Override
  public <ST> ST fromRawState(final TextState raw, final Class<ST> stateType) {
    return JsonSerialization.deserialized(raw.data, stateType);
  }

  @Override
  public TextState toRawState(CartState state, int stateVersion, Metadata metadata) {
    final String serialization = JsonSerialization.serialized(state);
    return new TextState(state.id, CartState.class, typeVersion(), serialization, stateVersion, metadata);
  }

  @Override
  public TextState toRawState(final String id, final CartState state, final int stateVersion, final Metadata metadata) {
    final String serialization = JsonSerialization.serialized(state);
    return new TextState(id, CartState.class, typeVersion(), serialization, stateVersion, metadata);
  }
}
```

{% hint style="info" %}
Initially it is not necessary to create a `StateAdapter<S,E>` during early development if you are using the text edition of a given store, such as `ObjectStore<String>`, `StateStore<String>`, or `Journal<String>`. Instead you may benefit from the `DefaultTextStateAdapter`. This default adapter is used when no adapter is registered for a given state type.\
\
However, when state types change, you must definitely implement adapters for the changing types. In this case the adapters play an important role of upgrading, referred to as upcasting, the persisted `State<T>` to the new version of the state type.

See: `io.vlingo.xoom.symbio.DefaultTextStateAdapter`
{% endhint %}

To make the adapters available to stores, use the `StateAdapterProvider`.

```java
import io.vlingo.xoom.symbio.StateAdapterProvider;

StateAdapterProvider stateAdapterProvider =
  StateAdapterProvider.instance(world);

stateAdapterProvider.registerAdapter(
  CartState.class, new CartStateAdapter());
```

## `EntryAdapter` and `EntryAdapterProvider`

When using domain events, `Source<T>` types, such as concrete `DomainEvent` types, may be persisted to a store database. Such `DomainEvent` instances, such as `CartCreated` and `ProductAddedToCart`, must be serialized to a form that can be inserted into the underlying database as an instances of `Entry<T>`. Two types of `Entry<T>` are supported, `TextEntry` and `BinaryEntry`. The `TextEntry` is backed by a `String`, which is appropriate for serializing with JSON. The `BinaryEntry` is backed by a `byte[]`, which may be used to hold the result of binary serialization (e.g. Protobuf and Avro).

{% hint style="info" %}
It is strongly advised to never use Java default serialization. If you are unaware why, search for `"problems with Java serialization"`.
{% endhint %}

Adapters are created by implementing `EntryAdapter<S,E>`. These adapt `Source<T>` instances to `Entry<T>` instances, and `Entry<T>` instances to `Source<T>` instances. For example, `CartCreated` instances may be adapted to `TextEntry` instances, and the same `TextEntry` instances adapted back to the corresponding `CartCreated` instances. Such an adapter would be named `CartCreatedAdapter`.

```java
import io.vlingo.xoom.common.serialization.JsonSerialization;
import io.vlingo.xoom.symbio.BaseEntry.TextEntry;
import io.vlingo.xoom.symbio.EntryAdapter;
import io.vlingo.xoom.symbio.Metadata;

public final class CartCreatedAdapter implements EntryAdapter<CartCreated, TextEntry> {
  @Override
  public CartCreated fromEntry(TextEntry entry) {
    return JsonSerialization.deserialized(entry.entryData(), CartCreated.class);
  }

  @Override
  public TextEntry toEntry(CartCreated source, Metadata metadata) {
    String serialization = JsonSerialization.serialized(source);
    return new TextEntry(CartCreated.class, 1, serialization, metadata);
  }

  @Override
  public TextEntry toEntry(CartCreated source, String id, Metadata metadata) {
    String serialization = JsonSerialization.serialized(source);
    return new TextEntry(id, CartCreated.class, 1, serialization, metadata);
  }

  @Override
  public TextEntry toEntry(CartCreated source, int version, String id, Metadata metadata) {
    final String serialization = JsonSerialization.serialized(source);
    return new TextEntry(id, CartCreated.class, 1, serialization, version, metadata);
  }
}
```

The `EntryAdapter<S,E>` provides three overloaded methods for adapting from a `Source<S>` to an `Entry<E>`, and one for adapting from `Entry<E>` to `Source<S>`. In the above example the `Source<S>` type `CartCreated` is adapted to a `TextEntry` using JSON, and the persisted `TextEntry` back to a `CartCreated`.

{% hint style="info" %}
Initially it is not necessary to create an `EntryAdapter<S,E>` during early development if you are using the text edition of a given store, such as `ObjectStore<String>`, `StateStore<String>`, or `Journal<String>`. Instead you may benefit from the `DefaultTextEntryAdapter`. This default adapter is used when no adapter is registered for a given `Source<S>` type.\
\
However, when `Source<S>` types change, you must definitely implement adapters for the changing types. In this case the adapters play an important role of upgrading, referred to as upcasting, the persisted `Entry<E>` to the new version of the `Source<S>`type.

See: `io.vlingo.xoom.symbio.DefaultTextEntryAdapter`
{% endhint %}

To make the adapters available to stores, use the `EntryAdapterProvider`.

```java
import io.vlingo.xoom.symbio.EntryAdapterProvider;

EntryAdapterProvider entryAdapterProvider =
  EntryAdapterProvider.instance(world);

entryAdapterProvider.registerAdapter(
  CartCreated.class, new CartCreatedAdapter());

entryAdapterProvider.registerAdapter(
  ProductAddedToCart.class, new ProductPlacedInCartAdapter());
...
```


# Grid

Use XOOM LATTICE as a distributed data and compute grid where actors can send messages to other actors across a cluster of a few or many nodes.

This **XOOM LATTICE** component provides an API for distributed computations and data processing across multiple nodes in a cluster. It supports distributed parallel processing by sending computational execution requests to actors on any node in a [**XOOM CLUSTER**](/xoom-cluster) with the potential to receive results in return, if the protocol specifies a completable future outcome. This as well as elastic resiliency are embodied in the **XOOM LATTICE Grid**.

## Using the Grid

The **XOOM LATTICE Grid** is a distributed compute construct that is implemented as a **XOOM ACTORS** [`Stage`](/xoom-actors#a-stage-for-actors). The `Grid` API is the same as you would expect from any `Stage` with one exception: the `Actor` implementations that should be started on a `Grid` must have a grid-compatible `Address`. There are no other requirements, such as implementing a special interface or extending an abstract base class.

To start the `Grid` use one of the static `Grid.start(...)` methods. You may then start any actor that has a grid-compatible `Address` as you would normally do on a `Stage`.

```java
final Grid grid = Grid.start("product-service", "product-grid");

final Product product = grid.actorFor(Product.class, ProductEntity.class);
```

In the above example the `ProductEntity` actor instance is assigned a grid-compatible `Address`, and is therefore reachable by any message sender on the `Grid`.

### Using Models On the Grid

All **XOOM LATTICE** base [model types](/xoom-lattice/entity-cqrs) are compatible with the grid without any changes. The following are the types.

```java
// model entities
import io.vlingo.lattice.model.sourcing.EventSourced;

import io.vlingo.lattice.model.sourcing.CommandSourced;

import io.vlingo.lattice.model.object.ObjectEntity;

import io.vlingo.lattice.model.stateful.StatefulEntity;

// model processes (a.k.a. sagas)
import io.vlingo.lattice.model.process.ObjectProcess;

import io.vlingo.lattice.model.process.SourcedProcess;

import io.vlingo.lattice.model.process.StatefulProcess;
```

Use all of these base types as you would if not using the grid.

### Grid Actor Distribution

Each node in the grid has a representative abstraction name `GridNode`. Each `GridNode` in the cluster has a copy of a *hash ring* data structure. Without going into details on how a hash ring works, it is used to determine where in the cluster a given actor is to be distributed and subsequently found within the grid. An actor's node location is determined by where the hash of its `Address` distributes on the hash ring data structure. For example, if there are three nodes in the cluster, each actor `Address` must hash into one of the three nodes. This means that a given actor purposely has a single instance in a single grid node in the cluster; that is, that one actor instance is pinned to a given node.&#x20;

When a message is sent to a grid-compatible actor, the grid node of the message sender looks up in the hash ring for the node on which that actor is located. The message is then serialized and sent over the network to that node. The receiving grid node searches up the actor locally and delivers the message through the actor's mailbox.

There is, of course, an optimization if the message is sent to an actor that is on the same node as the sender. Such a condition delivers the message directly through the target actor's mailbox without any network overhead.

### Scenarios

There are several grid operational scenarios to be aware of. Although service and application developers will not need to do anything special when creating actors in the grid and sending messages from many client actors to many target actors, it is useful to understand the common scenarios.

{% hint style="info" %}
Some of the support for the following scenarios is strictly handled by the cluster. In such cases the local grid node is involved only to update its knowledge of the current cluster conditions. Such include updating its hash ring and providing the service/application with a status that indicates that this node is considered healthy and operational.
{% endhint %}

#### Actor-To-Actor Message

An actor on a given grid node sends a message to an actor on a grid node somewhere in the cluster. The sender has a protocol reference to the target actor and sends a message via a protocol method invocation. The target actor's grid-compatible `Address` is used to look up the grid node on which it is pinned. The message is serialized, sent across a network socket channel to the node of the target actor, deserialized, and delivered to the actor via its mailbox.

![Actor-to-actor message sending across nodes and within the same node.](/files/-MB2oXOsTBc0ImypB6qm)

It is possible/likely that some sender actors will be on the same node as the target actor. In that case, the message send is optimized and delivered directly to the actor's mailbox.

#### Node Experiences a Network Partition

A node that experiences a network partition will fail to receive continuous health updates from other nodes that can no longer see it. The partitioned node will be considered lost from the other nodes that can't see it, and that node will in short time understand that it has lost the cluster quorum with the other cluster nodes (as per the **XOOM CLUSTER** [specification](/xoom-cluster#cluster-health-quorum-and-leadership)). This partitioned node then enters into an idle state. When the node understands that it is in an idle state it will provide this information to the clients running in the local node.

![Cluster Node 2 has experienced a network partition. Nodes 1 and 3 are still in a quorum.](/files/-MB2r5fuQAunyEDPtIk4)

In some network partition cases any N nodes out of M total may see each other, and yet there must be P nodes excluded from the cluster. In the case of a three-node cluster, N=2, M=3, and P=1.

One of the N nodes will be elected leader of the quorum. Any node in the set of P that is not seen by the leader will be prevented from entering the cluster. Should any partitioned node within the set of P claim to be leader among the N and/or P nodes that it can see (it has the highest value node id among any other nodes it can see), the nodes that receive its declaration of leadership will reject that claim. In turn any of the rejecting nodes will inform the failed leadership-declaring node (within P) of the real leader (within N) that it recognizes. This is strictly handled by the cluster and involves the grid only to provide information that it is not in the cluster quorum.

#### Node Leaves

A node that is downed within the cluster has left it, which will be communicated to all remaining nodes.

![Node 2 leaves the cluster as downed or crashed. Its actors are recovered on Nodes 1 and 3.](/files/-MB3176sJY1A7uLiWj9t)

The actors that were distributed to the node that left must continue to operate within the grid on the nodes still in the cluster quorum. Thus, the actors that would otherwise be lost can be recovered onto a different node. Consider the following types of recovery.

* Actors with ephemeral or transient state, and model actors that have persistent state, will be recovered on a different node according to the adjusted hash ring. This will not actually occur until a message is sent to any such actor.
* Actors that have non-transient state but that are not persistent model actor types cannot be fully recovered on other nodes with the state they previously held on the downed node. One way to ensure that the actor state can be maintained is to place in a **XOOM LATTICE** **Space***.* A Space is a distributed, in-memory, key-value store. As long as the cluster nodes remain running on which a given Space key-value is persistent in memory, any actor using that Space key-value can restore from that state as needed.

#### Node Joins

A node that newly joins a cluster will cause the hash ring to adjust to that node, meaning that the actors that were on any preexisting nodes may be repartitioned on to one or more other nodes. In other words, a node joining the cluster changes the hashing results because there are now more nodes than previously available.

![Node 2 joins the cluster and actors on Nodes 1 and 3 are repartitioned onto Node 2.](/files/-MB31Og0aSSyi59Mm9lH)

This repartitioning could be quite expensive if the actors were to be immediately relocated. Instead what happens is the same that occurs when a cluster node leaves. The recovery onto a different node will occur only when a message is sent to any such relocated actor.

The implementation of the typical scenario is: when the cluster node updates its hash ring to include the newly joined node, it scans its internal directory for actors whose Address indicates that they no longer belong, and evicts those actors. The actors evicted from that node will not be repartitioned until receiving their next message. Any messages for the evicted actors that are received latently are relayed to the node that now contains the given actors.

There are a few challenges to this typical scenario.

* An evicted actor with messages still in its mailbox must be given the opportunity to process those messages. Thus, before evicting such an actor, its remaining mailbox messages must be sent to the grid node that is now responsible for it.
* It is possible that when multiple nodes are joining within a short time frame, or one or more nodes leave the cluster near the same time as one or more joining, there may be some shuffling of actors until the repartitioning settles. The best that a given evicting node can do is relay received messages to actors that it is no longer responsible for to the node it currently understands to be the one hosting such actors. This will cause some additional latency.

There is no way to avoid these challenges, because there is no way for a given node to predict that something about the cluster will change just following its update of its own hash ring.

{% hint style="info" %}
In distributed computing, there is no now.
{% endhint %}

Yet, these challenges do emphasize that the eviction process must be asynchronous to the ongoing receipt of cluster health and actor targeted messages. That enables the node to immediately update its hash ring to its current understanding of possible ongoing cluster changes. As a result, the asynchronous eviction process has the opportunity to check for a possible refreshed hash ring as it decides whether or not to evict a given actor, and if evicted, which node should receive it's messages—at least as of that very instant in time.

### Dealing with Grid Heap Pressure (Memory Highwater Mark)

If you are using the XOOM Lattice Grid you likely will need assistance from the actor infrastructure to deal with heap pressure; that is, reaching a point where application/service memory is becoming scarce. (This situation might also be called a "highwater mark.") Using the [Actor Eviction Service can help with this, which you will learn about under the Actors chapter](/xoom-actors#automatic-eviction-of-seldom-used-actors).

Recall that a `Grid` is a specialization (extension) of `Stage`. When a `Grid` is instantiated, its construction process [forces the eviction service to be enabled](/xoom-actors#stage-directory-eviction-service) on its behalf. This is accomplished by using either a default configuration or the one configured through the XOOM Actors plugin configuration, but the `enabled` flag is force-set to `true` regardless of what is configured by default (suggested disabled). Note that this has no effect on other `Stage` instances, such as the default `Stage`. To reiterate, the forced enablement is performed only for a `Grid` as it is being newly instantiated, and it will remain in effect for the lifetime of the `Grid`.


# Exchange

Using the VLINGO XOOM message and event exchange across Bounded Contexts.

This **XOOM LATTICE** component provides an `Exchange` abstraction over Publish-Subscribe messaging for exchanges or topics. This is a means to publish messages to exchanges/topics inside or outside your current application/service, and to subscribe to such messages. The `Exchange` provides translators from internal to external message types, and from external to internal message types.

## Understanding the Exchange

There are a few key abstractions. The following subsections describe each.

### Exchange

The `Exchange` itself is the primary protocol. It defines a message exchange, such as a queue or topic, through which any number of related `ExchangeSender`, `ExchangeReceiver`, and `ExchangeAdapter` components are registered, and messages are sent. The protocol is defined as follows.

```java
public interface Exchange {
  void close();
  <T> T channel();
  <T> T connection();
  String name();
  <L,E,EX> Exchange register(final Covey<L,E,EX> covey);
  <L> void send(final L local);
}
```

The defined behaviors are described next.

```java
void close();
```

Close the `Exchange` and any underlying resources. Given that the `Exchange` is backed by some middleware messaging mechanism, and connections and other allocated resources to the mechanism are closed.

```java
<T> T channel();
```

Answers the underlying channel, which is implementation dependent. The `T` type is a parameter that determines the dynamic cast to the runtime type.

```java
<T> T connection();
```

Answers the underlying connection, which is implementation dependent. The `T` type is a parameter that determines the dynamic cast to the runtime type.

```java
String name();
```

Answers the name of this `Exchange` as a `String`.

```java
<L,E,EX> Exchange register(final Covey<L,E,EX> covey);
```

Registers a `Covey` with the `Exchange`. A `Covey` is a set of `Exchange` components used to send, receive, and translate messages. The `Covey` is explained in a below subsection.

```java
<L> void send(final L local);
```

Sends the `local` message to the `Exchange` after first adapting it to an `Exchange`-compatible message. Any given message has three forms:

1. Local—The type used by the local system to represent the message sent or received
2. External—The type the message will have when it is received on the external service
3. Exchange—The type used to transport the message on the Exchange from sender to receiver(s). The Exchange type holds an instance of the External type.

#### ConnectionSettings

The `ConnectionSettings` is a configuration for making a connection to the underlying messaging mechanism, including information for the host, port, virtual host, and user.

```java
public class ConnectionSettings {
  public final String hostName;
  public final String password;
  public final int port;
  public final String username;
  public final String virtualHost;
  ...
}
```

There are also a number of factory methods for creating the value state.

#### Covey

A covey by definition is a group or set. We use a `Covey` as a set of `Exchange` components used for translating, sending, and receiving messages. A given `Exchange` will have one `Covey` for each local message type, either as a sender or a receiver of that message type.

```java
public class Covey<L,E,EX> {
  public ExchangeAdapter<L,E,EX> adapter;
  public ExchangeReceiver<L> receiver;
  public ExchangeSender<EX> sender;
  public final Class<L> localClass;
  public final Class<E> externalClass;
  public final Class<EX> exchangeClass;
  ...
}
```

The `adapter` is an `ExchangeAdapter` that is capable of adapting messages to their three forms, Local, External, and Exchange.

The `receiver` is an `ExchangeReceiver` of messages of local type, meaning that the `ExchangeAdapter` has already adapted the incoming message to the local type.

The `sender` is an `ExchangeSender` of messages of exchange type through the `Exchange`, meaning that the `ExchangeAdapter` has already adapted the local message to an outgoing type.

Each of the `Class` instances is the type of a message form: `localClass`, `externalClass`, `exchangeClass`.

### Queue

A `Queue` is just a specialized `Exchange`. It is expected that a `Queue` is not a fanout type but one that is point-to-point. Being point-to-point does not prevent the receiver end from enlisting multiple`Queue` competing consumers. The `Queue` protocol is identical to the `Exchange`.

### ExchangeSender

A sender of messages to an `Exchange` or `Queue`.&#x20;

```java
public interface ExchangeSender<E> {
  void send(final E message);
}
```

The single protocol operation is as follows.

```java
void send(final E message);
```

Sends the `E` exchange typed message through the underlying exchange or queue, meaning that the `ExchangeAdapter` has already adapted the local message to an outgoing type.

From this it may be apparent that the `Exchange#send()` does not actually send the message. Instead it dispatches the local message through the `Forwarder` for translation to the exchange type, and then the `Forwarder` dispatches the message to the `ExchangeSender`.

#### Forwarder

The forwarder of all local and exchange messages, forwarding local messages through an `ExchangeSender` and exchange messages through the `ExchangeReceiver`. It is the `Forwarder` that holds the `Covey` instances in behalf of the `Exchange` or `Queue`, and thus manages translation from local to exchange types and from exchange to local types.

#### MessageParameters

A builder of message parameters and set of metadata attributes, any number of which are common to associate with messages as parameters. These are to be used as appropriate or ignored if unneeded. The chosen parameters are built using the fluent interface.

```java
public class MessageParameters {
  public static enum DeliveryMode { Durable, Transient }
  public static enum Priority { High, Normal, Medium, Low, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9 }

  private String applicationId;
  private String contentEncoding;
  private String contentType;
  private String correlationId;
  private String deliveryId;
  private DeliveryMode deliveryMode;
  private String exchangeName;
  private Map<String,Object> headers;
  private String messageId;
  private String other1;
  private String other2;
  private String other3;
  private Priority priority;
  private String queueName;
  private boolean redeliver;
  private String replyTo;
  private String returnAddress;
  private List<String> routing;
  private long timestamp;
  private long timeToLive;
  private String tag;
  private String typeCode;
  private String typeName;
  private String userId;
  ...
}
```

There are factory methods and builder methods, as well as public accessors for each parameter. Many of the metadata parameters are common to AMQP, but may also be useful for any type of messaging protocol.

### ExchangeReceiver

A receiver of messages from an `Exchange`, which may be implemented for each unique message type. The message type received has already been mapped and adapted from the exchange-typed message, and this is in the form of a local message.

```java
public interface ExchangeReceiver<L> {
  void receive(final L message);
}
```

The single protocol operation is as follows.

```java
void receive(final L message);
```

The implementor receives the delivered `L` local typed message from the `Exchange`. The message is of local type `L` having already been mapped and adapted from the exchange-typed message.

### ExchangeAdapter

Adapts local messages of type `L` to exchange messages of type `EX` that hold external type `E`. This may involve mapping, in which case the underlying implementation must arrange for an `ExchangeMapper` to be registered and used. Note that the L and E types may be different between `ExchangeAdapter` and `ExchangeMapper`.

```java
public interface ExchangeAdapter<L,E,EX> {
  L fromExchange(final EX exchangeMessage);
  EX toExchange(final L localMessage);
  boolean supports(final Object exchangeMessage);
}
```

The parameters of `L`, `E`, and `EX` are the local form, the external form, and the exchange form types, respectively. The operations of this protocol work as follows.

```java
L fromExchange(final EX exchangeMessage);
```

Answers the `L` typed local message from the `exchangeMessage` of type `EX`.

```java
EX toExchange(final L localMessage);
```

Answers the `EX` typed exchange message from the `localMessage` of type `L`.

```java
boolean supports(final Object exchangeMessage);
```

Answers whether or not the adapter supports the `exchangeMessage`. This is used by the `Forwarder` to find the `Covey` used for the type of `exchangeMessage`.

#### ExchangeMapper

Supports mapping a local type message to external type, and a external type message to local type.

```java
public interface ExchangeMapper<L,E> {
  E localToExternal(final L local);
  L externalToLocal(final E external);
}
```

The parameters of `L` and `E` are the local form type and the external form type, respectively. The mapper operations are used as follows.

```java
E localToExternal(final L local);
```

Answers the external typed message given the local typed message.

```java
L externalToLocal(final E external);
```

Answers the local typed message given the external typed message.

## Usage

This section demonstrates how to use the `Exchange`. It provides a very simple usage example based on the RabbitMQ implementation.

To use the RabbitMQ implementation you first get connection to an `Exchange`.

```java
final Exchange exchange =
    ExchangeFactory.fanOutInstance(
        settings(),
        "test-fanout",
        true);
```

This factory method is specific to the RabbitMQ implementation. The `settings()` is defined as:

```java
private ConnectionSettings settings() {
  return ConnectionSettings.instance(
      "localhost",
       ConnectionSettings.UndefinedPort,
       "/",
       "guest",
       "guest");
}
```

The connection is to RabbitMQ on `localhost` and uses the default port by passing the value of `UndefinedPort`, which is `-1`. The `virtualHost` is `"/"` and the `username` and `password` are both `"guest"`.&#x20;

Now that the `Exchange` is open we can register a `Covey` to handle a given set of message types.

```java
exchange
  .register(Covey.of(
      new MessageSender(exchange.connection()),
      new TextMessageReceiver(),
      new TextExchangeAdapter(),
      String.class,
      String.class,
      Message.class));
```

To keep the example simple, both the local and external message types are `String`. The exchange message type is `Message`, which is a specialized RabbitMQ type.

```java
package io.vlingo.lattice.exchange.rabbitmq;

import io.vlingo.lattice.exchange.MessageParameters;

public class Message {
  public final MessageParameters messageParameters;
  public final byte[] payload;

  public Message(final byte[] payload, final MessageParameters messageParameters) {
    this.payload = payload;
    this.messageParameters = messageParameters;
  }

  public Message(final String payload, final MessageParameters messageParameters) {
    this.payload = payload.getBytes();
    this.messageParameters = messageParameters;
  }

  public String payloadAsText() {
    return new String(payload);
  }
}
```

The `Message` holds a `byte[] payload` and an instance of `MessageParameters` as metadata. The `Message` may be constructed using a `byte[]` or a `String`, which is converted to a `byte[]`, along with `MessageParameters`.

Now here is more specific detail on the `Covey` registration on the `Exchange`. The `MessageSender` is a predefined implementation of `ExchangeSender` specifically for RabbitMQ. You instantiate the `MessageSender` with the `Exchange`'s connection.

The `TextMessageReceiver` and `TextExchangeAdapter` are specifically for `String` messages. The `TextMessageReceiver` is implemented as follows.

```java
public class TextMessageReceiver implements ExchangeReceiver<String> {
  public TextMessageReceiver() { }

  @Override
  public void receive(final String message) {
    ...
  }
}
```

Your `receive()` method will apply the message as appropriate for your service/application. The following is the `TextExchangeAdapter`.

```java
public class TextExchangeAdapter implements ExchangeAdapter<String,String,Message> {
  private ExchangeMapper<String,String> mapper = new TextExchangeMapper();

  @Override
  public String fromExchange(final Message exchangeMessage) {
    final String local = mapper.externalToLocal(exchangeMessage.payloadAsText());
    return local;
  }

  @Override
  public Message toExchange(final String localMessage) {
    return new Message(localMessage, MessageParameters.bare().deliveryMode(DeliveryMode.Durable));
  }

  @Override
  public boolean supports(final Object exchangeMessage) {
    return Message.class == exchangeMessage.getClass();
  }
}
```

This specific adapter supports any `Message` received from the `Exchange`. To adapt from an `Exchange`-received `Message` to a `String`, the adapter calls on the `TextExchangeMapper`. To get a `String` from the `byte[] payload`, the adapter uses `Message#payloadAsText()`.&#x20;

Going from a `localMessage` to a `Message` for the `Exchange` requires constructing with the `localMessage` that is converted into a `byte[]`, and providing a `MessageParameters` instance indicating that the `Message` must be sent as durable.

This is the mapper implementation.

```java
public class TextExchangeMapper implements ExchangeMapper<String,String> {

  @Override
  public String localToExternal(final String local) {
    return new String(local);
  }

  @Override
  public String externalToLocal(final String external) {
    return new String(external);
  }
}
```

Unsurprisingly this mapper, in mapping from `String` to `String`, has almost no heavy-lifting functionality. Note that a new `String` is created from both local and external `String` messages to ensure the instances are different.

That's all that is required for a simple text-based message exchange between a sending service and a receiving service.

A more sophisticated set of message types, adapters, and mappers are shown next. Note that the following message types all have `equals()`, `hashCode()`, and `toString()`, but are excluded here for clarity.

```java
public class LocalType1 {
  public final String attribute1;
  public final int attribute2;

  public LocalType1(final String value1, final int value2) {
    this.attribute1 = value1;
    this.attribute2 = value2;
  }
}
```

```java
public class LocalType2 {
  public final String attribute1;
  public final float attribute2;

  public LocalType2(final String value1, final float value2) {
    this.attribute1 = value1;
    this.attribute2 = value2;
  }
}
```

The external message types are corresponding to the similarly named local types are as follows.

```java
public class ExternalType1 implements Message {
  public final String field1;
  public final String field2;

  public ExternalType1(final String value1, final int value2) {
    this.field1 = value1;
    this.field2 = Integer.toString(value2);
  }
}
```

```java
public class ExternalType2 implements Message {
  public final String field1;
  public final String field2;

  public ExternalType2(final String value1, final float value2) {
    this.field1 = value1;
    this.field2 = Float.toString(value2);
  }
}
```

The local types hold `String`, `int`, and `float` types, while the external types hold only `String` attribute types. Also the attribute names are different. This justifies the need for an adapter and mapper for each local to external type. First are the adapter and mapper for `LocalType1` and `ExternalType1`.

```java
public class ExchangeAdapter1 implements ExchangeAdapter<LocalType1,ExternalType1,ExchangeMessage> {
  private ExchangeMapper<LocalType1,ExternalType1> mapper = new TestExchangeMapper1();

  @Override
  public LocalType1 fromExchange(final ExchangeMessage externalMessage) {
    final ExternalType1 external = JsonSerialization.deserialized(externalMessage.payload, ExternalType1.class);
    final LocalType1 local = mapper.externalToLocal(external);
    return local;
  }

  @Override
  public ExchangeMessage toExchange(final LocalType1 localMessage) {
    final ExternalType1 external = mapper.localToExternal(localMessage);
    final String payload = JsonSerialization.serialized(external);
    return new ExchangeMessage(ExternalType1.class.getName(), payload);
  }

  @Override
  public boolean supports(final Object exchangeMessage) {
    if (ExchangeMessage.class != exchangeMessage.getClass()) {
      return false;
    }
    return ExternalType1.class.getName().equals(((ExchangeMessage) exchangeMessage).type);
  }
}
```

```java
public class ExchangeMapper1 implements ExchangeMapper<LocalType1,ExternalType1> {

  @Override
  public ExternalType1 localToExternal(final LocalType1 local) {
    return new ExternalType1(local.attribute1, local.attribute2);
  }

  @Override
  public LocalType1 externalToLocal(final ExternalType1 external) {
    return new LocalType1(external.field1, Integer.parseInt(external.field2));
  }
}
```

Next are the adapter and mapper for `LocalType2` and `ExternalType2`.

```java
public class ExchangeAdapter2 implements ExchangeAdapter<LocalType2,ExternalType2,ExchangeMessage> {
  private ExchangeMapper<LocalType2,ExternalType2> mapper = new TestExchangeMapper2();

  @Override
  public LocalType2 fromExchange(final ExchangeMessage externalMessage) {
    final ExternalType2 external = JsonSerialization.deserialized(externalMessage.payload, ExternalType2.class);
    final LocalType2 local = mapper.externalToLocal(external);
    return local;
  }

  @Override
  public ExchangeMessage toExchange(final LocalType2 localMessage) {
    final ExternalType2 external = mapper.localToExternal(localMessage);
    final String payload = JsonSerialization.serialized(external);
    return new ExchangeMessage(ExternalType2.class.getName(), payload);
  }

  @Override
  public boolean supports(final Object exchangeMessage) {
    if (ExchangeMessage.class != exchangeMessage.getClass()) {
      return false;
    }
    return ExternalType2.class.getName().equals(((ExchangeMessage) exchangeMessage).type);
  }
}
```

```java
public class ExchangeMapper2 implements ExchangeMapper<LocalType2,ExternalType2> {

  @Override
  public ExternalType2 localToExternal(final LocalType2 local) {
    return new ExternalType2(local.attribute1, local.attribute2);
  }

  @Override
  public LocalType2 externalToLocal(final ExternalType2 external) {
    return new LocalType2(external.field1, Float.parseFloat(external.field2));
  }
}
```

You may define any number of adapters and mappers to deal with the translations between local and external message types. Each of the sets will be held by a separate `Covey` and registered with the `Exchange` or `Queue`.


# Processes

XOOM LATTICE long-running process orchestrations, aka Sagas, with guided steps to results.

Processes can be used to manage complex, coarse-grained, long-running business transactions. Each step in the process is orchestrated until a given outcome is reached, which may be a successful completion.

{% hint style="info" %}
Some processes may never end in that they may repeat indefinitely, producing one or more smaller subsets of successful outcomes with each iteration.
{% endhint %}

Because such a process runs longer than for a single transaction and may spread across any number of Bounded Contexts (i.e. microservices), and because the process may at some point be temporarily evicted from memory, the process itself must be persistent. The **XOOM LATTICE** tools assist in managing such processes, whether by means of object persistence, stateful command models, or sourced with events and commands.

{% hint style="info" %}
Note that a long-running process is often referred to as [***Saga***](https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf)*.* Even so, we here acknowledge that this use of the name Saga to refer to such a process is not typically according to the original pattern definition, although it may be designed as such. Primarily this would be accomplished by emulating a rollback by applying compensating transactions to the point where any previous transactions are essentially undone. This is known as *backward recovery,* but there is also a second choice known as *forward recovery,* and the two may be combined.
{% endhint %}

### How Processes Work

As a general rule, a process is informed of an outcome, and in reaction to that outcome causes another action to be taken. This will repeat as the process is informed of the outcome of the previous action that it caused, and then cause yet another action to be taken.

Typically a `DomainEvent` will trigger the process to start. The process will then emit a `Command`, which is to cause the next step in the process. When the `DomainEvent` from that step outcome is seen, process will again emit a `Command`, which is to cause the next step in the process. This repeats until the process has completed (if in fact it is meant to complete). The process tracks the current state of the state machine, which along with the next `DomainEvent` it sees, will determine the next step to be taken.

![A process that spans three different Bounded Contexts.](/files/-M7aeWqWWAfUs8PnLru6)

The above diagram shows how the process starts by a user submitting a command and then proceeds through five total steps. Note that a `DomainEvent` is seen by the process as a stimulus, and the process then emits a `Command` to cause the next action. This pattern repeats until completion is reached on the far right.

### Process Types

A process is a [finite state machine](https://en.wikipedia.org/wiki/Finite-state_machine). **XOOM LATTICE** provides a protocol for processes, the `Process`.

![The Process and three abstract types, each corresponding to a model entity type.](/files/-M9CBNexg-BmVdxNxsj_)

There are three `Process` standard implementors that are abstract base types. These base classes are meant to be extended by concrete implementors.

| Type              | Description                                                                                                                                                        |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SourcedProcess`  | Uses Command Sourcing and/or Event Sourcing to maintain the state of the process and to direct next steps.                                                         |
| `ObjectProcess`   | Use a persistent object-relational mapped object to maintain the state of the state machine. The extender must still emit commands or events to direct next steps. |
| `StatefulProcess` | Use a persistent key-value to maintain the state of the state machine. The extender must still emit commands or events to direct next steps.                       |

These are all documented in detail below.

Especially in the case of implementing a `Process`, the `SourcedProcess` is generally the best choice. The use of `Command` and/or `DomainEvent` types to direct the steps of the process are a natural fit. You may still, however, accomplish the same by using `Command` and/or `DomainEvent` types within an `ObjectProcess` and `StatefulProcess`. It may be more a matter of whether you prefer to always persist state [snapshots](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#eventsourced), which you must always do with these two process types.

### Process Protocol

The protocol for processes is defined in **XOOM LATTICE**.

```java
package io.vlingo.lattice.model.process;

import java.util.List;
import java.util.function.Supplier;

import io.vlingo.common.Completes;
import io.vlingo.lattice.model.Command;
import io.vlingo.lattice.model.DomainEvent;
import io.vlingo.symbio.Source;

public interface Process<T> {

  Chronicle<T> chronicle();

  String id();

  void process(final Command command);

  <R> Completes<R> process(final Command command, final Supplier<R> andThen);

  void process(final DomainEvent event);

  <R> Completes<R> process(final DomainEvent event, final Supplier<R> andThen);

  <C> void processAll(final List<Source<C>> sources);

  <C,R> Completes<R> processAll(final List<Source<C>> sources, final Supplier<R> andThen);

  void send(final Command command);

  void send(final DomainEvent event);
}
```

As expected with the **VLINGO XOOM** platform, the protocol is quite simple. The operations work as described in the following subsections.

#### `Chronicle<T> chronicle()`

Returns the current state of the process as a `Chronicle<S>`, where `S` is the type of the state. Since a `Process` is a state machine, the current state held by the `Chronicle<S>` is the state of the state machine.

```java
public class Chronicle<S> {
  public final S state;

  public Chronicle(final S state) {
    this.state = state;
  }

  public Chronicle<S> transitionTo(final S state) {
    return new Chronicle<>(state);
  }
}
```

The API makes no assumptions that the full state itself will be persisted, but makes it possible. Since the `Process` may be `CommandSourced` or `EventSourced`, or a combination of both, it could well be that there is no need to use the `Chronicle<S>` for full-state persistence. In such cases the Process may require minimal state transitions, and thus any state-representing stream may not be large enough to justify the use of [snapshots](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#eventsourced).

You use `transitionTo()` to create a new `Chronicle<S>` that wraps the new state of the state machine.

It is meant for you to extend the `Chronicle<S>` to manage your more fine-grained state transitions.

#### `String id()`

Returns the global unique identity of the `Process`, which should likely be the `id()` or `streamName()` of the underlying base types: `SourcedProcess`, `ObjectProcess`, `StatefulProcess`.

#### `void process(Command command)`

Wraps the `Command` inside a `ProcessMessage` and persists it to the underlying storage, and then sends it through the configured [message exchange](/xoom-lattice/exchange).

#### `<R> Completes<R> process(Command command, Supplier<R> andThen)`

Performs as does `process(Command)`, and also returns the `Completes<R>` that provides the eventual outcome of the `Supplier<R>` parameter `andThen`. After the `Command` is safely persisted, the `andThen` is executed and its value is given as outcome of the `Completes<R>`.

#### `void process(DomainEvent event)`

Wraps the `DomainEvent` inside a `ProcessMessage` and persists it to the underlying storage, and then sends it through the configured [message exchange](/xoom-lattice/exchange).

#### `<R> Completes<R> process(DomainEvent event, Supplier<R> andThen)`

Performs as does `process(DomainEvent)`, and also returns the `Completes<R>` that provides the eventual outcome of the `Supplier<R>` parameter `andThen`. After the `DomainEvent` is safely persisted, the `andThen` is executed and its value is given as outcome of the `Completes<R>`.

#### `<C> void processAll(List<Source<C>> sources)`

Wraps each of the `Source<C>` instances inside its own `ProcessMessage` and persists all of them to the underlying storage, and then sends each through the configured [message exchange](/xoom-lattice/exchange).

#### `<C,R> Completes<R> processAll(List<Source<C>> sources, Supplier<R> andThen)`

Performs as does `processAll(List<Source<C>>)`, and also returns the `Completes<R>` that provides the eventual outcome of the `Supplier<R>` parameter `andThen`. After all `Source<C>` instances are safely persisted, the `andThen` is executed and its value is given as outcome of the `Completes<R>`.

{% hint style="info" %}
Note that the above six `process...()` operations support guaranteed at-least-once delivery as long as the persistence succeeds. Additionally, these operations provide traceability from/to where and why the messages were sent and delivered, and the persistence make the messages useful in the future. It is often impossible to predict all the uses of long-term persisted messages, but they have immediate purpose and generally future applicability.

The following two `send()` operations will only succeed if the messaging mechanisms successfully enqueues the message and the queue/topic/exchange is durable. However, even if the send succeeds there is no traceability from/to where and why the message was sent and delivered, nor is the message persisted long-term. In fact, the durable queue (et al) will delete the message after its deliver is confirmed.
{% endhint %}

#### `void send(Command command)`

Sends the `Command` through the configured [message exchange](/xoom-lattice/exchange) without first persisting it.

#### `void send(DomainEvent event)`

Sends the `DomainEvent` through the configured [message exchange](/xoom-lattice/exchange) without first persisting it.

### Using the Process Types

The abstract base `Process` types—`SourcedProcess`, `ObjectProcess`, and `StatefulProcess`—are described in the following subsections.

#### `SourcedProcess`

To use a Command Sourced and/or Event Sourced Process type, extend the `SourcedProcess`. Recall from the above diagram that generally a process is stimulated by a `DomainEvent` and then causes the next action by emitting a `Command`. The fact that `Command` instances are persisted to represent the process state, this makes the process Command Sourced, as in sourced by commands.

```java
public class ManagedOrderProcess extends SourcedProcess<OrderState> implements OrderProcess {
  private OrderProcessState state;
  
  public ManagedOrderProcess() {
    super(); // uses address id as streamName
  }
  
  @Override
  public void orderPlaced(Order order) {
    state = OrderProcessState.with(order);
    process(new AuthorizePayment(state.order.paymentInfo));
  }
  
  @Override
  public void paymentAuthorized(PaymentAuthorization paymentAuthorization) {
    state = state.with(paymentAuthorization);
    process(new PickItems(state.order.items));
  }
  
  ...
}
```

Note that the `DomainEvent` instances are not received directly by the process. Instead an exchange listener receives the DomainEvent, looks up the process, and dispatches one of the process protocol messages, such as `orderPlaced()` and `paymentAuthorized()`.

#### `StatefulProcess`

The `StatefulProcess` is very similar to the `SourcedProcess`, except that you must implement a few overrides necessary for the `StatefulProcess` and underlying `StatefulEntity` abstract base type.

```java
public class ManagedOrderProcess extends StatefulProcess<OrderState> implements OrderProcess {
  private Chronicle<OrderProcessState> chronicle;
  
  public ManagedOrderProcess() {
    super(); // uses address id as streamName
  }
  
  @Override
  public Chronicle<OrderProcessState> chronicle() {
    return chronicle;
  }
  
  @Override
  public void orderPlaced(Order order) {
    state = OrderProcessState.with(order);
    process(new AuthorizePayment(state.order.paymentInfo));
  }
  
  @Override
  public void paymentAuthorized(PaymentAuthorization paymentAuthorization) {
    state = state.with(paymentAuthorization);
    process(new PickItems(state.order.items));
  }

  ...

  @Override
  protected void state(final OrderProcessState state) {
    this.chronicle = chronicle.transitionTo(state);
  }

  @Override
  protected Class<OrderProcessState> stateType() {
    return OrderProcessState.class;
  }
}
```

The `chronicle()` is required by the `StatefulProcess`, and the `state()` and `stateType()` are required by the `StatefulEntity`.

#### `ObjectProcess`

The `ObjectProcess` is very similar to the `SourcedProcess`, except that you must implement a few overrides necessary for the `ObjectProcess` and underlying `ObjectEntity` abstract base type.

```java
public class ManagedOrderProcess extends ObjectProcess<OrderState> implements OrderProcess {
  private Chronicle<OrderProcessState> chronicle;
  
  public ManagedOrderProcess() {
    super(); // uses address id as streamName
  }
  
  @Override
  public Chronicle<OrderProcessState> chronicle() {
    return chronicle;
  }
  
  @Override
  public void orderPlaced(Order order) {
    chronicle = new Chronicle(OrderProcessState.with(order));
    process(new AuthorizePayment(state.order.paymentInfo));
  }
  
  @Override
  public void paymentAuthorized(PaymentAuthorization paymentAuthorization) {
    chronicle.state.setPaymentAuthorization(paymentAuthorization);
    process(new PickItems(state.order.items));
  }

  ...

  @Override
  protected OrderProcessState stateObject() {
    return chronicle.state;
  }

  @Override
  protected void state(final OrderProcessState state) {
    this.chronicle = chronicle.transitionTo(state);
  }

  @Override
  protected Class<OrderProcessState> stateType() {
    return OrderProcessState.class;
  }
}
```

The `chronicle()` is required by the `ObjectProcess`, and the `stateObject()`, `state()`, and `stateType()` are required by the `ObjectEntity`.


# Spaces

XOOM Spaces uses our cluster-based Grid as both a distributed object storage and a means of object exchange within a single scaled microservice (i.e. Bounded Context).

XOOM Spaces facilitates local and distributed object storages and exchanges. A distributed space can exist over a number of clustered XOOM Grid nodes, and is transactionally replicated for fail-safe access. A distributed space keeps frequently used data near the actor behaviors and processes that need it.

Such technologies are often referred to as data grids and data fabrics. Even so, the distributed cached data is only half of the story. The point is to use the distributed object storage for the business-driven operational purposes of the application.

### Using Spaces

To start a local or distributed Spaces first you need to obtain an `Accessor` instance:

```java
Accessor myAccessor = Accessor.using(grid, "myAccessor");
```

An `Accessor` instance is used to create either a local or a distributed space. Overloaded `spaceFor(...)`  methods are used to create a local `Space` instance, whereas the `distributedSpaceFor(...)` overloaded methods are employed to create a distributed `Space` instance. It is important to mention here that local and distributed spaces are represented by the `Space` protocol, which in both cases is backed by an actor. When the Space is local only, the actor resides only on the one node. On the other hand, a distributed `Space` has a backing actor on a number of different clustered `Grid` nodes.

{% hint style="info" %}
The current implementation of distributed spaces replicates all items of every space to all grid nodes. There is a replication transaction around all `put()`and `take()` operations. To avoid excessive overhead on larger clusters, transactions can be configured to require only a fraction of total node replication confirmations before they are considered fully committed. For example, you might use `0.25` for a replication factor, which means that 25% of total nodes must confirm the replication of a `put()` before the transaction is considered committed. Yet, after the limited replication is considered committed, the remainder of the replications will continue in the background until confirmed by all nodes.

Future releases will feature grid node replication to only a subset of all nodes. For example, a total replication to three out of nine cluster nodes could be considered fully replicated. This uses the reasoning that it is highly unlikely to (near) simultaneously lose all three nodes from the same cluster.
{% endhint %}

### Space type

The `Space` protocol is the central component of Spaces API:

```java
public interface Space {
  <T> Completes<KeyItem<T>> put(final Key key, final Item<T> item);
  <T> Completes<Optional<KeyItem<T>>> get(final Key key, final Period until);
  <T> Completes<Optional<KeyItem<T>>> take(final Key key, final Period until);
}
```

It contains the `Space` messages `put()`, `get()`, and `take()`. The `get()` and `take()` methods accept `Period` parameter. This value indicates how long the result will be to be awaited. Also any new `Item` added to a `Space` has a `Lease` property. This property defines the length of time the `Item` will be stored, which can be indefinitely. When a lease expires, the `Item` is evicted from the `Space`. The `Period` and `Lease` values work together.

The following table describes the full `Space` protocol.

| Message                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `put(Key key, Item<T> item)`  | Puts a new `Item<T>` that is referenced by the `Key` into the `Space`, or replaces an existing `Item<T>` in the `Space` matching `Key` with the given `Item`. The new `Item` and its `Key` are eventually answered as a `KeyItem` pair.                                                                                                                                                                                                                                                      |
| `get(Key key, Period until)`  | Gets and eventually answers the `Item` identified by the Key from the Space. If the `Key` does not (yet) exist, a periodic query is run until the defined `Period` elapses or the `Key` is resolved, whichever occurs first.  The `Period` may be `None`, `Forever`, or some other period of time between the two extremes. The found `Item` and its `Key` are eventually answered as an `Optional` of `KeyItem` pair; otherwise, if not found, an empty `Optional` is eventually answered.  |
| `take(Key key, Period until)` | Takes the `Item` identified by the `Key` out from the `Space` by removing it. If the `Key` does not (yet) exist, a periodic query is run until the defined `Period` elapses or the `Key` is resolved, whichever occurs first.  The `Period` may be `None`, `Forever`, or some other period of time between the two extremes. The found `Item` and its `Key` are eventually answered as an `Optional` of `KeyItem` pair; otherwise, if not found, an empty `Optional` is eventually answered. |

A full example of using distributed Spaces with transactional write-through and full cluster-wide replication is available in this [xoom-distributed-spaces](https://github.com/vlingo/xoom-examples/tree/master/xoom-distributed-spaces) example project. See the simplicity our our API in the following REST resource handler that makes direct use of distributed Spaces. Both the REST resource handler and the Spaces API are fully reactive, and yet completely fluent and understandable:

```java
public class SpacesResource extends DynamicResourceHandler {

    private static final String accessorName = "distributed-accessor";
    private static final String spaceName = "distributed-space";

    public SpacesResource(final Stage stage) {
        super(stage);
    }

    private Completes<Response> get(String key) {
        Accessor accessor = Accessor.named((Grid) stage(), accessorName);
        if (accessor.isNotDefined()) {
            accessor = Accessor.using((Grid) stage(), accessorName);
        }

        Space space = accessor.distributedSpaceFor(spaceName);
        return space.get(new Key1(key), Period.None)
                .andThen(keyItem1 -> keyItem1
                        .map(keyItem2 -> Response.of(Response.Status.Ok, (String) keyItem2.object))
                        .orElse(Response.of(Response.Status.NotFound)));
    }

    private Completes<Response> put(SpaceData data) {
        Accessor accessor = Accessor.named((Grid) stage(), accessorName);
        if (accessor.isNotDefined()) {
            accessor = Accessor.using((Grid) stage(), accessorName);
        }

        Space space = accessor.distributedSpaceFor(spaceName);
        final Key1 key1 = new Key1(data.key);

        return space.put(key1, Item.of(data.value, Lease.Forever))
                .andThen(item -> Response.of(Response.Status.Ok));
    }

    private Completes<Response> delete(String key) {
        Accessor accessor = Accessor.named((Grid) stage(), accessorName);
        if (accessor.isNotDefined()) {
            accessor = Accessor.using((Grid) stage(), accessorName);
        }

        Space space = accessor.distributedSpaceFor(spaceName, 1, Duration.ofMillis(1_000));
        Completes<Optional<KeyItem<Object>>> takeCompletes = space.take(new Key1(key), Period.None);

        return takeCompletes
                .andThen(keyItem1 -> keyItem1
                        .map(keyItem2 -> Response.of(Response.Status.Ok, (String) keyItem2.object))
                        .orElse(Response.of(Response.Status.NotFound)));
    }

    @Override
    public Resource<?> routes() {
        return ResourceBuilder.resource("Distributed Spaces",
                ResourceBuilder.get("/spaces/{key}")
                        .param(String.class)
                        .handle(this::get),
                ResourceBuilder.post("/spaces")
                        .body(SpaceData.class)
                        .handle(this::put),
                ResourceBuilder.delete("/spaces/{key}")
                        .param(String.class)
                        .handle(this::delete));
    }
}
```

Try it for yourself. You can start with the [xoom-distributed-spaces](https://github.com/vlingo/xoom-examples/tree/master/xoom-distributed-spaces) example project and make changes, and then build your own distributed data grid/fabric microservice.


# Projections

The XOOM LATTICE way to project state, Domain Events, and other Source types into a CQRS Query Model.

Projections are an important part of the component set required to support [CQRS](https://kalele.io/really-simple-cqrs/), whether or not you are using Event Sourcing. Recall that in CQRS there are two models, one called the *Command Model* and another called the *Query Model.*&#x20;

{% hint style="info" %}
The *Command Model* is often referred to as the "Write Model" and the *Query Model* as the "Read Model." These AKAs are quite inaccurate because you actually read from and write to both models. We prefer the names *Command Model* and *Query Model* because these adhere to the pattern name, CQRS, and express the purpose of each of the two models.
{% endhint %}

A projection is a component that takes one set of states and transforms those into another state. This is typically how it works:

1. The Command Model causes a state mutation and emits one or more Domain Events
2. The new Domain Events are persisted into a `Journal`
3. The emitted Domain Events are dispatched/routed to a set of Projection components based on their interest in a given Domain Event type
4. The Projection components interpret how each Domain Event should be reflected into the portion of the Query Model for which they are responsible, and project that interpretation into the persistent Query Model

In all of the above steps, you can replace "Domain Event" with "entity state," because you may decide not to use Domain Events in your Command Model. In other words, the full state of a Command Model entity may be interpreted for projection into the Query Model. Of course if you use Event Sourcing you will always project Domain Events into the Query Model.

![The upper area of the diagram shows Events being projected into the Query Model.](/files/-MLvCn8FR3OXjMbWLboq)

With the **XOOM LATTICE** projection components, we provide the means to project an entity's state and various concrete `Source<?>` types—`DomainEvent` and `Command`, for example—into a CQRS query model.

There are two steps required to use projections. You must implement one or more projections and you must configure those projections to be used within your service/application. These two topics are covered below.

## Projection Set Up and Configuration

The components used to manage the data filtering, routing, and the actual projections, must be created. The following are the component types.

1. The `ProjectToDescription` is a description of how data and events are filtered and selected. You may configure a `ProjectToDescription` for projecting `State<T>` and also for projecting `Source<T>` instances, such as `DomainEvent` types. Both are described below.
2. The `Dispatcher` and `ProjectionDispatcher` to be registered with the storage mechanism is created by means of an actor that implements both protocols. Two such are the `BinaryProjectionDispatcherActor` and `TextProjectionDispatcherActor`, and used when a binary store or text store is used, respectively.
3. The store is created and `Dispatcher` registered with it.

The following describes each of the above steps.

### `ProjectToDescription` for `State<T>`

A `ProjectToDescription` may be defined for state data and for events. The following shows a description defined for a state object.

```java
import io.vlingo.lattice.model.projection.ProjectionDispatcher.ProjectToDescription;

ProjectToDescription userProjectTo =
  ProjectToDescription.with(
    UserProjectionActor.class,
    "User:new", "User:contact", "User:name");
```

State data may have associated `Metadata`, and the `Metadata` instance may have a named `operation` that caused the state to transition to the current value. The above description indicates that if the state data contains an `operation` that matches `"User:new"`, `"User:contact"`, or `"User:name"`, the dispatcher will route the data to the `UserProjectionActor`.

The following demonstrates how the `operation` name is associated with the new state. In this case the command is to replace the user's name with a different name. The transitioned state and the descriptive operation is applied. After the state is persisted, the `Dispatcher` is given the opportunity to route the new state to a projection. As seen in the description of the previous code snippet, matching the `"User:name"` operation will cause the new state to be routed to the `UserProjectionActor`.

```java
  @Override
  public void withName(final Name name) {
    return apply(state.withName(name), "User:name");
  }
```

We provide a [comprehensive example](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-http-frontservice/src/main/java/io/vlingo/frontservice/infra/projection) of using this full-state projection technique, known as the [***vlingo-http-frontservice***](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-http-frontservice)*.*

### `ProjectToDescription` for `Source<T>`

A `ProjectToDescription` may be defined for state data and for events. The following shows a description defined for events.

```java
import io.vlingo.lattice.model.projection.ProjectionDispatcher.ProjectToDescription;

ProjectToDescription forumProjectTo =
  ProjectToDescription.with(
    ForumProjectionActor.class,
    ForumStarted.class, ForumClosed.class, ForumModeratorAssigned.class);
```

The above description indicates that if a concrete `DomainEvent` is one of the types `ForumStarted`, `ForumClosed`, or `ForumModeratorAssigned`, the dispatcher will route the event to the `ForumProjectionActor`.

The following demonstrates how the `ForumStarted` event occurs. After the event is persisted, the `Dispatcher` is given the opportunity to route it to a projection. As seen in the description of the previous code snippet, matching the `ForumStarted` event will cause it to be routed to the `ForumProjectionActor`.

```java
public void startForum(Moderator moderator, String topic, String description) {
  apply(new ForumStarted(moderator, topic, description));
}
```

Note however that keeping the `ProjectToDescription` up to date with new and changing event types could be error prone by being overlooked. Instead of referencing each event type, you may instead reference the Java package that contains all of the events.

```java
ProjectToDescription forumProjectTo =
  ProjectToDescription.with(
    ForumProjectionActor.class,
    ForumStarted.class.getPackage());
```

### `Dispatcher` and `ProjectionDispatcher`

The following demonstrates how the `ProjectToDescription`, `Dispatcher`, `ProjectionDispatcher`, `TextProjectionDispatcherActor`, and `Journal` are wired for use.

```java
import io.vlingo.actors.Protocols;
import io.vlingo.lattice.model.projection.ProjectionDispatcher.ProjectToDescription;
import io.vlingo.lattice.model.projection.TextProjectionDispatcherActor;
import io.vlingo.symbio.store.journal.Journal;
import io.vlingo.symbio.store.journal.jdbc.JDBCJournalActor;

List<ProjectToDescription> descriptions = Arrays.asList(forumProjectTo);

Protocols dispatcherProtocols =
  world.stage().actorFor(
    new Class<?>[] { Dispatcher.class, ProjectionDispatcher.class },
    Definition.has(TextProjectionDispatcherActor.class, descriptions));

Protocols.Two<Dispatcher, ProjectionDispatcher> dispatchers =
  Protocols.two(dispatcherProtocols);

Journal journal =
  Journal.using(world.stage(), JDBCJournalActor.class,
    dispatchers._1, configuration);
```

You may want to have an isolated component to configure your projections, such as this `ProjectionDispatcherProvider` example.

```java
package com.dashdawn.infra.projections;

import java.util.Arrays;
import java.util.List;

import io.vlingo.actors.Definition;
import io.vlingo.actors.Protocols;
import io.vlingo.actors.Stage;
import io.vlingo.lattice.model.projection.ProjectionDispatcher;
import io.vlingo.lattice.model.projection.ProjectionDispatcher.ProjectToDescription;
import io.vlingo.lattice.model.projection.TextProjectionDispatcherActor;
import io.vlingo.symbio.store.dispatch.Dispatcher;

@SuppressWarnings("rawtypes")
public class ProjectionDispatcherProvider {
  private static ProjectionDispatcherProvider instance;

  public final ProjectionDispatcher projectionDispatcher;
  public final Dispatcher storeDispatcher;

  public static ProjectionDispatcherProvider instance() {
    return instance;
  }

  public static ProjectionDispatcherProvider using(final Stage stage) {
    if (instance != null) return instance;

    final List<ProjectToDescription> descriptions =
            Arrays.asList(
                    new ProjectToDescription(DashboardProjectionActor.class, com.dashdawn.model.dashboard.Events.class.getPackage()),
                    new ProjectToDescription(WaveBoardDetailsProjectionActor.class, com.dashdawn.model.waveboard.Events.class.getPackage()),
                    new ProjectToDescription(ProfileProjectionActor.class, "Profile:new", "Profile:twitter", "Profile:linkedIn", "Profile:website"));

    final Protocols dispatcherProtocols =
            stage.actorFor(
                    new Class<?>[] { Dispatcher.class, ProjectionDispatcher.class },
                    Definition.has(TextProjectionDispatcherActor.class, Definition.parameters(descriptions)));

    final Protocols.Two<Dispatcher, ProjectionDispatcher> dispatchers = Protocols.two(dispatcherProtocols);

    instance = new ProjectionDispatcherProvider(dispatchers._1, dispatchers._2);

    return instance;
  }

  private ProjectionDispatcherProvider(final Dispatcher storeDispatcher, final ProjectionDispatcher projectionDispatcher) {
    this.storeDispatcher = storeDispatcher;
    this.projectionDispatcher = projectionDispatcher;
  }
}
```

There are three primary objects created.

1. Notable are the three `ProjectToDescription` instances created, which are formed into a single `List<ProjectToDescription>`. Each of the descriptions indicate how various command model changes will be dispatched into the actor instance whose type is the first parameter. For example, this `DashboardProjectionActor` instance will be created inside the `ProjectionDispatcher` and all `DomainEvent` types defined as inner classes of the `com.dashdawn.model.dashboard.Events` class, will be dispatched to it. The same goes for the `WaveBoardDetailsProjectionActor` and the inner `Events` types defined in its package.
2. The `descriptions` are then used to create the `ProjectionDispatcher`, which is implemented by the `TextProjectionDispatcherActor` provided by **XOOM LATTICE.** Actually this actor implements two protocols, both the `Dispatcher` and the `ProjectionDispatcher`. The `Dispatcher` is used by the `Journal` to dispatch newly appended events to the `ProjectionDispatcher`. (This is implemented by the abstract base `ProjectionDispatcherActor`, which is extended by the concrete actors, `TextProjectionDispatcherActor` and `BinaryProjectionDispatcherActor`). The two protocol references answered by `actorFor()` are captured in the `Protocols` type.
3. Lastly the `ProjectionDispatcherProvider` instance is created, where both protocol references are held and available to dependents.

### Configuring the Dispatcher

The following is an example of how the `Dispatcher` is used, where the command model storage will use it to dispatch events into the projections. Note that the command model store knows nothing about projections, only the `Dispatcher`.

```java
ProjectionDispatcherProvider projectionDispatcherProvider =
  ProjectionDispatcherProvider.using(world.stage());

CommandModelStoreProvider commandModelStoreProvider =
  CommandModelStoreProvider
      .using(
          world.stage(),
          registry,
          projectionDispatcherProvider.storeDispatcher);
```

The above code may be placed in your `Bootstrap` or `Startup` class containing a `main()`.

## Implementing With the `Projection` Interface

The following is an example of a `Projection` designed to handle state mutation operations. It corresponds to the above section **`ProjectToDescription` for `State<T>`**.

```java
public class UserProjectionActor extends Actor implements Projection {
  ...
  @Override
  public void projectWith(Projectable projectable, ProjectionControl control) {
    User.UserState state = projectable.object();
    UserData current = UserData.from(state);
    Confirmer confirmer = control.confirmerFor(projectable);

    switch (projectable.becauseOf()[0]) {
      case "User:new":
        ...
        break;
      case "User:contact":
        ...
        break;
      case "User:name":
        ...
        break;
    }

    confirmer.confirm();
  }
}
```

The `Projectable` contains the data to be projected. The `ProjectionControl` is used to confirm that the `Projectable` has been projected so that the `Dispatcher` will not route it again. The code inside each of the cases would create or update the views effected by the state mutations.

The full example of the above projection approach is in the [`xoom-http-frontservice`](https://github.com/vlingo/xoom-examples/tree/master/xoom-http-frontservice).

The following is an example of a `Projection` designed to handle events. This example corresponds to the above section **`ProjectToDescription` for `Source<T>`**.

```java
public static class ForumProjectionActor extends Actor implements Projection {
  ...
  @Override
  public void projectWith(final Projectable projectable, final ProjectionControl control) {
    projectable.entries().forEach(entry -> {
      switch (entry.typed().getSimpleName()) {
      case "ForumStarted":
        ...
        break;
      case "ForumClosed":
        ...
        break;
      case "ForumModeratorAssigned":
        ...
        break;
      }
    });
    
    control.confirmProjected(projectable.projectionId());
  }
}
```

Since there may be one or more events that were applied, persisted, dispatched, and routed to the projection, the projection must iterate over all entries so as not to miss any. The code inside each of the cases would create or update the views effected by the events. A much cleaner approach follows.

## Implementing With the `StateStoreProjectionActor`

There is an `Actor` abstract base type for this: `StateStoreProjectionActor`. This is a much more powerful abstract than directly using the `Projection` interface. As the name indicates, this projection base is used to project into a [`StateStore`](/xoom-symbio/state-storage).

{% hint style="info" %}
Since object-relational mapping and other object persistence approaches are less efficient than key-value stores, we have decided not to support ORM-based projections at this time.
{% endhint %}

Here is the a condensed code listing of the `StateStoreProjectionActor`.

```java
package io.vlingo.lattice.model.projection;

public abstract class StateStoreProjectionActor<T> extends Actor
    implements Projection ... {

  private final List<Source<?>> adaptedSources;
  private final EntryAdapter<Source<?>, Entry<?>> entryAdapter;
  private final StateAdapter<Object, State<?>> stateAdapter;
  private final ReadResultInterest readInterest;
  private final WriteResultInterest writeInterest;
  private final StateStore stateStore;

  public StateStoreProjectionActor(final StateStore stateStore) {
    this(stateStore, defaultTextStateAdapter(), defaultTextEntryAdapter());
  }
  
  public StateStoreProjectionActor(
          final StateStore stateStore,
          final StateAdapter<Object, State<?>> stateAdapter,
          final EntryAdapter<Source<?>, Entry<?>> entryAdapter) {

    this.stateStore = stateStore;
    this.stateAdapter = stateAdapter;
    this.entryAdapter = entryAdapter;
    this.readInterest = selfAs(ReadResultInterest.class);
    this.writeInterest = selfAs(WriteResultInterest.class);

    this.adaptedSources = new ArrayList<>(2);
  }

  public void projectWith(final Projectable projectable, final ProjectionControl control) {
    upsertFor(projectable, control);
  }

  protected boolean alwaysWrite() {
    return true;
  }

  protected T currentDataFor(final Projectable projectable) {
    return projectable.object();
  }

  protected int currentDataVersionFor(final Projectable projectable, final T previousData, final int previousVersion) {
    return alwaysWrite() ? projectable.dataVersion() : (previousVersion == -1 ? 1 : (previousVersion + 1));
  }

  protected String dataIdFor(final Projectable projectable) {
    String dataId = projectable.dataId();

    if (dataId.isEmpty()) {
      try {
        dataId = typedToIdentifiedDomainEvent(sources().get(0)).identity();
      } catch (Exception e) {
        // ignore; fall through
      }
    }

    return dataId;
  }

  protected <S extends Source<?>, E extends Entry<?>> EntryAdapter<S,E> entryAdapter() {
    return (EntryAdapter<S,E>) this.entryAdapter;
  }

  // Override if using full-state projections
  protected T merge(final T previousData, final int previousVersion, final T currentData, final int currentVersion) {
    return currentData;
  }

  // Override if using Event Sourcing projections
  protected T merge(final T previousData, final int previousVersion, final T currentData, final int currentVersion, final List<Source<?>> sources) {
    return merge(previousData, previousVersion, currentData, currentVersion);
  }

  protected void prepareForMergeWith(final Projectable projectable) {
    adaptedSources.clear();

    for (Entry <?> entry : projectable.entries()) {
      adaptedSources.add(entryAdapter.anyTypeFromEntry(entry));
    }
  }

  protected List<Source<?>> sources() {
    return adaptedSources;
  }

  protected <ST extends State<?>> StateAdapter<?,ST> stateAdapter() {
    return (StateAdapter<?,ST>) this.stateAdapter;
  }

  protected void upsertFor(final Projectable projectable, final ProjectionControl control) {
    ...
  }

  protected <S> S typed(final Object state) {
    return (S) state;
  }

  protected <E> E typed(final DomainEvent event) {
    return (E) event;
  }

  protected <E> E typed(final Source<?> source) {
    return (E) source;
  }

  protected IdentifiedDomainEvent typedToIdentifiedDomainEvent(final Source<?> source) {
    return (IdentifiedDomainEvent) source;
  }
}
```

{% hint style="info" %}
In the following documentation we explain a number of available overridable base class methods. Note that these are all optional, except that one of the two `merge(...)` methods should be overridden.

Override the following method if you are performing full-state projections:

`protected T merge(`\
&#x20;   `final T previousData,`\
&#x20;   `final int previousVersion,`\
&#x20;   `final T currentData,`\
&#x20;   `final int currentVersion)`

Override the following method if you are performing projections for Event Sourcing:

`protected T merge(`\
&#x20;   `final T previousData,`\
&#x20;   `final int previousVersion,`\
&#x20;   `final T currentData,`\
&#x20;   `final int currentVersion,`\
&#x20;   `final List> sources)`

The default implementation behaviors of all non-merge methods will very likely serve your needs fully.
{% endhint %}

To create a new type of projection, extend `StateStoreProjectionActor`, as demonstrated next. This example overrides the `merge(...)` that is best used with Event Sourcing.

```java
package com.dashdawn.infra.projections.dashboard;

import static com.dashdawn.model.dashboard.Events;

import io.vlingo.lattice.model.DomainEvent;
import io.vlingo.lattice.model.IdentifiedDomainEvent;
import io.vlingo.lattice.model.projection.Projectable;
import io.vlingo.lattice.model.projection.StateStoreProjectionActor;
import io.vlingo.symbio.Entry;

public class DashboardProjectionActor extends StateStoreProjectionActor<ControllerView> {
  private static final DashboardView Empty = new DashboardView();

  public DashboardProjectionActor() {
    super(QueryModelStoreProvider.instance().store);
  }

  @Override
  protected DashboardView merge(
          final DashboardView previousData,
          final int previousVersion,
          final DashboardView currentData,
          final int currentVersion,
          final List<Source<?>> sources) {

   final DashboardView view  =
           previousData == null
                ? currentData
                : previousData;

    for (final Source<?> event : sources) {
      switch (match(event)) {
      case DashboardDefined:
        final DashboardDefined defined = typed(event);
        view.id = defined.id;
        view.title = defined.title;
        view.summary = defined.summary;
        view.status = Status.Inactive.name();
        break;
      case DashboardStreamed:
        final DashboardStreamed streamed = typed(event);
        view.streamValue = streamed.value;
        view.status = Status.Streaming.name();
        break;
      case DashboardStreamHalted:
        final DashboardStreamHalted halted = typed(event);
        view.previousStreamValue = view.streamValue;
        view.streamValue = "";
        view.status = Status.Halted.name();
        break;
      case DashboardStreamRestarted:
        final DashboardStreamRestarted restarted = typed(event);
        view.streamValue = view.previousStreamValue;
        view.status = Status.Restarted.name();
        break;
      case WaveBoardOpened:
        final WaveBoardOpened opened = typed(event);
        view.waveBoardName = opened.name;
        view.waveBoardDevicePort = opened.port;
        view.waveBoardCalibration = opened.calibration;
        view.status = Status.WaveBoardOpened.name();
        break;
      case ...
      case ...
      case ...
      case Unmatched:
        logger().warn("Event of type " + event.typeName() + " was not matched.");
        break;
      }
    }
    return view;
  }

  private DashboardView match(final DomainEvent event) {
    try {
      return DashboardViewProjectableType.valueOf(event.typeName());
    } catch (Exception e) {
      return DashboardViewProjectableType.Unmatched;
    }
  }
}
```

This projection is next examined in detail, starting with the constructor.

```java
  public DashboardProjectionActor() {
    super(QueryModelStoreProvider.instance().store);
  }
```

The `DashboardProjectionActor` constructor uses the super constructor that takes only the `StateStore` used to write and read `DashboardView` instances.  This single-parameter constructor provides a default `StateAdapter` and `EntryAdapter` for the concrete projection to use. These are part of **XOOM SYMBIO**  and are known as [`DefaultTextStateAdapter`](https://docs.vlingo.io/vlingo-symbio/adapters#default-adapters) and [`DefaultTextEntryAdapter`](https://docs.vlingo.io/vlingo-symbio/adapters#default-adapters).

```java
  public StateStoreProjectionActor(final StateStore stateStore) {
    this(stateStore, defaultTextStateAdapter(), defaultTextEntryAdapter());
  }
```

There is a second constructor for `StateStoreProjectionActor` that takes an additional two parameters, one for the `StateAdapter` and one for the `EntryAdapter`.&#x20;

```java
  public StateStoreProjectionActor(
          final StateStore stateStore,
          final StateAdapter<Object, State<?>> stateAdapter,
          final EntryAdapter<Source<?>, Entry<?>> entryAdapter) {
    ...
  }
```

These adapters are used to adapt from persistent `State` and `Entry` types to the model types. When the single argument constructor is used you get the default `StateAdapter` and `EntryAdapter`.&#x20;

{% hint style="info" %}
Since there is only one `EntryAdapter` supported, but no doubt several or many `DomainEvent` types needed, your own custom `EntryAdapter` must internally hold the full number of `EntryAdapter` instances needed for all `DomainEvent` types. This might use a `Map` with keys of `Class<? extends DomainEvent>` and values of concrete `EntryAdapter` instances. The outer `EntryAdapter` registered with the `StateStoreProjectionActor` would operate by looking up the specific concrete `EntryAdapter` by `DomainEvent` type, dispatch to it, and answer its return value.
{% endhint %}

The `DashboardProjectionActor` implements the `Projection` protocol, but there is a default implementation of method `projectWith()` provided by the abstract base class`StateStoreProjectionActor`. The implementation of this method is quite simple for most uses. If you need a more involved implementation you may override the default provided by the abstract base class.

```java
  public void projectWith(final Projectable projectable, final ProjectionControl control) {
    upsertFor(projectable, control);
  }
```

The simple step is to "upsert" (i.e. insert or update, depending on existence) to current `Projectable`, which may hold a state, or entries, or both.

```java
  protected void upsertFor(final Projectable projectable, final ProjectionControl control) {
    final T currentData = currentDataFor(projectable);

    prepareForMergeWith(projectable);

    final String dataId = dataIdFor(projectable);

    final BiConsumer<T,Integer> upserter = (previousData, previousVersion) -> {
      final int currentDataVersion = currentDataVersionFor(projectable, previousData, previousVersion);
      final T data = merge(previousData, previousVersion, currentData, currentDataVersion, sources());
      final Confirmer confirmer = ProjectionControl.confirmerFor(projectable, control);
      if (alwaysWrite() || !data.equals(previousData)) {
        stateStore.write(dataId, data, currentDataVersion, writeInterest, confirmer);
      } else {
        confirmProjection(confirmer);
      }
    };

    stowMessages(ReadResultInterest.class, WriteResultInterest.class);

    stateStore.read(dataId, currentData.getClass(), readInterest, upserter);
  }
```

The `upsertFor()` does the following.

1. Asks `currentDataFor(projectable)` for its notion of the current state, as in the state that is now being projected. You may override `currentDataFor(projectable)`. This may or may not be useful, but if it is, you must return the value that is considered current from the `Projectable`. This method is generally used only for full-state projections rather than those based on `DomainEvent` instances.
2. Requests that the projection `prepareForMergeWith()`. The default behavior adapts any `entries()` in the `Projectable` to `Source<?>` instances, holding them in an internal `List<Source<?>>`. The concrete extender may get the adapted `Source<?>` instances using the `sources()` method. These are provided by default with the second `merge(...)` method that is used for Event Sourcing projections. If you have some alternative or additional preparation to do before the merge this method must be overridden.
3. Reads the current `T` value from the `StateStore` (see the last statement in the method) and passes a `BiConsumer<T, Integer> upserter`. When the read completes, the `upserter` is used to merge the `previousData` with the `currentData` and/or apply any `Source<?>` instances.
4. Writes the merged state back to the `StateStore` if `alwaysWrite()` is `true` or if the newly merged data is not equal to the previous data. This happens inside the `upserter`.

The `DashboardProjectionActor` implements `currentDataFor()` as follows.

```java
public class DashboardProjectionActor extends StateStoreProjectionActor<ControllerView> {
  private static final DashboardView Empty = new DashboardView();

  ...

  protected DashboardView currentDataFor(final Projectable projectable) {
    return Empty;
  }

  ...
}
```

As previously indicated, the `currentDataFor()` may or may not be useful in terms of providing a new state. This implementation answers an `Empty` instance of the `DashboardView`, which will be used by the `merge()` as an accumulator of modifications. This particular override example is unnecessary but demonstrates an alternative to the default implementation. Assume that we decide not to implement the above override and remove the `Empty` value declaration as well as the `currentDataFor()` method override.

If you are not projecting from events, but the full state of the domain object, an implementation of `currentDataFor()` and `merge()` similar to the [previous section is necessary](/xoom-lattice/projections#implementing-with-the-projection-interface).

Next the `DashboardProjectionActor` is given the opportunity to prepare for the merge.

```java
public class ControllerProjectionActor extends StateStoreProjectionActor<ControllerView> {
  private String dataId;
  private final List<IdentifiedDomainEvent> events;

  ...
  
  @Override
  protected void prepareForMergeWith(final Projectable projectable) {
    events.clear();

    for (Entry <?> entry : projectable.entries()) {
      events.add(entryAdapter().anyTypeFromEntry(entry));
    }
  }
  
  ...
}
```

In this implementation the `prepareForMergeWith()` adapts all `Entry` instances into instances of the `DomainEvent` specialization `IdentifiedDomainEvent`.  This gives the concrete event types the means to provide the identity of the event instance. As indicated above, this specific implementation of `prepareForMergeWith()` is redundant because it does the same that the default behavior already does. You would choose to override `prepareForMergeWith()` only if you required behavior beyond the above implementation.

Immediately following `prepareForMergeWith()` the `upsert()` calls `dataIdFor()`.

```java
  @Override
  protected String dataIdFor(final Projectable projectable) {
    dataId = events.get(0).identity();
    return dataId;
  }
```

As seen above, the `dataId` is provided by the first (and possibly only) instance of the `IdentifiedDomainEvent` in the `events` list. Recall that this `events` list was just previously populated by the `prepareForMergeWith()`. This example `dataIdFor()` method override is likely redundant because the default behavior provides a more thorough implementation, first checking for the `Projectable dataId()`, and if that is not available, looks for the identity from one of the first `IdentifiedDomainEvent`. If neither of these are available then the `dataId` will be a blank `String`, and an override of this method would be necessary to provide a custom value.

If you are using the default implementation of `prepareForMergeWith()`, the source/event instances are retrieved as follows. Here again, your `DomainEvent` instances must be of the extends `IdentifiedDomainEvent` type, which can provide the `identity()` of the entity that emitted them.

```java
  protected String dataIdFor(final Projectable projectable) {
    String dataId = projectable.dataId();

    if (dataId.isEmpty()) {
      try {
        dataId = typedToIdentifiedDomainEvent(sources().get(0)).identity();
      } catch (Exception e) {
        // ignore; fall through
      }
    }

    return dataId;
  }
```

The following is the `DashboardProjectionActor` implementation of `merge()` and its helper method `mergeInto()`, assuming that the `prepareForMergeWith()` was also overridden and a local `List<DomainEvent>` of `events` was collected by it. This example shows an alternative to using the more appropriate `merge(...)` override that provides the `List<Source<?>>` parameter.

```java
public class DashboardProjectionActor extends StateStoreProjectionActor<ControllerView> {
  private static final DashboardView Empty = new DashboardView();

  private final List<IdentifiedDomainEvent> events;
  private Projectable projectable;

  ...

  @Override
  protected DashboardView merge(
          final DashboardView previousData,
          final int previousVersion,
          final DashboardView currentData,
          final int currentVersion) {

    return mergeInto(currentData);
  }

  ...
  
  @Override
  protected void prepareForMergeWith(final Projectable projectable) {
    events.clear();

    for (Entry <?> entry : projectable.entries()) {
      events.add(entryAdapter().anyTypeFromEntry(entry));
    }
  }

  private DashboardView mergeInto(final DashboardView view) {
    for (final DomainEvent event : events) {
      switch (match(event)) {
      case DashboardDefined:
        final DashboardDefined defined = typed(event);
        view.id = defined.id;
        view.title = defined.title;
        view.summary = defined.summary;
        view.status = Status.Inactive.name();
        break;
      case DashboardStreamed:
        final DashboardStreamed streamed = typed(event);
        view.streamValue = streamed.value;
        view.status = Status.Streaming.name();
        break;
      case DashboardStreamHalted:
        final DashboardStreamHalted halted = typed(event);
        view.streamValue = "";
        view.status = Status.Halted.name();
        break;
      case DashboardStreamRestarted:
        final DashboardStreamRestarted restarted = typed(event);
        view.streamValue = streamed.value;
        view.status = Status.Restarted.name();
        break;
      case WaveBoardOpened:
        final WaveBoardOpened opened = typed(event);
        view.waveBoardName = opened.name;
        view.waveBoardDevicePort = opened.port;
        view.waveBoardCalibration = opened.calibration;
        view.status = Status.WaveBoardOpened.name();
        break;
      case ...
      case ...
      case ...
      case Unmatched:
        logger().warn("Event of type " + event.typeName() + " was not matched.");
        break;
      }
    }
    return view;
  }

  ...
}
```

The `merge()` passes the `currentData` to be used by `mergeInto()` as an accumulator of the new state. Any preexisting state on the `currentData` that coincides with the interpretation of the `DomainEvent` will be overwritten/replaced.

Because the `Projectable` may have multiple entries (serialized `DomainEvent` instances), the `mergeInto()` iterates over the entire collection of events deserialized by the method `prepareForMergeWith()`.

Assuming you are using the default `prepareForMergeWith()` implementation, you would iterate as follows, using the `sources()` method rather than a collection that you gathered on your own.

```java
  ...
  
  private DashboardView mergeInto(final DashboardView view) {
    for (final Source<?> event : sources()) {
      switch (match(event)) {
      case DashboardDefined:
        final DashboardDefined defined = typed(event);
        ...
      case DashboardStreamed:
        final DashboardStreamed streamed = typed(event);
        ...
      }
    }
    return view;
  }
  
  ...
```

The `switch` uses an `enum` of `DashboardViewProjectableType` to match on each of the `DomainEvent` instances.

```java
public enum DashboardViewProjectableType {
  DashboardDefined,
  DashboardStreamed,
  DashboardStreamHalted,
  DashboardStreamRestarted,
  WaveBoardOpened,
  
  Unmatched
}
```

&#x20;The `DomainEvent` type is matched to the enum by the `match()` method. A non-match produces the `Unmatched` type, which is ignored by `mergeInto()`, but logged as a warning.

```java
  private DashboardView match(final DomainEvent event) {
    try {
      return DashboardViewProjectableType.valueOf(event.typeName());
    } catch (Exception e) {
      return DashboardViewProjectableType.Unmatched;
    }
  }
```

Once a specific type is matched, the `mergeInto()` maps event attributes to `DashboardView` attributes. Any preexisting values that are mapped are overwritten on the `view` accumulator. The iteration and matching is done for any number of events, which may be included with the current `Projectable` or others received in the future.&#x20;

```java
      case DashboardDefined:
        final DashboardDefined defined = typed(event);
        view.id = defined.id;
        view.title = defined.title;
        view.summary = defined.summary;
        view.status = Status.Inactive.name();
        break;
```

{% hint style="info" %}
Note that the design of the `DashboardView` to directly use public mutable attributes was done to keep the implementation simple, albeit somewhat "dangerous" according to opinions. It doesn't seem like a bad thing in this specific case because the view object is used in very specific limited ways. Feel free to include accessor methods for reading and writing in your designs.
{% endhint %}

When the `merge()` completes, the modified `DashboardView` is written to the `StateStore`.

### Specialized Data Versions and Updates

The `StateStoreProjectionActor<T>` provides a default means to determine the current version of the data to be merged and then updated to the database. It works like this:

```java
Given: Projectable projectable

Version: projectable.dataVersion()
```

In other words, by default the data version provided by the `Projectable` is used as the version for the current data to be merged and updated to the database. This is how all of the above examples obtain the current data version for inserts/updates. It is based on a policy to always update the current merged data. That is, the data is always written no matter whether it is the same as the previous data, or different.

Yet, in some cases you may want to use a different versioning policy and also conditionally write the newly merged data instance only if it is different from the previous data. This is useful for idempotent operations, such as when the `Projectable` is redelivered due to a latent or failed delivery confirmation. In such cases the `StateStoreProjectionActor<T>` provides a secondary policy, which is to automatically increment the previous version by one and to also test the current merged data with the previous data to qualify the need to update the data to the database.

To use the secondary policy, you should override the `alwaysWrite()` method. By default it returns `true`. Your override should return `false` instead.

```java
public abstract class StateStoreProjectionActor<T> extends Actor ...
  ...
  @Override
  protected boolean alwaysWrite() {
    return false; // only write changed data
  }
  ...
```

The second method involved in the policy is `currentDataVersionFor()`, which you *need not override* if the secondary policy works for your specific projection use case.

```java
public abstract class StateStoreProjectionActor<T> extends Actor ...
  ...
  protected int currentDataVersionFor(final Projectable projectable, final T previousData, final int previousVersion) {
    return alwaysWrite() ? projectable.dataVersion() : (previousVersion == -1 ? 1 : (previousVersion + 1));
  }
  ...
```

As you can see, the `currentDataVersionFor()` provides both policies in one line of code. If `alwaysWrite()` answers `true`, the `projectable.dataVersion()` is returned as was explained above. Otherwise, when `alwaysWrite()` answers `false`, the next sequential version from the one previously stored in the databased is returned. Note that in the case where there was no previous data in the database for the given identity, the `previousVersion` is `-1`. Thus, there is the one special case where `1` must be explicitly returned as the initial version.

As previously indicated, using the secondary version and write policy is useful when your use case must be idempotent. Yet, there is another case to consider. If you are projecting multiple entity states and/or events into a single projection data instance, the versions from the various instances will almost certainly collide with each other.

For example, `ProductDefined` from one `Product` entity will have version `1`, and `ProductDefined` from a different `Product` entity will also have version `1`. This is unavoidable because `ProductDefined` is always the first event emitted from a `Product`. If you attempt to merge the `ProductDefined` that is delivered after the first initially delivered `ProductDefined`, the merged/updated data will have version `1` just as the previous data did. Writing this version will cause an optimistic concurrency violation in the `StateStore`, because the version will make the new data look as if it is based on stale state. By overriding `alwaysWrite()` to answer `false`, your current/merged data version will always be one greater than the previous data version.

But what about the idempotent check? In the case where `alwaysWrite()` answers `false`, there will be a pre-update check requiring the current data to be different from the previous data.

```java
public abstract class StateStoreProjectionActor<T> extends Actor ...
  ...
  protected void upsertFor(final Projectable projectable, final ProjectionControl control) {
    final T currentData = currentDataFor(projectable);

    prepareForMergeWith(projectable);

    final String dataId = dataIdFor(projectable);

    final BiConsumer<T,Integer> upserter = (previousData, previousVersion) -> {
      final int currentDataVersion = currentDataVersionFor(projectable, previousData, previousVersion);
      final T data = merge(previousData, previousVersion, currentData, currentDataVersion, sources());
      final Confirmer confirmer = ProjectionControl.confirmerFor(projectable, control);
      if (alwaysWrite() || !data.equals(previousData)) {
        stateStore.write(dataId, data, currentDataVersion, writeInterest, confirmer);
      } else {
        confirmProjection(confirmer);
      }
    };

    stowMessages(ReadResultInterest.class, WriteResultInterest.class);

    stateStore.read(dataId, currentData.getClass(), readInterest, upserter);
  }
  ...
```

Notice specifically this statement.

```java
      ...
      if (alwaysWrite() || !data.equals(previousData))
      ...
```

The data difference check is managed by using the `equals()` of the data's type. The updating write is performed only when the current and previous data are not equal. Note that the `equals()` implementation must check for value equality (compare type equality as well as equality of all corresponding data attributes/fields) rather than entity equality (compare ids only).


# Routers

Use routers to offload command and event dispatching toward an eventual outcome.

Message-driven command routing to handlers offloads the responsibility of dispatching potential effects to the domain model. When using CQRS the model is known as the Command Model or Write Model.

The following shows a fully asynchronous/concurrent command routing component available with XOOM Lattice.

See the package `io.vlingo.xoom.lattice.router`:

| Type                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CommandRouter`                              | <p>The interface protocol for command routers. Provides a static factory method to create any of three types of routers:<br></p><ul><li><code>LoadBalancingCommandRouter</code></li><li><code>PartitioningCommandRouter</code></li><li><code>RoundRobinCommandRouter</code></li></ul><p>All concrete <code>CommandRouter</code> types must implement this protocol:</p><p> <code>void route(final RoutableCommand command)</code></p>                                         |
| `CommandDispatcher<P, C extends Command, A>` | All commands routed through a `CommandRouter` must implement the `CommandDispatcher` interface. The `P` is the type name of the protocol to which the command will be sent. The `C` is the type name of *this* command type, which must be a subclass of `io.vlingo.xoom.lattice.model.Command`. The `A` is the answer type to be provided by the command, and is normally a `Completes<T>` where `T` is the type to be answered asynchronously.                              |
| `RoutableCommand`                            | A command to be routed through a defined `CommandRouter`. This is a standard container for a concrete command type. In other words, create a command type, such as `Rename`, that implements the protocol `CommandDispatcher` and instantiate a new `RoutableCommand` with the `Rename` command inside. The `RoutableCommand` is sent through the `CommandRouter` and the `Rename` command internally knows how to send a message to its `P` generic protocol type parameter. |

The next section explains how to use these types and components.

## Commands and Dispatching

You can see examples of this use in the XOOM Schemata implementation source code. The following demonstrates how a single command set is defined and used by Schemata.

### Instantiating the Command

This examines the XOOM Schemata command set that support schema definitions. Since the command types are somewhat redundant other than the parameter details, the entire source is not shown.

As a design choice, all commands for a given feature are defined inside an outer parent class. In the case of schema definition commands, the parent class is `SchemaCommands`. Inside `SchemaCommands` where are a number of concrete command types. The `SchemaCommands` is a factory that instantiates all the concrete command types as needed. See [the main source](https://github.com/vlingo/xoom-schemata) for full details, such as all necessary imports, etc.

```java
package io.vlingo.xoom.schemata.resource;

import io.vlingo.xoom.common.Completes;
import io.vlingo.xoom.lattice.model.Command;
import io.vlingo.xoom.lattice.router.CommandDispatcher;
import io.vlingo.xoom.lattice.router.CommandRouter;
import io.vlingo.xoom.lattice.router.CommandRouter.Type;
import io.vlingo.xoom.lattice.router.RoutableCommand;
...

class SchemaCommands {
  private final CommandRouter router;
  private final Stage stage;

  SchemaCommands(final Stage stage, final int routees) {
    this.stage = stage;
    this.router = CommandRouter.of(stage, Type.LoadBalancing, routees);
  }
  ...
}
```

The `SchemaCommands` parent is instantiated with the `Stage` and the number of `routees` to be create for the router. The constructor creates a new `CommandRouter` that is the type used for `LoadBalancing`.

Once the `SchemaCommands` instance exists, it can be used to instantiate individual command instances. The first factory used is `categorizeAs()` that instantiates a `CategorizeAs` that is wrapped in a `RoutableCommand`.

```java
class SchemaCommands {
  ...
  RoutableCommand<Schema,CategorizeAs,SchemaState> categorizeAs(
          final SchemaId schemaId,
          final Category category) {

    final CategorizeAs categorizedAs = new CategorizeAs(category);

    RoutableCommand<Schema,CategorizeAs,SchemaState> command =
            RoutableCommand
              .speaks(Schema.class)
              .to(SchemaEntity.class)
              .at(schemaId.value)
              .createsWith(Definition.parameters(schemaId))
              .named(Schema.nameFrom(schemaId))
              .delivers(categorizedAs)
              .answers(Completes.using(stage.scheduler()))
              .handledBy(categorizedAs);

    router.route(command);

    return command;
  }
  ...
}
```

The `RoutableCommand` generic type parameters are as follows:

1. The `P` protocol is the `Schema` domain model interface.
2. The `C` command type is `Command` subclass `CategorizeAs`.
3. The A answer type is `SchemaState`, which is the type used to hold and transfer the `Schema` type's immutable state data.

{% hint style="info" %}
Note that the `SchemaCommands` does not provide a factory method for the initial `Schema` type instance. That's because we use a factory method on the protocol type interface itself that's used to instantiate the initial `Schema` domain model object. The protocol commands other than the factory methods are provided.
{% endhint %}

The parameters to the command are `SchemaId` and `Category`. First the `CategorizeAs` concrete command type itself is instantiated with the two parameters. Next the instance of `CategorizeAs` is wrapped by a new `RoutableCommand` , and it is then routed. Finally the `RoutableCommand` is answered from the factory.

The `RoutableCommand` answer is used to receive the `SchemaState` instance when it arrives by way of the `Completes<SchemaState>`. The REST resource handler type `SchemaResource` initially received an HTTP `PATCH` request and used the `SchemaCommands` factory method `categorizeAs()` in order to create the `RoutableCommand`. Once the `RoutableCommand` is returned to the `SchemaResource` request handler, the request handler registers a function on the `Completes<SchemaState>` that will deliver the eventual outcome when it arrives.

```java
public class SchemaResource extends DynamicResourceHandler {
  private final Grid grid;
  private final SchemaCommands commands;
  private final SchemaQueries queries;

  public SchemaResource(final Grid grid) {
    super(grid.world().stage());
    this.grid = grid;
    this.commands = new SchemaCommands(grid, 10);
    this.queries = StorageProvider.instance().schemaQueries;
  }
  ...
  public Completes<Response> categorizeAs(final String organizationId, final String unitId, final String contextId, final String schemaId, final String category) {
    return commands
            .categorizeAs(SchemaId.existing(organizationId, unitId, contextId, schemaId), Category.valueOf(category)).answer()
            .andThenTo(state -> Completes.withSuccess(Response.of(Ok, entityResponseOf(serialized(SchemaData.from(state))))));
  }
  ...
}
```

When the function is executed, the final outcomes is produced and in turn is put into a completes to be used by the XOOM HTTP server as a response to the client.

### Dispatching the Command

The `CategorizeAs` command type itself plays and important role beyond carrying a parameter payload. When the router is ready to delivery the command, it uses the command itself to perform the dispatching.

```java
public class SchemaResource extends DynamicResourceHandler {
    ...
    private static class CategorizeAs extends Command implements CommandDispatcher<Schema,CategorizeAs,Completes<SchemaState>> {
    private final Category category;

    CategorizeAs(final Category category) {
      this.category = category;
    }

    @Override
    public void accept(final Schema protocol, final CategorizeAs command, final Completes<SchemaState> answer) {
      protocol.categorizeAs(command.category).andThen(state -> answer.with(state));
    }
  }
  ...
}
```

To actually deliver the `CategorizeAs` command to its destination, the router uses the `accept()` on  the `CategorizeAs` concrete `CommandDispatcher`, a Java functional interface, to do so. The `accept()` method sends the `categorizeAs()` message and parameters to the `SchemaEntity` actor through its registered protocol.

## Other Examples

See the full [XOOM Schemata source code](https://github.com/vlingo/xoom-schemata) for more examples.


# Streams

The VLINGO XOOM platform Reactive Streams built on XOOM Actors.

The XOOM Streams component implements the [Reactive Streams specification](https://www.reactive-streams.org/) for the VLINGO XOOM platfor&#x6D;*.* It is fully based on XOOM Actors to provide reactive concurrency for stream processing.

There are four abstractions used by the Reactive Streams specification, which are entirely implemented in XOOM Streams.

| Protocol       | Description                                                                                                                                                                                                                                                                                    |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Processor`    | Both a `Subscriber` and a `Publisher`, first receiving a stream of elements and then publishing those following a probable transformation. This is perfect for defining streaming pipelines.                                                                                                   |
| `Publisher`    | A provider of a potentially unbounded number of sequenced elements, pushing them according to the demand received from its one or more `Subscriber` interests.                                                                                                                                 |
| `Subscriber`   | Receives signals from the `Publisher` to which it is subscribed. The signals indicate that a `Subscription` has been granted, that a next element is available, that an error has occurred, and if the end of stream is reached, that the stream is completed.                                 |
| `Subscription` | A reference to the contract between `Publisher` and `Subscriber`, which is used by the `Subscriber` to request 1 to N sequenced elements from the `Publisher`, and to cancel its subscription. The value of N may be effectively unbounded, which is indicated by requesting `Long.MAX_VALUE`. |

![The four abstractions of Reactive Streams.](/files/-M9Brft0IxmpPoy1NxPd)

It is possible that you will never implement a `Publisher`, `Subscriber`, `Subscription`, or `Processor` yourself. Default implementations of these are provided by XOOM Streams. You will, instead implement `Source` and `Sink` types.

The `Subscriber` requests a `Subscription` from a `Publisher` and specifies the number of elements it can accept. By specifying the number of elements it can accept, *backpressure* is enforced on the `Publisher` so that it does not overwhelm the `Subscriber`.

![A Subscriber requests N elements from the Publisher, creating a backpressure contract.](/files/-M9Bsdd-zWi9VUBzJkuD)

The following is an example of how to create a `Publisher` that produces a sequenced series of `Long` values and a `Subscriber` with a `Sink` that prints those as `String` values.

```java
final long max = 10;

final Publisher publisher =
  world.actorFor(
    Publisher.class,
    StreamPublisher.class,
    Source.rangeOf(1, max + 1),
    PublisherConfiguration.defaultDropHead());

final Subscriber subscriber =
  world.actorFor(
    Subscriber.class,
    StreamSubscriber.class,
    Sink.printToStdout("> "),
    max);

publisher.subscribe(subscriber);
```

With no further code the above produces the following output.

```java
// RESULTS
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
```

Similarly a `Processor` is created, which is both a `Subscriber` to an upstream `Publisher` and a `Publisher` to an downstream `Subscriber`.&#x20;

![A Processor is a Subscriber on the left side and a Publisher on the right side.](/files/-M9BwWQtsdhRVuMDzaBv)

The following example reuses the `Publisher` and `Subscriber` from the previous example, but injects the `Processor` in between the two, where the `Processor` transforms the `Long` values to `Double` values.

```java
final LongToDoubleMapper transformer = new LongToDoubleMapper();

final Processor<String,Integer> processor =
  world.actorFor(
    Processor.class,
    StreamProcessor.class,
    transformer,
    10,
    PublisherConfiguration.defaultDropHead());

processor.subscribe(subscriber);

publisher.subscribe(processor);

```

The above produces this output.

```java
// RESULTS
> 1.0
> 2.0
> 3.0
> 4.0
> 5.0
> 6.0
> 7.0
> 8.0
> 9.0
> 10.0
```

## Sources and Sinks

A `Source` is the source of a stream of elements relayed by a `Publisher`. A `Sink` is the destination of the elements provided to a `Subscriber` by its `Publisher`. Next are ways that these may be used.

### `Source`

You may reuse predefined `Source` types, but you will also develop your own implementations. This is the `Source` protocol as provided by XOOM Streams.

```java
package io.vlingo.xoom.reactivestreams;

public interface Source<T> {
  Completes<Elements<T>> next();
  Completes<Elements<T>> next(final int maximumElements);
  Completes<Elements<T>> next(final long index);
  Completes<Elements<T>> next(final long index, final int maximumElements);
  Completes<Boolean> isSlow();
}
```

The job of a `Source` is to take requests for the next elements in a stream, which are returned as a `Completes<Elements<T>>`. This means that the `Elements<T>` are completed at some future time. See [`Completes<T>`](/xoom-common#completes) for details on use.

The `isSlow()` protocol answers a `Completes<Boolean>` indicating whether the `Source` will tend to be slow in providing next elements. The following demonstrates how you may answer.

```java
@Override
public Completes<Boolean> isSlow() {
  return Completes.withSuccess(false);
}
```

Of course, answering `true` or `false` accurately is vitally important. If your Source is slow, stating so enables the `Publisher` to decide on the kind of `Scheduler` to use between probes for next elements. A slow `Source` will be managed by repeated schedule-once timer intervals, while a fast `Source` will be managed by a consistently schedule-many repeating time interval.

The following is an example of a fast `Source` that lazily (not all preallocated in a `List`) provides a range of `Long` values.

```java
package io.vlingo.xoom.reactivestreams.source;

import io.vlingo.xoom.common.Completes;
import io.vlingo.xoom.reactivestreams.Elements;
import io.vlingo.xoom.reactivestreams.Source;

public class LongRangeSource implements Source<Long> {
  private long current;
  public final long endExclusive;
  public final long startInclusive;

  public LongRangeSource(final long startInclusive, final long endExclusive) {
    assert(startInclusive <= endExclusive);
    assert(startInclusive >= 0 && startInclusive <= Long.MAX_VALUE);
    this.startInclusive = startInclusive;
    assert(endExclusive >= 0 && endExclusive <= Long.MAX_VALUE);
    this.endExclusive = endExclusive;

    this.current = startInclusive;
  }

  @Override
  public Completes<Elements<Long>> next() {
    if (current < endExclusive) {
      final Long[] element = new Long[1];
      element[0] = current++;
      return Completes.withSuccess(new Elements<>(element, false));
    }
    return Completes.withSuccess(new Elements<>(new Long[0], true));
  }

  @Override
  public Completes<Elements<Long>> next(final int maximumElements) {
    return next();
  }

  @Override
  public Completes<Elements<Long>> next(long index) {
    return next();
  }

  @Override
  public Completes<Elements<Long>> next(final long index, final int maximumElements) {
    return next();
  }

  @Override
  public Completes<Boolean> isSlow() {
    return Completes.withSuccess(false);
  }

  @Override
  public String toString() {
    return "LongRangeSource [startInclusive=" + startInclusive +
              " endExclusive=" + endExclusive + " current=" + current + "]";
  }
}
```

See the Javadocs on [`Source`](https://javadoc.io/doc/io.vlingo/vlingo-streams/latest/index.html) for full API explanations.

There are factory methods available to create `Source` instances, and default implementation types of which these produce instances.

```java
public interface Source<T> {
  static <T> Source<T> empty() ...
  static <T> Source<T> only(final T... elements) ...
  static Source<Long> rangeOf(final long startInclusive, final long endExclusive) ...
  static <T> Source<T> with(final Iterable<T> iterable) ...
  static <T> Source<T> with(final Iterable<T> iterable, final boolean slowIterable) ...
  static <T> Source<T> with(final Supplier<T> supplier) ...
  static <T> Source<T> with(final Supplier<T> supplier, final boolean slowSupplier) ...
}
```

The number of these and the backing `Source` types will grow over future releases.

### `Sink`

You may reuse predefined `Sink` types, but you will develop your own implementations. This is the `Sink` protocol as provided by XOOM Streams.

```java
public interface Sink<T> {
  void ready();
  void terminate();
  void whenValue(final T value);
}
```

The `ready()` indicates that the `Sink` should become prepared to handle incoming values. The `terminate()` indicates that the `Sink` is being terminated and will no longer receive values. The `whenValue(T value)` is used to provide the next available value from the `Subscriber`.

The following is an example of a `Sink` that prints received values.

```java
package io.vlingo.xoom.reactivestreams.sink;

import java.io.PrintStream;
import io.vlingo.xoom.reactivestreams.Sink;

public class PrintSink<T> implements Sink<T> {
  private final PrintStream printStream;
  private final String prefix;
  private boolean terminated;

  public PrintSink(final PrintStream printStream, final String prefix) {
    this.printStream = printStream;
    this.prefix = prefix;
    this.terminated = false;
  }

  @Override
  public void ready() {
    // ignored
  }

  @Override
  public void terminate() {
    terminated = true;
  }

  @Override
  public void whenValue(final T value) {
    if (!terminated) {
      printStream.println(prefix + value.toString());
    }
  }

  @Override
  public String toString() {
    return "PrintSink[terminated=" + terminated + "]";
  }
}
```

See the Javadocs on [`Sink`](https://javadoc.io/doc/io.vlingo/vlingo-streams/latest/index.html) for full API explanations.

There are factory methods available to create `Sink` instances, and default implementation types of which these produce instances.

```java
public interface Sink<T> {
  static <T> Sink<T> consumeWith(final Consumer<T> consumer) ...
  static <T> Sink<T> printToStdout(final String prefix) ...
  static <T> Sink<T> printToStderr(final String prefix) ...
  static <T> Sink<T> printTo(final PrintStream printStream, final String prefix) ...
}
```

The number of these and the backing `Sink` types will grow over future releases.

## `Stream`

Some functions in the VLINGO XOOM platform, such as queries provided by XOOM Symbio, answer a `Completes<Stream>`. The `Stream` that is eventually available inside the `Completes` is used to consume the elements of streaming data.

```java
package io.vlingo.xoom.reactivestreams;

public interface Stream {
  <S> void flowInto(final Sink<S> sink);
  <S> void flowInto(final Sink<S> sink, final long flowElementsRate);
  <S> void flowInto(final Sink<S> sink, final long flowElementsRate, final int probeInterval);
  void request(final long flowElementsRate);
  void stop();
}
```

The `flowInto()` overrides are used to start the stream flowing into a given `Sink<S>`. Besides causing the flow to begin, additional options are available. To control the initial rate at which elements flow, as in the number of elements that will arrive in a single burst, pass a value for `flowElementsRate`. If no parameter is provided, the default is `100`.

```java
public static final long DefaultFlowRate = 100;
```

To indicate the number of milliseconds between probes for `Source<T>` elements, pass `probeInterval`.  The default if not explicitly provided by the client is `5` milliseconds. There are other constants that you may use. Ultimately the performance of stream throughput is based on the amount of throughput available to the `Source<S>` and the speed at which the `Source<T>` is probed by the `StreamPublisher` to retrieve that data.

```java
// 5 milliseconds
public static final int DefaultProbeInterval = PublisherConfiguration.DefaultProbeInterval;
// 2 milliseconds
public static int FastProbeInterval = PublisherConfiguration.FastProbeInterval;
// 1 millisecond
public static int FastestProbeInterval = PublisherConfiguration.FastestProbeInterval;
```

The `request()` operation may be used to change the flow rate after the initial rate has been established. The `stop()` method may be used to completely terminate the flow of elements from the `Source<T>` and `Publisher<T>`. Note, however, that since the flow is asynchronous it is possible that some elements are already incoming to the `Sink<S>` and thus will not be prevented from arriving. If no parameter is provided, the default is `5`.

For examples of how `Stream` is used, see [Streaming Persistent Data](https://docs.vlingo.io/vlingo-streams#streaming-persistent-data).

## Operators

In XOOM Streams an operator is used to perform a specific kind of data transformation. When using a `StreamProcessor` you will probably want to transform the `StreamSubscriber` side of the processor's incoming data to another type that is outgoing through its `StreamPublisher` side. You can use an operator to do that.

```java
package io.vlingo.xoom.reactivestreams;

public interface Operator<T,R> {
  void performInto(final T value, final Consumer<R> consumer);
}
```

The `Operator<T, R>` takes type `T` as an input `value` and provides type `R` as output. Output is delivered to a `Consumer<R>` of type `R`,  which means the `R` value is produced before the `Consumer<R>` receives it. This is where the implementation of the `Operator<T, R>` plays in. Note that there are currently three factory methods provided on the `Operator` interface:

```java
package io.vlingo.xoom.reactivestreams;

public interface Operator<T,R> {
  static <T> Operator<T,T> filterWith(final Predicate<T> filter) {
    return new Filter<>(filter);
  }

  static <T,R> Operator<T,R> flatMapper(final Function<T, Source<R>> mapper) {
    return new FlatMapper<T,R>(mapper);
  }

  static <T,R> Operator<T,R> mapWith(final Function<T,R> mapper) {
    return new Mapper<>(mapper);
  }

  ...
}
```

Thus, there are three basic kinds of operators, a filter, a flat-mapper, and a mapper.

| Factory      | Operator Description                                                                                                                                                                                                                                                       |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Filter`     | Produces the same type that it takes as input, but may produce less output than it receives as input.                                                                                                                                                                      |
| `Mapper`     | Produces a different type than it takes as input, as it is responsible to map/transform the input to another type. Actually the mapper may produce the same type of output as the input, but perhaps the data inside the type has been enriched or restricted in some way. |
| `FlatMapper` | Works like `Mapper`, but also flattens the stream by reducing the inner structure to the single one produced by the mapping `Function`.                                                                                                                                    |

Here is an example filter:

```java
final List<String> list =
  Arrays.asList("ABC", "321", "123", "456", "DEF", "214");

final List<String> results = new ArrayList<>();

final Operator<String,String> filter =
  Operator.filterWith((s) -> s.contains("1"));

list.forEach(possible ->
  filter.performInto(possible, (match) -> results.add(match)));

Assert.assertEquals(3, results.size());
Assert.assertEquals("321", results.get(0));
Assert.assertEquals("123", results.get(1));
Assert.assertEquals("214", results.get(2));
```

In this example (broken down into multiple steps for clarity) a `filter` is created that filters in all `String` instances that contain the substring `"1"`, and filters out all others. Then the `List<String>` of six elements is iterated over and the filter's `performInto()` operation is used. If the filter `Predicate<T>` of `s.contains("1")` is satisfied, the match is added to the `List<String>` of `results`, which then contains elements `"321"`, `"123"`, and `"214"`.

Next is an example of a mapper:

```java
final List<String> list = Arrays.asList("123", "456", "789");

final List<Integer> results = new ArrayList<>();

final Operator<String,Integer> mapper =
  Operator.mapWith((s) -> Integer.parseInt(s));

list.forEach(digits ->
  mapper.performInto(digits, (number) -> results.add(number)));

Assert.assertEquals(3, results.size());
Assert.assertEquals(123, (int) results.get(0));
Assert.assertEquals(456, (int) results.get(1));
Assert.assertEquals(789, (int) results.get(2));
```

In this example (broken down into multiple steps for clarity) a `mapper` is created that maps all `String` instances of digit characters to `Integer` numbers. The `List<String>` of three elements is iterated over and the mapper's `performInto()` operation is used. The new value is added to the `List<Integer>` of `results`, which then contains elements `123`, `456`, and `789`.

The following demonstrates how a mapper can use flat-map (but it's easier than this; see below.):

```java
final List<String> list1 = Arrays.asList("1", "2", "3");
final List<String> list2 = Arrays.asList("4", "5", "6");
final List<String> list3 = Arrays.asList("7", "8", "9");

final List<List<String>> lists = Arrays.asList(list1, list2, list3);

final List<Integer> results = new ArrayList<>();

final Function<List<List<String>>, List<Integer>> mapper =
        (los) -> los.stream()
          .flatMap(list -> list.stream().map(s -> Integer.parseInt(s)))
          .collect(Collectors.toList());

final Operator<List<List<String>>,List<Integer>> flatMapper =
  Operator.mapWith(mapper);

flatMapper.performInto(lists, (numbers) -> results.addAll(numbers));

Assert.assertEquals(9, results.size());
Assert.assertEquals(1, (int) results.get(0));
Assert.assertEquals(2, (int) results.get(1));
Assert.assertEquals(3, (int) results.get(2));
```

Note that there is a `List<List<String>> lists` that is a list of lists. The `mapper` is created that internally uses the Java `Stream::flatMap`. The `mapper` first streams over the `List<List<String>> lists`. It then uses `flatMap` to handle each of the single `List<String> list`. It then streams over each of those lists, and each individual `String` is transformed to an `Integer`.

Yet, you can perform this more easily using the `FlatMapper` operator. Here's a `FlatMapper` solution to a different problem:

```java
final Operator<Long, Long> flatMap = Operator.flatMapWith((record) -> new LongRangeSource(record, record + 2));
final List<Long> providedLongs = new CopyOnWriteArrayList<>();

flatMap.performInto(1L, providedLongs::add);
flatMap.performInto(3L, providedLongs::add);

Assert.assertEquals(Arrays.asList(1L, 2L, 3L, 4L), providedLongs);
```

In this example, the flat-mapper is given a function that instantiates a `LongRangeSource`, which is a stream source that contains a `startInclusive` and an `endExclusive` value. In the first `performInto()` the `startInclusive` is `1` and the `endExclusive` of two greater, which is `3`; the first numeric range is thus `1` to `2`. The second range is `3` to `4`. The flat-mapper reads every value in each `LongRangeSource` and adds it to the collection referenced by `providedLongs`. When completed the two containers are flattened such that only the inner ranges are preserved in the `providedLongs`.

You can give a `StreamProcessor` an `Operator<T, R>` such as these, or use them in your `Source` and `Sink` implementations.

We will be adding more functional interfaces to our various types over future releases.

## Streaming Your Data

There are several ways to stream your data. You have already seen specific examples in the above content. In this section you are introduced to other ways.

### Streaming Persistent Data

Data that is persisted inside a XOOM Streams store can be streamed out to one or more subscribers. One of the most basic examples is provided by the `StateStore`.

```java
package io.vlingo.symbio.store.state;

public interface StateStoreReader {
  ...
  Completes<Stream> streamAllOf(final Class<?> stateType);
  Completes<Stream> streamSomeUsing(final QueryExpression query);
}
```

A `StateStoreReader` is provided as part of the `StateStore` protocol. Thus, you may ask a `StateStore` to stream data from it's internal storage. The two interfaces provided support streaming all of a given state type; that is, a `stateType` is a Java `Class<?>` of which all states of that type are stored in a single container. In some storage mechanisms that container may be a database table or an in-memory grid region.

By requesting a stream of all of a given `stateType`, the `StateStoreReader` queries that data from the container and provides an instance of `io.vlingo.xoom.reactivestreams.Stream`.

```java
// somewhere many EquityState instances are written
final Equity equity = new Equity(...);
...
store.write(equity.id, equity.state, equity.version, interest);

...

final Completes<Stream> stream =
  store.streamAllOf(EquityState.class);

stream.andThen(all ->
  all.flowInto(new ConsumerSink<>((equityState) -> reportOn(equityState));
```

You may also constrain your query to a subset of the whole container. The query is storage-type dependent.

```java
final Completes<Stream> stream =
  store.streamSomeUsing(
    QueryExpression.using(
      EquityState.class,
      "select ... from tbl_equity where ..."));

stream.andThen(some ->
  some.flowInto(new ConsumerSink<>((equityState) -> reportOn(equityState));
```

You may also stream persisted `Source<?>` types, such as `DomainEvent` and `Command` instances. For example, the `Journal<T>` provides this streaming interface through the `JournalReader<T>`, which in turn is an`EntryReader<T>`.

```java
// Journal
package io.vlingo.symbio.store.journal;

public interface Journal<T> {
  ...
  <ET extends Entry<?>> Completes<JournalReader<ET>>
     journalReader(final String name);
}

// JournalReader
package io.vlingo.symbio.store.journal;

public interface JournalReader<T extends Entry<?>> extends EntryReader<T> { }

// EntryReader
package io.vlingo.symbio.store.journal;

public interface EntryReader<T extends Entry<?>> {
  ...
  Completes<Stream> streamAll();
}
```

These are used in the following example, first to request the `JournalReader`, then the `Stream` of all `EntryBundle` instances, and then to flow the stream into the `Sink<EntryBundle>` for reporting on each event.

```java
final Sink<EntryBundle> sink =
  Sink.consumeWith((bundle) -> reportOn(bundle.source));

journal
    .journalReader("events-reporter")
    .andThenTo(reader -> reader.streamAll())
    .andThen(stream -> stream.flowInto(sink, 50));
```

All stores—`ObjectStore`, `StateStore`, and `Journal`—support persisting a totally ordered stream of `Source<?>` entries, such as `DomainEvent` and `Command`. You may obtain any of the total streams using the same basic techniques.


# Schemata

The VLINGO XOOM platform schema registry.

The XOOM Schemata component is a schema registry. It provides the means for *Bounded Contexts,* à la services and applications, built using VLINGO XOOM to publish standard types that are made available to dependent Bounded Contexts as client services. The published standard types are known as *schemas,* and the registry hosts the schemas for given organizations and the services within.�

One of the big problems with exchanging information across Bounded Contexts, implemented as microservices and applications, is when changes to the information structure, data types, and attribute/property names, cause incompatibilities for the dependents. Experience proves that such changes are infrequently known to consuming dependents. When that is the case, essential integrations break down.

Another challenge is maintaining type safety of the exchanged information across Bounded Contexts when a consumer deserializes (or unmarshals) data from the exchange format into a consumable local object. Further, various Bounded Contexts may be implemented in a number of different programming languages, and the process of deserializing is tedious or impossible due to incompatibilities in formats between producer and consumer data types.

XOOM Schemata provides the means to eliminate such problems and minimize challenges by maintaining semantic versioning across the range of standard types known as schemas. This tool also facilitates consumer build dependencies on the schema types according to the local programming language.

## Published Language

XOOM Schemata supports what is know in DDD as the *Published Language*. If you have either of Vaughn Vernon's DDD books you can read more about *Published Language* in those. Still, we provide a basic overview of its uses here.

A few very important points in conjunction with developing a *Published Language* are,

1. A *Published Language* should not be directly related to the internal domain model of your *Bounded Context*, and the internal domain model of your *Bounded Context* should not depend on the types defined in your *Published Language.* The types defined in your *Published Language* may be *fundamentally* the same or similar, but they are not the same *things*. Separate the two.
2. A *Published Language* is used for presenting API types and data in an open and well-documented way. These are used by clients to communicate with a *Bounded Context,* and for a *Bounded Context* to communicate with client services outside its boundary.
3. Your domain model is more closely tied to the concepts learned and discovered by your team that are related to its shared mental model and specific *Ubiquitous Language.* A *Published Language* is driven by the needs of *Bounded Contexts* (clients, or otherwise collaborating/integrating applications and services) outside your *Bounded Context* that needs to use data to communicate and/or understand the outcomes that your *Bounded Context* produces. Your *Published Language* should be based on your *Ubiquitous Language,* but it may not (and often should not) share everything about its internal structure, typing, and data.
4. There is a *Context Mapping* strategic design pattern of DDD known as *Conformist.* Closely related to the previous point #3, the goal of *Published Language* is to prevent collaborating/integrating *Bounded Contexts* (clients, or otherwise collaborating or integrating applications and services) from being required to conform to your internal domain model and be affected by its ongoing changes. Instead, consumers would adhere to a common standard *Published Language,* or even translate from a standard *Published Language* into their own *Ubiquitous Language.*
5. If collaborators/integrators did conform directly to your *Ubiquitous Language,* every change in your domain model would ripple into their external *Bounded Contexts,* having negative maintenance impacts. There are times when being a *Conformist* can be advantageous. It requires less conceptual design to adhere to another model, but with less flexibility in your *Context.* In such cases, data types used by conforming collaborators/integrators can likewise be defined inside XOOM Schemata. Even so, here  focus is given to the more inviting and flexible *Published Language.*

{% hint style="info" %}
One exception to the strong suggestion for your domain model to not consume types from your *Published Language* may be with your *Domain Events.* It may make sense to use these in your domain model because it can reduce the amount of mapping between *Domain Events* defined in your domain model and those used for persistence and messaging, for example. Still, sharing types could be problematic and good judgment should be used in deciding whether or not to do so. This is generally a tradeoff in the development overhead of maintaining separate types and mapping them, and reducing the runtime overhead of mapping between types and the memory management garbage that this produces.
{% endhint %}

## Use Cases

The following provides some typical use cases that are supported by the *Published Language* of a given *Bounded Context.* There may be concepts and schema structuring that are unfamiliar, but any such will be explained soon. It's most important that you now understand *why* the XOOM Schemata exists and *why* it is used.

1. A client sends a `Command` request to a *Bounded Context*. The client must communicate that request using types and data that the *Bounded Context* understands. The *Bounded Context* defines a schema inside XOOM Schemata such as: `Org.Unit.Context.Commands.DoSomethingForMe`. That `Command` has some data structure, such as for the REST HTTP request body payload, or for a message payload if using messaging.
2. A client sends a `Query` request to a *Bounded Context*. For example, a client sends a `GET` request using REST over HTTP. The *Bounded Context* must respond with a result, and the `200 OK` response body definition is defined as a `Document`. That Document result is defined in XOOM Schemata and may have a name in the following format`Org.Unit.Context.Documents.TypeThatWasQueried`.
3. After use case #1 above completes, the *Bounded Context* emits a `DomainEvent`. The type and data of that outgoing `DomainEvent` is defined in XOOM Schemata and may have a name in the following format `Org.Unit.Context.Events.SomethingCompleted`.
4. It is possible that any one of #1, #2, and/or #3 use additional complex data types within their definition. These additional complex data types would be defined by the *Bounded Context* under `Org.Unit.Context.Data`, perhaps as `Org.Unit.Context.Data.SomethingDataType`.
5. It is possible (even likely) that any one of #1, #2, and/or #3, if based on messaging (or possibly even REST), will define one or more types within `Org.Unit.Context.Envelope`, such as `Org.Unit.Context.Envelope.Notification`. Such an `Envelope` type "wraps" a `Command`,  a`Document`, and/or a`Domain Event`, and is used to communicate metadata about the incoming `Command` or the resulting `Document` and published `Domain Event`.
6. The publisher of a schema can require changes to it. The clients/consumers could fail to correctly consume the exchanged information due to being uninformed about the changes. To protect against such failures, XOOM Schemata manages schema versions by disallowing breaking changes based on semantic versioning. All breaking changes must be made only using the next highest major version. To use the minor or patch version requires nonbreaking changes.
7. The teams working in a given Bounded Context are free to choose whichever programming language and technology stack they deem best for their work. When any Bounded Context must consume information from any other, each could use different a language and set of technologies. The publisher of a schema and any consumers must be able to exchange the information in a type-safe manner even when language and technologies differ. XOOM Schemata facilitates generating consumer-side types based on a language-neutral format.

The functionality that accommodates these use cases is described next.

## Concepts and Design

The XOOM Schemata presents the following basic logical interface and hierarchy:

```
Organization
  Unit
    Context
      Commands
        Schema
          SchemaVersion (Specification, Version, Status)
          ...
        ...
      Data
        Schema
          SchemaVersion (Specification, Version, Status)
          ...
        ...
      Documents
        Schema
          SchemaVersion (Specification, Version, Status)
          ...
        ...
      Envelopes
        Schema
          SchemaVersion (Specification, Version, Status)
          ...
        ...
      Events
        Schema
          SchemaVersion (Specification, Version, Status)
          ...
        ...
```

From the top of the hierarchy the nodes are defined as follows.

**Organization:** The top-level division. This may be the name of a company or the name of a prominent business division within a company. If there is only one company using this registry then the Organization could be a major division within the implied company. There may be any number of Organizations defined, but there must be at least one.

**Unit:** The second-level division. This may be the name of a business division within the Organization, or if the Organization is a business division then the Unit may be a department or team within a business division. Note that there is no reasonable limit on the name of the Unit, so it may contain dot notation in order to provide additional organizational levels. In an attempt to maintain simplicity we don't want to provide nested Unit types because the Units themselves can become obsolete with corporate and team reorganizations. It's best to name a Unit according to some non-changing business function rather than physical departments.

**Context:** The logical application or (micro)service within which schemas are to be defined and for which the schemas are published to potential consumers. You may think of this as the name of the *Bounded Context,* and it may even be appropriate to name it the top-level namespace used by the Context, e.g. `com.saasovation.agilepm`. Within each Context there may be a number of category types used to describe its *Published Language* served by its *Open-Host Service.* Currently these include: Commands, Data, Documents, Envelopes, and Events. Some of the parts are meant to help define other parts, and so are building blocks. Other parts are the highest level of the Published Language. These are called out in the following definitions.

**Commands:** This is a top-level schema type where Command operations, such as those supporting CQRS, are defined by schemas. If the Context's *Open-Host Service* is REST-based, these would define the payload schema submitted as the HTTP request body of `POST`, `PATCH`, and `PUT` methods. If the *Open-Host Service* is an asynchronous-message-based mechanism (e.g. RabbitMQ or Kafka), these would define the payload of Command messages sent through the messaging mechanism.

**Data:** This is a building-block schema type where general-purpose data records, structures, or objects are defined and that may be used inside any of the other schema types (e.g. type `Token`). You may also place metadata types here (e.g. type `Metadata` or more specifically, type `CauseMetadata`).

**Documents:** This is a top-level schema type that defines the full payload of document-based operations, such as the query results of CQRS queries. These documents are suitable for use as REST response bodies and messaging mechanism payloads.

**Envelopes:** This is a building-block schema type meant to define the few number of message envelopes that wrap message-based schemas. When sending any kind of message, such as Command messages and Event messages, it is common to wrap these in an Envelope that defines some high-level metadata about the messages being sent by a sender and being received by a receiver.

**Events:** This is a top-level schema type that conveys the facts about happenings within the Context that are important for other Context's to consume. These are known as Domain Events but may also be named Business Events. The reason for the distinction is that some viewpoints consider Domain Events to be internal-only events; that is, those events only of interest to the owning Context. Those holding that viewpoint think of events of interest outside the owning Context as Business Events. To avoid any confusion the term Event is used for this schema type and may be used to define any event that is of interest either inside or outside the owning Context, or both inside and outside the owning Context.

**Schema:** Under every top-level schema category (or type, such as Commands and Events) are any number of Schema definitions. Besides a category, a Schema has a name and description. Every Schema has at least one Schema Version, which holds the actual Specification for each version of the Schema. Thus, the Schema itself is a container for an ordered collection of Schema Versions that each have a Specification.

**Schema Version:** Every Schema has at least one Schema Version, and may have several versions. A Schema Version holds the Specification of a particular version of the Schema, and also holds a Description, a Semantic Version number, and a Status. The Description is a textual/prose description of the purpose of the Schema Version.

**Specification:** A Schema Version's Specification is a textual external DSL (code block) that declares the data types and shape of the Schema at a given version. Any new version's Specification must be backward compatible with previous versions' of the given Schema if the new version falls within the same major version. The DSL is shown in detail below.

**Semantic Version:** A semantic version is a three-part version, with a *major,* *minor,* and *patch* value, with each subsequent version part separated by a dot (decimal point), such as `1.2.3` for example. Here `1` is the major version, `2` is the minor version, and `3` is the patch version. If any two Schema Versions share the same major version then it is required that their Specifications be compatible with each other. Thus, the newer version, such as `1.2.0`, must be compatible with the Specification of `1.1.3`, and `1.1.3` must be compatible with `1.2.0`. On the other hand, version `2.0.0` can be incompatible with version `1.2.0`, using the change in major version to make necessary breaking changes. When `2.0.0` becomes the published production version, all dependents must have upgraded to safely consume it.

**Status:** The Schema Version Status has four possible values: `Draft`, `Published`, `Deprecated` and `Removed`. The `Draft` is the initial status and means that the Specification is unofficial and may change. Dependents may still use a `Draft` status Schema Version for test purposes, but with the understanding that the Specification may change at any time. When a Schema Version is considered production-ready, its status is upgraded to `Published`. Marking a Schema Version as `Published` is performed manually by the Context team after it has satisfied it's team and consumer dependency requirements. When your team decides to transition from one Schema Version to another, you might want to mark the old version as `Deprecated`, which gives out a console warning when that version is consumed. If, for some reason, it is necessary to forever remove a Schema Version, it can be marked as `Removed`. It may then still be viewed but not used. It can only be "restored" by defining a new Schema Version with its specification, with the understanding that it may require modification to become backward compatible with any now previous version(s).

### Schema Version Specification DSL

The following demonstrates all the features supported by the typing language:

```java
{category} TypeName {
  type typeAttribute
  version versionAttribute
  timestamp timestampAttribute

  boolean booleanAttribute = true
  boolean[] booleanArrayAttribute { true, false, true }
  byte byteAttribute = 0
  byte[] byteArrayAttribute { 0, 127, 65 }
  char charAttribute = 'A'
  char[] charArrayAttribute = { 'A', 'B', 'C' }
  double doubleAttribute = 1.0
  double[] doubleArrayAttribute = { 1.0, 2.0, 3.0 }
  float floatAttribute = 1.0
  float[] floatArrayAttribute = { 1.0, 2.0, 3.0 }
  int intAttribute = 123
  int[] intArrayAttribute = { 123, 456, 789 }
  long longAttribute = 7890
  long[] longArrayAttribute = { 7890, 1234, 5678 }
  short shortAttribute = 32767
  short[] shortArrayAttribute = { 0, 1, 2 }
  string stringAttribute = "abc"
  string[] stringArrayAttribute = { "abc", "def", "ghi" }
  TypeName typeNameAttribute1
  category.TypeName typeNameAttribute2
  category.TypeName:1.2.1 typeNameAttribute3
  category.TypeName:1.2.1[] typeNameArrayAttribute1
}
```

The following table describes the available types and a description of each.

| Datatype                    | Description                                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{category}`                | This must be replaced by one of the concrete category types: `command`, `data`, `document`, `envelope`, and `event`.                                                                                                                                                                                                                                                                                                  |
| `type`                      | The datatype specifically defining that the type-name of the specification type should be included in the message itself with the given attribute name. (Note that this may be placed instead on the Envelope.)                                                                                                                                                                                                       |
| `version`                   | The datatype specifically defining that the semantic version of the given Schema Version should be included in the message itself with the given attribute name. (Note that this may be placed instead on the Envelope.)                                                                                                                                                                                              |
| `timestamp`                 | The datatype specifically defining that the timestamp of when the given instance was created to be included in the message itself with the given attribute name. (Note that this may be placed instead on the Envelope.)                                                                                                                                                                                              |
| `boolean`                   | <p>The boolean datatype with values of true and false only, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a true or false:<br></p><p><code>boolean flag = true</code></p>                                                                                                                                             |
| `boolean[]`                 | <p>The boolean array datatype with multiple values of true and false only, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of true and false values:<br></p><p><code>boolean\[] flags = { true, false, true }</code></p>                                                           |
| `byte`                      | <p>The 8-bit signed byte datatype with values of -128 to 127, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a byte literal:<br></p><p><code>byte small = 123</code></p>                                                                                                                                               |
| `byte[]`                    | <p>The 8-bit signed byte array datatype with multiple values of - 128 to 127, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of byte values:<br></p><p><code>byte\[] smalls = { 1, 12, 123 }</code></p>                                                                           |
| `char`                      | <p>The char datatype with values supporting UTF-8, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a character literal:<br></p><p><code>char initial = 'A'</code></p>                                                                                                                                                   |
| `char[]`                    | <p>The char array datatype with multiple UTF-8 values, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of character values:<br><br><code>char\[] initials = { 'A', 'B', 'C' }</code></p>                                                                                           |
| `double`                    | <p>The double-precision floating point datatype, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a double literal:<br></p><p><code>double pi = 3.1416</code></p>                                                                                                                                                        |
| `double[]`                  | <p>The double-precision floating point array datatype, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of double values:<br><br><code>double\[] stats = { 1.54179, 7.929254, 32.882777091 }</code></p>                                                                             |
| `float`                     | <p>The single-precision floating point datatype, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a float literal:<br><br><code>float pi = 3.14</code></p>                                                                                                                                                               |
| `float[]`                   | <p>The single-precision floating point array datatype, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of float values:<br><br><code>float\[] stats = { 1.54, 7.92, 32.88 }</code></p>                                                                                             |
| `int`                       | <p>The 32-bit signed integer datatype with values of -2,147,483,648 to 2,147,483,647, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an integer literal:<br></p><p><code>int value = 885886279</code></p>                                                                                                              |
| `int[]`                     | <p>The 32-bit signed integer datatype with multiple values of -2,147,483,648 to 2,147,483,647, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of integer values:<br><br><code>int\[] values = { 885886279, 77241514, 9772531 }</code></p>                                         |
| `long`                      | <p>The 64-bit signed integer datatype with values of -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a long literal:<br><br><code>long value = 15329885886279</code></p>                                                                                       |
| `long[]`                    | <p>The 64-bit signed integer datatype with multiple values of -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of long values:<br><br><code>long\[] values = { 15329885886279, 24389775639272, 45336993791291 }</code></p> |
| `short`                     | <p>The 16-bit signed integer datatype with values of -32,768 to 32,767, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a short literal:<br><br><code>short value = 12986</code></p>                                                                                                                                    |
| `short[]`                   | <p>The 16-bit signed integer datatype with multiple values of -32,768 to 32,767, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of short values:<br><br><code>short\[] values = { 12986, 3772, 10994 }</code></p>                                                                 |
| `string`                    | <p>The string datatype with values supporting multi-character UTF-8 strings, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and a string literal:<br><br><code>string value = "ABC"</code></p>                                                                                                                             |
| `string[]`                  | <p>The string array datatype with multiple values supporting multi-character UTF-8 strings, to be included in the message with the given attribute name. This value may be defaulted if the declaration is followed by an equals sign and an array literal containing a number of string values:<br><br><code>string\[] initials = { "ABC", "DEF", "GHI" }</code></p>                                                 |
| `category.TypeName`         | The explicit complex Schema type of a given Category in the current Context to be included in the message with the given attribute name. The version is the tip, as in the most recent version. There is no support for default values other than `null`, which may be supported using the *Null Object* pattern.                                                                                                     |
| `category.TypeName[]`       | The explicit complex Schema type array of a given Category in the current Context to be included in the message with the given attribute name. The version is the tip, as in the most recent version. There is no support for default values.                                                                                                                                                                         |
| `category.TypeName:1.2.3`   | The explicit complex Schema type of a given Category in the current Context to be included in the message with the given attribute name. The version is the one declared following the colon (`:`). There is no support for default values other than null, which may be supported using the *Null Object* pattern.                                                                                                   |
| `category.TypeName:1.2.3[]` | The explicit complex Schema type array of a given Category in the current Context to be included in the message with the given attribute name. The version is the one declared following the colon (`:`). There is no support for default values.                                                                                                                                                                     |

Any given complex Schema type may be included in the Specification, but doing so may limit to some extent consumption across multiple collaborating technical platforms. We make every effort to ensure cross-platform compatibility, but the chosen serialization type may be a limiting factor. We thus consider this an unknown until full compatibility can be confirmed by you and your team.

An additional warning is appropriate regarding direct domain model usage of Schema types. These Schema types are not meant to be used as first-class domain model *Entities,* *Aggregates,* or *Value Objects.* The Events category types may be used as *Domain Events* in the domain model, but if so we strongly suggest keeping the specifications simple (not include complex types). Thus,

1. Define your domain model *Entities* and *Value Objects* strictly in your domain model code, not using a Schema Specification.
2. Determine the positive and negative consequences of defining *Domain Events* only in the schema registry and using them both in the domain model and for your Published Language. It may or may not work well in your case.

Schema Specifications are primarily about data and expressing present and past intent, not behavior. Consider Schema Specification to be more about *local-Context migrations* of supported *Domain Events* and *inter-Context collaboration and integration* of all other Schema types.

## Running XOOM Schemata

There are a few steps required to run XOOM Schemata.

### Download Distribution

\[Available soon]

### Docker

[Docker images](https://hub.docker.com/r/vlingo/xoom-schemata) are published for every Schemata build (stable and snapshots). Stable Docker images follow XOOM Platform's version (i.e. `1.7.7`), while the latest snapshot is published under the `latest` tag.

The `XOOM_ENV` environment variable can be used to specify the configuration Schemata should be run with. To run Schemata with in-memory database, use the `dev` configuration:

```
$ docker run -eXOOM_ENV=dev -p9019:9019 vlingo/xoom-schemata:1.7.7
```

`prod` configuration will require a PostgreSQL database. You can learn about running in developer and other modes in the project repository's [`README`](https://github.com/vlingo/xoom-schemata).

### Build

Use git to checkout the repository, build, and run:

```bash
$ git checkout https://github.com/vlingo/xoom-schemata.git
...
$ mvn clean package -P frontend
...
$ java -jar target/xoom-schemata-{version}-jar-with-dependencies.jar prod
```

If you do not have Maven installed and thus don't have the `mvn` command, you can use the provided Maven Wrapper. The following is an abstract example for \*nix followed by a concrete example:

```
$ "{yourInstallPath}/xoom-schemata/mvnw.cmd" clean package -P frontend -f "{yourInstallPath}/xoom-schemata\pom.xml"

$ /Users/janedoe/work/vlingo/xoom-schemata/mvnw.cmd" clean package -P frontend -f "/Users/janedoe/work/vlingo/xoom-schemata\pom.xml"
```

The following is an abstract example for Windows followed by a concrete example:

```
D:\> "{yourInstallPath}\xoom-schemata\mvnw.cmd" clean package -Pfrontend -f "{yourInstallPath}\xoom-schemata\pom.xml"

D:\> "D:\Users\JaneDoe\vlingo\xoom-schemata\mvnw.cmd" clean package -Pfrontend -f "D:\Users\JaneDoe\vlingo\xoom-schemata\pom.xml"
```

You must use the specific version to identify the code version that you checked out. Replace `{version}` with a given release version, such as `1.7.7`. The jar would be named `xoom-schemata-1.7.7-jar-with-dependencies.jar`, and thus the full command line would be:

```bash
$ java -jar target/xoom-schemata-1.7.7-jar-with-dependencies.jar prod
```

The prod command-line argument is used to run the production database rather than the development database. The production database is Postgres. You can learn about running in developer and other modes in the project repository's [`README`](https://github.com/vlingo/xoom-schemata).

## Working with Schema Specifications and Schema Dependencies

XOOM Schemata provides an HTTP API and a web user interface. Both can be used to manage master data, like organizations and units, as well as schema definitions. Typically, you'll use the GUI to edit master data and browse existing schemata and the API to integrate schema registry interactions with your development tooling and build pipelines. Maven users also have the possibility of using [XOOM Build Plugins](/xoom-build-plugins#integration-with-vlingo-schemata) to publish and consume schemas.

### Using the GUI

The UI provides a treeview used to browse the available data and a view for each level in the hierarchy described above: *Organizations*, *Units*, *Contexts*, *Schemas* and *Schema Versions*. These are accessible via the menu to the left. We also have Dark Mode (top-right).

#### Defining elements

The following shows the process of defining one *Organization* containing one *Unit* with a single *Context*. Once you did this, you can go ahead and define your *Schemas* along with their *Schema Versions*.

![Defining an Organization](/files/-MM1eMHVlktRs8GojQyV)

![Defining a Unit](/files/-MM1gM4d6dC5dG3ESF0q)

When defining a Context, you need to use namespace syntax (e.g. com.example.demo):

![Defining a Context (with namespace)](/files/-MM1jdX7VdIcrVLI0bpv)

To be able to create concrete specifications (in *Schema Versions*), you'll first need to define the *Schema* meta data. You can choose between all the categories mentioned in [Use Cases](/xoom-schemata#use-cases). When defining a Schema, use initial cap (e.g. SomethingDefined):

![Defining a Schema (with category and name)](/files/-MM1lwlozd1JOLPfWpMw)

When defining a Schema Version, we suggest to always keep semantic versions in order and without version gaps, so you should only use the three buttons for their respective purpose:

![Defining a Schema Version 1/2 (with current version)](/files/-MM2-TeqKZNhXLSzSM45)

While there are many benefits in keeping your specification sources with your project's source code, the GUI still provides an editor to work with specifications. One example use case for this is if you want to describe a contract or small API surface of an external system outside your control and consume the events it publishes.

![Defining a Schema Version 2/2 (with specification)](/files/-MM22pWxN7Kf2mHR9aCA)

After now having defined one of every hierarchy-element, you can switch over to `Home`.

#### Browsing Schemata

In the home view, you can browse existing Schema Versions by drilling down the hierarchy. Once you've selected the version you're interested in, you can:

* Review its specification
* Update its specification as long as the *Schema Version* is still a `Draft`
* Transition between the four lifecycle states `Draft`, `Published`, `Deprecated` and `Removed`

![Viewing Schema Version Details (with specification)](/files/-MM29DWTgqgr-rH17m5H)

* Review source code generated from the specification (click on `Code`)

![Viewing Generated Source Code](/files/-MM2FWG4bZnWAfi6VOeM)

* Review and update its description (click on `Description`, then click on `Preview`)

![Viewing Schema Version Description](/files/-MM2KArrjOTl85iDOHj8)

When you've made some changes to the description and decide not to save them, you can use`Revert` to just set it back to its initial state.

#### Redefining elements

After having defined a hierarchy element, you can also redefine it:

![Redefining an Organization](/files/-MM2SAG0EtnPXWebLuzr)

This works with every hierarchy element, other than *Schema Version*, as it mustn't be modified if it is not still a `Draft`. If it is a `Draft`, you can modify it on `Home`. If not, you can define a new Schema Version.

When publishing a new version of an existing schema, the updated specification is validated in regard to the new semantic version according to the following rules:

* New `patch` version (e.g. `1.2.5` to `1.2.6`): The specification needs to remain unchanged, only meta data can be updated
* New `minor` version (e.g. `1.2.5` to `1.3.0`): Only new fields may be added, there must be no removals, type changes or reordering of fields
* New `major` version (e.g. `1.2.5` to `2.0.0`): No restrictions

If these rules are violated, you'll be presented a list of additions, removals, reorderings and type changes. The colors correspond to the `New Major/Minor/Patch` button colors.

![Trying to define a new Schema Version with incompatible changes](/files/-MM2Zaz2dmErAN74k9mO)

After changing to a new major version, we can define without problems.

### Using the Maven plugin

The [XOOM Build Plugins](/xoom-build-plugins) provides goals to talk to the schema registry as part of the build. To use it, include it in the build section of your project's `pom.xml` and configure the goals as shown below.

```
<project ...>
  <build>
    <plugins>
      <plugin>
        <groupId>io.vlingo</groupId>
        <artifactId>xoom-build-plugins</artifactId>
        <version>1.9.4</version>
        <executions>
        ...
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
  </project>
```

Schemata within the registry are identified by references consisting of organization, unit, context namespace, schema name, and schema version. A schema reference pointing to the Schema `MySchema` `1.0.5` in the namespace `com.example` of the unit `RnD` within the `ACME` organization would look like this: `ACME:RnD:com.example:MySchema:1.0.5`.

#### Publishing schema to the registry

By default, the plugin expects your schema specification `.vss` files to be in the `src/main/vlingo/schemata` folder within your project. To publish these to the registry, you need to configure the `push-schema` goal with:

* the target registry URL, your organization, and unit.
* the schema reference and the previous version, in case you're updating a previous version for each schema

A complete configuration for this goal might look like the example below. For additional details on configuration parameters and defaults, please refer to [XOOM Build Plugins](/xoom-build-plugins).

```
<execution>
  <id>push</id>
  <goals>
    <goal>push-schema</goal>
  </goals>
  <configuration>
    <srcDirectory>${basedir}/src/main/vlingo/schemata</srcDirectory>
    <schemataService>
      <url>http://localhost:9019</url>
      <clientOrganization>VLINGO</clientOrganization>
      <clientUnit>examples</clientUnit>
    </schemataService>
    <schemata>
      <schema>
        <ref>Vlingo:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:0.0.1</ref>
        <src>SchemaDefined.vss</src>
        <previousVersion>0.0.0</previousVersion>
      </schema>
      <schema>
        <ref>Vlingo:examples:io.vlingo.xoom.examples.schemata:SchemaPublished:0.0.1</ref>
      </schema>
    </schemata>
  </configuration>
</execution>
```

#### Consuming source code from the registry

The `pull-schema` goal provides for retrieving sources generated from schemata stored in the registry. Per default, the generated sources will be written to `target/generated-sources/vlingo` and be included in the project's compile path. The goal needs to be configured with:

* the schemata instance URL, your organization, and unit
* the reference of each schema version to consume

The following example makes the build put a `SchemaDefined.java` file generated from the schema version identified by the reference`Vlingo:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:2.0.1` file into `target/...`

```
<execution>
  <id>pull</id>
  <goals>
    <goal>pull-schema</goal>
  </goals>
  <configuration>
    <schemataService>
      <url>http://localhost:9019</url>
      <clientOrganization>VLINGO</clientOrganization>
      <clientUnit>examples</clientUnit>
    </schemataService>
    <schemata>
      <schema>
        <ref>Vlingo:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:2.0.1</ref>
      </schema>
    </schemata>
  </configuration>
</execution>
```

#### Round-trip example

This example shows how to integrate two bounded contexts mediated by the schema registry. In this section, we'll set up two maven projects, one publishing schemata to the registry and one consuming these.

First, make sure you have a schema registry instance running on `localhost:9019`. Please refer to [xoom-schemata-integration](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-schemata-integration) on how to set this up.

Open the GUI and create an organization, one unit with two contexts `io.vlingo.xoom.examples.consumer` and `io.vlingo.xoom.examples.producer`. In the producer context, also create a schema called `MyFirstEvent`. Refer to the [Using the GUI](/xoom-schemata#using-the-gui) section above on how to do this.

Set up one project called `consumer` and one called `producer` by running the following twice, once using `consumer` and once `producer` as `artifactId` and in `package`.

```
mvn archetype:generate -B \
 -DarchetypeGroupId=pl.org.miki -DarchetypeArtifactId=java8-quickstart-archetype -DarchetypeVersion=1.0.0 \
 -DgroupId=io.vlingo.xoom.examples \
 -DartifactId=consumer \
 -Dpackage=io.vlingo.xoom.examples.consumer
```

In the producer project, include the `xoom-build-plugins` configuration for pushing schemata as described above. Make sure the schema reference correctly points to your organization, unit, and context.

```
<plugin>
  <groupId>io.vlingo</groupId>
  <artifactId>xoom-build-plugins</artifactId>
  <version>1.1.0</version>
  ...
  <executions>
    <execution>
      <id>push</id>
      <goals>
        <goal>push-schema</goal>
      </goals>
      <configuration>
        <schemataService>
          <url>http://localhost:9019</url>
          <clientOrganization>VLINGO</clientOrganization>
          <clientUnit>examples</clientUnit>
        </schemataService>
        <schemata>
          <schema>
            <ref>Vlingo:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0</ref>
          </schema>
        </schemata>
    </configuration>
  </execution>
  </executions>
</plugin>
```

Now create a schema specification file called `MyFirstEvent.vss` in `producer/src/main/vlingo/schemata` with the following contents.

```
event MyFirstEvent {
  timestamp occurredOn
  type eventType
  version eventVersion
}
```

Within the producer project, run:

```
$ mvn io.vlingo.xoom:xoom-build-plugins:push-schemata@push
```

The build output should indicate the schema was pushed successfully.

```
[INFO] --- vlingo-build-plugins:1.7.7:push-schema (push) @ producer ---
[INFO] vlingo/maven: Pushing project schemata to xoom-schemata registry.
[INFO] Setting source to MyFirstEvent.vss for XOOM:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0
[INFO] Pushing XOOM:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0 to http://localhost:9019/versions/XOOM:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0.
[INFO] Successfully pushed http://localhost:9019/versions/XOOM:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0
```

Open the GUI and review the schema version you just pushed.

Now we are set up to consume this schema. Open the pom.xml in the consumer project and configure the build plugin to pull sources generated from this schema. Note that you'll also need to include a dependency to `xoom-lattice` as the code currently generated is tied to that. But don't fret, we'll have the possibility to plug in custom code generators soon.

```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>io.vlingo.xoom.examples</groupId>
  <artifactId>consumer</artifactId>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>io.vlingo</groupId>
        <artifactId>xoom-build-plugins</artifactId>
        <version>1.1.0</version>
        <executions>
          <execution>
            <id>pull</id>
            <goals>
              <goal>pull-schema</goal>
            </goals>
            <configuration>
              <schemataService>
                <url>http://localhost:9019</url>
                <clientOrganization>VLINGO</clientOrganization>
                <clientUnit>examples</clientUnit>
              </schemataService>
              <schemata>
                <schema>
                  <ref>VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0</ref>
                </schema>
              </schemata>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-lattice</artifactId>
      <version>1.9.4</version>
    </dependency>
    ...
  </dependencies>
</project>
```

Run `mvn install` in the `consumer` project and have a look into `target/generated-sources/vlingo` and into `target/classes` to make sure the code was pulled and compiled. The build output indicates that as well.

```
[INFO] --- xoom-build-plugins:1.7.7:pull-schema (pull) @ consumer ---
[INFO] xoom-build-plugins: Pulling code generated from XOOM Schemata registry.
[INFO] SchemataService{url=http://localhost:9019, clientOrganization='VLINGO', clientUnit='examples'}
[INFO] Retrieving version data for VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0 from http://localhost:9019/versions/VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0/status
[WARNING] VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0 status is 'Draft': don't use in production builds
[INFO] Pulling VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0 from http://localhost:9019/code/VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0/java
[INFO] Pulled VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0
[INFO] Writing VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.0.0 to /private/tmp/consumer/target/generated-sources/vlingo/io/vlingo/xoom/examples/producer/event/MyFirstEvent.java
[INFO] Wrote /private/tmp/consumer/target/generated-sources/vlingo/io/vlingo/xoom/examples/producer/event/MyFirstEvent.java
```

You might have noted that the build emitted a warning that you're using a `Draft` version, so let's fix that. Head over to the GUI, publish the schema from the `Home`-View (as seen in[ Using the GUI](/xoom-schemata#using-the-gui)) and re-run the build. Now the warning is gone.

XOOM Schemata does not only validate the version lifecycle but also whether changes are valid given semantic versioning. To see how this looks like, make incompatible changes to your specification and try to publish them as a new `minor` version.

In this example, we'll remove the `version` attribute, change the type of the `timestamp` attribute and change the name of the `type` attribute.

```
event MyFirstEvent {
  long occurredOn
  type changeEventType
}
```

In the `producer` pom, change the version number in the schema reference to `1.1.0` and add a line indicating the `previousVersion` and run `mvn install` in the `producer` project. You'll note that pushing the schema fails with the list of changes you made. Also try to create the new version via the GUI and review the validation messages there.

```
<schema>
  <ref>VLINGO:examples:io.vlingo.xoom.examples.producer:MyFirstEvent:1.1.0</ref>
  <previousVersion>1.0.0</previousVersion>
</schema>
```

Once you update the major version (`2.0.0`), the build will run fine again. You can now update your consumer to pull the new version.


# GraphQL Server

The XOOM GraphQL server for smooth legacy integration with complex queries made simple.

The XOOM GraphQL server component is based on [XOOM HTTP](/xoom-http). The `GraphQLResource` is a dynamic resource handler implemented as the Reactive HTTP endpoint used to submit queries to our GraphQL server for asynchronous execution. The `GraphQLResource` registers the URL `/graphql` as the only HTTP resource specific to GraphQL applications, and thus handles all GraphQL operations. The single endpoint is logical and actually scales with a configurable number of backing actors. As expected, our GraphQL server is end-to-end Reactive.

## Queries and Mutations

Queries can be as simple as asking for specific fields and/or nested fields on objects. Queries can accept arguments to fields.

More advanced concepts such as aliases, fragments, operation name, variables, and directives are supported as well. While queries perform data fetching, mutations perform state transformations. The following is a basic example of a find query handled by our GraphQL server:

```graphql
query {
    bookById(id: "book-1") {
        id
        name
        pageCount
        author {
            firstName
            lastName
        }
    }
}
```

And the following is an example of mutation on a resource entity. The *upsert*  query means to insert or update as needed, making it an idempotent operation:

```graphql
mutation {
    upsertBook(id: "book-8", name: "The Mysterious Stranger", pageCount: 200, authorId: "author-2") {
        id
        name
        pageCount
        author {
            firstName
            lastName
        }
    }
}
```

## Schemas and Types

XOOM GraphQL adopts a schema-first approach. The design of a GraphQL API starts with defining a schema. The grammar used for writing schemas is called *Schema Definition Language* (SDL). A schema definition supports all GraphQL concepts, such as object types, fields, arguments, scalar types, enumeration types, lists and non-null, as well as interfaces and union types. Server side integration with a specific schema is done by following naming conventions. Classes and methods must match with schema definition components. Queries are validated, and any validation mismatches are signaled as failures. Here is an example schema:

```graphql
# The Root Query for the application
type Query {
  bookById(id: ID): Book 
}

# The Root Mutation for the application
type Mutation {
  upsertBook(id: ID!, name: String!, pageCount: Int, authorId: ID!): Book
}

type Book {
  id: ID
  name: String
  pageCount: Int
  author: Author
}

type Author {
  id: ID
  firstName: String
  lastName: String
}
```

The schema types `Book` and `Author` map to class `Book` and `Author`, respectively:

```java
public class Book {
    private String id;
    private String name;
    private int pageCount;
    private Author author;

    public Book(String id, String name, int pageCount, Author author) {
        this.id = id;
        this.name = name;
        this.pageCount = pageCount;
        this.author = author;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getPageCount() {
        return pageCount;
    }

    public Author getAuthor() {
        return author;
    }

    public Book updateWith(final Book from) {
        this.name = from.name;
        this.pageCount = from.pageCount;
        this.author = from.author;

        return this;
    }
}
```

```java
public class Author {
    private String id;
    private String firstName;
    private String lastName;

    public Author(String id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }
}
```

The next topic is resolvers, which link data query results to schemas.

## Resolvers

Each query or mutation must have a resolver that is associated by a naming convention. A resolver is responsible for actually performing a specific operation. All resolvers are registered to a `GraphQLProcessor`. The `GraphQLProcessor` is used by the previously discussed `GraphQLResource`. The `GraphProcessor` is fully Reactive, being implemented as an actor.

This is a basic (and incomplete) query resolver type:

```java
package io.vlingo.xoom.graphql.resolvers;

import graphql.kickstart.tools.GraphQLQueryResolver;
import io.vlingo.xoom.graphql.Store;
import io.vlingo.xoom.graphql.model.Book;

public class BookQuery implements GraphQLQueryResolver {
    public Book getBookById(String bookId) {
        // query handling...
    }
}
```

And here is a mutation resolver example (also incomplete):

```java
package io.vlingo.xoom.graphql.resolvers;

import graphql.kickstart.tools.GraphQLMutationResolver;
import io.vlingo.xoom.graphql.Store;
import io.vlingo.xoom.graphql.model.Book;

public class BookMutation implements GraphQLMutationResolver {
    public Book upsertBook(final String id, final String name, final int pageCount, final String authorId) {
        // mutation handling...
    }

    private Book upsertBook(final Book book) {
        // mutation handling...
    }
}
```

For more complete examples, see the [example source code](https://github.com/vlingo/xoom-graphql/tree/master/src/test/java/io/vlingo/xoom/graphql).

## Client Integration

XOOM GraphQL supports seamless client side integration that makes for smooth query and mutation operations. There are generated classes for types, queries, mutations, requests, responses, and projections. Both the server side and client side are fully Reactive. Our Reactive HTTP client provided by XOOM HTTP can use the generated classes end-to-end.

The following is an example of a Reactive client consuming a GraphQL response from a query that is executed reactively; note the use of `.andFinallyConsume(...)`:

```java
package io.vlingo.xoom.graphql.integration;

import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest;
import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequest;
import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection;

import io.vlingo.xoom.actors.World;
import io.vlingo.xoom.http.resource.Client;
import io.vlingo.xoom.http.resource.Server;

public class BookStoreTest {
    private static final String host = "localhost";
    private static final int port = 8080;

    private static World world;
    private static Server server;
    private static Client client;
    
    ...

    private Response performRequest(final GraphQLOperationRequest request, final GraphQLResponseProjection responseProjection) {
        final GraphQLRequest graphQLRequest = new GraphQLRequest(request, responseProjection);
        final String graphQLQuery = graphQLRequest.toHttpJsonBody();

        final AccessResponseConsumer responseConsumer = new AccessResponseConsumer();

        client.requestWith(
                Request
                        .has(Method.POST)
                        .and(URI.create("/graphql"))
                        .and(RequestHeader.contentLength(graphQLQuery))
                        .and(RequestHeader.keepAlive())
                        .and(Body.from(graphQLQuery)))
                .andFinallyConsume(responseConsumer::consume);

        return responseConsumer.accessResponse();
    }
    
    @BeforeAll
    public static void setUp() throws Exception {
        world = World.startWithDefaults("xoom-graphql-test");

        GraphQLProcessor processor = TestBootstrap.newProcessor(world.stage());
        GraphQLResource graphQLResource = new GraphQLResource(world.stage(), processor);

        server = Server.startWith(world.stage(), Resources.are(graphQLResource.routes()), port, Configuration.Sizing.define(),
                new Configuration.Timing(4L, 2L, 100L));

        Address address = Address.from(Host.of(host), port, AddressType.NONE);
        client = Client.using(Client.Configuration.defaultedKeepAliveExceptFor(world.stage(), address, new UnknownResponseConsumer()));
    }
}
```

Don't forget testing your client-side and server-side query and mutation components!

## Unit Tests

End-to-end unit tests cover client side tests as well as server side tests together with full communication between both parties.

The classes in the `io.vlingo.xoom.graphql.client.model` package are generated based on schema definition. The following is an example unit test:

```java
package io.vlingo.xoom.graphql.integration;

import io.vlingo.xoom.graphql.client.model.*;

public class BookStoreTest {
@Test
    public void queryExistingBookTest() {
        final BookByIdQueryRequest bookRequest = BookByIdQueryRequest.builder()
                .setId("book-1")
                .build();

        final AuthorResponseProjection authorResponseProjection = new AuthorResponseProjection()
                .firstName()
                .lastName();

        final BookResponseProjection bookResponseProjection = new BookResponseProjection()
                .id()
                .name()
                .pageCount()
                .author(authorResponseProjection);

        Response response = performRequest(bookRequest, bookResponseProjection);
        Assertions.assertEquals("200", response.statusCode);

        BookByIdQueryResponse queryResponse = JsonSerialization.deserialized(response.entity.content(), BookByIdQueryResponse.class);
        Assertions.assertEquals(0, queryResponse.getErrors().size());

        Book book = queryResponse.bookById();
        Assertions.assertEquals("book-1", book.getId());
        Assertions.assertEquals("Romeo and Juliet", book.getName());
        Assertions.assertEquals("William", book.getAuthor().getFirstName());
        Assertions.assertEquals("Shakespeare", book.getAuthor().getLastName());
    }
}
```

See the [source code](https://github.com/vlingo/xoom-graphql/tree/master/src/test/java/io/vlingo/xoom/graphql) for more examples.


# Symbio (Reactive Storage)

The VLINGO XOOM Reactive CQRS and Event Sourcing storage and projections.

## What Is Symbio?

The idea behind the name "symbio" is that there is a symbiotic relationship between domain models and persistence, and persistence and domain models. They depend on each other, but in a way that neither "life form" may be entirely conscious of the other. This is certainly true of the domain model more so than the data model.

The XOOM Symbio parent tool is a set of protocols and default in-memory implementations. The protocols are usable by concrete implementations. The in-memory implementations are useful for testing.

There are three primary kinds of storage mechanism protocols available: `ObjectStore`, `StateStore` (i.e. Key-Value and NoSQL), and `Journal`. Among these there are a number of concrete implementations. For example, there are Postgres implementations of all three: `ObjectStore`, `StateStore`, and `Journal`.

{% hint style="info" %}
An important point to consider is, if you use the XOOM Lattice entity types, there is no need to learn the operations of the storage types. You get all storage persistence for free when you use one of `ObjectEntity`, `StatefulEntity`, and `EventSourced`.
{% endhint %}

Each storage type is discussed in the following subsections. Additionally there is a separate useful discussion about Adapters, which are used to translate between application or service state and persistent state.

| Type                                             | Description                                                                                                                                                                                                                                               |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ObjectStore](/xoom-symbio/object-storage)       | <p></p><p>An object storage in which <code>StateObject</code> instances are self defined, including their identity. This is often thought of as object-relational mapping, which certainly can be and is supported, but is not limited to such.</p>       |
| [StateStore](/xoom-symbio/state-storage)         | The basic state storage protocol in which `StateObject` instances are persisted as key-value tuples, with CLOB/BLOB values. This is used as a NoSQL database, but may use an RDBMS as the storage engine.                                                 |
| [Journal](/xoom-symbio/sourcing-journal-storage) | Used within a Bounded Context (microservice) to store `DomainEvent` and `Command` instances. Each use of the `Journal` appends some number of `Entry` instances, which are serialized `DomainEvent` and `Command` instances, and perhaps State snapshots. |
| [Adapters](/xoom-symbio/adapters)                | Used to roundtrip translate between service/application state and storage state.                                                                                                                                                                          |


# Journal Storage

Store event and command entries in journals that collectively define state.

A `Journal` , like a ledger, keeps a record of all occurrences of important happenings in a domain model of a Bounded Context. A `Journal` may be thought of in terms of Event Sourcing, because event instances may be journaled over the lifetime of a given Entity/Aggregate that capture the result of actions that were carried out on it. The captured set of ordered events of a given Entity/Aggregate together form its event stream. A single `Journal` may be used to hold the event streams of all Entity/Aggregate instances of a Bounded Context.

However, a `Journal` need not be limited to persisting only events. The XOOM Symbio defines an abstract base class known as `Source`. A `Source` is parameterized by a specific type. There are no concrete `Source` types defined in XOOM Symbio. In XOOM Lattice there are a few concrete `Source` types defined: [`Command`](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#sourced), [`DomainEvent`](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#sourced), and [`Process`](https://docs.vlingo.io/vlingo-lattice/processes).

A `Command` is the expression of the intention to execute a command action. Although there is an expressed intention to carry out the command, the choice is up to the command receiver to accept and execute it, or to reject it. The command receiver is generally an Entity/Aggregate, but doesn't have to be; it could be a Domain Service or other kind of service. The `Command` type is a `Source`, an thus commands may be persisted in a `Journal`. Persisting a `Command` is generally done to ensure that it is guaranteed to be offered as an intention to be carried out at some future time. Generally Process Managers (or Sagas) will be `CommandSourced` because they issue commands to be carried out in response to previous outcomes. These previous outcomes are generally received by the Process Managers as `DomainEvent` instances.

A `DomainEvent` is a record of a significant business occurrence within a domain model. A `DomainEvent` may not be rejected, in the sense that it is a captured fact. However, it may be ignored by all unconcerned parties. Generally if there will be an action carried out in response to the fact of a `DomainEvent`, it will be by means of translating the `DomainEvent` to a `Command`, and thus the corresponding `Command` may be rejected.

A component that is `EventSourced` and a component that is `CommandSourced` are really quite similar, but the semantics are inverted for each. An `EventSourced` component receives commands and emits events in response. A `CommandSourced` component receives notification of event occurrences and emits commands in response. The receipt of a command by an `EventSourced` component need not be in the form of an object; it may be the receipt of a protocol message with parameters received by an actor asynchronously. The same applies for a `CommandSourced` component, which may be informed of a previous event occurrence by sending it a protocol message with parameters that is received asynchronously by the implementing actor.

Since it is possible for a Process Manager (or Saga) to emit both `Command` instances and `DomainEvent` instances, the instances will be wrapped in a `ProcessMessage`. This enables a Process Manager to stream all of its `Source` instances in a generic way.

The point of these `Source` types is that they may be used to represent the state of a given component, either one that is `EventSourced` or one that is `CommandSourced`, or a `ProcessMessage` that may be sourced by both commands and events. The state of any such component, such as an Entity/Aggregate is a stream of such `Source` types, ordered by the sequence in which they originally occurred.

You may think of a `Journal` as having the following logical columns, and which are actual persistence columns when using a relational database, for example.

| ID                                               | StreamName                                                  | StreamVersion                                                  | EntryData                   | EntryType                                      | Metadata                        |
| ------------------------------------------------ | ----------------------------------------------------------- | -------------------------------------------------------------- | --------------------------- | ---------------------------------------------- | ------------------------------- |
| A unique identity assigned to this source entry. | The unique identity of the component that owns this stream. | The index order of the occurrence of this entry in the stream. | The serialized source data. | The fully-qualified class name of this source. | Any data about the source data. |

A `Journal` need not be implemented in a relational database. It may use a key-value store or another kind of storage. Even so, logically the above elements must be supported by the storage mechanism.

A `Journal` may maintain snapshots of any given sourced type instances as a performance optimization when they have accumulated large streams. If snapshots are used the Journal must maintain them and provide the means to merge the stream from a given version into the snapshot state.

{% hint style="info" %}
An important point to consider is, if you use the XOOM Lattice entity type `EventSourced`, `CommandSourced`, or `ProcessMessage`, there is no need to learn the operations of the `Journal`. You get all storage persistence for free when you use one of the sourced entity abstract base types.
{% endhint %}

To obtain a `Journal`, create an actor with the protocol and the implementation you will use to store the source streams of your Bounded Context.

```java
Journal<String> journal =
  stage.actorFor(
    Journal.class,
    PostgresJournalActor.class,
    dispatcher,
    configuration);
```

As a convenience the Journal provides a factory method for creating the instance.

```java
Journal<T> using(
      final Stage stage,
      final Class<A> implementor,
      final Dispatcher<Dispatchable<Entry<T>,RS>> dispatcher,
      final Object...additional);
```

The `PostgresJournalActor` is the implementation of the Journal protocol for the Postgres database. The `Dispatcher` is used to accept newly appended `Source` instances, such as for various `DomainEvent` types, and relay them to consumers. The consumers may be projection processors that build and maintain CQRS query models, and that feed messaging topics and exchanges to publish the occurrences.

The following are the means to append `Source` instances to the `Journal`.

```java
void append(final String streamName, final int streamVersion, final Source<S> source, final AppendResultInterest interest, final Object object);

void append(final String streamName, final int streamVersion, final Source<S> source, final Metadata metadata, final AppendResultInterest interest, final Object object);

void appendWith(final String streamName, final int streamVersion, final Source<S> source, final ST snapshot, final AppendResultInterest interest, final Object object);

void appendWith(final String streamName, final int streamVersion, final Source<S> source, final Metadata metadata, final ST snapshot, final AppendResultInterest interest, final Object object);

void appendAll(final String streamName, final int fromStreamVersion, final List<Source<S>> sources, final AppendResultInterest interest, final Object object);

void appendAll(final String streamName, final int fromStreamVersion, final List<Source<S>> sources, final Metadata metadata, final AppendResultInterest interest, final Object object);

void appendAllWith(final String streamName, final int fromStreamVersion, final List<Source<S>> sources, final ST snapshot, final AppendResultInterest interest, final Object object);

void appendAllWith(final String streamName, final int fromStreamVersion, final List<Source<S>> sources, final Metadata metadata, final ST snapshot, final AppendResultInterest interest, final Object object);
```

The difference between these message types is the number of `Source` instances that will be appended, either one or more than one, and whether or not a snapshot will be persisted, and whether or not `Metadata` is provided.

The `AppendResultInterest` is used to asynchronously communicate the result of the append to the sender. The result maybe be a success or failure, and will contain the data provided for the append operation, along with any `Object` instance that is optionally sent.

Although the `Dispatcher` registered with the `Journal` is used to guarantee delivery of the original `Source` and corresponding persisted serialized `Entry`, clients may desire to read the `Journal` contents at any future time. To do so the client obtains a `JournalReader`.

```java
Completes<JournalReader<ET>> journalReader(final String name);
```

The `JournalReader` is returned asynchronously by means of a `Completes` and is given the `name` provided as a parameter. If the same `name` is requested in the future of this actor's in-memory lifetime, the same `JournalReader` is returned.

The `JournalReader` provides the following protocol.

```java
void close();
Completes<String> name();
Completes<T> readNext();
Completes<List<T>> readNext(final int maximumEntries);
void rewind();
Completes<String> seekTo(final String id);
```

All query messages that answer values do so asynchronously using `Completes`. The parameterless `readNext()` answers the single next available `Entry` in the `Journal`. The `readNext(maximumEntries)` answers the next available `Entry` instances up to the `maximumEntries`. The `rewind()` moves the read start location back to the beginning of the `Journal`. The `seekTo()` is used to seek to a given `Entry` position in the `Journal`, or to simply provide the current position.

| ID          | Description                                                                                                                                  |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`        | Seek to the `Entry` that possesses the `id` corresponding to the given `id` (e.g. position or sequence).                                     |
| `Beginning` | Seek to the beginning of the `Journal`, which is the same as using `rewind()`. Answers the current position following the operation.         |
| `End`       | Seek to the end of the `Journal`, which is the position past the current last `Entry`. Answers the current position following the operation. |
| `Query`     | Do not seek in either direction. Only answers the current position.                                                                          |

To read individual Entry/Aggregate `Source` streams, use the `StreamReader`. You may obtain this also from the `Journal`.

```java
Completes<StreamReader<T>> streamReader(final String name);
```

As with the `JournalReader`, the `StreamReader` is returned asynchronously by means of a `Completes` and is given the `name` provided as a parameter. If the same `name` is requested in the future of this actor's in-memory lifetime, the same `StreamReader` is returned.

The `StreamReader` works as follows.

```java
Completes<Stream<T>> streamFor(final String streamName);
Completes<Stream<T>> streamFor(final String streamName, final int fromStreamVersion);
```

Both of the message implementations are obligated to optimize the `Stream` that is answered. Optimizing the stream means that if a snapshot is available it is read first, and only the `Entry` instances that follow the snapshot's version are read. This optimization applies to both `streamFor()` query messages.

The `streamFor(streamName)` will answer the full `Stream` of the Entity/Aggregate uniquely identified by `streamName` if a snapshot is unavailable. The `streamFor(streamName)` uses `streamFor(streamName, 1)`. The`streamFor(streamName, fromStreamVersion)` answers the sub-portion of the`Stream` uniquely identified by `streamName` starting at the `fromStreamVersion` until the stream's end. The `Stream` is defined as follows.

```java
public class Stream<T> {
  public final State<T> snapshot;
  public final List<BaseEntry<T>> entries;
  public final String streamName;
  public final int streamVersion;

  public boolean hasSnapshot();
  public int size();
}
```

The `snapshot`, if any, and the `entries`, are all in serialized form; that is, the `State<T>` and `BaseEntry<T>` respectively. The `T` parameter indicates whether it is a text `String` based serialization or a binary serialization of `byte[]`. This depends on the concrete `Journal` implementation used. To render the `Entry` instances and possible `State` to their native form, use the `EntryAdapter` and `StateAdapter` respectively.

## Concrete Implementations

The following provides information on using various `Journal` implementations. We provide specific guidance on using PostgreSQL, but this is nearly the same across other databases when using JDBC .

### Using XOOM Symbio JDBC

XOOM Symbio JDBC comes with a high-performance implementation of an event journal based on a PostgreSQL backend. To start using the event journal you will need to add XOOM Symbio dependencies to your project, using either Maven or Gradle. Remember to get the latest version from Maven Central to be up to date and enjoy the latest features and improvements.

{% tabs %}
{% tab title="Maven" %}

```markup
<dependency>
  <groupId>io.vlingo.xoom</groupId>
  <artifactId>xoom-symbio</artifactId>
  <version>1.7.0</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>io.vlingo.xoom</groupId>
  <artifactId>xoom-symbio-jdbc</artifactId>
  <version>1.7.0</version>
  <scope>compile</scope>
</dependency>

```

{% endtab %}

{% tab title="Gradle" %}

```groovy
dependencies {
    compile 'io.vlingo:vlingo-symbio:1.3.0'
    compile 'io.vlingo:vlingo-symbio-jdbc:1.3.0'
}
```

{% endtab %}
{% endtabs %}

After setting up the project to use XOOM Symbio the next step is to set up your PostgreSQL database.

### Setting Up PostgreSQL

XOOM Symbio will need access to a PostgreSQL Schema and a set of tables and indexes to ensure the behavior of the application. However, it doesn't need to be dedicated only to XOOM Symbio. If you already have your application deployed and using a pre-existing schema, you can reuse for XOOM Symbio JDBC.

{% hint style="info" %}
If you don't have a PostgreSQL on your development machine, we suggest you to use Docker and `docker-compose`, so you can easily recreate a local development cluster. [You can use this `docker-compose.yaml` as an example.](https://github.com/vlingo/vlingo-symbio-jdbc/blob/master/docker-compose.yaml)
{% endhint %}

The event journal will not create and update the needed set of tables and indexes required to work. You may use the following script that will create the necessary tables.

```sql
CREATE TABLE tbl_xoom_symbio_journal (
  e_id                      BIGSERIAL PRIMARY KEY,
  e_stream_name             VARCHAR(512) NOT NULL,
  e_stream_version          INTEGER      NOT NULL,
  e_entry_data              TEXT         NOT NULL,
  e_entry_type              VARCHAR(512) NOT NULL,
  e_entry_type_version      INTEGER      NOT NULL,
  e_entry_metadata          TEXT         NOT NULL
);

CREATE INDEX tbl_xoom_symbio_journal_idx ON tbl_xoom_symbio_journal (e_stream_name, e_stream_version);

CREATE TABLE tbl_xoom_symbio_journal_snapshots (
  s_stream_name             VARCHAR(512) PRIMARY KEY,
  s_stream_version          INTEGER      NOT NULL,
  s_snapshot_data           TEXT         NOT NULL,
  s_snapshot_data_version   INTEGER      NOT NULL,
  s_snapshot_type           VARCHAR(512) NOT NULL,
  s_snapshot_type_version   INTEGER      NOT NULL,
  s_snapshot_metadata       TEXT         NOT NULL
);

CREATE TABLE tbl_xoom_symbio_journal_dispatchables (
  d_dispatch_id             VARCHAR(512) PRIMARY KEY,
  d_originator_id           VARCHAR(512) NOT NULL,
  d_created_on              BIGINT       NOT NULL,
  d_state_id                VARCHAR(512) NULL,
  d_state_data              TEXT         NULL,
  d_state_data_version      INT          NULL,
  d_state_type              VARCHAR(512) NULL,
  d_state_type_version      INTEGER      NULL,
  d_state_metadata          TEXT         NULL,
  d_entries                 TEXT         NOT NULL
);

CREATE TABLE tbl_xoom_symbio_journal_offsets (
  o_reader_name             VARCHAR(128) PRIMARY KEY,
  o_reader_offset           BIGINT       NOT NULL
);
```

{% hint style="info" %}
We recommend that you run this script using a SQL migration system like [**Flyway**](https://flywaydb.org/) instead of doing it manually. Doing so will ensure that the system is easy to reproduce. You can see an example of an Event Sourced application that uses **Flyway** [here](https://github.com/vlingo/vlingo-examples/blob/fa8d6736cb9215f6db4e2443bf7ac63f978c3c14/vlingo-eventjournal/src/main/java/io/vlingo/eventjournal/Bootstrap.java#L29).
{% endhint %}

Even if we acknowledge that this configuration works with good performance, you might need to change how indexes and tables are created and stored in your cluster depending on your current set up.

### Opening the Event Journal

Before starting to emit events you need to open a connection to your database.

```java
final Configuration configuration = new Configuration(
      new NoopConfigurationInterest(), // You will need to create your own ConfigurationInterest
      "org.postgresql.Driver",
      StateStore.DataFormat.Text,
      DB_URL,   // Valid JDBC URL
      DB_NAME,  // Database name
      DB_USER,  // Database username
      DB_PWD,   // Database password
      false,    // Use a SSL Connection (true in production)
      "",       // Originator id (ignored for the event journal)
      false     // Create tables (ignored for the event journal)
  );
```

With an open connection to your Postgres cluster, creating the Journal is as easy as creating a new actor that implements the `Journal` protocol. For JDBC-compatible databases you use`JDBCJournalActor`**.** There is a `JournalListener` with useful hooks during the lifecycle of the Event Journal, so you can implement yours or keep it empty (but it can't be null).

```java
final World world = World.startWithDefaults("event-sourced-app");
final Journal journal = world.actorFor(
        Journal.class,
        Definition.has(JDBCJournalActor.class, Definition.parameters(configuration, new NoOpDispatcher()))
);
```

### Appending Events to the Event Journal

The Postgres Journal at this moment only supports text events. Appending events is transactional and you only need a single method call:

```java
journal.append((1) counterName, (2) version++, (3) textEvent, (4) resultInterest, (5) context);
```

1. The name of the Event Stream where the event will be published. Usually it's the ID of the aggregate root that will publish this event.
2. The version of the Event Stream, it should be incremental and starting from 1.
3. A TextEvent that will contain the event information.
4. An interest that will be executed with the result of the operation.
5. Context to be given to the interest. It can be any object.

You can see an example [here](https://github.com/vlingo/vlingo-examples/blob/master/vlingo-eventjournal/src/main/java/io/vlingo/eventjournal/counter/CounterActor.java).

### Choosing a Journal

There are several options for the backing storage engines and the options will continue to grow over time. Of the various RDBM databases it may be more a matter of which database is supported in your enterprise. It may be a performance concern, and perhaps you have concluded that PostgreSQL is more performant than MySQL or another.

We will be adding support for NoSQL databases. Stay in touch for announcements.


# State Storage

Using the XOOM Symbio Key-Value and NoSQL storage.

The state storage type persists key-value pairs, offering the features of a NoSQL database. The `key` is a business `id` and the `value` is the serialized state of an entity. You may also transactionally append `DomainEvent` instances, and other `Source` types, such as `Command`, along with states.

## Configuring and Starting the `StateStore`

Every `StateStore` is implemented as an `Actor`. Thus, you must use the `World` or one of its `Stage` instances to create the `StateStore`. Before doing this there are a few dependencies you must create, including `Configuration`. These get sent in as parameters to the `StateStore` constructor.

Every entity type must be registered. This is how the `StateStore` knows the table (or other persistence collection type) name to use for a given entity type.

```java
// using the class simple name
final String productStoreName = Product.class.getSimpleName();

StateTypeStateStoreMap.stateTypeToStoreName(Product.class, productStoreName);

// using the scheme name
final String productStoreName =
    "tbl_xoom_symbio_state_" +
    Product.class.getSimpleName();

StateTypeStateStoreMap.stateTypeToStoreName(Product.class, productStoreName);
```

Further, each persistent entity and `Source`—`DomainEvent` or `Command`—should have a serialization and deserialization [adapter](/xoom-symbio/adapters).

```java
import io.vlingo.xoom.symbio.EntryAdapterProvider;

EntryAdapterProvider provider = EntryAdapterProvider.instance(world);

// ProductDefinedAdapter is a io.vlingo.xoom.symbio.EntryAdapter
provider.registerAdapter(ProductDefined.class, new ProductDefinedAdapter());

// ProductStateAdapter is a io.vlingo.xoom.symbio.StateAdapter
provider.registerAdapter(ProductState.class, new ProductStateAdapter());
```

The following is the configuration used to create a new `StateStore` for a given database, which in this case is Postgres.

```sql
import io.vlingo.xoom.lattice.model.projection.ProjectionDispatcher;
import io.vlingo.xoom.lattice.model.projection.ProjectionDispatcher.ProjectToDescription;
import io.vlingo.xoom.lattice.model.projection.TextProjectionDispatcherActor;
import io.vlingo.xoom.symbio.store.common.jdbc.Configuration;
import io.vlingo.xoom.symbio.store.common.jdbc.postgres.PostgresConfigurationProvider;
import io.vlingo.xoom.symbio.store.dispatch.Dispatcher;
import io.vlingo.xoom.symbio.store.state.jdbc.StorageDelegate;
import io.vlingo.xoom.symbio.store.state.jdbc.postgres.PostgresStorageDelegate;

World world = World.startWithDefaults("product-service");
...
List<ProjectToDescription> descriptions =
    Arrays.asList(new ProjectToDescription(UserProjectionActor.class, Events.class.getPackage()),
    ...);

Dispatcher dispatcher =
    world.actorFor(Dispatcher.class, TextProjectionDispatcherActor.class, descriptions);

Configuration configuration =
    PostgresConfigurationProvider.configuration(...);

StorageDelegate delegate =
    new PostgresStorageDelegate(configuration, world.defaultLogger());

StateStore stateStore =
    world.actorFor(StateStore.class, JDBCStateStoreActor.class,
       dispatcher, delegate);
```

This creates a new `Actor`-based `StateStore` that is ready to receive and process persistence messages.

{% hint style="info" %}
An important point to consider is, if you use the XOOM Lattice entity type`StatefulEntity`, there is no need to learn the operations of the `StateStore`. You get all storage persistence for free when you use the `StatefulEntity` abstract base types. Yet, you still must apply the above configuration steps.
{% endhint %}

## Writing `State` and `Source` Instances

The following is the code that persists a given state and any sources (e.g. `DomainEvent`) to the `StateStore`.

```sql
stateStore.write(id, state, stateVersion, events, metadata, writeInterest);
```

The `write()` is used as follows.

```sql
import io.vlingo.xoom.symbio.store.state;
...
stateStore.write(productState.id, productState, 1, productState.events, productState.metadata, writeInterest, writeTracker);
```

Note that a `ProductEntity` actor should be designed with a `ProductState` that is the actual persistence state.

The `WriteInterest` will receive the write outcome of success or failure.

```java
import io.vlingo.xoom.symbio.store.state;
...
public class ProductWriteInterest extends Actor implements WriteResultInterest {
  void writeResultedIn(final Outcome<StorageException,Result> outcome, final String id, final S state, final int stateVersion, final List<Source<C>> sources, final Object object) {
    final WriteTracker writeTracker = (WriteTracker) object;
        
    outcome
      .andThen(result -> {
        // success actions...

        return result;
      })
      .otherwise(cause -> {
        // failure actions...
        
        final String message = writeTracker.failureMessageFor(cause);

        logger().error(message, cause);

        throw new IllegalStateException(message, cause);
      });
  }
}
```

## Reading `State` Instances

You may read a state from a `StateStore` as follows.

```sql
stateStore.read(id, entityType, readInterest, referenceObject);
```

The `read()` is used as follows.

```sql
import io.vlingo.xoom.symbio.store.state;
...
stateSore.read(productState.id, ProductState.class, 1, readInterest, ignoreNotFound);
```

The `readInterest` is the `ReadResultInterest` that receives the outcome of the read operation, with the `referenceObject` passed back to it. The `ReadResultInterest` works as follows.

```java
import io.vlingo.xoom.symbio.store.state.StateStore.ReadResultInterest;

public class ProductReadInterest extends Actor implements ReadResultInterest {
  final public <ST> void readResultedIn(final Outcome<StorageException, Result> outcome, final String id, final ST state, final int stateVersion, final Metadata metadata, final Object object) {
    outcome
      .andThen(result -> {
        // success actions...
        
        return result;
      })
      .otherwise(cause -> {
        // failure actions...

        final boolean ignoreNotFound = (boolean) object;
        if (!ignoreNotFound) {
          final String message = "State not restored for: " + getClass() + "(" + id + ") because: " + cause.result + " with: " + cause.getMessage();
          logger().error(message, cause);
          throw new IllegalStateException(message, cause);
        }
        return cause.result;
      });
  }
}
```

## Streaming Over `Entry` Instances of `Source` Types

[Streaming](/xoom-streams) is an extremely important part of reactive. For queries, it prevents dealing with all results at one time by enabling a message-driven model where you see one element at a time as it is pushed to your consumer. You may stream over all instances of `ProductState` as follows.

```java
Stream<ProductState> stream = stateStore.streamAllOf(ProductState.class);
```

You may instead stream over a constrained subset of `ProductState` instances.

```java
Stream<ProductState> stream = stateStore.streamSomeUsing(productStateQuery);
```

A `QueryExpression` may be defined as follows.

```sql
import io.vlingo.xoom.symbio.store;

Stream<ProductState> stream =
    stateStore.streamSomeUsing(
        QueryExpression.using(ProductState.class, "select ..."));

// or

Stream<ProductState> stream =
    stateStore.streamSomeUsing(
        QueryExpression.using(ProductState.class, "select ...", QueryMode.ReadOnly);
```

## Creating `StateStore` Database Tables

There are several implementations of the `StateStore`. One primary type is for JDBC over relational databases. There are also implementations for Amazon DynamoDB and Apache Geode. The following provides set up and configuration for each of these.

### Using Relational Databases with JDBC

Although the `StateStore` can auto-create all necessary tables, you may want to pre-create the necessary tables. There will be a unique table for every entity type stored. Note the `{0}` parameter in the following table naming scheme. You will replace this parameter with your entity type name, which may be the class simple name. This must include the prefix `"tbl_"`. For example, a class named `Product` would have the table named `tbl_product`.&#x20;

More formally, you may want to use the pattern `tbl_xoom_symbio_state_{0}`, the class simple name replacing the parameter. For the class named Product, your table would be named `tbl_xoom_symbio_state_product`. Using this scheme visually documents that your table is specifically used by the SYMBIO `StateStore`.This is the table creation script for Postgres.

```sql
CREATE TABLE {0} (
  s_id                      VARCHAR(128) PRIMARY KEY,
  s_type                    VARCHAR(256) NOT NULL,
  s_type_version            INT NOT NULL,
  s_data                    {1} NOT NULL,
  s_data_version            INT NOT NULL,
  s_metadata_value          TEXT NOT NULL,
  s_metadata_op             VARCHAR(128) NOT NULL
);

```

Note that the `s_data` column is created according to your preferred storage type, text or binary. The following table explains per database.

| Database | Column Type                                                                               |
| -------- | ----------------------------------------------------------------------------------------- |
| HSQLDB   | The ***Text*** type is defaulted to `LONGVARCHAR(65535)`.                                 |
| HSQLDB   | The ***Binary*** type is defaulted to `VARBINARY(65535)`.                                 |
| MariaDB  | See MySQL.                                                                                |
| MySQL    | The ***Text*** type is defaulted to `TEXT`.                                               |
| MySQL    | The ***Binary*** type is defaulted to `VARBINARY(4096)`.                                  |
| Postgres | The ***Text*** type is defaulted to `JSONB`, making your entities' attributes searchable. |
| Postgres | The ***Binary*** type is defaulted to `BYTEA`.                                            |
| YugaByte | See Postgres.                                                                             |

You indicate your preferences in the configuration.

```java
// Configuration
package io.vlingo.xoom.symbio.store.common.jdbc.Configuration;

public class Configuration {
  ...
  public final DataFormat format;
  ...
}
```

```java
// DataFormat
package io.vlingo.xoom.symbio.store;

public enum DataFormat {
  Binary,
  Text
};
```

The following format type and column type pair up: `DataFormat.Binary` and `s_data` column type `BYTEA`. Likewise the following two are used together:`DataFormat.Text` and `s_data` column type `TEXT`. You must consistently use the same types across all tables that use the same `StateStore`.

The following table must be created to support dispatching write events from the `StateStore`. This is how we ensure that `Dispatchables` are delivered via the `Dispatcher`.

```sql
CREATE TABLE tbl_xoom_symbio_dispatchables (
  d_id                         BIGSERIAL PRIMARY KEY,
  d_created_at                 TIMESTAMP NOT NULL,
  d_originator_id              VARCHAR(32) NOT NULL,
  d_dispatch_id                VARCHAR(128) NOT NULL,
  d_state_id                   VARCHAR(128) NOT NULL,
  d_state_type                 VARCHAR(256) NOT NULL,
  d_state_type_version         INT NOT NULL,
  d_state_data                 {1} NOT NULL,
  d_state_data_version         INT NOT NULL,
  d_state_metadata_value       TEXT NOT NULL,
  d_state_metadata_op          VARCHAR(128) NOT NULL,
  d_state_metadata_object      TEXT,
  d_state_metadata_object_type VARCHAR(256),
  d_entries                    TEXT
);

CREATE INDEX idx_dispatchables_dispatch_id
     ON tbl_xoom_symbio_dispatchables (d_dispatch_id);
 
CREATE INDEX idx_dispatchables_originator_id
     ON tbl_xoom_symbio_dispatchables (d_originator_id);

```

The same rules for the `DataFormat` and `d_state_data` column type apply for the `tbl_xoom_symbio_dispatchables` table. You must consistently use the same types across all tables that use the same `StateStore`.

The following is the table used to store `DomainEvent` instances and other `Source` types such as `Command`.

```sql
CREATE TABLE tbl_xoom_symbio_state_entry (
  e_id                         BIGSERIAL PRIMARY KEY,
  e_type                       VARCHAR(256) NOT NULL,
  e_type_version               INT NOT NULL,
  e_data                       {1} NOT NULL,
  e_metadata_value             VARCHAR(4000) NOT NULL,
  e_metadata_op                VARCHAR(128) NOT NULL
);
```

The same rules for the `DataFormat` and `d_state_data` column type apply for the `tbl_xoom_symbio_state_entry` table and its `e_data` column. You must consistently use the same types across all tables that use the same `StateStore`.

The following table supports totally ordered streaming reads of the `Entry` instances stored in the `tbl_xoom_symbio_state_entry` table. The readers implement the interface`StateStoreEntryReader<T>`, which extends `EntryReader<T>`.

```sql
CREATE TABLE tbl_xoom_symbio_state_entry_offsets (
  reader_name                   VARCHAR(128) PRIMARY KEY,
  reader_offset                 BIGINT NOT NULL
);
```

Each `EntryReader<T>` type has a `name` and a current `offset`, which are used to track the current position in the stream. The stream position/offset corresponds to a value of `e_id` in the `tbl_xoom_symbio_state_entry` table.

### NoSQL Storage Engines

The Symbio `StateStore` support extends beyond relational databases storage engines. Two of the prominent NoSQL persistence mechanisms are DynamoDB and Apache Geode. The set up for these is handled by the `StateStore` implementation and when registering types, such as by using `StateTypeStateStoreMap` and `EntryAdapterProvider`. When using [Lattice](https://docs.vlingo.io/vlingo-lattice/entity-cqrs), these are managed by the [`StatefulTypeRegistry`](https://docs.vlingo.io/vlingo-lattice/entity-cqrs#statefultyperegistry).


# Object Storage

Using XOOM Symbio to store objects.

An `ObjectStore` provides the protocol for reactively persisting and reconstituting objects. Storing objects has the advantage of searching for given instances by any number of their attributes/properties, effectively as if the objects are living in memory with only the need to ask for them by means of partial state characteristics. The objects stored are typically state types of Entity/Aggregate instances, which have unique identities. These state types are extenders of the `StateObject` abstract base class.

```java
import io.vlingo.xoom.symbio.store.object.StateObject;

public final class ProductState extends StateObject {
  private String name;
  private SKU sku;
  private RFID rfid;
  private Money price;
  ...
  
  public ProductState(long id, String name, SKU sku, RFID rfid, Money price) {
    super(id);
    
    this.name = name;
    this.sku = sku;
    this.rfid = rfid;
    this.price = price;
  }
}
```

Typically this `ProductState` would be held by the Aggregate `ProductActor`, where the actor implements the `Product` protocol.

```java
public ProductActor extends Actor implements Product {
  private ProductState state;
  
  public ProductActor(long id, String name, SKU sku, RFID rfid, Money price) {
    this.state = new ProductState(id, name, sku, rfid, price);
  }
  
  ...
}
```

In recent years object storage has been managed by a technique known as object-relational mapping (ORM), where objects are disassembled to fit into the relational table, row, and column structures. In such cases SQL expressions are used to create, read, update, and delete such objects. Using Java means that the SQL operations will be managed using JDBC, but will often employ a mapping layer on top of that. Some well-known ORM tools are TopLink/EclipseLink, Hibernate, various implementations of JPA, and others, such as Cayenne. There are other abstractions, such as Jdbi, that are not classified as an ORM, but provide worthy querying and mapping techniques that are much less invasive than ORM tools. All of these are or can be supported by a XOOM Symbio `ObjectStore` implementation.

Additionally, there is a XOOM Symbio `ObjectStore` implementation for Apache Geode. Apache Geode is an in-memory data fabric, compute grid, and distributed cache, which can hold object states.

{% hint style="info" %}
An important point to consider is, if you use the XOOM Lattice entity type `ObjectEntity`, there is no need to learn the operations of the `ObjectStore`. You get all storage persistence for free when you use the `ObjectEntity` abstract base types. Yet, you must still set up your backing database mechanism, including your chosen ORM configurations. We do not cover ORM details here.
{% endhint %}

## Object Persistence Protocols

The `ObjectStore` protocol extends `ObjectStoreReader` and `ObjectStoreWriter`, defining a single message type in addition: `close()`.

```java
public interface ObjectStore extends ObjectStoreReader, ObjectStoreWriter {
  void close();
}
```

First consider the `ObjectStoreWriter`. It is composed of a number of variations of `persist()` and `persistAll()` message types, with differences being in the number of parameters supported in each. The richest form of the two message types follow.

```java
<T extends PersistentObject, E> void persist(
  final T persistentObject,
  final List<Source<E>> sources,
  final Metadata metadata,
  final long updateId,
  final PersistResultInterest interest,
  final Object object);

<T extends PersistentObject, E> void persistAll(
  final Collection<T> persistentObjects,
  final List<Source<E>> sources,
  final Metadata metadata,
  final long updateId,
  final PersistResultInterest interest,
  final Object object);
```

As noted, there are variations of these two message types that have less parameters, providing defaults to the richer message types in their implementations. The full complement of parameters and types are described next.

| Parameter                         | Description                                                                                                                                                                                                                                                                                                                                                    |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `T persistentObject`              | `T` is a subclass of `PersistentObject`, which has two attributes: `long persistenceId` and `long version`, and serves as the means to persist the corresponding object with a primary key of `persistenceId`and a `version` indicating how many times the object has be modified.                                                                             |
| `Collection<T> persistentObjects` | The same as `T persistentObject`, but as a collection of one or more.                                                                                                                                                                                                                                                                                          |
| `List<Source<E>> sources`         | The `List` of `Source` instances, which are concrete subclasses of `DomainEvent`,  `Command`, or `ProcessMessage` (see [XOOM Lattice](/xoom-lattice) for details).                                                                                                                                                                                             |
| `Metadata metadata`               | The metadata to associate with the stored data.                                                                                                                                                                                                                                                                                                                |
| `long updateId`                   | The identity indicating that this persistence operation is considered an update of one or more previously read objects, or `-1L` if it is a creation, not an update, operation. A non-negative `updateId` will have been provided with the result of a read query. See `QueryExpression` and its `QueryMode`, which will be either `ReadOnly` or `ReadUpdate`. |
| `PersistResultInterest interest`  | A protocol backed by an `Actor` that will receive indication of the results following the persistence operation. During tests this protocol may be mocked as a plain object, but must be designed for concurrent access (see [`AccessSafely`](/xoom-actors#testing-actors)). See below for the definition of this protocol.                                    |
| `Object object`                   | An object that will be sent along with the `PersistResultInterest`. It may be `null`or a valid instance of any application (or service) defined type.                                                                                                                                                                                                          |

When using `ObjectStoreWriter`, the sender must provide an `Actor` or mocked test object that implements the `PersistResultInterest`protocol.

```java
public static interface PersistResultInterest {
  void persistResultedIn(final Outcome<StorageException,Result> outcome, final Object persistentObject, final int possible, final int actual, final Object object);
}
```

Next consider the `ObjectStoreReader` protocol. It provides a number of query methods, with variations on required and optional parameters.

```java
void queryAll(
  final QueryExpression expression,
  final QueryResultInterest interest,
  final Object object);
  
void queryObject(
  final QueryExpression expression,
  final QueryResultInterest interest,
  final Object object);
```

The difference between the two types of methods is the number of objects that should be included in the query results, either one or a one-or-more result.

| Parameter                      | Description                                                                                                                                                                                                                                                                                                           |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `QueryExpression expression`   | The expression used to resolve the query. See below for the definition of this protocol.                                                                                                                                                                                                                              |
| `QueryResultInterest interest` | A protocol backed by an `Actor` that will receive indication of the results following the query operation. During tests this protocol may be mocked as a plain object, but must be designed for concurrent access (see [`AccessSafely`](/xoom-actors#testing-actors)). See below for the definition of this protocol. |
| `Object object`                | An object that will be sent along with the `QueryResultInterest`. It may be `null`or a valid instance of any application (or service) defined type.                                                                                                                                                                   |

The `QueryExpression` is defined as follows. There are two extensions of the basic `QueryExpression`, which are `ListQueryExpression` and `MapQueryExpression`.

```java
public class QueryExpression {
  public final QueryMode mode;
  public final String query;
  public final Class<?> type;
  ...
}

public class ListQueryExpression extends QueryExpression {
  public final List<?> parameters;
  ...
}

public class MapQueryExpression extends QueryExpression {
  public final Map<String,?> parameters;
  ...
}
```

These class definitions include a number of factory methods for conveniently and expressively creating new instances of each.

The difference between these three query expression types is how parameters are supplied at runtime. The plain `QueryExpression` is a single parameterless expression. The parameters of a `ListQueryExpression` are ordered for setting as positional parameters 1, 2, 3, etc., or as a list of comma delimited parameters. The `MapQueryExpression` parameters are named using the `String` map keys, with the corresponding values to be set in the query expression, such as expression target `:id` matched with key `"id"` and value `"8d8acfe97a"`.

When using `ObjectStoreReader`, the sender must provide an `Actor` or mocked test object that implements the `QueryResultInterest`protocol.

```java
public static interface QueryResultInterest {
  void queryAllResultedIn(final Outcome<StorageException,Result> outcome, final QueryMultiResults results, final Object object);
  void queryObjectResultedIn(final Outcome<StorageException,Result> outcome, final QuerySingleResult result, final Object object);
}
```

When the receiver is informed of a query result, it is expressed as either a multiple *All* result or a single *Object* result. Note that the `Outcome` may be a `StorageException` or a successful `Result`. The `QueryMultiResults` holds a collection of resulting objects and `QuerySingleResult` holds a single object result.

## ObjectStore Implementations

There are a number of implementations of the `ObjectStore`.

### Component: `xoom-symbio`

You may use the in-memory implementation for testing.

```java
import io.vlingo.xoom.symbio.store.object.inmemory.InMemoryObjectStoreActor;
```

### Component: `xoom-symbio-geode`

This is the implementation of the `ObjectStore` for Apache Geode.

```java
import io.vlingo.xoom.symbio.store.object.geode.GeodeObjectStoreActor;
```

### Component: `xoom-symbio-jdbc`

These depend on specific database mechanisms, such as PostgreSQL, MySQL, MariaDB, and HSQLDB.

```java
// for Jdbi
import io.vlingo.xoom.symbio.store.object.jdbc.JDBCObjectStoreActor;
import io.vlingo.xoom.symbio.store.object.jdbc.jdbi.JdbiObjectStoreDelegate;

// for JPA
import io.vlingo.xoom.symbio.store.object.jdbc.jpa.JPAObjectStoreActor;
import io.vlingo.xoom.symbio.store.object.jdbc.jpa.JPAObjectStoreDelegate;
```


# Adapters

Using XOOM Symbio adapters to translate between service/application, messaging, and storage state.

Use XOOM Symbio adapters to translate object state within a service or application to serialized states that are suitable for network-based messaging and long-term database storage. To explain the details within this topic we refer to the following components.

| Type                      | Description                                                                                                                                                                                                                                                                |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `StateAdapter<S,RS>`      | The interface defining the behaviors of an adapter for application and serialized states.                                                                                                                                                                                  |
| `DefaultTextStateAdapter` | The default `StateAdapter` used when no type-specific adapter is registered with the `StateAdapterProvider`.                                                                                                                                                               |
| `StateAdapterProvider`    | The registry and provider of `StateAdapter` instances by state type, as well as adapter behaviors using type lookups.                                                                                                                                                      |
| `State<T>`                | The abstract base type that supports binary, object, and text serialization states.                                                                                                                                                                                        |
| `BinaryState`             | The concrete type that supports `State<byte[]>`.                                                                                                                                                                                                                           |
| `ObjectState`             | The concrete type that supports `State<Object>`.                                                                                                                                                                                                                           |
| `TextState`               | The concrete type that supports `State<String>`.                                                                                                                                                                                                                           |
| `EntryAdapter<S,E>`       | The interface defining the behaviors of an adapter for application sources and serialized entries.                                                                                                                                                                         |
| `DefaultTextEntryAdapter` | The default `EntryAdapter` used when no type-specific adapter is registered with the `EntryAdapterProvider`.                                                                                                                                                               |
| `EntryAdapterProvider`    | The registry and provider of `EntryAdapter` instances by source type, as well as adapter behaviors using type lookups.                                                                                                                                                     |
| `Entry<T>`                | The interface that defines a serialized state persisted to a `Journal<T>`. A journal entry may be a serialized `Source<T>` concrete implementation such as those defined in [XOOM Lattice](/xoom-lattice)**:** `Command`, `DomainEvent`, and `ProcessMessage`, and others. |
| `BaseEntry<T>`            | The abstract base type that supports entry binary, object, and text serialization.                                                                                                                                                                                         |
| `BinaryEntry`             | The concrete type that supports `Entry<byte[]>`.                                                                                                                                                                                                                           |
| `ObjectEntry`             | The concrete type that supports `Entry<Object>`.                                                                                                                                                                                                                           |
| `TextEntry`               | The concrete type that supports `Entry<String>`.                                                                                                                                                                                                                           |
| `NullEntry`               | The concrete type that implements the *Null Object* pattern for `Entry<byte[]>`, `Entry<Object>`, and `Entry<String>`.                                                                                                                                                     |

## Using Adapters

There are a few ways to use adapters. You may use the default adapters or implement your own. The use of the default adapters may be good enough to get your service or application up and running quickly. As time passes and your `DomainEvent` and/or `Command` types change, you will need to replace the defaults with your own implementations.

### Default Adapters

The XOOM Symbio tooling provides default `StateAdapter` and `EntryAdapter` types for both `State` and `Entry`. These default adapters will be used automatically when the service or application has not registered a custom adapter for a given state or source type. This means that you do not need to register these default adapters with the `StateAdapterProvider` or the `EntryAdapterProvider`.

The current default adapters are the `DefaultTextStateAdapter` and the `DefaultTextEntryAdapter`. Because these are default adapters you will not need to import them into your main code, although the import statements are shown here for clarity.

```java
import io.vlingo.xoom.symbio.DefaultTextEntryAdapter;
import io.vlingo.xoom.symbio.DefaultTextStateAdapter;
```

Both of these serialize from service and application object state to JSON text where the `State` and `Entry` types are `TextState` and `TextEntry`, respectively. They also deserialize from `TextState` and `TextEntry` back to service and application object state.

If you use a different text format other than JSON, or if you use binary, you must provide your own custom adapters. We may provide other default adapter types in the future depending on demand.

### Implementing Custom Type Adapters

The following is an example of the implementation of a `StateAdapter`.

```java
import io.vlingo.xoom.common.serialization.JsonSerialization;
import io.vlingo.xoom.symbio.Metadata;
import io.vlingo.xoom.symbio.State;
import io.vlingo.xoom.symbio.State.TextState;
import io.vlingo.xoom.symbio.StateAdapter;

public class ProductStateAdapter implements StateAdapter<ProductState,State<String>> {
  @Override public int typeVersion() { return 1; }

  @Override
  public Product fromRawState(final State<String> raw) {
    return JsonSerialization.deserialized(raw.data, ProductState.class);
  }

  @Override
  public <ST> ST fromRawState(final State<String> raw, final Class<ST> stateType) {
    return JsonSerialization.deserialized(raw.data, stateType);
  }

  @Override
  public State<String> toRawState(final ProductState state, final int stateVersion) {
    return toRawState(state.id, state, stateVersion, Metadata.nullMetadata());
  }

  @Override
  public State<String> toRawState(final String id, final ProductState state, final int stateVersion, final Metadata metadata) {
    final String serialization = JsonSerialization.serialized(state);
    return new TextState(id, ProductState.class, typeVersion(), serialization, stateVersion);
  }
}
```

This `ProductStateAdapter` is responsible for adapting from the `Product` service/application object state to what is called the *raw state* and back again from raw state to the `Product` service/application state.

The raw state is suitable for traveling across a network and being persisted into database storage. This is handled by the two methods named `toRawState()`.

The service/application state is, as the name indicates, used as operational state. Adapting from raw state back to service/application state is handled by the two methods named `fromRawState()`.

There is another method, `typeVersion()`, that provides the current version of the operational state type. This specific implementation indicates version `1`.  This version may also be encoded as a [`SemanticVersion`](https://docs.vlingo.io/vlingo-common#semantic-versions), as is provided with [XOOM Common](/xoom-common)*.*

The current type version is automatically encoded into the raw state. When adapting back from the raw state to the operational state, you must check the raw state's type version to determine if it must be upgraded to the current operational state type version. This is available via the variable `public final int typeVersion` in `State<T>`. (This is an immutable variable and does not require an accessor method.)

Next is an example of an `EntryAdapter` for the `CartInitialized` event.

```java
public class CartInitializedAdapter implements EntryAdapter<CartInitialized, TextEntry> {
  @Override
  public CartInitialized fromEntry(final TextEntry entry) {
    return JsonSerialization.deserialized(entry.entryData(), CartInitialized.class);
  }

  @Override
  public TextEntry toEntry(final CartInitialized source, final Metadata metadata) {
    final String serialization = JsonSerialization.serialized(source);
    return new TextEntry(CartInitialized.class, 1, serialization, metadata);
  }

  @Override
  public TextEntry toEntry(final CartInitialized source, final String id, final Metadata metadata) {
    final String serialization = JsonSerialization.serialized(source);
    return new TextEntry(id, CartInitialized.class, 1, serialization, metadata);
  }

  @Override
  public TextEntry toEntry(final CartInitialized source, final int version, final String id, final Metadata metadata) {
    final String serialization = JsonSerialization.serialized(source);
    return new TextEntry(id, CartInitialized.class, 1, serialization, version, metadata);
  }
}
```

The same design guidance applies for `EntryAdapter` implementations as for `StateAdapter`.

#### Registering Custom Type Adapters

Custom type adapters are registered with adapter providers. When the adapter provider is created it is registered with an associated unique identity in the `World`. The registration is a means to avoid the use of static variables to hold the adapter providers. It also makes it convenient for the various XOOM Symbio storage mechanisms to access the adapters when moving data into and out of the underlying databases.

To register a custom type adapter you first must allocate adapter providers, and then register each custom type adapter with a given adapter provider. The first example demonstrates registering state adapters.

```java
World world = World.startWithDefaults("my-service");

StateAdapterProvider stateAdapterProvider =
    StateAdapterProvider.instance(world);

stateAdapterProvider.registerAdapter(
    ProductState.class, new ProductStateAdapter());

stateAdapterProvider.registerAdapter(
    CartState.class, new CartStateAdapter());
```

The second example demonstrates registering entry adapters.

```java
World world = World.startWithDefaults("my-service");

EntryAdapterProvider entryAdapterProvider =
    EntryAdapterProvider.instance(world);

entryAdapterProvider.registerAdapter(
    CartInitialized.class, new CartInitializedEntryAdapter());

entryAdapterProvider.registerAdapter(
    ProductPlacedInCart.class, new ProductPlacedInCartEntryAdapter());
```

You should determine which states and sources (e.g. `DomainEvent` and `Command` types) must be exchanged **across** collaborating services and establish their schemas in the [XOOM Schemata](/xoom-schemata) schema registry.


# Cluster

Scaling your services with resilience using XOOM Cluster.

## Resiliency and Scale

The XOOM Cluster is a key component that sits on top of XOOM Actors to support the development of scalable and fault-tolerant tools and applications. Additional tools that build out the VLINGO XOOM platform will almost always be constructed on top of XOOM Cluster. You should also implement and deploy your services/applications in clusters.

Consider the following documentation specifically the how-to guides for XOOM Cluster; that is, how to configure it, how to run it, how it's designed, how it works. For practical use, including actor-based compute grid, service/application partitioning and scale, and cluster-wide data caching, see [XOOM Lattice](/xoom-lattice).

Besides scalable fault-tolerance, the XOOM Cluster also provides cluster-wide, synchronizing attributes of name-value pairs. This enables the cluster to share live and mutating operational state among all nodes. Likewise, application-level services can also make use of cluster-wide, synchronizing attributes in order to enhance shared application/service values.

![A three-node cluster with actors sending messages to actors across nodes.](/files/-MBkHhR8NIzAMx_DxQ4o)

Referring to the *cluster* diagram, if one of the three nodes is lost, the cluster will still maintain a quorum and remain healthy. However, if two nodes are lost and only one node remains in a running state, the quorum is lost and the cluster is considered unhealthy. In that case the one remaining node will enter an idle state and await one or more of the other nodes to return to active operation. When that occurs, the cluster will again constitute a quorum and reach a healthy state. Although many service/application clusters will require only three nodes for optimal use, clusters can support far more than three nodes. Yet, because of the performance and efﬁciencies of our platform, you may rarely need many nodes. Even a 9-node, 21-node, or 49-node cluster may be considered quite large due to our efficiency standards.

## Using the **XOOM Cluster**

You must first configure the cluster for your intended use. Currently this involves creating a Java `xoom-cluster.properties` file, which [looks like this](https://github.com/vlingo/xoom-cluster/blob/master/src/test/resources/xoom-cluster.properties).

The different properties are explained next.

### Cluster Limits, Timing, and Integration Configurations

<table data-header-hidden><thead><tr><th width="300">Property</th><th width="365.3333333333333">Value</th><th>Default</th></tr></thead><tbody><tr><td><code>cluster.op.buffer.size</code></td><td>The maximum size of a single operational message, which are actually tiny, other than DIR. Assuming short host names, 4096 would support approximately 90-99 nodes with DIR.</td><td></td></tr><tr><td><code>cluster.app.buffer.size</code></td><td>The maximum size of a single cluster client (tool, application, service) message. You may be able to tune this to be much smaller depending on the size of application/service messages.</td><td>10240</td></tr><tr><td><code>cluster.app.incoming.probe.interval</code></td><td>The interval (in milliseconds) within which the application inbound stream will be probed for available messages.</td><td>10</td></tr><tr><td><code>cluster.op.outgoing.pooled.buffers</code></td><td>The number of polled buffers for outgoing asynchronous operations messages.</td><td>20</td></tr><tr><td><code>cluster.app.outgoing.pooled.buffers</code></td><td>The number of polled buffers for outgoing asynchronous application messages.</td><td>50</td></tr><tr><td><code>cluster.msg.charset</code></td><td>The default Java character set type.</td><td>UTF-8</td></tr><tr><td><code>cluster.app.class</code></td><td>The fully-qualified name of the <code>Class</code> that serves as the client application/service instance used to integrate with the cluster. This class must implement the interface <code>ClusterApplication</code>, or extend the class <code>ClusterApplicationAdapter</code>. For example, <code>com.myapplication.cluster.MyClusterApp</code>could be the name of the class.</td><td></td></tr><tr><td><code>cluster.app.stage</code></td><td>The name of the <code>Stage</code> within which the client application/service instance is created. For example, <code>myapplication.stage</code>, may be the name of the <code>Stage</code> within which the<code>com.myapplication.cluster.MyClusterApp</code> instance is created.</td><td></td></tr><tr><td><p><code>cluster.attributes</code></p><p><code>.redistribution.interval</code></p></td><td>The interval in milliseconds within which the new and changed application/service level attributes maintained by the cluster are distributed and redistributed.</td><td>1000</td></tr><tr><td><p><code>cluster.attributes</code></p><p><code>.redistribution.retries</code></p></td><td>The number of retries for redistributing unconfirmed attribute changes.</td><td>20</td></tr><tr><td><code>cluster.startup.period</code></td><td>The interval in milliseconds within which each newly joined node takes the opportunity to discover the other nodes from the cluster. Within this period the communication with the other nodes is suspended.</td><td>5000</td></tr><tr><td><code>cluster.nodes.quorum</code></td><td>Under elastic scale, this is the least number of live nodes expected for a healthy cluster quorum.</td><td></td></tr><tr><td><code>cluster.seeds</code></td><td>Under elastic scale, this is the list of all seed nodes within the respective cluster. A seed is a regular node with the seed functionality enabled. This list has the following format: <code>&#x3C;seed1Host>.&#x3C;seed1Port>,&#x3C;seed2Host>.&#x3C;seed2Port></code>.</td><td></td></tr></tbody></table>

### Cluster Node Configurations

The properties (configuration) of each node are specified at startup, as argument, in the format `id:name:isSeed:host:opPort:appPort`. The specific properties and names are as follows.

| Node Description Property | Value                                                                                                                                                                                                                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | The unique identity of the given node with the name `node`.                                                                                                                                                                                                                           |
| `name`                    | The unique name of the node that must match one of the names in the `cluster.nodes` property.                                                                                                                                                                                         |
| `isSeed`                  | Indicates whether this node is a seed node. A seed node is one that will, virtually speaking, always be available for other nodes to receive service. Values are `true` or `false`. Each node which is seed as well must be declared in the seed list using `host:opPort` parameters. |
| `host`                    | The DNS name of the network host of the node with name `node`.                                                                                                                                                                                                                        |
| `opPort`                  | The port number that is assigned to the cluster node's operational socket channel.                                                                                                                                                                                                    |
| `appPort`                 | The port number that is assigned to the cluster node's incoming application/service socket channel.                                                                                                                                                                                   |

All of the above configurations should be tuned and assigned specifically for your cluster's operations. You should have a higher number of nodes than cluster.nodes.quorum to form a healthy cluster. Seed functionality facilitates the discovery of the nodes within the cluster and is mainly used at start up. Following startup the seed functionality is no longer needed and seed nodes simply act as regular nodes. The XOOM Cluster is developed based on a peer-to-peer, highly scalable cluster membership protocol, which manages membership after start up.

### Cluster Application

Each cluster node must have a configured cluster application `Stage` and `Class`. These are defined above as `cluster.app.stage` and  `cluster.app.class`. See the above respective integration configurations for details. Any class serving as a cluster application must implement the interface `ClusterApplication` and be an `Actor`. Both of these requirements are supported by extending the `ClusterApplicationAdapter` abstract base class. This adapter enables you to override only the integration methods of interest.

{% hint style="info" %}
You likely will not need to provide your own `ClusterApplication` implementation because our recommendation is to use the [XOOM Lattice Grid](/xoom-lattice/grid), which is based on XOOM Cluster. See below following the code example.
{% endhint %}

The following example is the `MyClusterApplication` that represents the supported integration interface, which demonstrates each available integration method.

```java
public class MyClusterApplication extends ClusterApplicationAdapter {
  private AttributesProtocol client;
  private final Node localNode;
  
  public MyClusterApplication(final Node localNode) {
    this.localNode = localNode;
  }

  @Override
  public void start() {
    logger().debug("APP: ClusterApplication started on node: " + localNode);
  }
  
  @Override
  public void stop() {
      logger().debug("APP: Local node is going to be stopped...");
  }

  @Override
  public void handleApplicationMessage(final RawMessage message, final ApplicationOutboundStream responder) {
     logger().debug("APP: Received application message: " + message.asTextMessage());
  }

  @Override
  public void informAllLiveNodes(final Collection<Node> liveNodes, final boolean isHealthyCluster) {
    for (final Node id : liveNodes) {
       logger().debug("APP: Live node confirmed: " + id);
    }
    printHealthy(isHealthyCluster);
  }

  @Override
  public void informNodeIsHealthy(final Id nodeId, final boolean isHealthyCluster) {
    logger().debug("APP: Node reported healthy: " + nodeId);
    printHealthy(isHealthyCluster);
  }

  @Override
  public void informNodeJoinedCluster(final Id nodeId, final boolean isHealthyCluster) {
    logger().debug("APP: " + nodeId + " joined cluster");
    printHealthy(isHealthyCluster);
  }

  @Override
  public void informNodeLeftCluster(final Id nodeId, final boolean isHealthyCluster) {
    logger().debug("APP: " + nodeId + " left cluster");
    printHealthy(isHealthyCluster);
  }

  @Override
  public void informAttributesClient(final AttributesProtocol client) {
    logger().debug("APP: Attributes Client received.");
    this.client = client;
    if (localNode.id().value() == 1) {
      client.add("fake.set", "fake.attribute.name1", "value1");
      client.add("fake.set", "fake.attribute.name2", "value2");
    }
  }

  @Override
  public void informAttributeSetCreated(final String attributeSetName) {
     logger().debug("APP: Attributes Set Created: " + attributeSetName);
  }

  @Override
  public void informAttributeAdded(final String attributeSetName, final String attributeName) {
    final Attribute<String> attr = client.attribute(attributeSetName, attributeName);
    logger().debug("APP: Attribute Set " + attributeSetName + " Attribute Added: " + attributeName + " Value: " + attr.value);
    if (localNode.id().value() == 1) {
      client.replace("fake.set", "fake.attribute.name1", "value-replaced-2");
      client.replace("fake.set", "fake.attribute.name2", "value-replaced-20");
    }
  }

  @Override
  public void informAttributeRemoved(final String attributeSetName, final String attributeName) {
    final Attribute<String> attr = client.attribute(attributeSetName, attributeName);
    logger().debug("APP: Attribute Set " + attributeSetName + " Attribute Removed: " + attributeName + " Attribute: " + attr);
  }

  @Override
  public void informAttributeSetRemoved(final String attributeSetName) {
    logger().debug("APP: Attributes Set Removed: " + attributeSetName);
  }

  @Override
  public void informAttributeReplaced(final String attributeSetName, final String attributeName) {
    final Attribute<String> attr = client.attribute(attributeSetName, attributeName);
    logger().debug("APP: Attribute Set " + attributeSetName + " Attribute Replaced: " + attributeName + " Value: " + attr.value);
    if (localNode.id().value() == 1) {
      client.remove("fake.set", "fake.attribute.name1");
    }
  }

  private void printHealthy(final boolean isHealthyCluster) {
    if (isHealthyCluster) {
       logger().debug("APP: Cluster is healthy");
    } else {
       logger().debug("APP: Cluster is NOT healthy");
    }
  }
}
```

You would implement your own cluster application, overriding the methods that interest you. Note that when using the [XOOM Lattice Grid](/xoom-lattice/grid), the `ClusterApplication` is provided for you by the Grid. Thus, only low-level cluster nodes are required to provide a `ClusterApplication`.

### Cluster-Wide Attributes

Note that the above `MyClusterApplication` has a property named `client`, which is an `AttributesProtocol`. The `AttributesProtocol` is the gateway to establishing the use of cluster-wide attributes. This `client` has the means to add new attributes, modify existing ones, and remove them.

```java
public class MyClusterApplication extends ClusterApplicationAdapter {
  private AttributesProtocol client;
  ...
    client.add("Set1", "Attribute1", "value1");
  ...
    client.replace("Set1", "Attribute1", "value2");
  ...
    client.remove("Set1", "Attribute1");
}
```

Here `"Set1"` is the name of a set of attributes with a specific name. All attributes added must be within a named set. The `"Attribute1"` is the name of an attribute within `"Set1"`. The `"value1"` is the initial value of `"Attribute1"` and `"value2"` is a different value that is later assigned to `"Attribute1"`. As these attribute setting operations take place, the sets of attributes are replicated across nodes within the cluster. Revisiting the `MyClusterApplication` lifecycle messages in the above code shows how each node in the cluster is informed of newly added, replaced, and removed attributes.

An attribute may be given using various types. As expected these include: `Byte`, `Short`, `Integer`, `Long`, `Character`, `Float`, `Double`, `Boolean`, and `String`. Currently there is no support for more complex objects.

Any object with a reference to the `AttributesProtocol` or `AttributesClient` (a non-`Actor` implementation of `AttributesProtocol`)  may add new attributes, modify existing ones, and remove them. The same protocol provides the means to query for current attribute sets and attributes within specific sets.

```
final Collection<AttributeSet> allSets = client.all();
final Collection<Attribute> allSetAttributes = client.allOf("Set1");
```

Since the client is purposely not backed by an `Actor` the query results will be immediate. The contents of the `Collection` results will be whatever the node currently has and will not reflect changes pending delivery from other nodes.

### Starting the Cluster

You must start each node in the cluster. The cluster will not become fully operational until a quorum of nodes are started and capable of communicating across their operational socket channels.

The `main()` startup class within the `xoom-cluster` JAR file is:

```
io.vlingo.xoom.cluster.NodeBootstrap
```

To start each node in the cluster, use the following commands. The first command may be used with Maven.

```
$ mvn exec:java -Dexec.args=1:node1:localhost:false:17171:17172
```

This second command would be used directly with the Java VM (actually setting the `classpath` as appropriate).

```
$ java -classpath path1:path2 io.vlingo.xoom.cluster.NodeBootstrap 1:node1:localhost:false:17171:17172
```

{% hint style="info" %}
The separator you should use between `classpath` entries is determined by your runtime environment. For Un\*x flavored environments this is `:` as show above. For Windows this is the `;` separator, such as `path1;path2`.
{% endhint %}

These two example commands start only the node named `node1`. You would perform a startup for each of the nodes named and configured in the Java `xoom-cluster.properties`.

Start each node by providing the node's name, as explained above, as the parameter to the `main()` class `NodeBootstrap`.

## Cluster Health and Membership

A cluster will composed of a dynamic number of nodes. Nodes can elastically join or leave the cluster. The minimum number nodes for a healthy cluster is `cluster.nodes.quorum`. The cluster membership is implemented based on [SWIM](https://www.cs.cornell.edu/projects/Quicksilver/public_pdfs/SWIM.pdf) (Scalable Weakly-consistent Infection-style Process Group Membership Protocol) protocol.


# Directory

Registering and discovering services with XOOM Directory.

## Service Registration and Discovery

The XOOM Directory component supports service registration and discovery. When a new Bounded Context, implemented as a microservice, is started, it registers itself with the XOOM Directory.

![The resilient XOOM DIRECTORY cluster is used to register your services and discover others.](/files/-MOngVAWGE7PqcF5K2s7)

As a result, other *Bounded Contexts* will discover the services that they must collaborate with. This happens when the XOOM Directory broadcasts the registration details, including hosts and ports, around the enterprise.&#x20;

This is a cluster-capable component, which means it is meant to be run within the XOOM Cluster for reactive high availability. The cluster leader node is responsible for receiving registrations and broadcasting services information to listeners. Other nodes in the directory cluster maintain replicated registration information. If the leader node of the XOOM Directory fails, another node takes over leadership and takes over in receiving registrations and broadcasting. You should deploy each XOOM Directory cluster with at least three nodes, but five nodes would be even more robust.

## Using the **XOOM Directory**

The following shows you how to register a service/application with the XOOM Directory and how to discover other services/applications that have registered with it. First configure the directory using the `xoom-directory.properties` file, which [looks like this](https://github.com/vlingo/xoom-directory/blob/master/src/main/resources/xoom-directory.properties).

The different properties are explained next.

### Setting Up a Directory

| Property                                       | Description                                                                                                                                                                                                                       | Default       |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `directory.group.address`                      | The directory service uses UDP to broadcast registration information to subscribers. This is the UDP group address for broadcasting.                                                                                              | `237.37.37.1` |
| `directory.group.port`                         | The port on which the `directory.group.address` operates.                                                                                                                                                                         | `37371`       |
| `directory.incoming.port`                      | On whatever IP address (possibly via a DNS domain name pointer) the directory service is running on, it will use this port number. The full address, including IP address and port, is broadcast by the directory service itself. | `37399`       |
| `directory.message.buffer.size`                | The size in bytes of the buffer used to process outgoing and incoming messages.                                                                                                                                                   | `32767`       |
| `directory.message.processing.interval`        | The interval (in milliseconds) between directory service message processing.                                                                                                                                                      | 50            |
| `directory.unregistered.service.notifications` | The number of times that the directory service will broadcast that a given service has unregistered.                                                                                                                              | 20            |

### Directory Client

The following provides the client perspective in interacting with the directory service. A client of the directory service must depend on the `xoom-directory` JAR file:

```markup
<dependency>
  <groupId>io.vlingo.xoom</groupId>
  <artifactId>xoom-directory</artifactId>
  <version>x.y.z</version>
</dependency>
```

Replace the version number `x.y.z` with the actual [released](https://github.com/vlingo/xoom-directory/releases) version, such as `1.7.0`.

Once configured you can start the `DirectoryClient` component, which is an `Actor`.

```java
final DirectoryClient client =
  DirectoryClient.instance(stage, interest, group);
  
// or...

final DirectoryClient client =
  DirectoryClient.instance(stage, interest, group, maxMessageSize,
       processingInterval, processingTimeout);
```

The parameters are discussed in the the following table.&#x20;

| Parameter            | Description                                                                                                                                                                                                                                |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `stage`              | The `Stage` in which the `DirectoryClient` actor should live.                                                                                                                                                                              |
| `interest`           | The `ServiceDiscoveryInterest`, which is a subscriber to service discovery information notifications provided by the directory.                                                                                                            |
| `group`              | The `io.vlingo.xoom.wire.multicast.Group` to join in order to receive broadcast notifications.                                                                                                                                             |
| `maxMessageSize`     | If overriding the default of `32767`, provide this value.                                                                                                                                                                                  |
| `processingInterval` | If overriding the default of 50 milliseconds, provide this value.                                                                                                                                                                          |
| `processingTimeout`  | If overriding the default of 10 retries, provide this value. This is the number of times that the receiver attempts to read new incoming notification data before giving up, with additional read attempts following `processingInterval`. |

After the `DirectoryClient` is started, you may send it messages to request registration of your service/application. This is accomplished using the `register()` message.

```java
final ServiceRegistrationInfo info =
    new ServiceRegistrationInfo(
        "agilepm-context",
        Arrays.asList(
          new Location("1.2.3.45", 1111),
          new Location("1.2.3.46", 1111),
          new Location("1.2.3.47", 1111)));

directoryClient.register(info);
```

The above example registers the service named `"agilepm-context"` with three nodes, each on different servers with different IP addresses. The nodes available with your service are configured as the nodes within a [XOOM Cluster](/xoom-cluster#cluster-node-configurations). When the  `"agilepm-context"` is shutting down it can unregister itself from the directory services. Unregistering will inform other services that the named service is not currently available.

```java
directoryClient.unregister("agilepm-context");
```

The client must supply a `ServiceDiscoveryInterest` during the registration of the`DirectoryClient`. This `ServiceDiscoveryInterest` instance is responsible for informing its interests in any particular service, and in reacting to the notification of newly discovered services and recently unregistered services.

```java
public class AgilePMServiceDiscoveryInterest extends Actor
    implements ServiceDiscoveryInterest {
  
  final List<String> myInterests =
    Arrays.toList("collaboration-service", "identity-access-service");
  
  final Map<String,ServiceRegistrationInfo> discoveredServices =
    HashMap<>();
  
  // ...
  
  @Override
  public boolean interestedIn(final String serviceName) {
    return myInterests.contains(serviceName);
  }

  @Override
  public void informDiscovered(final ServiceRegistrationInfo discoveredService) {
    if (interestedIn(discoveredService.name))
      discoveredServices.put(discoveredService.name, discoveredService));
    }
  }

  @Override
  public void informUnregistered(final String unregisteredServiceName) {
    discoveredServices.remove(unregisteredServiceName);
  }
}
```

In time the local service—the `agilepm-service`—will gain access to the services that it depends on—`"collaboration-service"` and  `"identity-access-service"`. This knowledge includes the IP addresses of the dependent services, which is one means to reach those services, such as with REST requests. How can this information be spread to all nodes in the service/application cluster? You can have a `ServiceDirectoryInterest` subscriber listening in every node. Or, you may decide to put the relevant `ServiceRegistrationInfo` into one or more [cluster-wide attributes](/xoom-cluster#cluster-wide-attributes).

## Implementation

The best place to see the implementation of the XOOM Directory service is in its main processing component[`io.vlingo.xoom.directory.model.DirectoryServiceActor`](https://github.com/vlingo/vlingo-directory/blob/master/src/main/java/io/vlingo/directory/model/DirectoryServiceActor.java). The directory information is both maintained here and broadcast from this point. For this discussion see the following packages:

```java
io.vlingo.xoom.cluster.model.application
io.vlingo.xoom.cluster.model.attribute
io.vlingo.xoom.directory.client
io.vlingo.xoom.directory.model
io.vlingo.xoom.wire.multicast
```

This is where XOOM Cluster and UDP multicasting meet. See the XOOM Wire component for its `MulticastPublisherReader`, which is alluded to in this discussion and used by the `DirectoryServiceActor`.

The `DirectoryService` protocol includes `assignLeadership()`, which is how a given XOOM Directory cluster node knows that it is in the lead and is the active UDP multicaster/publisher. Any other cluster nodes are standby in case the leader node is lost for any reason.&#x20;

A `DirectoryClient`, which is any service that wants to register and/or discover via the XOOM Directory, sends and receives availability information in the form of `ServiceRegistrationInfo` by supporting the `ServiceDiscoveryInterest` protocol.

Ultimately the [`io.vlingo.xoom.directory.model.DirectoryApplication`](https://github.com/vlingo/xoom-directory/blob/master/src/main/java/io/vlingo/xoom/directory/model/DirectoryApplication.java), which is a `ClusterApplication` via the `ClusterApplicationAdapter`, informs its own `DirectoryServiceActor` to go into either active or passive mode. Active mode is described above. Passive mode is any cluster node member that is not the leader. These (most typically 2 of 3 nodes in the cluster) simply collect publishable data that the leader receives. The leader tells them this via the cluster `AttributesProtocol attributesClient`. This means that the leader uses the cluster-wide attribute publishing facility to share registration information with all passive nodes. If the leader is lost, then a passive node will be elected as the leader, and already has *most* or all of the current registration information. Any lag in current registration information will soon be cleared up when directory clients begin live (pulse-based) updating to the new directory leader.


# Common Tools

Some common tools reused by multiple VLINGO XOOM platform components.

## Common Tools

This is an overview of the more important tools found in XOOM Common.

### Completes

The `Completes<T>` interface defines the means to receive and react to the results from an asynchronous operation at some time in the future. Using the word "future" may be a giveaway to this tool, because in various languages and toolkits this concept is known as `Future<T>`. We purposely avoided the use of "future" terminology, because the preexisting components work inconsistently and also house some complex naming and behavior that we, of course, simplified. Here is how to put `Completes<T>` to good use.

```java
final Completes<Integer> result = calculator.factorialOf(42);
```

This example sends a message to an `Actor` asynchronously. Because the delivery to the underlying `Actor` that implements the `Calculator` protocol behaviors is asynchronous, there is no way for the result of the behavior to be known immediately. The contract to the client is a result that expresses the intention to later provide an `Integer` result. The eventual answer of type `Integer` is a parameter to `Completes`. After the message `factorialOf(n)` has been received by the `Actor` and the calculation has completed, the `Actor` answers the result, which is also delivered asynchronously. Eventually the internals of the `Completes<T>` implementation sees the calculated result, at which time it hands the result to any functions that have been registered by the client with the `Completes<T>`.

As you can see in the above example, no such functions have been registered, so the eventual outcome is lost. Let's rectify that omission.

```java
final Completes<Integer> result = calculator.factorialOf(42);

result.andThenConsume(factorial -> System.out.println("Factorial of 42: " + factorial));
```

This is not a very interesting usage of the factorial result, but it does show that when the result has completed and been delivered to the `Completes<T>` internals, the client is given the opportunity to do something with the value. In this case the client simply prints the result. This can be expressed in a more condensed fashion.

```java
calculator
  .factorialOf(42)
  .andThenConsume(factorial ->
      System.out.println("Factorial of 42: " + factorial));
```

The `andThenConsume(c)` is a means to register a `Consumer<Integer>` that does not produce a return value. There are other means to register functions, and the majority are concerned mostly with pipelining results from one kind of filter to another.

```java
calculator
  .factorialOf(42)
  .andThen(factorial -> factorial * factorial)
  .andThenTo(squared -> calculator.factorialOf(squared))
  .andThenConsume(factorial -> System.out.println("Factorial: " + factorial));
```

The first `andThen(f)` registers a `Function<T,R>` that will be applied synchronously when the factorial is available. The factorial result is the `T` parameter and the `R` return value becomes the result of `andThen(f)`. This result, which is the square of the original factorial calculation, becomes the input to the `andThenTo(f)`. Notice the difference in naming. The `andThen(f)` is synchronous, but the `andThenTo(f)` handles an asynchronous result. This is used to pass the squared outcome of `andThen(f)` to the calculator to determine the factorial of the *"factorial of 42 and then squared"-*&#x76;alue. In other words, the `andThenTo(f)` is expecting you to send a message to an actor that will produce another eventual result. The `Actor` and protocol used could be any one, it's just that here the `Calculator` protocol and implementing `Actor` was reused.

Finally, after the second factorial is calculated, the result is consumed and printed to the console.

The following are the optional and required parameters that may be passed to `andThen()`. The exact same optional and required parameters are available to `andThenTo()`.

```java
Completes andThen(final long timeout, final T failedValue, final Function function); 
Completes andThen(final T failedValue, final Function function); 
Completes andThen(final long timeout, final Function function); 
Completes andThen(final Function function);
```

{% hint style="info" %}
Note that `andThen(f)` as well as `andThenTo(f)` support the same parameters. However, the `andThen(f)` requires a return value of `Completes<T>`, while `andThenTo(f)` allows returning a different type that is parameterized by the client sender.
{% endhint %}

You can express whether or not a given operation should complete within a specific time frame, and if it does not, that a failure value will be the outcome rather than a normal result. How do you know whether the timeout has occurred and the failed value is the result?

```java
reservations
  .reserveTravel(ticketInfo)
  .andThenTo(2_000, Failed.value(), reservation -> booking.record(reservation))
  .otherwiseConsume(failed -> traveler.inform(ticketInfo, failed));
```

When a timeout occurs, the `otherwiseConsume()` is invoked rather than the function that is registered with `andThenTo()`.

The methods `otherwise(failedValue)` and `otherwiseConsume(failedValue)` are available. If you provide a `timeout` threshold but not a `failedValue`, the `failedValue` defaults to `null`.

Optionally, the `Actor` may answer the `failedValue` as a result of its behavior, which will also cause the `otherwise(failedValue)` to be invoked. Thus, it is not only a timeout that can possibly cause the `otherwise()` handler to be invoked.

For more information about the `Completes<T>` facilities take a look at the interface definition found in the `xoom-common` project (repository), in [`io.vlingo.xoom.common.Completes`](https://github.com/vlingo/xoom-common/blob/master/src/main/java/io/vlingo/xoom/common/Completes.java).

{% hint style="info" %}
Beware of consuming `Completes<T>` results inside an `Actor`. When the function of the`andThen(f)` or other `andThen???(f)` is applied, the thread is not one assigned to the `Actor` for receiving a message. Rather, the thread is one assigned to a background `Actor` specifically designated to deliver the `Completes<T>` results to the `andThen()`function. Thus, it is quite possible/likely that the function is applied at the same time that the enclosing `Actor` is handling a message delivery via its mailbox for an implemented protocol. If both threads simultaneously modify the state of the `Actor` there will be races on state access and mutation. This will inevitably cause data corruption.

If your `Actor` must consume a `Completes<T>` results, you should self-send that result to a protocol designed for this purpose. For example,

```java
// inside an actor
reservations
  .reserveTravel(ticketInfo)
  .andThenTo(2_000, Failed.value(), reservation ->
      selfAs(Booking.class).record(reservation))
  .otherwiseConsume(failed ->
      traveler.inform(ticketInfo, failed));
```

In the above example the `Actor` requesting `reserveTravel()` is the `BookingActor` that implements the `Booking` protocol. Inside `andThenTo()` the function sends `record(reservation)` to the `Booking`, which will eventually be received by the enclosing `BookingActor`. The `BookingActor` will thus receive this`record(reservation)` message through its mailbox on a thread that has exclusive access to its state to effect the reservation recording.
{% endhint %}

There is another kind of failure, one that involves receiving an exception as a result. To deal with these, you use `recoverFrom()`.  Consider this example:

```
reservations
  .reserveTravel(ticketInfo)
  .andThenTo(2_000, Failed.value(), reservation -> booking.record(reservation))
  .otherwiseConsume(failed -> traveler.inform(ticketInfo, failed))
  .recoverFrom(cause -> reservationsObserver.error(ticketInfo, cause));
```

In the above example, cascading failure is naturally avoided and `recoverFrom()` is used to report the cause of the exceptional problem to a component that can handle to problem using an alternate workflow.

### Outcome

An `Outcome` is a result of an operation that may be either successful or a failure. If the resulting `Outcome` is a success then the client may respond in a positive manner, and if a failure in a recovery or compensating manner. Thus, there are two concrete types available, `Success` and `Failure`.

For example, a persistence operation may have a successful or failure outcome, depending on whether the expected persistence occurred or not. In such a contract, the outcome may be declared as the following type: `Outcome<StorageException, Result>`

The `Outcome` producer may provide one or the other, but not both. If successful, the behavior would produce something such as the following.

`Success.of(Result.Success)`

Or, if the requested behavior resulted in failure based on the `Exception` value of `e`, the following may be the product of the component.

`Failure.of(new StorageException(Result.Failure, e.getMessage(), e))`

Of course, the `Outcome` will have one value or the other, either `StorageException` or `Result`. How is it determined by the client and reacted to?

```java
outcome
  .andThen(result -> {
    // do things based on success
    return result;
  })
  .otherwise(cause -> {
    // do things based on failure
    throw new StorageException(cause.result, message, cause);
  });
```

This is a familiar interface as seen in the `Complete<T>` API. When the operation is successful the `andThen(f)` operation is executed. When the operation is a failure the `otherwise(f)` operation is executed, with the `Exception` cause as the parameter. The `otherwise(f)` is not required to throw an `Exception`, but may answer the same or different `Result` value that is found in the `cause`.

There are additional behaviors available with [`Outcome`](https://github.com/vlingo/xoom-common/blob/master/src/main/java/io/vlingo/xoom/common/Outcome.java), both for [`Success`](https://github.com/vlingo/xoom-common/blob/master/src/main/java/io/vlingo/xoom/common/Success.java) and [`Failure`](https://github.com/vlingo/xoom-common/blob/master/src/main/java/io/vlingo/xoom/common/Failure.java).

### Scheduler

Every `Stage` has its own `Scheduler`, which may be used to produce time-lapsed events that are sent to an `Actor`.

```d
// inside an actor
final DataPacket packet = new DataPacket(0);
stage().scheduler().schedule(selfAs(Scheduled.class), packet, 100, 1_000);
```

An `Actor` can schedule itself or another `Actor`, such as one or more of its children, for some timed event notification. In other words, it need not pass itself as the `Scheduled` instance.

The above example registers a repeating schedule that will begin within `100` milliseconds of the registration and will repeat every `1` second (`1_000` milliseconds). The Actor scheduling itself for notifications must implement the `Scheduled` protocol, and it passes an `Actor` enabled reference to that effect using the runtime method `selfAs()`. The `Actor` can associate some specific data with which it will be notified on each event, which in this example is the `DataPacket` instance `packet`. This `DataPacket` type is only used for the example, and would be replaced with your own type, or you can pass `null` if the data is unused.

Similarly you can schedule a single notification. The interval will not not be repeated as in the above example.

```java
// inside an actor
final DataPacket packet = new DataPacket(0);
stage().scheduler().scheduleOnce(selfAs(Scheduled.class), packet, 100, 1_000);
```

When registering a `Scheduled` object you are provided a `Cancellable` instance. You may use this instance to cancel one-time or repeating occurrences.

```java
this.cancellable = stage().scheduler().scheduleOnce(...);
...
cancellable.cancel();
```

The `Actor` receiving the timed event will be notified using the `intervalSignal()` method of the `Scheduled` protocol.

```java
public interface Scheduled {
  void intervalSignal(final Scheduled scheduled, final Object data);
}
```

It may be implemented something like the following.

```java
@Override
public void intervalSignal(final Scheduled scheduled, final Object data) { 
  ((DataPacket) data).ifAccumulatedEnd(cancellable -> cancellable.cancel());
}
```

### Serialization

Serializing objects to a format that can be sent over the network and/or persisted is an important feature of any distributed computing platform. The **VLINGO XOOM** platform will provide several different serialization capabilities. Currently we support only a single serialization option.

#### JSON Serialization

The JSON serializer is provided by class `JsonSerialization`. Internally this utility uses the `com.google.gson.Gson` serializer, which supports field-level access rather than requiring JavaBean accessor methods. The following operations are available.

Serializes the `Object` parameter to a `String`:

```java
public static String serialized(final Object instance);
```

Serializes the `List<T>` parameter to a `String`:

```java
public static <T> String serialized(final List<T> instance);
```

Deserializes the `serialization` parameter to an instance of `Class<T>`:

```java
public static <T> T deserialized(String serialization, final Class<T> type);
```

Deserializes the `serialization` parameter to an instance of `Type`:

```java
public static <T> T deserialized(String serialization, final Type type);
```

Deserializes the `serialization` parameter to an instance of a `List` of type `Type`:

```java
public static <T> List<T> deserializedList(String serialization, final Type listOfType);
```

### Tuples

A tuple is a data structure that collects two or more related values together, but without giving the group of values a type specific to their whole composition. By definition there is a tuple-0 and a tuple-1, but in such cases Java and other programming languages would typically use `void` and the single value type, respectively, to represent those tuples. Using a tuple type eliminates the need to create many tiny types just to shuttle around individual values of which it is unimportant to give a domain-specific type.

Our toolkit provides `Tuple2`, `Tuple3`, and `Tuple4`. Each of these tuple types support the specific number of values indicated by the trailing number of the name.

To get a `Tuple2`, use class method `from()` as follows:

```java
final Tuple2<Integer,Integer> deux = Tuple2.from(4, 2);
```

To access the values of the tuple, use the public final instances directly:

```java
System.out.println("Value 1: " + deux._1);
System.out.println("Value 2: " + deux._2);
```

Similarly with `Tuple3` and `Tuple4`, you may use the following:

```java
final Tuple3<Integer,Integer,String> trois = Tuple3.from(4, 2, "42");
System.out.println("Value 1: " + trois._1);
System.out.println("Value 2: " + trois._2);
System.out.println("Value 3: " + trois._3);

final Tuple4<Integer,Integer,String,String> quatre = Tuple4.from(4, 2, "42", "four");
System.out.println("Value 1: " + quatre._1);
System.out.println("Value 2: " + quatre._2);
System.out.println("Value 3: " + quatre._3);
System.out.println("Value 4: " + quatre._4);
```

### Semantic Versions

Our toolkit supports semantic versioning, which defines a version with three parts: major, minor, and patch. Each part of the semantic version representation is separated by a dot (decimal point):

```java
major.minor.patch
```

Each part of the version is a number, the following representing a major version of `1`, a minor version of `7`, and a patch version of `3`:

```java
1.7.3
```

{% hint style="info" %}
Note that the `major` version may have a maximum value of `32_767`, and the `minor` and `patch` values are limited to `255` each. The minimum value of all parts is `0`.
{% endhint %}

Using our `SemanticVersion` utility tool, the representations supported are both packed integer and text format. These are the available operations.

Answers a new `SemanticVersion` instance with the given `major`, `minor`, and `patch` values:

```java
public static SemanticVersion from(final int major, final int minor, final int patch);
```

Answers a new `SemanticVersion` instance with the given `major`, `minor`, and `patch` values as represented by the `version` parameter. The `version` parameter must have the representation `"x.y.z"`, where `x`, `y`, and `z`, are numbers:

```java
public static SemanticVersion from(final String version);
```

Answers a `String` representation of the semantic version represented by the packed version integer value:

```java
public static String toString(final int version);
```

Answers a new integer value that is a packed representation of the given `major`, `minor`, and `patch` parameter values:

```java
public static int toValue(final int major, final int minor, final int patch);
```

Answers a packed integer representation of the given `major`, `minor`, and `patch` values as represented by the `version` parameter. The `version` parameter must have the representation `"x.y.z"`, where `x`, `y`, and `z`, are numbers:

```java
public static int toValue(final String version);
```

The `SemanticVersion` instances provide the following behaviors.

Answers `true` if the receiver `SemanticVersion` is compatible with the previous `SemanticVersion` parameter:

```java
public boolean isCompatibleWith(final SemanticVersion previous);
```

The two are compatible if one of these is true:\
(a) the `major` version of the receiver is one greater than the previous `major` version, and all other values are the same\
(b) the `minor` version of the receiver is one greater than the previous `minor` version, and all other values are the same\
(c) the `patch` version of the receiver is one greater than the previous `patch` version, and all other values are the same.

Answers a new `SemanticVersion` with its `major` version one greater than the receiver's, and all other values the same:

```java
public SemanticVersion withIncrementedMajor();
```

Answers a new `SemanticVersion` with its `minor` version one greater than the receiver's, and all other values the same:

```java
public SemanticVersion withIncrementedMinor();
```

Answers a new `SemanticVersion` with its `patch` version one greater than the receiver's, and all other values the same:

```java
public SemanticVersion withIncrementedPatch();
```

Answers the receiver as its `String` representation:

```java
public String toString();
```

Answers the receiver as its packed integer representation:

```java
public int toValue();
```


# Build Plugins

Automate VLINGO XOOM platform related build tasks.

The XOOM build plugin provides build-time tools for automating steps that would be tedious if performed manually.

To use `xoom-build-plugins` in your builds, simply add it as build plugin in your `pom.xml`. The [build tasks](/xoom-build-plugins#build-tasks) section below describes the supported goals and their configuration.

```
<project ...>
  <build>
    <plugins>
      <plugin>
        <groupId>io.vlingo.xoom</groupId>
        <artifactId>xoom-build-plugins</artifactId>
        <version>1.7.0</version>
        <executions>
        ...
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
  </project>
```

## Build Tasks

There are currently two build tasks supported by the plugin. One is for using [XOOM Schemata](/xoom-schemata) and one for generating proxies for XOOM ACTORS. These are both covered in this section.

### Integration with XOOM Schemata

There are two uses of the plugin that integrates your build with [VLINGO Schemata](/xoom-schemata):

* Push schemas from your project to the schema registry: Makes your schemas available to dependent projects.
* Pulls from the schema registry to you project: Enabled your project to depend on the schemas of other projects, or to retrieve fresh definitions of your own schemas from the registry.

Various projects for services and applications (e.g. Bounded Contexts) must interact with others. To make interaction, such as collaboration and integration, more manageable, you use the [VLINGO Schemata](/xoom-schemata) schema registry to publish and consume the exchanged type definitions. This implements the Published Language pattern using the registry to exchange type safe definitions and the corresponding source code. For a detailed description of schema specifications and registry usage, see [VLINGO Schemata](/xoom-schemata).

Specifications of Domain Events published by your services and applications should be kept along with its source code. Consumed types should not be committed with your sources but rather generated on demand. This makes updating to new event versions easy and will trigger build warnings or errors if you're depending on a version that is unsafe to use, e.g. if it becomes `deprecated`.

The `push-schema` and `pull-schema` goals of `xoom-build-plugins` enable you to perform the vital build tasks.&#x20;

Both goals need to be configured with the URL of the [VLINGO Schemata](/xoom-schemata) instance to push to and the client organization and unit of the current project, e.g.

```
<configuration>
  <schemataService>
    <url>http://localhost:9019</url>
    <clientOrganization>VLINGO</clientOrganization>
    <clientUnit>examples</clientUnit>
  </schemataService>
</configuration>
```

#### Goal: push-schema

The `push-schema` goal publishes schema specifications from your sources to the schema registry.&#x20;

By default the path to your specification files defaults to `src/main/vlingo/schemata` and can be overridden by specifying `configuration.srcDirectory`

The `push-schema` goal doesn't bind to any lifecycle phase by default.

For each schema, you'll need to define:

* Its reference consisting of the organization, unit, context namespace, schema name, and version, e.g. `VLINGO:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:1.0.1`
* The corresponding source file (optional, defaults to `<schema-name-reference>.vss`)
* The previous version of the schema in case you're updating an existing schema.

The following example configuration will push the schemas `SchemaDefined v2.1.0` as an update to `v2.0.4` and `SchemaPublished v0.0.1` stored in `src/main/vlingo` to the registry running on `localhost:9019` :

```
<build>
<plugins>
  <plugin>
    <groupId>io.vlingo.xoom</groupId>
    <artifactId>xoom-build-plugins</artifactId>
    <version>1.7.7</version>
    <executions>
      <execution>
        <id>push</id>
        <goals>
          <goal>push-schema</goal>
        </goals>
        <configuration>
          <srcDirectory>${basedir}/src/main/vlingo</srcDirectory>
          <schemataService>
            <url>http://localhost:9019</url>
            <clientOrganization>VLINGO</clientOrganization>
            <clientUnit>examples</clientUnit>
          </schemataService>
          <schemata>
            <schema>
              <ref>VLINGO:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:2.1.0</ref>
              <src>SchemaDefinedButWithACustomFileName.vss</src>
              <previousVersion>2.0.4</previousVersion>
            </schema>
            <schema>
              <ref>VLINGO:examples:io.vlingo.xoom.examples.schemata:SchemaPublished:0.0.1</ref>
            </schema>
          </schemata>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>
```

The schema will be pushed when the `push-schema` goal is run:

```
$ mvn io.vlingo.xoom:xoom-build-plugins:push-schemata@push
```

`@push` in the example above indicates the ID of the plugin execution (see the previous snippet with plugin configuration).

It's also possible to automatically push the schema during a chosen Maven phase. With the following example, Maven will push the schema when `mvn install` is run:

```
<build>
<plugins>
  <plugin>
    <groupId>io.vlingo.xoom</groupId>
    <artifactId>xoom-build-plugins</artifactId>
    <version>1.7.7</version>
    <executions>
      <execution>
        <id>push</id>
        <phase>install</phase>
        <goals>
          <goal>push-schema</goal>
        </goals>
        <configuration>
          <!-- schema configuration -->
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>
```

#### Goal: pull-schema

The `pull-schema` goal retrieves code generated by the schema registry and puts it into the`target/generated-sources/vlingo` output folder in the `generate-sources` lifecycle phase by default. You can override this default by specifying `configuration.outputDirectory`. The output folder is added to maven's compile path automatically. The specifications to pull are listed using their reference.

The following example will pull java code generated from the schemas defined in the previous section when running `mvn generate-sources`.

```
<build>
  <plugins>
    <plugin>
      <groupId>io.vlingo.xoom</groupId>
      <artifactId>xoom-build-plugins</artifactId>
      <version>1.1.0</version>
      <executions>
        <execution>
          <id>pull</id>
          <goals>
            <goal>pull-schema</goal>
          </goals>
          <configuration>
            <schemataService>
              <url>http://localhost:9019</url>
              <clientOrganization>VLINGO</clientOrganization>
              <clientUnit>examples</clientUnit>
            </schemataService>
            <schemata>
              <schema>
                <ref>VLINGO:examples:io.vlingo.xoom.examples.schemata:SchemaDefined:2.1.0</ref>
              </schema>
              <schema>
                <ref>VLINGO:examples:io.vlingo.xoom.examples.schemata:SchemaPublished:0.0.1</ref>
              </schema>
            </schemata>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
```

[This example shows](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-schemata-integration) working integrations between services by using the plugin.

As with `push-schema`, it's also possible to trigger `pull-schema` on demand:

```
$ mvn io.vlingo.xoom:xoom-build-plugins:pull-schemata@pull
```

`@pull` in the example above indicates the ID of the plugin execution (see the previous snippet with plugin configuration).

### Generating proxies for XOOM Actors

An important part of the XOOM architecture is the use of [proxies](https://docs.vlingo.io/architecture#actor-proxy) to enable type-safe asynchronous message sending. The proxies are not implemented manually by XOOM SDK users. The platform SDK takes care of that for you by auto-generating and compiling them. Having actual classes generated is essential because it avoids the overhead of runtime dynamic proxies that use reflection. There are two ways that XOOM Actors supports proxy generation:

* Runtime generation: Requires no thought, planning, or effort. The sources are seamlessly generated once, compiled, generally during service or application startup. Any protocol interfaces and actor types that are not created until after startup will be generated and compiled at that time. The overhead is quite minimal, going unnoticed.
* Build-time generation: Requires including this build plugin and listing the names of service/application protocol interfaces in the build script. The proxies will be generated during regular builds.

For both of these options, the proxies are not generated into main source, but rather the area that your build tool designates as the generated sources area. In the case of both proxy generation options, you can cache the proxies by copying the source files from the generated sources area to the main source. This will provide a slight performance optimization over runtime generation, but will offer no advantages if using build-time generation.

{% hint style="info" %}
If you decide to cache proxies, you must not edit the source code.
{% endhint %}

The one downside to caching proxies is that any changes to the protocol interface will not be immediately supported in the cached generated proxies. You will see build errors instead. The best way to avoid this is to delete the proxy source, run one or more tests that require the proxy, which causes the regeneration according to the current proxy interface. Then copy the newly generated source into your main source.

{% hint style="info" %}
It is assumed that you would delete an obsolete proxy source, regenerate, and copy so as to recache the source, all before committing source to revision control. Doing so will retain the history of the changes rather than appearing that the source was deleted and then newly added later.
{% endhint %}

The following is and example of using the plugin with configuration for Maven builds:

```
...
  <build>
    <plugins>
      <plugin>
        <groupId>io.vlingo.xoom</groupId>
        <artifactId>xoom-build-plugins</artifactId>
        <version>${xoom.build.plugins.version}</version>
        <executions>
          <execution>
            <id>generateProxies</id>
            <phase>compile</phase>
            <goals>
              <goal>actorProxyGen</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <actorProtocols>
            <param>io.vlingo.xoom.maven.actortest.Test1Protocol</param>
            <param>io.vlingo.xoom.maven.actortest.Test2Protocol</param>
          </actorProtocols>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <executions>
          <execution>
            <id>default-compile</id>
            <phase>generate-sources</phase>
          </execution>
          <execution>
            <id>build-generated-code</id>
            <phase>compile</phase>
            <goals>
              <goal>compile</goal>
            </goals>
            <configuration>
              <generatedSourcesDirectory>${project.build.directory}/generated-sources</generatedSourcesDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>${project.build.directory}/generated-sources</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
...
```

Note that the use of the Java-based `xoom-build-plugins` requires the use of two other plugins, namely:

* `maven-compiler-plugin` with the (default) groupId of `org.apache.maven.plugins`
* `build-helper-maven-plugin` with `groupId` of `org.codehaus.mojo`

If you prefer to use build-time generated proxies, [see this example](https://github.com/vlingo/vlingo-build-plugins-test).


# Telemetry

The Reactive metrics collection toolkit for the VLINGO XOOM platform.

Use XOOM Telemetry for measure performance, throughput, and latency, for your project components. This is currently an experimental tool and at this time supports XOOM Actors by way of tapping mailboxes.

The following is a brief usage guide.

## Usage Guide

XOOM Telemetry provides a telemetry registry that can be used within any actor to push metrics to your APM or monitoring system. By default, XOOM Telemetry uses an implementation backed by [Micrometer](https://micrometer.io/), so most common backends are supported, including JMX, Prometheus, and StatsD.

### Registering the Telemetry Registry

XOOM Telemetry provides a `Telemetry` object that will be used by actors to push metrics. The easiest way to register the `Telemetry` object is by using the `DefaultTelemetryProvider`, which will create a `MicrometerTelemetry` that exports all it's metrics to JMX. The snippet to configure telemetry follows.

```java
// Probably you will already have a World defined with your own configuration :)
World world = World.startWithDefaults("measurements");

// The DefaultTelemetryProvider uses Micrometer
TelemetryProvider<MeterRegistry> telemetryProvider = new DefaultTelemetryProvider();

// Provides a Telemetry registry based on the created world
Telemetry<MeterRegistry> telemetry = telemetryProvider.provideFrom(world);

// Registers the telemetry object in the world
world.registerDynamic("telemetry", telemetry);
```

### Sending Metrics From Actors

All actors hosted by XOOM Actors live in a `Stage`, each of which is part of a `World`. All actors through their `World` can access the `Telemetry` provider and send metrics to the registry asynchronously, thus reducing the performance impact of monitoring actors.

The `Telemetry` object is usually acquired by the actor during the instantiation, as it will be needed during the whole lifecycle of the actor. A single instance is all that is needed. To provide some context, consider the following example.

Here's a `Counter` protocol to be implemented by an actor. The actor will count seconds and, on each second, send a metric with the counter to the registry.

```java
public interface Counter {
    void count();
}
```

The protocol now requires and actor to implement it in order to provide behavior. Create a new `CounterActor` class that, implementing `Counter`, performs the business of counting. First note the constructor.

```java
public class CounterActor extends Actor implements Counter {
    private final Telemetry<?> telemetry;
    private final String name;

    public CounterActor(String name) {
        this.telemetry = Telemetry.from(this.stage().world()); // <-- getting the telemetry!
        this.name = name;
    }

    public void count() {
        // will focus later on this
    }
}
```

Because the `Telemetry` object lives in the same `World` as the actor, the instance is available from the actor's `World` reference. By getting the registered `Telemetry`, it's now possible to send metrics at will from inside the actor. Next consider the `count()` behavior.

```java
public void count() {
    telemetry.count("Count", 1, Telemetry.Tag.of("Name", name));
}
```

That's it.

One-liners deserve explanation, even though the telemetry design is rather intuitive. The telemetry count method contains three parameters:

| Parameter   | Explanation                                                                                                                                                                                                                                            | Example Value                          |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
| Metric Name | The name of the metric that will be registered in the `MetricRegistry`. It should be unique.                                                                                                                                                           | `"Count"`                              |
| `Delta`     | The amount to add to the metric in the registry. This value can be negative if the desire is to subtract an amount. For example, when the metric is `5`, and a delta of `1` is given when using `count()`, the total in the registry will then be `6`. | `1`                                    |
| `Tags`      | List of tags (`vararg` in Java) that will be sent to the metric registry. Depending on the metric registry, later, metrics can be grouped and filtered using these tags.                                                                               | `Telemetry.Tag.of("MyTag", "MyValue")` |

{% hint style="success" %}
If you are using the default telemetry provider, as in this example, you can see the metrics using the [JConsole](https://docs.oracle.com/javase/8/docs/technotes/guides/management/jconsole.html) that comes with your JDK. Connect to the local process using debugging.
{% endhint %}

![JConsole targeting a local process with a Counter.](/files/-MPLq3hLfjgra_pDaRfG)

The `Telemetry` provide three different methods to send metrics, with different use cases. We've already seen `count` .

| Method  | Parameters                                      | Description                                                                                                                                                                              |
| ------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `count` | `String metric, int delta, Tag... tags`         | Increases the metric by "delta". Generates percentiles and averages.                                                                                                                     |
| `gauge` | `String metric, int delta, Tag... tags`         | Increases the metric by `delta`. Does not generate any additional metric.                                                                                                                |
| `time`  | `String metric, Callable callable, Tag... tags` | Registers the amount of time required for the callable to finish and returns the result. It (still) does not support asynchronous methods. You will need to use `gauge` to measure them. |

### Integration With Actors

XOOM Actors provide a plugin mechanism that allows XOOM Telemetry to supply a mailbox provider, and thus automatically measure the amount of messages and processing time, per actor. This is really useful for monitoring systems in production, as the low number of messages and processing time in actors indicates that the system is healthy.

The recommended way to plug in the mailbox telemetry is before starting the `World`. The easiest way to accomplish that is by using the `xoom-actors.properties` file. Adding the plugin should be enough to have all the metrics ready to read through JMX.

```
plugin.name.telemetry = true
plugin.telemetry.classname = io.vlingo.xoom.telemetry.TelemetryPlugin

plugin.name.mailboxTelemetry = true
plugin.mailboxTelemetry.classname = io.vlingo.xoom.telemetry.plugin.mailbox.MailboxTelemetryPlugin
```

The plugin provides the following metrics aggregated by the actor class.  All metrics are tagged with the address of the actor, so metrics can be gathered also by actor.

| Metric                          | Description                                                                     |
| ------------------------------- | ------------------------------------------------------------------------------- |
| `pending`                       | Number of messages pending in the mailbox                                       |
| `idle`                          | Number of times the actor tried to query the mailbox but it was empty           |
| `failed.send.EXCEPTION_NAME`    | Number of times an actor could not send a message due to `EXCEPTION_NAME`       |
| `failed.deliver.EXCEPTION_NAME` | Number of times XOOM Actors could not deliver a message due to `EXCEPTION_NAME` |

![Pending messages metric for our CounterActor in JConsole.](/files/-MPM78Jf1T9Q2wFTFHl_)

{% hint style="success" %}
Using the properties file is recommended most of the times as it simplifies configuration and can be handled relatively easily and versioned without changing Java code. However, to use the `xoom-actors.properties` file, you will need to start your world with the `start()` method instead of `startWithDefaults()`. Any previously used plugin configuration using Java code is no longer needed as it is replaced by the properties configuration.
{% endhint %}

{% hint style="success" %}
Because the VLINGO XOOM platform is built entirely on actors, all internal actors are also monitored, so metrics for the `DeadLettersActor` (for example) can also be monitored as easy as server/application actors. This will be plugged in for ***all*** actors: `Journal` instances, XOOM HTTP servers, queue consumers, and all others can be monitored with no additional effort.
{% endhint %}

### Using a Custom Micrometer Provider

XOOM Telemetry, by default, exports all the information to JMX. However, in production setups, you might desire to export metrics to more reliable platforms, such as Prometheus, StatsD, CloudWatch, etc. Micrometer already works out of the box with all of the aforementioned, so XOOM Telemetry can be adapted to export your service/application metrics as well.

To do so, create a new `TelemetryProvider` and implement the `provideFrom()` method to return a new `Telemetry` object that is set up for the desired observation console. Here's an example for DataDog.

```java
public class DatadogTelemetryProvider implements TelemetryProvider<MeterRegistry> {
    @Override
    public Telemetry<MeterRegistry> provideFrom(World world) {
        DatadogConfig config = new DatadogConfig() {
            @Override
            public Duration step() {
                return Duration.ofSeconds(10);
            }

            @Override
            public String apiKey() {
                return "YOUR_API_KEY";
            }

            @Override
            public String get(String k) {
                return null; // accept the rest of the defaults
            }
        };

        MeterRegistry registry = new DatadogMeterRegistry(config, Clock.SYSTEM);
        return new MicrometerTelemetry(registry);
    }
}
```

{% hint style="warning" %}
XOOM Telemetry does not provide all Micrometer dependencies, only the core. If you want to use DataDog with Micrometer, you will need to add the dependency to your `build.gradle` or `pom.xml` as explained in the [documentation for Micrometer](https://micrometer.io/docs/registry/datadog). The same goes for other observation tools.
{% endhint %}

Given the use of DataDog, define the appropriate provider in the properties file.

```
plugin.name.telemetry = true
plugin.telemetry.classname = io.vlingo.xoom.telemetry.TelemetryPlugin
plugin.telemetry.providerClass = com.myapp.infrastructure.DatadogTelemetryProvider
```

Our team welcomes your feedback and contributions for improving the XOOM Telemetry functionality.


# Wire

Wire protocol full-duplex TCP, UDP multicast, as well as RSocket messaging implementations.

### Javadoc and Source Code

The XOOM Wire component offers various network protocols implemented through XOOM Actors.  Since this component may not necessarily be used beyond our own platform components, such as [XOOM HTTP](/xoom-http), [XOOM Cluster](/xoom-cluster) and [XOOM Directory](/xoom-directory), we do not document it thoroughly herein. We suggest seeing the [Javadoc](https://javadoc.io/doc/io.vlingo/vlingo-wire/latest/index.html) for more details. You will also find the [source code](https://github.com/vlingo/vlingo-wire) handy.

### TCP Support

There are various implementations of TCP support. These are generally used for client-server interactions. Uses can be seen primarily in XOOM HTTP, such as the following.

```java
// general
io.vlingo.xoom.wire.node.Address
io.vlingo.xoom.wire.node.AddressType
io.vlingo.xoom.wire.node.Host

// server
io.vlingo.xoom.wire.channel.RequestChannelConsumer
io.vlingo.xoom.wire.channel.RequestResponseContext
io.vlingo.xoom.wire.fdx.bidirectional.ServerRequestResponseChannel

// clients
io.vlingo.xoom.wire.channel.ResponseChannelConsumer
io.vlingo.xoom.wire.fdx.bidirectional.ClientRequestResponseChannel
```

### Practical UDP Multicast

The purpose of supporting UDP is for multicast, or in other words, broadcast publishing of information. One typical use case is a UDP multicaster service that needs to know what to multicast in behalf of other services. This is the combination of *Point-to-Point Channel* and *Publish-Subscribe* patterns, and a form of *Message Router.* Thus, our UPD multicast is a use-case-specific component, although it can be used for basic UDP multicast of foreknown information.

The XOOM Wire component `MulticastPublisherReader` is both a UDP multicast *publisher* and a TCP socket *reader*. The client of the `MulticastPublisherReader` takes a `ChannelReaderConsumer` as a constructor parameter, and when it receives TCP requests it relays the requests to the `ChannelReaderConsumer`. Why? Because the `MulticastPublisherReader` only knows how to publish two things:

1. It's own availability, which it does by multicasting its own TCP address, which it holds in its `publisherAddress` instance variable. This TCP address is how other services can tell it what to publish, which leads to...
2. Whatever its client tells it to multicast. This is done via its `ChannelPublisher` protocol method `void send(final RawMessage message)`. These are received via TCP requests, for publishing of the information in the `RawMessage`. One example of such is registration by services that want their availability know to other services.

[The best place to see this in use is in the XOOM Directory service](/xoom-directory#implementation).

### RSocket Support

RSocket is currently used only by XOOM Cluster, but we will soon add support in XOOM Streams for high-throughput, low latency streaming over the network. You will find our current RSocket support in:

[`io.vlingo.xoom.wire.fdx.bidirectional.rsocket.RSocketServerChannelActor`](https://github.com/vlingo/xoom-wire/blob/master/src/main/java/io/vlingo/xoom/wire/fdx/bidirectional/rsocket/RSocketServerChannelActor.java)[`io.vlingo.xoom.wire.fdx.inbound.rsocket.RSocketChannelInboundReader`](https://github.com/vlingo/xoom-wire/blob/master/src/main/java/io/vlingo/xoom/wire/fdx/inbound/rsocket/RSocketChannelInboundReader.java)[`io.vlingo.xoom.wire.fdx.outbound.rsocket.RSocketOutboundChannel`](https://github.com/vlingo/vlingo-wire/tree/master/src/main/java/io/vlingo/wire/fdx/outbound/rsocket/RSocketOutboundChannel.java)


# Auth-Auth

Platform-wide identity and access management using XOOM Auth.

## Identity and Access

The XOOM Auth service provides security for the various components of the VLINGO XOOM platform, and was initially designed to be used primarily purpose. It may also be used by services and applications that you and your team create.

![](/files/-MPKw6nqv78EoVcXvViI)

It supports the following authentication and authorization concepts: `Tenants`, `Users` with `Profiles`, `Groups`, `Roles` with `Permissions` and `Constraints`. The XOOM Auth service may also be used by any service/application that you create, but it is not a requirement that your organization adopt it as your security standard.

## How To Use

:warning: The XOOM Auth service is currently in experimental preview mode. More documentation to be supplied when the service is fully released.


# Containerization

How to use Docker, Kubernetes, and Helm Charts to deploy your VLINGO XOOM platform services.

The following shows how to set up a Reactive, scalable, event-driven application based for VLINGO XOOM, being deployed on Kubernetes and packaged by Helm Chart.

### Quick start with VLINGO XOOM

First, we need a project structure that allows us to start building our application. That's when [XOOM Designer](https://docs.vlingo.io/vlingo-xoom/xoom-starter) comes to play. It saves a lot of effort providing a web/graphical user interface to generate initial development resources such as application files, directory structure, `Dockerfile` and much more. Once it is [installed](https://docs.vlingo.io/vlingo-xoom/xoom-starter#installation), you can use the project generator wizard running the following command: &#x20;

```
$ ./xoom gui
```

This command will open your preferred browser. Just fill in [the wizard steps](https://docs.vlingo.io/vlingo-xoom/xoom-starter#application-generation) so the project will be generated and ready to start the development.

### Building the Docker image

If you choose either Docker or Kubernetes on [the deployment step](https://docs.vlingo.io/vlingo-xoom/xoom-starter#deployment-step), a `Dockerfile` will be placed in the root folder:

```
FROM adoptopenjdk/openjdk11-openj9:jdk-11.0.1.13-alpine-slim
COPY target/xoom-example-*.jar xoom-example.jar
EXPOSE 8080
CMD java -Dcom.sun.management.jmxremote -noverify ${JAVA_OPTS} -jar xoom-example.jar
```

That means the image is ready to be built along with the executable `jar`. Both tasks are performed through a single Starter CLI command:

```
$ ./xoom docker package
```

Now, let's tag and publish this local image into [Docker Hub](https://hub.docker.com/).

```
$ ./xoom docker push
```

You can find more information on `xoom docker push`  and other containerization shortcut commands [here](https://docs.vlingo.io/vlingo-xoom/xoom-starter#containerization-commands).

### Alternative Without VLINGO XOOM

The previous steps are pretty similar for a **VLINGO XOOM** service or application without **VLINGO XOOM**. The executable `jar`, including the dependency jars, can be generated with the following plugin configuration:

```
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.6.0</version>
  <executions>
    <execution>
      <goals>
        <goal>java</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <mainClass>io.vlingo.xoom.app.infra.Bootstrap</mainClass>
  </configuration>
</plugin>
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <finalName>vlingo-xoom-app</finalName>
    <descriptors>
      <descriptor>assembly.xml</descriptor>
    </descriptors>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <mainClass>io.vlingo.xoom.app.infra.Bootstrap</mainClass>
        <classpathPrefix>dependency-jars/</classpathPrefix>
      </manifest>
    </archive>
  </configuration>
</plugin>
```

The `Dockerfile` requires the `jar` with dependencies:

```
FROM adoptopenjdk/openjdk11-openj9:jdk-11.0.1.13-alpine-slim
COPY target/vlingo-xoom-app-withdeps.jar vlingo-xoom-app.jar
EXPOSE 8082
CMD java -Dcom.sun.management.jmxremote -noverify ${JAVA_OPTS} -jar vlingo-xoom-app.jar
```

Now, besides the application itself, the Docker image is ready to be built and published:

```
$ ./mvn clean package && docker build ./ -t vlingo-xoom-app:latest
$ ./docker tag vlingo-xoom-app:latest [publisher]/vlingo-xoom-app:latest 
$ ./docker push [publisher]/vlingo-xoom-app
```

### Kubernetes Deployment

Kubernetes is the chosen tool for container orchestration. In this scenario, it will run a single node cluster serving the VLINGO XOOM application. Whereas `kubeadm` is [installed](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/), the cluster initialization is showed below:

```
$ ./sudo kubeadm init --pod-network-cidr=192.168.0.0/16
```

Secondly, the settings folder should be mapped:

```
$ ./mkdir -p $HOME/.kube
$ ./sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ ./sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

Kubernetes supports multiple [networking model](https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-networking-model) implementations. For now, we choose [Calico](https://docs.projectcalico.org/v2.0/getting-started/kubernetes/). Its network policy configuration file can be added using `kubectl`, the command line tool for controlling Kubernetes clusters:

```
$ ./kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml   
```

Considering the single node cluster is the option for this example, the last step is to prepare the master node by removing taints which, in short, prevents a deployable unit ([Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod/)) to run on it.  &#x20;

```
$ ./kubectl taint nodes --all node-role.kubernetes.io/master-
```

### **Management and Deployment With Helm Chart**

At this point, we need to tell Kubernetes what is the[ application desired state](https://kubernetes.io/docs/concepts/#kubernetes-master) and how we want to expose our services, number of replicas, allocated resources... The simpler way is through [Helm](https://helm.sh/), a special tool for Kubernetes application management. It simplifies installation, upgrade, scaling and other common tasks. Getting started, let's create a chart, which is a collection of files inside of a directory. This is how it's made:

```
$ ./helm create xoom-example
```

&#x20;The output looks like the following structure:

```
xoom-example/
  Chart.yaml          # A YAML file containing information about the chart
  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
  README.md           # OPTIONAL: A human-readable README file
  values.yaml         # The default configuration values for this chart
  values.schema.json  # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
  charts/             # A directory containing any charts upon which this chart depends.
  crds/               # Custom Resource Definitions
  templates/          # A directory of templates that, when combined with values,
                      # will generate valid Kubernetes manifest files.
  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
```

In this basic scenario, all we need to do is editing `values.yaml` , informing the Docker image repository, service type / port and number of replicas:

```
# Default values for xoom-example.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 3

image:
  repository: [publisher]/xoom-example
  
  ...
  
service:
  type: ClusterIP
  port: 8080
```

Using `lint`, we can check if the chart is well-formed after the addition:

```
$ ./helm lint xoom-example

==> Linting xoom-example
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

```

With `template` command, we can see all files that Helm will generate and install into Kubernetes:&#x20;

```
# Source: xoom-example/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: RELEASE-NAME-xoom-example
  labels:
    helm.sh/chart: xoom-example-0.1.0
    app.kubernetes.io/name: xoom-example
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
---
# Source: xoom-example/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: RELEASE-NAME-xoom-example
  labels:
    helm.sh/chart: xoom-example-0.1.0
    app.kubernetes.io/name: xoom-example
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 8080
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: xoom-example
    app.kubernetes.io/instance: RELEASE-NAME
---
# Source: xoom-example/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: RELEASE-NAME-xoom-example
  labels:
    helm.sh/chart: xoom-example-0.1.0
    app.kubernetes.io/name: xoom-example
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: xoom-example
      app.kubernetes.io/instance: RELEASE-NAME
  template:
    metadata:
      labels:
        app.kubernetes.io/name: xoom-example
        app.kubernetes.io/instance: RELEASE-NAME
    spec:
      serviceAccountName: RELEASE-NAME-xoom-example
      securityContext:
        {}
      containers:
        - name: xoom-example
          securityContext:
            {}
          image: "xoom-example:1.16.0"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}
---
# Source: xoom-example/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "RELEASE-NAME-xoom-example-test-connection"
  labels:
    helm.sh/chart: xoom-example-0.1.0
    app.kubernetes.io/name: xoom-example
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    "helm.sh/hook": test-success
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['RELEASE-NAME-xoom-example:8080']
  restartPolicy: Never

```

We finish the deployment step executing the `install` command:

```
$ ./helm install xoom-example
```

A new Pod is created by Kubernetes to hold the `xoom-example` app. You should check if it's running fine:

```
$ ./kubectl get pods

NAME                           READY   STATUS    RESTARTS   AGE
xoom-example-765bf4c7b4-26z48  1/1     Running   0          64s
```

Also, it is recommended to check the application logs:

```
$ ./kubectl logs xoom-example-765bf4c7b4-26z48
```

Helm also supports a packaging and versioning mechanism, that is, a set of commands that allows us to package the Chart structure and files to make it collaborative. First, an `index.yaml` file should be created based on a Git repository, that will be the chart repository:

```
$ ./helm repo index chart-repo/ --url https://<username>.github.io/chart-repo
```

Next, the remote repository is added:

```
$ ./helm repo add chart-repo https://<username>.github.io/chart-repo
```

At last, enable the chart installation from the repository:

```
$ ./helm install my-repo/hello-world --name=hello-world
```

### More information

Find a complete [code example on GitHub](https://github.com/vlingo/xoom-examples/tree/master/xoom-kubernetes-cluster), built on a DDD microservices architecture, combining Kubernetes, Helm Chart and VLINGO XOOM.


# Tools and Patterns for Specific Use Cases

## Common Use Cases

1. Use case
2. Use case
3. Use case
4. Use case
5. Use case

{% hint style="info" %}
&#x20;Please add use cases that should be covered and contribute what you know.
{% endhint %}


# Appendix A: Deploy to Pivotal Cloud Foundry

The basic steps necessary to deploy a service that uses the VLINGO XOOM platform components to the Pivotal Cloud Foundry.

These are the basic steps necessary to deploy a service that uses the VLINGO XOOM platform components to the Pivotal Cloud Foundry. The [final section](https://docs.vlingo.io/appendix-a-deploy-to-pivotal-cloud-foundry#see-a-working-example) below provides a working example.

### Docker

The first thing we need to do is to generate a docker image and push it to any registry. We will use the [Docker Hub](https://hub.docker.com/) registry for this example.

> You can use any Docker Registry that you want, either Docker Hub, any private Docker Registry, or GCR. If you want more information about how to deploy from any of these registries, check [this link](https://docs.cloudfoundry.org/devguide/deploy-apps/push-docker.html).

#### Docker Image Publish

1. Register to [Docker Hub](https://hub.docker.com/signup)
2. Once logged in, create a repository for each image. The field **Name** is the name of the docker image. This is the identifier along with the account name.
3. After that, login to the registry with your [docker cli](https://docs.docker.com/engine/reference/commandline/login/) by typing `docker login` in your shell/terminal.
4. Now you are ready to push your image to DockerHub repository using `docker-release.sh`

   ```
    ./docker-release.sh <account_name/name>
   ```

Once the script finishes, the docker image is published to DockerHub and ready to be deployed.

**Docker Image Implementation**

The `Dockerfile` is implemented using MultiStage build:

* The build stage extends `FROM maven:alpine`. The single responsibility of this stage is to install dependencies (caching layers) and generate the jar.
* The runtime stage extends `FROM openjdk:alpine` and works executing the jar generated by build stage. It will `EXPOSE` the external ports to the host.

### Pivotal Cloud Foundry

Now that the image is pushed to Docker Hub, push them into Pivotal Platform.

The first requirement is to create an account in [Pivotal](https://docs.run.pivotal.io/starting/). Obtain access to the console and then create an organization manually. It's as simple as entering input inside *Create an Org*.

The next step is to [install the CF CLI](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) on your computer.

Once the Cloud Foundry CLI is installed on your machine, login to your Pivotal account:

```
$ cf login -a https://api.run.pivotal.io
```

A Cloud Foundry connection is established using your Pivotal account. Copy the `example-manifest.yml` to your project and rename it to `manifest.yml`. Open the manifest file and edit the three configurable variables:

1. service\_name: The name of the service inside the Pivotal Cloud Foundry platform.
2. docker\_image: The docker image name is composed of your account name and the repository name (e.g: vlingo/project1)
3. subdomain: This is your public end-point within domain `.cfapps.io`

You may also configure environment variables, instances, memory, disk quota, etc. See [Deploying with Application Manifests](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html) for possible manifest configurations.

Along with your configured `manifest.yml`, push your project:

```
$ cf push
```

> This command by default checks whether a `manifest.yml` exists in the directory, and if so, uses it to push to the platform.

That's all it takes! The service/application is in the Pivotal Cloud Foundry, deployed and working. Use the Pivotal Console to see your services, the logs, and any other project infrastructure artifacts.

### See a Working Example

See [`xoom-examples`](https://github.com/vlingo/vlingo-examples) for a working configuration. This demonstrates how to integrate two or more services that are deployed to the Pivotal Cloud Foundry platform. View the [`xoom-http-frontservice`](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-http-frontservice) and [`xoom-http-backservice`](https://github.com/vlingo/vlingo-examples/tree/master/vlingo-http-backservice) as microservices, and the [`DEPLOY.md`](https://github.com/vlingo/vlingo-examples/blob/master/vlingo-http-frontservice/DEPLOY.md) for further instructions.


# FAQ

Frequently Asked Questions

### **Q:** My actors seem to hang or deadlock. What's wrong?

**A:** It is possible that you are experiencing one or a few things that can cause these kinds of problems. Consider the following.

* When you are using actors you have a finite number of physical computer threads to run message handlers. If you exhaust all of the available physical threads simultaneously and block them for relatively long periods of time, you will experience these situations. This may happen due to blocking or otherwise slow message handling. It is sometimes an environmental problem. This is an overarching problem with the following points providing more details.
* Blocking a thread means that it is parked like a non-moving car in a garage. There are no two ways about it. If you block on file or network I/O, or for any other operation to complete, your physical thread is blocked. There is nothing that makes a Java thread block but frees the physical thread behind it. The physical thread blocks if your Java thread blocks. If all/most of your threads are blocked, you aren't processing messages as would be possible if blocking could be eliminated.
* You may be using `Completes::await()` or `Future::get()`, which are blocking operations. If these are used by your actors, throughput will be stopped for as long as the blocking operation requires to finish. Note that both forms of `Completes::await()` are meant to be used for tests only, and it is only the test case that should use either form of `Completes::await()`. Never use this in a production environment.
* You simply have too few machine cores to service all your actors' messages in a timely manner. This would be rare, but it's possible. We have seen the use of very thinly provisioned cloud server machines, such as dual core, used to handle long-running message handling with mandatory cloud node timeouts. Given two cores, you likely have four physical threads available (due to hyper-threading; 2 cores x 2 threads per core). If you are trying to service several or many actors with only four threads and three or four of them are blocking on I/O or other slow processing, your cloud node stands a high risk of health timeout and being shut down by the infrastructure.
* Related to the previous point, but not obvious, is that there may be less physical threads than you think. For example, if you are running on AWS, certain provisioning choices will change the standard 2 threads per core. Specifically AWS Fargate provides 1 thread per core, not 2. Thus, 2 cores yields 2 physical threads, not 4. This is typically unexpected by DevOps. Be sure you understand what you are getting out of your cloud VM.
* Too many actors are dependent on limited resources, such as pooled read/write buffers. Even if your actor messages are handled rapidly, they may still exhaust a resource pool with too many actors in stasis until messages arrive, that will never arrive due to resource overuse. To solve this, either allocate resource pools for smaller sets of related actors with predictable message processing, and/or make your resource pool(s) elastic. An elastic resource pool would grow its number of pooled resources on high demand, and shrink the number when demand decreases.
* Sometimes a service can become unresponsive due to inactivity of actors it depends on. This happens when a client actor sends a message to a service-providing actor and the service-providing actor fails to respond. This may occur when the service-providing actor crashes and loses the context of the message it was handling when it crashed. It may be possible for the actor that crashes to maintain the context across the supervisor's intervention and, if resumed from or ignoring the crash, the actor could take corrective measures and respond. In some cases this may be impractical or impossible, and it could be that the client actor must resend its request message. The client actor can detect this situation by means of a scheduled timer interval, giving the client actor intermittent opportunities to check on expected progress and take corrective measures if stalled.
* There may be other possibilities, but they are probably somehow related to the above. You may benefit by using one or more of the following:
  * [Create separate thread pools](https://docs.vlingo.io/xoom-actors#allocating-separate-actors-thread-pools) for different kinds of concurrent and parallel processing.
  * The following content is focused on the sub-subheading *Considering Scheduler Latency* under this [subheading](https://docs.vlingo.io/xoom-actors#scheduler-and-the-scheduled-protocol).
    * Use separate `Scheduler` instances.
    * Consider dealing with scheduling using different strategies.

### Q: My actor has experienced a race condition. Is this a bug in XOOM Actors?

**A:** Not likely. We suggest that it's actually theoretically impossible given the design of our actor foundation, which ensures that only one thread can dispatch one message to a given actor at any given time. Ok, but why are you experiencing a race condition?

* You aren't, but have a bug that makes it appear that you have experienced a race.
* You are, but it's caused by some client making a direct method invocation on an actor at the same time that a separate assigned thread is delivering a message. We try to make it very difficult to break the rules of the Actor Model, which include actors only accepting asynchronous messages one at a time. Still, we can't prevent a programmer from exposing `this` outside. For example, it is a bug to pass `this` to the `Scheduler` or to some service actor that our actor depends on. It will work because whatever protocol, such as `SomeProtocol`, the actor implements, will be provided by passing `this` to obtain a service. But that's wrong and a sure way to experience races. You should always pass `selfAs(SomeProtocol.class)` as a parameter to the `Scheduler` or another actor.
* You are, but it's because you have a `Completes<T>` expression evaluating inside your actor that mutates state at the same time that a separate assigned thread is delivering a message that mutates state. Some overlook the fact that `Completes<T>` delivers asynchronous outcomes via a pooled actor designed for that purpose. This means that a separate thread may be entering your actor because you have invited it in with the `Completes<T>` outcome. You can solve this problem in one of two ways:
  * Never use `Completes<T>` from inside an actor. Design collaborating actors to accept dependents as expected protocols. For example, `SomeProtocol` provides a service message (method) that takes a `SomeProtocolInterest` as a parameter. When the actor handling the `SomeProtocol` message delivery has finished, it replies to its dependent using `SomeProtocolInterest`. Of course the dependent actor implements the `SomeProtocolInterest` interface, and passes a reference using `selfAs(SomeProtocolInterest.class)`.
  * If you do use `Completes<T>` inside your actor, and admittedly this may be necessary given the design of some protocols, never modify your actor's state from a `Completes<T>` outcome handler, such as `andThen(function)`. Rather, send yourself a message that will be handled with exclusive access to your state. We suggest not exposing the protocol used for this purpose outside your actor and document the protocol as being for internal use only. As an example, your actor may implement `MyInternalProtocol` (by a different name) and the `Completes<T>` outcome pipeline handler dispatches to one of its messages (methods) such as: `selfAs(MyInternalProtocol.class).accept(someOutcomeData)`.

### Q: How do Java-based XOOM Actors and Erlang BEAM processes differ in how fairness of message processing is managed?

**A:** First note that there are some terminology differences between XOOM Actors and the Erlang BEAM. The term `Scheduler` in XOOM Actors is used for timers that schedule one or continuous future signals to an actor. The XOOM Actors term used for delivering messages to actors on threads is called dispatching. The Erlang BEAM uses the term scheduler and scheduling to describe how time slices are used to managed processes (a.k.a actors).

The Erlang BEAM doesn't assign OS threads to processes in the way that Java does. Instead it has a virtual OS of its own, which enables all kinds of ways to control fairness. Think of how Un\*x and Windows operating systems work. These literally interrupt the execution of a process that is running on a thread and dynamically assign that thread to another process. That's what the Erlang BEAM does to manage its runnable processes. Thus, the Erlang BEAM uses preemptive multitasking via its scheduler by giving processes time slices, and then task switching across any number of runnable processes. And, yes, the BEAM virtual OS is interrupted by the actual machine controlling OS to assign physical CPU threads to other processes running on the machine controlled by the OS.

On the other hand, Java uses cooperative multitasking, which relies on code to give up a thread (complete a message reaction) quickly. A JVM is interrupted by the machine controlling OS in mid execution of some/many code paths in order to assign physical CPU threads to other processes running on the machine controlled by the OS. Cooperative multitasking is far less fair than OS task switching based on fixed time slices because much depends on how long any given actor message deliver and handling requires before the actor voluntarily gives up its assigned thread.


