Integrating With Fusion Application Using Services (.Net: Service Reference)

Fusion Applications provides Web services that allow external systems to integrate with Fusion Applications. There are two types of services: ADF services and composite services. ADF services are created for a logical business object and provide functionality to access and manipulate these objects. The composite services are mostly process oriented and provide an orchestration of multiple steps.  

Information about the web services provided by Fusion Applications is hosted in Oracle Enterprise Repository (OER). The information provided by OER can be used to understand the functionality provided by the service and how the service can be called.

This series of articles describes how one can invoke SOAP web services provided by Fusion Applications using various technologies. In this article we will cover how to invoke a Fusion Application web service using Service Reference for .Net framework.

 Prerequisites

.Net development tool such as Visual Studio 2012 needs to be installed and configured

Implementing Web Service Call

.Net framework is a software framework for Microsoft Windows commonly used by the customers. We can generate a proxy through the Visual Studio by creating Service Reference. To integrate with a service first generate a Service Reference, in the address field enter the URL for the WSDL of the Fusion Application Service and click "Go", in this example I used CreditRuleService. The "Namespace" entered can then be used to access the objects generated in the code. In the example case the "Namespace" entered was "FusionServiceReference". In order to call a Fusion Applications web service we need to create a binding that matches the OWSM policy that the service is secured with. In this example the service is secured with "oracle/wss_username_token_over_ssl_service_policy" OWSM policy so we create a class for the custom binding as follows:

    public class UsernameTokenOverSslBinding : CustomBinding
    {
        public override BindingElementCollection CreateBindingElements()
       {
            BindingElementCollection bindingElements = new BindingElementCollection();
            bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
            MtomMessageEncodingBindingElement messageEncoding = new MtomMessageEncodingBindingElement();
            messageEncoding.MessageVersion = MessageVersion.Soap11;
            bindingElements.Add(messageEncoding);
            HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
            bindingElements.Add(transport);
            return bindingElements.Clone();
        }
    }

Do note that the binding configuration above is the minimum required for the given policy, depending on the policy additional configuration may be required.  The following is a complete example on how use the reference objects generated to find, create and delete a rule by calling a Fusion Applications Web Service:

using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using ServiceReferenceExample1Client.FusionServiceReference;

namespace ServiceReferenceExample1Client
{
    /// <summary>
    /// Custom binding that can be used to invoke Fusion Application services secured with OWSM policy
    /// </summary>
    /// <remarks>
    /// This custom binding can be used to invoke Fusion Application services secured with 
    /// "oracle/wss_username_token_over_ssl_service_policy" OWSM policy
    /// </remarks>
    public class UsernameTokenOverSslBinding : CustomBinding
    {
        public override BindingElementCollection CreateBindingElements()
        {
            BindingElementCollection bindingElements = new BindingElementCollection();
            bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
            MtomMessageEncodingBindingElement messageEncoding = new MtomMessageEncodingBindingElement();
            messageEncoding.MessageVersion = MessageVersion.Soap11;
            bindingElements.Add(messageEncoding);
            HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
            bindingElements.Add(transport);
            return bindingElements.Clone();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
           
 EndpointAddress endpointAddress = new EndpointAddress(new 
Uri("https://host:port/icCnSetupCreditRulesPublicService/CreditRuleService"));

            // Get instance of the service to be invoked
            CreditRuleServiceClient crs = new CreditRuleServiceClient(new UsernameTokenOverSslBinding(), endpointAddress);

            // Set the authentication details to be used for the service call
            crs.ClientCredentials.UserName.UserName = "username";
            crs.ClientCredentials.UserName.Password = "password";

            // Run the test case which includes queries, creates and deletes a rule
            callFindRule(crs);
            callCreateRule(crs);
            Rule rule = callFindRule(crs);
            callDeleteRule(crs, rule);
            callFindRule(crs);

        }

        /// <summary>
        /// Logic to find a object using a web service call
        /// </summary>
        /// <param name="crs">Instance of the credit rule service client</param>
        /// <returns>Rule with a given name in this case "JRAUTIAI_TEST_RULE1"</returns>
        static Rule callFindRule(CreditRuleServiceClient crs)
        {
            Rule result = null;
            try
            {
                // Populate the objects to be used as parameter
                FindCriteria findCriteria = new FindCriteria();
                ViewCriteria viewCriteria = new ViewCriteria();
                viewCriteria.conjunction = Conjunction.And;
                ViewCriteriaRow viewCriteriaRow = new ViewCriteriaRow();
                viewCriteriaRow.conjunction = Conjunction.And;
                viewCriteriaRow.upperCaseCompare = false;
                ViewCriteriaItem viewCriteriaItem = new ViewCriteriaItem();
                viewCriteriaItem.conjunction = Conjunction.And;
                viewCriteriaItem.upperCaseCompare = false;
                viewCriteriaItem.attribute = "Name";
                viewCriteriaItem.@operator = "=";
                string[] ruleNames = new string[1] { "JRAUTIAI_TEST_RULE1" };
                viewCriteriaItem.Items = ruleNames;
 
                ViewCriteriaItem[] vcis = new ViewCriteriaItem[1] { viewCriteriaItem };
                viewCriteriaRow.item = vcis;
                ViewCriteriaRow[] vcrs = new ViewCriteriaRow[1] { viewCriteriaRow };
                viewCriteria.group = vcrs;
                findCriteria.filter = viewCriteria;
 
                findCriteria.fetchStart = 0;
                findCriteria.fetchSize = -1;
                FindControl findControl = new FindControl();
 
                // Call the service with the appropriate parameters
                Rule[] rules = crs.findRule(findCriteria, findControl);
                if (null != rules && rules.Length > 0)
                {
                    result = rules[0];
                    foreach (Rule rule in rules)
                    {
                        Console.WriteLine("ruleId: " + rule.RuleId + " - orgId: " + rule.OrgId + " - name: " + rule.Name);
                    }
                }
                else
                {
                    Console.WriteLine("Rule JRAUTIAI_TEST_RULE1 not found ");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            return result;
        }
 
        /// <summary>
        /// Logic to create a rule, in this case we have hard coded the content of the new rule to simplify the example
        /// </summary>
        /// <param name="crs">Instance of the credit rule service client</param>
        static void callCreateRule(CreditRuleServiceClient crs)
        {
            try
            {
                // Populate the object to be used as parameter
                Rule rule = new Rule();
                rule.EnabledFlag = true;
                rule.OrgId = 300000000678473;
                rule.OrgIdSpecified = true;
                rule.UsageId = -1001;
                rule.UsageIdSpecified = true;
                rule.StartDate = new DateTime(2012, 1, 1);
                rule.StartDateSpecified = true;
                rule.EndDate = new DateTime(2012, 1, 31);
                rule.EndDateSpecified = true;
                rule.Name = "JRAUTIAI_TEST_RULE1";
 
                // Call the service with the appropriate parameters
                Rule result = crs.createRule(rule);
                Console.WriteLine("Rule JRAUTIAI_TEST_RULE1 created ");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
 
        /// <summary>
        /// Logic to delete a specific Rule
        /// </summary>
        /// <param name="crs">Instance of the credit rule service client</param>
        /// <param name="rule">Instance of the Rule to be deleted</param>
        static void callDeleteRule(CreditRuleServiceClient crs, Rule rule)
        {
            try
            {
                // Call the service with the appropriate parameters
                crs.deleteRule(rule);
                Console.WriteLine("Rule JRAUTIAI_TEST_RULE1 deleted ");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
} 

The above code does the following:

  1. Get instance of the service reference client to be invoked using custom binding and an endpoint address
  2. Set the authentication details to be used for the service call
  3. Run the test case which includes calls to create, delete and query a rule

Summary

In this article we covered an example using Service Reference for .Net framework to integrate with Fusion Applications using web services. In future articles other technologies for invoking Fusion Applications web services will be covered.

References




Comments:

Hi,

Could you please provide the CustomBinding information.

Thanks

Posted by Nagappan on November 18, 2015 at 03:20 AM PST #

Not sure I understand the question, the CustomBinding is a framework class:

https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.custombinding%28v=vs.110%29.aspx

--
Jani Rautiainen
Fusion Applications Developer Relations
https://blogs.oracle.com/fadevrel/

Posted by Jani Rautiainen on November 18, 2015 at 04:24 AM PST #

In fusion application we are consuming saleswebservice using DOTNET C#.
I can do the following operations in DOTNET.
1.GETCONTACT -by passing existing party id
2.UPDATECONTACT - passing the contact object received from the getcontact operation.
3.while Perfoming CreateContact i am getting the following exception

{"An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail."}

please help me understand the issue here...

Posted by connors on November 18, 2015 at 10:59 PM PST #

Do you have access to the server logs for additional details ? This is likely related to one of the attributes, but without details of the error its difficult to triage. You maybe interested in this similar discussion:
https://community.oracle.com/message/12940593

To triage you may want to start by confirming that the SOAP envelope used by the proxy works also using tool such as SOAP UI. To determine the exact SOAP envelope take a look at this article:
https://blogs.oracle.com/fadevrel/entry/integrating_with_fusion_application_using13

while its manipulating the received response you can use the same approach; instead of implementing the AfterReceiveReply method use the BeforeSendRequest to observe the content of the request.

--
Jani Rautiainen
Fusion Applications Developer Relations
https://blogs.oracle.com/fadevrel/

Posted by Jani Rautiainen on November 19, 2015 at 01:42 AM PST #

This is the inner exception when execute create contact method.
with SOAPUI tool it is working.

System.ServiceModel.Security.MessageSecurityException was unhandled
HResult=-2146233087
Message=An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at demoservice.fusservice.ContactService.createContact(createContactRequest request)
at demoservice.fusservice.ContactServiceClient.demoservice.fusservice.ContactService.createContact(createContactRequest request) in d:\Projects\demoservice\demoservice\Service References\fusservice\Reference.cs:line 7998
at demoservice.fusservice.ContactServiceClient.createContact(Contact contact) in d:\Projects\demoservice\demoservice\Service References\fusservice\Reference.cs:line 8004
at demoservice.UsernameTokenOverSslBinding.Program.Main(String[] args) in d:\Projects\demoservice\demoservice\Program.cs:line 63
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.ServiceModel.FaultException
HResult=-2146233087
Message=JBO-27008: Attribute PartyId in view object Contact cannot be set.
InnerException:

Posted by connors on November 20, 2015 at 01:54 AM PST #

when i add service reference: there was an error:
"Policy was not handled"
i tried to generate the proxy using svcutil.exe that is also showing the same error.

are the issues i raised before related to this policy file.

FYI : Update is working

Posted by connors on November 20, 2015 at 02:06 AM PST #

I do not think this has anything to do with the security policy, the issue seems like its related to the "nil" attribute. My guess is that .Net proxy is adding an empty attribute like:
<PartyId xsi:nil="true"/>

Which is causing the exception, if that's the case you can try adding "IsNullable=true" to the proxy methods or manipulate the SOAP envelope sent as request similar to what is described in:
https://blogs.oracle.com/fadevrel/entry/integrating_with_fusion_application_using13

Note that the above link manipulates the response, you want to manipulate the request if you choose that route.
If you are explicitly setting the pARTYiD in the proxy, then try alternate key like PartyNumber
When you state that "SOAPUI tool it is working" do you mean that the exact same SOAP envelope that you observed in .Net works in SOAP UI ?
Also can we move this discussion to the forums:
https://community.oracle.com/community/oracle-applications/fusion_applications/customizations__extensions_and_integrations/content

where its easier to communicate.
--
Jani Rautiainen
Fusion Applications Developer Relations
https://blogs.oracle.com/fadevrel/

Posted by Jani Rautiainen on November 20, 2015 at 04:39 AM PST #

I am also unable create Sales contact in Sales cloud application using sales webservices in C# visual studio 2012.

{"An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail."}

please help me understand the issue here...

Posted by guest on November 24, 2015 at 08:54 PM PST #

Refer to the details in previous updates; also can you post the details of your issue to the forums:
https://community.oracle.com/community/oracle-applications/fusion_applications/customizations__extensions_and_integrations/content

where its easier to communicate.
--
Jani Rautiainen
Fusion Applications Developer Relations
https://blogs.oracle.com/fadevrel/

Posted by Jani Rautiainen on November 24, 2015 at 08:57 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Follow us on twitter Fusion Applications Extensibility, Customizations and Integration forum Fusion Applications Dev Relations YouTube Channel
This blog offers news, tips and information for developers building extensions, customizations and integrations for Oracle Fusion Applications.

Search

Categories
Archives
« April 2016
SunMonTueWedThuFriSat
     
1
2
3
6
8
9
10
13
14
15
16
17
20
22
23
24
27
29
30
       
Today