Typing is a core issue in federated networked distributed applications, which are increasingly modeled as event-based systems. Constraining such a system to globally agreed types for exchanged event objects is impractical. To interpret event notifications, knowledge about their context is essential. To mediate between such semantic contexts, we developed ACTrESS, a distributed middleware addon for automatic context transformation in event-based software systems and message-oriented middleware (MOM) in general.
The following report describes in more detail our rule-based approach to specifying transformations and their safe application: "Sound Transformations For Message Passing Systems".
Table of Contents
Source Code
The Code of ACTrESS is available upon request.
Benchmarks
We use a micro-benchmark, a SPECjms2007-based benchmark, and a benchmark with a typical interaction from our traffic control application scenario.
Micro
The micro-benchmark uses generated event object types to see the influence of various parameters on the performance and push the system to its limits.
Download the event object types
Transformations
In this scenario, the A, B and C properties of type T4 were transformed by doubling or halving their value.
distributed | local |
deep structure | flat structure |
close (throughput) | close (latency) |
SPECjms2007
The SPECjms2007 standard benchmark specifies a workload where distribution centers, headquarters, and suppliers form a complex supply chain and interact by sending various inter-company notifications.
We designed a workload following the one specified in SPECjms2007. Event object types are taken directly from the specification.
Download the event object types
Transformations
Zip codes in all Address types are prepended with a country-specific letter.
InvoiceLineTypes were transformed by setting the unit to cm and accordingly dividing the price. Additionally, the taxes were reduced by 20%.
OfferLine types were treated the same way.
Since POrderLine types represent responses to above types containing related information, they were transformed inversely.
We want to illustrate the necessary effort to code these transformations manually. Typically the transformation code is executed in some message handling method and looks like this (we omit specification of the transformation functions):
...
} else if (object instanceof CallForOffers) {
CallForOffers o = (CallForOffers) object;
Address oldAddress = o.getDeliveryAddress();
Address newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setDeliveryAddress(newAddress);
} else if (object instanceof Offer) {
Offer o = (Offer) object;
Address oldAddress = o.getSupplierAddress();
Address newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setSupplierAddress(newAddress);
oldAddress = o.getDeliveryAddress();
newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setDeliveryAddress(newAddress);
oldAddress = o.getDeliveryAddress();
newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setDeliveryAddress(newAddress);
OfferLine oldOfferLine = o.getOfferLine();
OfferLine newOfferLine = (OfferLine) offerLineFunction.transformObject(oldOfferLine);
o.setOfferLine(newOfferLine);
} else if (object instanceof POrder) {
POrder o = (POrder) object;
Address oldAddress = o.getSupplierAddress();
Address newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setSupplierAddress(newAddress);
oldAddress = o.getDeliveryAddress();
newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setDeliveryAddress(newAddress);
oldAddress = o.getDeliveryAddress();
newAddress = (Address) addressFunction.transformObject(oldAddress);
o.setDeliveryAddress(newAddress);
POrderLine oldOrderLine = o.getOrderLine();
POrderLine newOrderLine = (POrderLine) offerLineFunction.transformObject(oldOrderLine);
o.setOrderLine(newOrderLine);
} else if (object instanceof POrderConf) {
...
With our approach, the necessary rules are:
Address = address
Since our rule-based approach allows for defining the transformation on Address-types at any nesting level, we do not have to create a separate rule for each event type containing one or more fields of type Address. This improves readability of code and reduces the lines of code.
OfferLine = offerline
POrderLine = porderline
Invoice.Address = identity
InvoiceLine = invoiceline
Traffic Control
This benchmark is about a traffic information scenario with many participants and lightweight notifications. The key idea in this scenario is to monitor traffic and pass that information to interested consumers: emergency cars, police, and (for a fee) taxis or logistics providers.
Download the event object types
Transformations
We modified TrafficGuideUpdate types by changing the format of the direction property and TrafficJamAtRoadWarning by simulating a transformation from latitude/longitude coordinates to a specific street name.
Recompile Overhead
With this benchmark we evaluate the overhead that incurs when a broker node encounters a new type or new rules. It then has to generate the new transformation code, compile it and load it. We started the broker with a set of transformation rules and after some time, a client sends a new rule set. As the graph shows, there is an initial overhead of less than 500ms for messages which have to wait on the compilation process. However, future messages use the newly compiled code and thus have the same latency as the original messages.