Introduction
SAS Business Orchestration Services is an orchestration framework that allows you to integrate multiple systems. It enables you to implement enterprise integration patterns that make it easier to send, transform, and enrich your data as they flow from one system to another. SAS Business Orchestration Services uses Apache Camel as its execution engine. Data are sent from one system to another in Camel is via routes. Routes are a series of steps that are performed by Camel to consume and process a message. When integrating multiple systems, some systems require extra steps to be taken to pull messages. One example of such a service is Apache Kafka. Apache Kafka is an event streaming platform that allows you to write, read, store, and process streams of events.
To showcase this functionality, we provide a sample route, in which a stream of ISO 8583 financial messages stored in a Kafka topic will be read, processed, and transformed into a Java Bean. ISO 8583 is a message format allowing different systems to exchange financial transaction data. These messages are used when customers use their credit or debit card to make a purchase at a store or for ATM transactions.
ISO 8583 to Bean Route
The route below reads an ISO 8583 message from a Kafka topic and converts the message to a Java bean via the following steps:
Pull the ISO 8583 messages from the Kafka Topic.
Unmarshal the ISO 8583 message into a Java Map.
Send the Map to the data type converter to be converted to a Bean.
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="kafka:helloKafka?brokers=kafka:8583Messages?brokers=localhost:9092"/>
<unmarshal>
<custom ref="sas-iso8583"/>
</unmarshal>
<log message="${body}"/>
<to uri="sas-convert-body-to:?mapperId=IsoToBeanMapper"/>
<to uri="log:IsoMessages"/>
</route>
</routes>
To connect to the Kafka topic, you must use the Camel Kafka component. To consume messages from the Kafka topic you must use the following format: <from uri=“kafka:topicName?brokers=hostname:port”/>. This functionality is displayed on line 4 of the route above. In lines 5-8, the ISO 8583 message is converted to a Map with SAS Business Orchestration Services custom unmarshalling, allowing for the data to be transformed to a Map. In line 9, the map is sent to the sas-convert-body-to endpoint to be converted to the Java bean. The mapperId=IsoToBeanMapper parameter indicates that the mapper file below is the file to be used for the conversion. The purpose of the Java bean is to illustrate the data fields in the ISO 8583 messages. To learn more about working with the ISO 8583 data format, see “ISO 8583 Data Format” in SAS® Business Orchestration Services 10.2: User’s Guide.
Field Mapping File
The field mapping XML file below is used to provide the necessary information to convert the ISO 8583 map to a Java bean. SAS Business Orchestration Services loads up the field mapping file and validates its format at start-up time. The converter processes fields in the order that they are defined in the field mapping file.
<?xml version="1.0"?>
<fieldMapper xmlns="https://www.sas.com/boss/fieldMapper-10.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.sas.com/boss/fieldMapper-10.2 fieldMapper-10.2.xsd"
targetType="com.sas.integration.demo.Iso8583Bean"
id="IsoToBeanMapper">
<field name="mti">
<sourceField name="0"/>
</field>
<field name="pan">
<sourceField name="2"/>
</field>
<field name="processingCode">
<sourceField name="3"/>
</field>
<field name="transactionAmount">
<sourceField name="4"/>
</field>
<field name="cardBillingAmount">
<sourceField name="6"/>
</field>
<field name="dateTime">
<sourceField name="7"/>
</field>
<field name="panCountryCode">
<sourceField name="20"/>
</field>
<field name="posCaptureCode">
<sourceField name="26"/>
</field>
<field name="air">
<sourceField name="38"/>
</field>
<field name="cati">
<sourceField name="41"/>
</field>
<field name="canl">
<sourceField name="43"/>
</field>
<field name="isoData">
<sourceField name="46"/>
</field>
<field name="nationalData">
<sourceField name="47"/>
</field>
<field name="addPrivateData">
<sourceField name="48"/>
</field>
</fieldMapper>
The target type attribute in line 5 of the mapping file provides the data type that is to be produced by the converter. In this example, the type is a Java Bean. Line 6 defines the mapper's id, to which the mapperId parameter in the ISO 8583 to Bean route refers. The field element declares a field in the Java Bean that is produced by the converter. These field names correspond with the instance variables in the Iso8583Bean class, shown in the Bean section. Nested inside each field element is the sourceField element, which declares which field in the input object should be read as the source value for that field element. Each source field name corresponds with the key for some value in the Map input object. The source fields in the Map are the decimal representations of the bitmap from the original ISO 8583 message. The decimal numbers represent different data fields that can be present in the ISO 8583 message. The ISO 8583 messages being used in this sample don't contain values for possible single data field, which is why some data fields aren't present in the Bean. To learn more about data fields in ISO 8583 messages, consult the ISO 8583 specification. For more information about the Field Mapping file, see “Working with Data Types” in SAS® Business Orchestration Services 10.2: User’s Guide.
Bean
Below is the Java class Iso8583Bean:
package com.sas.integration.demo;
public class Iso8583Bean {
private String mti;
private String pan;
private String processingCode;
private String transactionAmount;
private String cardBillingAmount;
private String dateTime;
private String panCountryCode;
private String posCaptureCode;
private String air;
private String cati;
private String canl;
private String isoData;
private String nationalData;
private String addPrivateData;
public String getMti() {
return mti;
}
public void setMti(String mti) {
this.mti = mti;
}
public String getPan() {
return pan;
}
public void setPan(String pan) {
this.pan = pan;
}
public String getProcessingCode() {
return processingCode;
}
public void setProcessingCode(String processingCode) {
this.processingCode = processingCode;
}
public String getTransactionAmount() {
return transactionAmount;
}
public void setTransactionAmount(String transactionAmount) {
this.transactionAmount = transactionAmount;
}
public String getCardBillingAmount() {
return cardBillingAmount;
}
public void setCardBillingAmount(String cardBillingAmount) {
this.cardBillingAmount = cardBillingAmount;
}
public String getDateTime() {
return dateTime;
}
public void setDateTime(String dateTime) {
this.dateTime = dateTime;
}
public String getPanCountryCode() {
return panCountryCode;
}
public void setPanCountryCode(String panCountryCode) {
this.panCountryCode = panCountryCode;
}
public String getPosCaptureCode() {
return posCaptureCode;
}
public void setPosCaptureCode(String posCaptureCode) {
this.posCaptureCode = posCaptureCode;
}
public String getAir() {
return air;
}
public void setAir(String air) {
this.air = air;
}
public String getCati() {
return cati;
}
public void setCati(String cati) {
this.cati = cati;
}
public String getCanl() {
return canl;
}
public void setCanl(String canl) {
this.canl = canl;
}
public String getIsoData() {
return isoData;
}
public void setIsoData(String isoData) {
this.isoData = isoData;
}
public String getNationalData() {
return nationalData;
}
public void setNationalData(String nationalData) {
this.nationalData = nationalData;
}
public String getAddPrivateData() {
return addPrivateData;
}
public void setAddPrivateData(String addPrivateData) {
this.addPrivateData = addPrivateData;
}
@Override
public String toString() {
return "Message type Indicator: " + mti +
"\nPrimary account number: " + pan +
"\nProcessing Code: " + processingCode +
"\nTransaction Amount: " + transactionAmount +
"\nCardholder billing amount: " + cardBillingAmount +
"\nTransmission date & time: " + dateTime +
"\nPAN extended: " + panCountryCode +
"\nPoint of service capture code: " + posCaptureCode +
"\nAuthorization identification response: " + air +
"\nCard acceptor terminal indentification: " + cati +
"\nCard acceptor name/location: " + canl +
"\nAdditional ISO data: " + isoData +
"\nAdditional national data: " + nationalData +
"\nAdditional private data: " + addPrivateData;
}
}
Summary
To summarize, SAS Business Orchestration Services allows you to seamlessly integrate systems like Apache Kafka and to parse complex data like ISO 8583 messages. To do so, you must establish a connection to a Kafka topic. Once that connection is established, unmarshal the ISO 8583 message into a map with a SAS Business Orchestration Services custom reference and convert it to a bean using the SAS Business Orchestration Services data type converter. Afterward, send the Java Bean to your endpoint. For additional information on SAS Business Orchestration Services and Apache Camel, consult the following resources:
SAS® Business Orchestration Services 10.2 User’s Guide
Camel Documentation
... View more