Enterprise Integration Zone is brought to you in partnership with:

I first started working on the IT industry in 2001 and I've been working as software architect and team leader since 2006, mainly on BPM/ERP applications for industries in the agriculture, energy, government, IT, telecom and content management industries, serving roles of Team Leader and software architect. Since 2011, I also started to specialize in SaaS applications and integration on the Cloud. Mariano is a DZone MVB and is not an employee of DZone and has posted 18 posts at DZone. You can read more from them at their website. View Full User Profile

Data as a Service: An OData Primer

07.15.2013
| 3452 views |
  • submit to reddit

It’s pretty common to hear and read about how everything in the IT business is going “as a service…”. So you start hearing about Software as a Service (SaaS), Platform as a Serivce (PaaS) and even Integration Platform as a Service (iPaaS, which is where our very own CloudHub platform plays on). But what about data?

, they’re everywhere

If you’re an avid reader of this blog, you probably read countless posts about how APIs are everywhere, making the integration of cloud services possible. Sometimes those APIs expose services and behavior, like when Facebook API let’s you change your status or when the Box API let’s you store a file. But what happens in the cases when I just plain and simply want to expose data? What if I don’t need to expose explicit behavior such as Facebook does when sending a friendship request? What if for me, allowing to query and optionally modify my data is enough?

For example, consider President’s Obama Open Data Policy. In case you’re not aware of it, President Obama ordered all government public information to be openly available in a machine readable format. That’s A LOT of data feeds to publish. Let’s make a quick list of things government’s IT officials would need to carry this out:

  • APIs: In order to consume these feeds, there has to be a way to connect to them. Just publishing government’s data bases out in the Internet wouldn’t work for many reasons (from security to scalability). Also, some level of communication/scalability/governance layer is necessary.
  • Standarization: With so many feeds to publish, a common stardard consumption is required. You don’t want to build and maintain a different infrastructure per each feed.
  • Compatible: It should be easy for existing systems to interact with these feeds

All of the above, is what stands for. Initially created by Microsoft but then opened to the public, is a REST based protocol that defines a standard way to expose/consume data feeds. Along its features we can mention:

  • REST based
  • Compatible with ATOM and JSON
  • Metadata support to discover data catalogs
  • Query language including aggregation functions
  • Full CRUD capabilities
  • Batch processing

Open Data Policy is just the tip of the iceberg. Many governments all around the world are taking on similar initiatives. In case you feel that government data is a little bit out of the ordinary compared to your average day at work, let’s take a look at other services that use OData:

  • Microsoft Dynamics CRM uses OData to expose its data catalog. You can query and modify its data and even execute some functionality using navigations.
  • Microsoft Azure uses OData to expose table information
  • Splunk: This Big Data company let’s you integrate through a OData API
  • Netflix & Ebay: Although recently deactivated, these two where using OData to allow remote queries to their databases.

Where does Mule fit in?

Well, as usually we have a connector for it. Since OData is a standard protocol, we were able to develop a OData connector that will let you into any service using it. As of today, the connector supports:

  • V1 and V2 protocol specifications
  • All CRUD set of operations, including search functions
  • ATOM and JSON feeds
  • Batch operations
  • Marshalling / Unmarshalling to your own Pojo model

A quick demo

Although the goal of this post is not to dive deep into the connector, let’s take a quick look at the connector’s demo app just to illustrate how it works. This app consumes the OData feed from the city of Medicine Hat in Alberta, Canada. It’s basically an OData API listing public information such a list of the city buildings. So, let’s see how to consume that!

First, open up Mule Studio and install it from the Cloud Connectors update site:

Then, let’s a start a flow with an http inbound endpoint. It’s configuration should look like this:

Then, drop the OData connector into the canvas. First, create the connector’s config:

Notice that the V1 and ATOM were selected as protocol version and format merely because that’s what the team at medicine hat used.

Once the config is created, use the Get Entities operation to retrieve all the buildings in the city:

In the screen above, you can see how the CityBuildings catalog was selected for querying and how you can add filters and projections to this query (although we won’t be showing that in this demo). Also, notice that we’re specifying a class as a return type. If not provided, then the connector will return an object model that represents the OData model. That is good but not really easy to work with. By being able to specify your own return type, you can easily make an object that carries the info you need and that is easier to integrate with other components such as DataMapper. In this case, our object looks like this:

public class CityBuilding {

	private String entityId;
	private String id;
	private String partitionKey;
	private String rowKey;
	private String type;
	private String name;
	private String address;
	
	public String getEntityId() {
		return entityId;
	}
	public void setEntityId(String entityId) {
		this.entityId = entityId;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPartitionKey() {
		return partitionKey;
	}
	public void setPartitionKey(String partitionKey) {
		this.partitionKey = partitionKey;
	}
	public String getRowKey() {
		return rowKey;
	}
	public void setRowKey(String rowKey) {
		this.rowKey = rowKey;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
}
Finally, we just add a Choice Router so that if no results came back we show a message saying so. If results were indeed found, then we transform the results to JSON format and print on the browser. This is how the final flow looks like: And this is how the Mule XML config looks like:
    <flow name="odata-demoFlow1" doc:name="odata-demoFlow1">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8080" doc:name="HTTP" path="buildings"/>
        <odata:get-entities config-ref="OData" entitySetName="CityBuildings"  doc:name="OData Cloud Connector" returnClass="com.mulesoft.modules.odata.demo.model.CityBuilding"/>
        <choice doc:name="Choice">
        	<when expression="#[payload.isEmpty()]">
        		<set-payload value="no results" doc:name="Set Payload"/>
        	</when>
        	<otherwise>
                <processor-chain doc:name="Processor Chain">
                    <json:object-to-json-transformer doc:name="Object to JSON"/>
                </processor-chain>
        	</otherwise>
        </choice>
    </flow>

That’s it! Try and enjoy!

Additional resources

Here’s a couple of helpful links:

I hope you found this post helpful. As always, your comments are very welcome. Thanks for reading!

Related posts:

  1. New CloudHub Platform Service for Application Data Storage
  2. Big Data & iPaaS: Come Hear Why They Are Better Together
  3. Application vs. Data Integration: Which is better?
  4. Dataloader.io Users Bulk Up for the Summer! Data loading stats for Salesforce.com
Published at DZone with permission of Mariano Gonzalez, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)