Interoperability between WCF and Oracle Application Server


Summary

This article is part of series intended to show how to use Web Services related technologies to interoperate applications running in different platforms, in this case, the most common scenario between Microsoft.NET and Oracle AS platforms. This article is to illustrate techniques and architecture that address the situation of one service running in WCF and a client consuming this service.

Creating a Web Service in Windows Communication Foundation.

This section describes how to create a Web Service using the Windows Communication Foundation, the new Microsoft platform for developing connected applications. Our target Web Service, like in the first article, will expose the functionality of Financial System.

The section contains the following topics:

  1. Installing Windows Communication Foundation.
  2. Defining the interface of the service and creating the Web Service.
  3. Deployment and running of the Web Service.

Installing Windows Communication Foundation.

You need to download from Microsoft Portal (
http://www.microsoft.com) the runtime environment (dotnetfx3.exe), the SDK (6.0.6000.0.0.WindowsSDK_Vista_rtm.DVD.Rel.DVD.Rel.img), and the Visual Studio extension for WCF (vsextwfx.msi). And finally, install this requirements in the this same order.

To create the Web Service in WCF, you have to start Visual Studio.NET and then select File|New|Project in the main menu. In the New Project windows at the Project Types tree go to Visual C#|NET Framework 3.0 and choose WCF Service Library from the Visual Studio installed templates area and enter a project name such as FinancialServiceLib, and a directory where to store the project's file. Under the hood Visual Studio.NET uses the extension for WCF to create the WCF components such as the configuration information, the interface of the service, the WCF service, the reference to WCF platforms objects, and the service host components for the case of using Windows or Console applications to host the service and it's remarkable to say that in other runtime environments such as Web Applications or Windows Services it is not necessary these components.

Defining the interface of the service and creating the Web Service.

To define the service's interface component, you must create the file IFinancialService.cs as illustrated in Listing 1.

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.Runtime.Serialization;

 

namespace FinancialServiceLib

{

    [ServiceContract()]

    public interface IFinancialService

    {

        [OperationContract]

        int Debit(int nAccount, int nAmount);

    }
}


Listing 1.

To create the Web Service component, you must define a class which implements the former interface in a file FinancialServiceLib.cs as illustrated in Listing 2.

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.Runtime.Serialization;

 

namespace FinancialServiceLib

{

    public class FinancialService : IFinancialService

    {

        public int Debit(int nAccount, int nAmount)

        {

            //Here comes the business logic.

            return nAmount;

        }

    }
}


Listing 2.


The service host component is defined as illustrated in Listing 3.

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.Runtime.Serialization;

 

namespace FinancialServiceLib

{

    public class FinancialServiceHost

    {

        public static ServiceHost objFinancialServiceHost = null;

        public static void StartService()

        {

            //Consider putting the baseAddress in the configuration system

            //and getting it here with AppSettings

            Uri baseAddress = new Uri("http://localhost:8080/FinancialService.svc");

 

            //Instantiate new ServiceHost

            objFinancialServiceHost = new ServiceHost(typeof(FinancialServiceLib.FinancialService), baseAddress);

 

            //Open myServiceHost

            objFinancialServiceHost.Open();

        }

        public static void StopService()

        {

            //Call StopService from your shutdown logic (i.e. dispose method)

            if (objFinancialServiceHost.State != CommunicationState.Closed)

                objFinancialServiceHost.Close();

        }

    }

}

Listing 3.

And finally, you create the configuration file with all the runtime information needed by the service host component for its initialization. You may define the address to access the service, the endpoints or interface and its underlying communication mechanism for this example, I use the binding wsHttpBinding, well as other information to bind successfully to the service such as security, policies, etc. For example, in this case, we allows the client to discover metadata of the service using the http protocol and the Get method, that is, you can use a browser to access the service definition structured according to the rules of WSDL and save this file in your computer directory (text highlighted in yellow).See Listing 4.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <services>

      <service name="FinancialServiceLib.FinancialService" behaviorConfiguration="FinancialServiceLib.FinancialServiceBeh">

        <endpoint contract=" FinancialServiceLib.IFinancialService" binding="wsHttpBinding" />

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name="FinancialServiceLib.FinancialServiceBeh">

          <serviceMetadata httpGetEnabled="true" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Listing 4.


Deployment and running of the Web Service.

To deploy and run the WCF service, we're going to create a Console application. Go to File|New|Project and choose Console Application template. Then add a reference to the library create in the last step by right-clicking on the console project, and select Add Reference and from the Add Reference windows at the Projects tab choose the FinancialServiceLib.

The business logic for this application is straightforward as illustrated in the following listing.

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            FinancialServiceLib.FinancialServiceHost.StartService();

 

            System.Console.WriteLine("Please, enter any key to finish ...");

            System.Console.ReadLine();

        }

    }

}

Listing 5.

Consuming the WCF Web Service.

This section describes how to consume the Web Service using Windows Communication Foundation.

The section contains the following topics:

  1. Creating the proxy.
  2. Running the application.

Creating the proxy.

You need to launch the JDeveloper IDE, and create an application and one project. Select File|New from the main menu. Enter a name for the application name, and a place to store the application components in Directory Name, and finally set a descriptive name for the project such as FinancialWCFService_Client.

To create the proxy, go to File|New and navigate the Categories tree to the Business Tier| Web Services and choose Web Service Proxy. Finally, you must follow the instruction of the wizard, setting the address where the WSDL reside, for example
http://localhost:8080/FinancialService.svc?wsdl, the package name and so on. Afterwards, you have generated a proxy to the WCF service as illustrated in the Listing 6.

// This source file is generated by Oracle tools and is subject to change

// It is a utility client for invoking the operations of the Web service port.

// For reporting problems, use the following

// Version = Oracle WebServices (10.1.3.1.0, build 061008.0900.00025)

package com.olam.jdbcexample.proxy;

import oracle.webservices.transport.ClientTransport;

import oracle.webservices.OracleStub;

import javax.xml.rpc.ServiceFactory;

import javax.xml.rpc.Stub;

public class WSHttpBinding_IFinancialServiceClient

{

    private com.olam.jdbcexample.proxy.IFinancialService _port;

    public WSHttpBinding_IFinancialServiceClient() throws Exception

    {

        ServiceFactory factory = ServiceFactory.newInstance();

        _port = ((com.olam.jdbcexample.proxy.FinancialService)factory.loadService

        (com.olam.jdbcexample.proxy.FinancialService.class)).getWSHttpBinding_IFinancialService();

    }

   

    /**

     * @param args

     */

    public static void main(String[] args)

    {

        try

        {

            com.olam.jdbcexample.proxy.WSHttpBinding_IFinancialServiceClient myPort = new

            com.olam.jdbcexample.proxy.WSHttpBinding_IFinancialServiceClient();

            System.out.println("calling " + myPort.getEndpoint());      

            int nResult = myPort.debit(3,200);

            System.out.println("Debit the account id 3, the amount 200 and result is "+nResult);

        }

        catch (Exception ex)

        {

            ex.printStackTrace();

        }

    }   

   
   
/**

     * delegate all operations to the underlying implementation class.

     */

    
    
public Integer debit(Integer nAccount, Integer nAmount) throws java.rmi.RemoteException

    {

        return _port.debit(nAccount, nAmount);

    }

   
   
/**

     * used to access the JAX-RPC level APIs

     * returns the interface of the port instance

    */

    public com.olam.jdbcexample.proxy.IFinancialService getPort()

    {

        return _port;

    }

    public String getEndpoint()
    {

        return (String) ((Stub) _port)._getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY);

    }

    public void setEndpoint(String endpoint)
    {

        ((Stub) _port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpoint);

    }

    public String getPassword()
    {

        return (String) ((Stub) _port)._getProperty(Stub.PASSWORD_PROPERTY);

    }

    public void setPassword(String password)
    {

        ((Stub) _port)._setProperty(Stub.PASSWORD_PROPERTY, password);

    }

    public String getUsername()
    {

        return (String) ((Stub) _port)._getProperty(Stub.USERNAME_PROPERTY);

    }

    public void setUsername(String username)
    {

        ((Stub) _port)._setProperty(Stub.USERNAME_PROPERTY, username);

    }

    public void setMaintainSession(boolean maintainSession)
    {

        ((Stub) _port)._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, Boolean.valueOf(maintainSession));

    }
   

    public boolean getMaintainSession()
    {

        return ((Boolean) ((Stub) _port)._getProperty(Stub.SESSION_MAINTAIN_PROPERTY)).booleanValue();

    }

    /**

     * returns the transport context

     */

   
   
public ClientTransport getClientTransport()
    {

        return ((OracleStub) _port).getClientTransport();

    }

}

Listing 6.

As you can see, the generated proxy has main operation (highlighted in yellow) to test the proxy. Then you must go to the Application Navigator and run this executable Java component.

Conclusions

This article explained the techniques used to implement the Web Service interoperability scenario between WCF and Oracle Application Server. Specifically, it covered how to invoke a WCF's Web Service from an Oracle platform's client.