Splitting and aggregating messages
7.1 Introducing correlation
The functionality of the components discussed in this chapter—aggregators, splitters, and resequencers—is based on the idea that certain messages are related in a particu- lar way. This section focuses on correlation from a functional perspective, introducing the main concepts behind it.
An aggregator, such as the one in figure 7.2, waits for messages in a certain group to arrive and then sends out the aggregate. In this particular case, the aggregator waits
Service Activator
Splitter Aggregator
Filter
Figure 7.1 Examples of endpoints processing a message in one-to-one, one-to-many, and many-to-one scenarios
124 CHAPTER 7 Splitting and aggregating messages
for all the items of an order to come in, and after they are received, it sends an order to its output channel.
The part we’re interested in first is how it determines what messages belong together. Details follow in later sections. Spring Integration uses the concept of a mes- sage group which holds all the messages that belong together in the context of an aggregator. These groups are stored with their correlation key in a message store. The correlation key is determined by looking at the message, and it may differ between endpoints.
Now is a good time to look at an analogy to help anchor the important terms used in this chapter.
7.1.1 A real-life example
Let’s say you’re having guests for dinner. Maybe you’re not the cooking kind, but you’re probably familiar with the concept of home cooking, and that’s more than enough. We’ll look at the whole process of preparing and serving a meal to see what’s involved in automating this process and how it applies in terms of messaging. For the sake of argument, we’ll ignore the possibility of ordering take-out (which would greatly decrease the complexity of the setup but would ruin the analogy). Figure 7.3 illustrates the scenario described in the rest of this section.
A recipe is split into ingredients that are aggregated to a shopping list. This shop- ping list is converted into bags filled with products from the supermarket. The bags are then split into products, which are aggregated to a mise en place, which is finally transformed into a meal. The channel configurations are considered trivial and are omitted from the diagram.
Involved in the dinner are the host (that’s you), the kitchen, the guests, and the shops. You orchestrate the whole event; the guests consume the end product and turn it into entertaining small talk and other things irrelevant to our story. The kitchen is the framework you use to transform the ingredients you get from the shop into the dinner.
Order items Orders
Aggregator
Figure 7.2 An aggregator is an endpoint that combines several related messages into one message.
ShoppingListAggregator RecipeSplitter ShoppingBagUnpacker MiseEnPlace Supermarket Recipe
Figure 7.3 The flow of messages in the home cooking example
125
Introducing correlation
We’re interested in the sequence of events that take place after a date is set. It starts with your selecting a menu and gathering the relevant recipes from your cookbook or the internet. The ingredients for the recipes must be bought at various shops, but to buy them one at a time, making a round trip to the shop for each prod- uct, is unreasonably inefficient, so you must find a smarter way to handle this process. The trick is to create a shopping list for each shop you must visit. You pick the ingredi- ents from each recipe, one by one, and put them on the appropriate shopping list. You then make a trip to each shop, select the ingredients, and deliver the ingredients back to your kitchen.
With the ingredients now in a central location, each shopping bag must be unpacked and the ingredients sorted according to recipe. Having all the right ingredi- ents (and implements) gathered together is what professional chefs call the mise en place. With all the necessary elements at hand, each dish can be prepared, which usu- ally involves putting the ingredients together in some way in a large container. When the dish is done, it’s divided among plates to be served.
But what does this have to do with messaging? Perhaps more than you think. 7.1.2 Correlating messages
Let’s say the recipe is a message. This message is split into ingredients, which can be sent by themselves as messages. The ingredients (messages) reach an aggregator that aggregates them to the appropriate shopping lists. The shopping lists (messages) then travel to the supermarket where the shopper turns them into bags filled with groceries (messages), which travel back to the kitchen (endpoint).
The shopping bags are unpacked (split) into products that are put together in dif- ferent configurations on the counter during the mise en place. These groups of ingredi- ents are then transformed into a course in a pan. The dish in the pan is split onto different plates (messages), which then travel to the endpoints that consume them at the table. What we see here is a lot of breaking apart and putting together of payloads. The recipes are split and the ingredients aggregated to grocery lists. The bags are unpacked and the products regrouped for the different courses. The dishes are split and assembled on plates.
Some observations can be made from this analogy that will be helpful to think back on later in the chapter. Splitting is a relatively easy job, but it’s important to keep track of which ingredients belong to which recipe. Messages (ingredients in this example) are given a Correlation ID to help track them. Most easy examples of splitting and aggregating use a splitter that takes a thing apart and an aggregator that turns all the split parts into a thing again. This is a simplistic example, so it’s good to keep a simple analogy in mind that does things differently. In a real enterprise, an aggregator often has no symmetric splitter.
It now becomes important to think about how we’ll know when the aggregate is done. Or to stay with the example, when is the shopping list done? The answer is that it’s only done when all the recipes have been split and all ingredients are on their
126 CHAPTER 7 Splitting and aggregating messages
appropriate list. This is still relatively simple but more interesting than to say that a list is done when all ingredients of one particular recipe are on it.
When aggregating is done without a previous symmetric splitting, it becomes harder to figure out which messages belong together, or in this example, which ingre- dients go on which list. Usually aggregation relies not on a message’s native key but on a key generated by a business rule. For example, it could be that all vegetable ingredi- ents go on the greenery list and all meat ingredients go on the butcher list. This assumes that you’re not just buying everything from the supermarket, but even if you do, it makes sense to organize your shopping list by type to avoid having to backtrack through the supermarket.
The next sections explain how the components introduced here are used. For those interested in the home cooking example, some code is available on the Spring Integration in Action repository (https://github.com/SpringSource/Spring-Integration -in-Action).