Click here to Skip to main content
14,975,411 members
Articles / DevOps
Article
Posted 16 Apr 2016

Stats

16.2K views
86 downloads
2 bookmarked

OData Interoperability with .Net and Java

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
18 Apr 2016CPOL6 min read
OData Interoperability with .Net C# and Java applications

Introduction

It's not easy to choose the right technology for a specific problem sometimes. This article provides a decision making process on OData technology selection in an environment with both .Net C# and Java applications running. It also provides code samples on how to create an OData RESTful service in .Net C# and sample code to consume the service in a Java application. OData interoperability looks great in these .Net and Java applications.

Background

We need to retrieve large data from oracle database and serialize the data in JSON format in a .Net C# application in Data Center A so that the JSON data can be consumed in a Java application in a Data Center B. The technology selection decision process has two steps.

Step 1: Do we use Web API with OData or WCF RESTful service using JSON.Net in the .Net application?

After researching online, we decided to use Web API with OData based on the following OData advantages.

- An open protocol which allows the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way.
- Microsoft initiated OData in 2007. OData v4 was standardized at OASIS.
- Can be interoperable with .NET, Java, PHP, iPhone, Android and more
- Is an OASIS standard that defines the best practices for building and consuming RESTful APIs.
- Helps you to focus on business logic without having to warry about the request/response headers, HTTP methods, media types, payload formats, and query options, etc
- Guides you about tracking changes, defining functions/actions for reusable procedures and sending asynchronous/batch requests etc.
- Provides facility for extension to fulfill any custom needs of your RESTful APIs

Step 2: Do we use odata4j or Apache Olingo library in the Java application?

After researching online, we decided to use Onlingo library in Java application because of the following.

- odata4j library is not going to support OData v4
- Apache Olingo serves client and server aspects of OData. It currently supports OData 2.0 and will also support OData 4.0. The latter is the OASIS version of the protocol: OASIS Open Data Protocol (OData) TC.

The next question is: How to make it working in the .Net C# and Java applications?

The tools and packages on the .Net C# side are as the following:

- Visual Studio 2015 with ASP.Net 5
- latest Microsoft.AspNet.Odata (e.g. OData 5.9.0)
- latest EntityFramework (e.g. EF 6.1.3)

The Tools and packages on the Java side are as the following:

- Eclipse Kepler (Not the latest version because Olingo library was tested on Juno and Kepler)
- Apache Olingo Library 4.2
- Maven 3.2.1

Using the code on .Net C# Side

There are great OData Tutorials at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api  . However, the sample code may not work if you are not using Visual Studion 2012 or 2013. I will just high-light the steps here and explicitly mention the configuration change in step 4 if you are using Visual Studio 2015. I will also attached the complete sample code at the end just in case.

Step 1: Create a new Visual Studio project:

In Visual Studio, from the File menu, select New > Project.

Expand Installed > Templates > Visual C# > Web, and select the ASP.NET Web Application template. Name the project "ODataPartService"

In the New Project dialog, select the Empty template. Under "Add folders and core references...", click Web API.

Step 2: Install the OData Packages

From the Tools menu, select NuGet Package Manager > Package Manager Console. In the Package Manager Console window, type:

C#
Install-Package Microsoft.AspNet.Odata

Step 3: Add a Model Class

In Solution Explorer, right-click the Models folder. From the context menu, select Add > Class.
Name the class Product. Here is the sample code in Product.cs file,

C#
namespace ProductService.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }
}

Step 4: Enable Entity Framework

From the Tools menu, select NuGet Package Manager > Package Manager Console. In the Package Manager Console window, type:

C#
Install-Package EntityFramework

Open the Web.config file, and add a connectionStrings element inside the configuration element, after the configSections element. Note: the Data source is not (localdb)\V11.0 but locadb\MSSQLLocalDB

XML
<connectionStrings><add name="ProductsContext" connectionString="Data Source=(localdb)\MSSQLLocalDB;
        Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
        AttachDbFilename=|DataDirectory|ProductsContext.mdf"
      providerName="System.Data.SqlClient" />  </connectionStrings>

Next, add a class named ProductsContext to the Models folder:

C#
public class ProductsContext : DbContext
{
    public ProductsContext()
            : base("name=ProductsContext")
    {
    }
    public DbSet<Product> Products { get; set; }
}

Step 5: Configure the OData endpoint

Added the following code to the Register method:

C#
public static void Register(HttpConfiguration config)
{
    // New code:
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Product>("Products");
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: null,
        model: builder.GetEdmModel());
}

Step 6: Add OData Controller and Query Entity Set

In Solution Explorer, right-click the Controllers folder and select Add > Class. Name the class ProductsController.

C#
public class ProductsController : ODataController
{
    ProductsContext db = new ProductsContext();
    private bool ProductExists(int key)
    {
        return db.Products.Any(p => p.Id == key);
    }
    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
}

Query Entity Set. More methods can be found in the OData Tutorial and in the attached code.

C#
[EnableQuery]
public IQueryable<Product> Get()
{
    return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
    IQueryable<Product> result = db.Products.Where(p => p.Id == key);
    return SingleResult.Create(result);
}

Step 7: Add a .Net C# Client to consume the OData service

Follow the tutorial at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-client-app or just use the attached code to build a c# client to consume the created OData v4 service. Note: There is no file called ProductClient.odata.config after the code generation if you use Visual Studio 2015. Instead, the OData service url needs to be modified in the ProductClient.tt file. Here is the sample code.

C#
public static class Configuration
{
 public const string MetadataDocumentUri = "http://localhost:38173/";
 public const bool UseDataServiceCollection = true;
 public const string NamespacePrefix = "ProductsApp";
 public const string TargetLanguage = "CSharp";
 public const bool EnableNamingAlias = true;
 public const bool IgnoreUnexpectedElementsAndAttributes = true;
}

Using the code on Java Side

There are great Olingo tutorials at https://olingo.apache.org/doc/odata4/index.html

However, the instruction may not work for you if your compuer is behind a proxy server and/or any other unknown issues with your computer. I encounterd the following issues when I tried my Java client to consume the OData service created in .Net C#.

Issue 1: Proxy issue when using Maven 3.2

The issue can be solved by adding a proxy element inside proxies element in the settings.xml config as the following. Note: The settings.xml file may not be in the Maven user default folder c:\Users\xxxx\.m2 Fdirectory. Instead, it may be in the Maven installation folder. e.g. C:\apache-maven-3.2.1\conf directory. Make sure to modify the correct settings.xml config file.

XML
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>username</username>
      <password>password</password>
      <host>roxy.yourdomain</host>
      <port>80</port>
      <nonProxyHosts>maven.org|apache.org</nonProxyHosts>
    </proxy>

Issue #2: Maven error when importing a sample Olingo Maven project. Here is the error.

http://www.codeproject.com/KB/webservices/1093859/ODataJavaError1.JPG

The issue can be solved by disabling Maven nature first.

http://www.codeproject.com/KB/webservices/1093859/ODataJavaError2.JPG

Then converting the project back to a maven project.

http://www.codeproject.com/KB/webservices/1093859/ODataJavaError3.JPG <br>

Issue #3: The Quick start guide is for OData v2 not for v4.

If you are using the latest OData v4 as explained in this article, be sure to select the right client sample to start with. It's better to use the Client sample with the Olingo source download package. Here are some sample codes to consume OData v4 servcie created in .Net C#. It should work with Java service as well because the sample client in the Olingo library uses a Java service as a test servcie. 

Java
public class OlingoSampleApp {
  private ODataClient client;
 
  public OlingoSampleApp() {
    client = ODataClientFactory.getClient();
  }
  public static void main(String[] params) throws Exception {
    OlingoSampleApp app = new OlingoSampleApp();
    app.perform("<a href="http://localhost:38173/">http://localhost:38173/</a>");
  }
  void perform(String serviceUrl) throws Exception {
    Edm edm = readEdm(serviceUrl);
    List<FullQualifiedName> ctFqns = new ArrayList<FullQualifiedName>();
    List<FullQualifiedName> etFqns = new ArrayList<FullQualifiedName>();
    for (EdmSchema schema : edm.getSchemas()) {
      for (EdmComplexType complexType : schema.getComplexTypes()) {
        ctFqns.add(complexType.getFullQualifiedName());
      }
      for (EdmEntityType entityType : schema.getEntityTypes()) {
        etFqns.add(entityType.getFullQualifiedName());
      }
    }
  public Edm readEdm(String serviceUrl) throws IOException {
    EdmMetadataRequest request = client.getRetrieveRequestFactory().getMetadataRequest(serviceUrl);
    ODataRetrieveResponse<Edm> response = request.execute();
    return response.getBody();
  }
}

.Net OData v4 Service: http://www.codeproject.com/KB/webservices/1093859/ProductService.zip

.Net OData Client: http://www.codeproject.com/KB/webservices/1093859/ProductsApp.zip

Java Client: http://www.codeproject.com/KB/webservices/1093859/OlingoSampleApp.zip

References

1. Wikipedia, 2015, Open Data Protocol, https://en.wikipedia.org/wiki/Open_Data_Protocol
2. OData team, 2015, OData – the best way to REST; http://www.odata.org/
3. JC Cimetiere, 2010, OData interoperability with .NET, Java, PHP, iPhone and more; https://blogs.msdn.microsoft.com/interoperability/2010/03/16/odata-interoperability-with-net-java-php-iphone-and-more/
4. Mike Wasson, 2014, OData, http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api  
5. Apache Olingo Team, 2015, How to use Apache Olingo as Client Library, https://olingo.apache.org/doc/odata2/tutorials/OlingoV2BasicClientSample.html
6. Apache Olingo team, 2015, Documentation Odata 4.0 Java Library, https://olingo.apache.org/doc/odata4/index.html
7. Odata4j team, 2015, odata4j, https://code.google.com/archive/p/odata4j/
8. Yi Ding, 2014, odata4j support for OData version 4.0, http://stackoverflow.com/questions/23333413/odata4j-support-for-odata-version-4-0

Points of Interest

It's interesting to write an article in here. It will be good if a member can upload an existing document.

History

Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shawn1Xu
Architect
United States United States
I am a software developer and architect and have a passion for new technologies.

Comments and Discussions

 
QuestionError in connection string Pin
Izhar A.19-Apr-16 18:25
MemberIzhar A.19-Apr-16 18:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.