Getting Started with the REST Adapter in OEP 12c

Introduction

It is undeniable that we are living in the age of data. With the explosion of the internet, mobile-based devices, and social networks, data is becoming the most abundant resource on earth. Another factor that is massively contributing to this trend is IoT, an acronym for “Internet of Things”. Within the IoT realm, there are more devices than ever before, and increased connectivity leads to higher volumes of data being generated at faster rates. While most companies spend millions of dollars every year to store that data for future analysis, some companies are already leveraging this data in real-time to gain valuable information.

Getting insight through in-motion data analysis is paramount for companies to stay ahead of the competition, and there is a high demand for solutions that can transform these huge amounts of data into something meaningful. But if the idea is to capture events from the internet, mobile-based devices, social networks, and IoT; few will be the cases where you will not come across the REST architectural style. Thus, it becomes imperative that Oracle Event Processing (OEP) developers get familiar with the new 12c REST adapter.

This article will provide a step-by-step guide to implementing OEP applications that leverage the 12c REST adapter, and demonstrate how to set up the support for handling CSV, JSON and XML payloads.

Case Study: Blog Data Processing

During this article, an application that processes blog entries will be created. The purpose of this application is receive events about blog entries via REST, but with data available in different types of payloads. After processing the events, the application prints each event in the output. Despite of the simplicity, the value of this scenario is to show how the 12c REST adapter can be used in OEP applications.

Setting Up the OSGi Dependencies

OEP is an OSGi-based technology. After you create a new OEP project in Oracle Fusion Middleware JDeveloper, it is a best practice to define all your package dependencies in the MANIFEST.MF file before starting development. This practice will save you time when dealing with Java import statements and during application deployment.

To start using the REST adapter, there is no special package to be imported, but the REST adapter by itself does not do much without having the capability to handle payloads like CSV, JSON and XML. For this reason, you need to import the following packages:

– com.oracle.cep.mappers.csv

– com.oracle.cep.mappers.jaxb

It is important to note that importing all of them is not necessary, unless of course, if you are going to handle all supported media types. For instance, if you do not intend to handle CSV payloads, you can definitely remove that package from the MANIFEST.MF file. However, for the purposes of this article, all the packages need to be imported.

Design your Event Types using Java

As you probably know, event types in OEP can be defined in two ways: through the declarative mode or by using a Java class. It is true that the declarative mode gives you the ability to change the event type without re-compiling any source-code; but on the other hand, using a Java class allows you to implement the event type behavior with more flexibility. While the discussion about pros and cons between these two approaches applies for regular OEP projects, when using the REST adapter you have no choice unless using a Java class. This is necessary because behind the scenes OEP uses Java Architecture for XML Binding (JAXB) to provide support for JSON and XML. Listing 1 shows the Java class implementation for the event type that will be used through this entire article.

package com.oracle.ateam.fmw.soa.samples;

import java.io.Serializable;

public class BlogEntry implements Serializable {
    
    private String guid;
    private String title;
    private String link;
    private int likes;

    // Getters and setters methods were
    // omitted for clarity purposes.
    
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!(object instanceof BlogEntry)) {
            return false;
        }
        final BlogEntry other = (BlogEntry) object;
        if (!(guid == null ? other.guid == null : guid.equals(other.guid))) {
            return false;
        }
        if (!(title == null ? other.title == null : title.equals(other.title))) {
            return false;
        }
        if (!(link == null ? other.link == null : link.equals(other.link))) {
            return false;
        }
        if (likes != other.likes) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        final int PRIME = 37;
        int result = 1;
        result = PRIME * result + ((guid == null) ? 0 : guid.hashCode());
        result = PRIME * result + ((title == null) ? 0 : title.hashCode());
        result = PRIME * result + ((link == null) ? 0 : link.hashCode());
        result = PRIME * result + likes;
        return result;
    }

}

Listing 1: Java class implementation for the event type.

To understand what can be done to customize the event type when using JSON and XML payloads, please consult the JAXB specification. Oracle also provides a good JAXB tutorial for beginners.

Setting Up the REST Adapter in OEP

Having the OEP project opened in JDeveloper, you will notice that there is no REST adapter component available in the components palette, at least not in the 12.1.3 version used during the writing of this article. In this case, you should manually add an adapter entry in the OEP assembly file. Listing 1 shows an inbound REST adapter that receives blog entries in a given context path.

<wlevs:adapter id="restAdapter" provider="rest-inbound">
   <wlevs:instance-property name="eventTypeName" value="BlogEntry" />
   <wlevs:instance-property name="contextPath" value="/insertBlogEntry" />
</wlevs:adapter>

Listing 2: REST adapter configuration for the OEP assembly file.

Once you add the adapter entry in the OEP assembly file, the EPN diagram will start to show it along with the others elements. Figure 1 shows the REST adapter being used in the OEP project.

Figure 1: REST adapter being used in the OEP project.

A REST adapter in OEP is nothing more than a Servlet, exposed through the Jetty web server that accepts HTTP requests sent to the configured contextPath property. During deployment, the OEP engine dynamically injects an OSGi HTTP Service reference into the adapter implementation. The adapter then uses this reference to register itself as a Servlet in order to start handling HTTP requests in runtime.

The REST adapter also needs to be associated to an event type. During each request, the adapter will try to map the incoming payload wrapped in the HTTP request to the event type configured in the eventTypeName property, using one of the associated mappers. Which mapper to use will be based on the analysis of the Content-Type header field. For this reason, always make sure that valid media type values are used by the upstream systems that send the events.

Overview about Payload Mappers

One of the most interesting things about REST is the fact that any media type can be used as the payload. This is different from SOAP which was originally designed to handle only XML payloads. Using REST, you can use any valid internet media type as the payload, although CSV, JSON and XML are found as being the most popular ones due its maturity in the computer software industry.

The REST adapter was designed to handle only HTTP interactions. For this reason, it delegates all tasks related to payload handling to custom implementations called mappers. A mapper is a Java class that implements payload marshalling and unmarshalling. For instance, in the case of the inbound REST adapter, the mapper is used to unmarshall the received payload and generates an event type instance, and in the case of the outbound REST adapter, the mapper is used to marshall the event type instance into a payload that is going to be sent.

OEP provides out-of-the-box mappers for CSV, JSON and XML. When using the REST adapter, you need to configure at least one of these mappers in the assembly file, and associate it with the REST adapter. If you fail to configure at least one of these mappers you will not be able to deploy your OEP application because the REST adapter will proactively throw an exception.

The next sections will cover the configuration details for the CSV, JSON and XML mappers. For testing, it is recommended that you use some type of browser-based UI that can perform REST requests. For Chrome users, there is an extension in Chrome Web Store called Advanced REST Client that fits our requirements.

Using the REST Adapter with CSV

The Comma-Separated Values (CSV) format is based on tabular data that can be a mix of numbers and text. There is no limit to the number of records that a CSV payload can have. The only restriction is that each record needs to contain the field values separated by a comma. To start using the CSV mapper, you need to configure in the assembly file a bean for the following class: com.oracle.cep.mappers.csv.CSVMapper.

Listing 3 shows the REST adapter with the CSV mapper associated.

<bean id="csvMapper" class="com.oracle.cep.mappers.csv.CSVMapper" />

<wlevs:adapter id="restAdapter" provider="rest-inbound">
   <wlevs:instance-property name="eventTypeName" value="BlogEntry" />
   <wlevs:instance-property name="contextPath" value="/insertBlogEntry" />
   <wlevs:instance-property name="csvMapper" ref="csvMapper" />
</wlevs:adapter>

Listing 3: REST adapter configuration with support to CSV.

It is important to note that the CSV payload must include a message header containing the field names, and this message header need to be the first record. The field names must match with the event type field names. Figure 2 shows an example of a REST request using CSV as payload.

Figure 2: REST request using CSV as payload.

All fields need to be set in the CSV payload, in both the message header and the records containing the values. In the records that contains the values, if not all values are available; you need to fill the field spot with a default value that matches with data type used in the event type.

Using the REST Adapter with JSON

The JavaScript Object Notation (JSON) is an open standard format that uses human readable text to transmit data objects using attribute-value pairs, with code for parsing and generating JSON readily available in a large variety of programming languages. OEP uses JAXB to handle JSON payloads, so in order to understand what an event type looks like in the JSON format; you need to serialize it using JAXB. To start using the JSON mapper, you need to configure in the assembly file a bean factory for the following class: com.oracle.cep.mappers.jaxb.JAXBMapperFactory.

Listing 4 shows the REST adapter with CSV and JSON mappers associated.

<bean id="csvMapper" class="com.oracle.cep.mappers.csv.CSVMapper" />

<bean id="jsonMapper" class="com.oracle.cep.mappers.jaxb.JAXBMapperFactory"
   factory-method="create">
   <property name="eventTypeName" value="BlogEntry" />
   <property name="mediaType" value="application/json" />
</bean>

<wlevs:adapter id="restAdapter" provider="rest-inbound">
   <wlevs:instance-property name="eventTypeName" value="BlogEntry" />
   <wlevs:instance-property name="contextPath" value="/insertBlogEntry" />
   <wlevs:instance-property name="csvMapper" ref="csvMapper" />
   <wlevs:instance-property name="jsonMapper" ref="jsonMapper" />
</wlevs:adapter>

Listing 4: REST adapter configuration with support to CSV and JSON.

Since OEP uses JAXB to handle JSON payloads, it is necessary to inform the JSON mapper which event type is being handled. This is accomplished through the property eventTypeName. The property mediaType allows you to set which value to expect in the Content-type header field. Figure 3 shows an example of REST request using JSON as payload.

Figure 3: REST request using JSON as payload.

Different from the CSV mapper that supports multiple records in the same payload, the JSON mapper supports only one record. In the JSON world this record is called the object root. Fortunately, the object root can contain child objects, so you are not restricted to send all the data in the object root.

Using the REST Adapter with XML

The eXtensible Markup Language (XML) is an open standard specification defined by W3C for a markup language, understandable both by humans and machines, used for the representation for arbitrary data structures. OEP uses JAXB to handle XML payloads, so in order to understand what an event type looks like in the XML format; you need to serialize it using JAXB. To start using the XML mapper, you need to configure in the assembly file a bean factory for the following class: com.oracle.cep.mappers.jaxb.JAXBMapperFactory.

Listing 5 shows the REST adapter with CSV, JSON and XML mappers associated.

<bean id="csvMapper" class="com.oracle.cep.mappers.csv.CSVMapper" />

<bean id="jsonMapper" class="com.oracle.cep.mappers.jaxb.JAXBMapperFactory"
   factory-method="create">
   <property name="eventTypeName" value="BlogEntry" />
   <property name="mediaType" value="application/json" />
</bean>

<bean id="xmlMapper" class="com.oracle.cep.mappers.jaxb.JAXBMapperFactory"
   factory-method="create">
   <property name="eventTypeName" value="BlogEntry" />
   <property name="metadata" value="blogEntryMetadata.xml" />
</bean>

<wlevs:adapter id="restAdapter" provider="rest-inbound">
   <wlevs:instance-property name="eventTypeName" value="BlogEntry" />
   <wlevs:instance-property name="contextPath" value="/insertBlogEntry" />
   <wlevs:instance-property name="csvMapper" ref="csvMapper" />
   <wlevs:instance-property name="jsonMapper" ref="jsonMapper" />
   <wlevs:instance-property name="xmlMapper" ref="xmlMapper" />
</wlevs:adapter>

Listing 5: REST adapter configuration with support to CSV, JSON and XML.

Since OEP uses JAXB to handle XML payloads, it is necessary to inform to the XML mapper which event type is being handled. This is accomplished through the property eventTypeName. Also, the XML mapper needs a special configuration file called JAXB bindings that the OEP developer can use to customize the XML payload. You can set which JAXB bindings file to use through the metadata property.

According to the JAXB specification, XML bindings can be implemented using the JAXB bindings file, via Java annotations or using a mix of both approaches. However, OEP ignores any Java annotation set in the event type implementation. For this reason, the JAXB bindings file is mandatory.

In the <ROOT>/wlevs/mappers/jaxb folder, create a file called blogEntryMetadata.xml just as shown in listing 6. Note that JDeveloper does not create the /mappers/jaxb folder during the project creation, so you will need to manually create this folder.

<?xml version="1.0"?>

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
   <java-types>
      <java-type name="com.oracle.ateam.fmw.soa.samples.BlogEntry">
         <xml-root-element name="blog-entry"/>
      </java-type>
   </java-types>
</xml-bindings>

Listing 6: JAXB bindings file used to customize the XML payload.

As you can see in listing 6, the root element of the XML payload was changed from BlogEntry (which is essentially the Java class name of the event type) to blog-entry. There are a lot of customizations that can be done in the JAXB bindings file, but covering all of them goes beyond the scope of this article. Figure 4 shows an example of REST request using XML as payload.

Figure 4: REST request using XML as payload.

Different from the CSV mapper that supports multiple records in the same payload but like JSON, the XML mapper supports only one record. In the XML world this record is called the root node. Fortunately, the root node can contain child nodes, so you are not restricted to send all the data in the root node.

You can download the final implementation of the project used in this article here.

Conclusion

The REST architectural style is becoming a common standard for system-to-system, things-to-system and things-to-things interactions, due its simplicity, portability and small footprint. These characteristics attract more and more developers that choose to build APIs using REST. Also, with data being generated at faster rates, companies are looking for solutions that can help them to identify business opportunities or threats through the analysis of in-motion data. Looking ahead at what the industry needed, Oracle introduced the REST adapter in the OEP 12c version.

This article showed a step-by-step guide that aims to help developers to leverage the REST adapter in OEP applications, providing best practices for development and explaining the adapter internals.

Add Your Comment