Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, April 11, 2018

Java SOAP WebService Proxy: SOAPHandler to print SOAP messages

Problem: We all know about creating webservice proxy from jdeveloper. Proxy generates few classes based on WSDL and associated XSD and allow us to invoke webservice as if we are simply calling some java method. Complexity of creating soap message and sending over network and receiving output is hidden from us. One of the problem we face many a time is to view SOAP request and response messages. If we can it would be very helpful for debugging.
In this blog I will be using SOAP handler to view SOAP messages.

Solution: Solution which I am going to show is using SOAP handler feature of web-service proxy.

Using proxy is very simple, we just work with normal java classes and complexity of invoking webservice is completely hidden. SOAP Handler is java class (with some guidelines) that can be injected with proxy and proxy will make sure to call methods of this class before sending a request and after receiving message.

SOAP Handler class must implement SOAPHandler<SOAPMessageContext> class.
A Sample SOAPHandler class can look like

import java.util.Collections;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class CalculatorSOAPHandler implements SOAPHandler<SOAPMessageContext> {
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }

    public boolean handleMessage(SOAPMessageContext messageContext) {
                Boolean outboundProperty = (Boolean)
            messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            System.out.println("Request message:");
        } else {
            System.out.println("Response message:");
        }
        
        try {
            System.out.println(messageContext.getMessage().getSOAPPart().getEnvelope().toString());
        } catch (SOAPException e) {
            e.printStackTrace();
        }


        return true;
    }

    public boolean handleFault(SOAPMessageContext messageContext) {
        return true;
    }

    public void close(MessageContext messageContext) {
    }
}


Now we need to inject this class in proxy or in other words we need to configure it with proxy so that it knows about this class. There are couple of ways to do that.
1. Specify SOAP handler while creating proxy in Proxy creating wizard.

In above diagram we are specifying a SOAP handler. We have not selected any port so handler will be registered against all web-service port. Jdev will not create any class. You must create class separately.

When we generate proxy, there is one most important class which has @WebServiceClient annotation. Above step will create a handler entry in that class as

@HandlerChain(file = "MyServiceProxy-HandlerChain.xml")

It will also create a HandlerChain.xml file, which will have entry of handler.
<ns0:handler-chains xmlns:ns0="http://java.sun.com/xml/ns/javaee">
    <ns0:handler-chain>
        <ns0:service-name-pattern xmlns:ns1="http://xmlns.oracle.com/SIH/SIHParentProcess/BPELParentProcess">ns1:bpelparentprocess_client_ep</ns0:service-name-pattern>
        <ns0:handler>
            <ns0:handler-name>CalculatorSOAPHandler</ns0:handler-name>
            <ns0:handler-class>com.san.wsproxy.client.CalculatorSOAPHandler</ns0:handler-class>
        </ns0:handler>
    </ns0:handler-chain>
</ns0:handler-chains>



Now when you run service you will see that handleMessage method of SOAP handler is getting called and its printing SOAP header and body.

Another way to associate SOAP handler class with proxy is simply modify client code.
2. With proxy generation you get a client class. It has a main method, which shows how to run a webservice. You can use this class to add security (WS-Security) header in soap message by setting OWSM policy. Similarly you can use this class also to associate handler with proxy.

Your client method would look something like

    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        CalculatorSoap calculatorSoap = calculator.getCalculatorSoap();
        // Add your code to call the desired methods.
       
        Binding binding = ((BindingProvider)calculatorSoap).getBinding();
        List handlerList = binding.getHandlerChain();
        handlerList.add(new CalculatorSOAPHandler());
        binding.setHandlerChain(handlerList);
             
             
        System.out.println(calculatorSoap.add(5, 6));
       
    }

Thats all, Now if you run service, you will see that SOAP messages are getting printed on console.



Below is the print of messages
Calling handleMessage
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"/>

<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <Add xmlns="http://tempuri.org/">
    <intA>5</intA>
    <intB>6</intB>
  </Add>
</S:Body>

Calling handleMessage
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"/>

<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <AddResponse xmlns="http://tempuri.org/">
    <AddResult>11</AddResult>
  </AddResponse>
</soap:Body>


Instead system.out.println, you can add ADF logger also to print messages. In that case your messages would appear in weblogic log as well.

Sunday, April 16, 2017

JCS/JCS-SX: Creating application server connection

Problem Description: I see most of the time people face issues while creating connection with JCS server using Jdev. Its pretty straight forward but we provide wrong details most of the time.

Solution

1. Use Resources pane and select New Connection > Application Server

2. If this JCS account then you can enable your weblogic ports 7001/7002 to public and make normal weblogic application server connection in Resource tab.


3. If its JCS-SX then you may want to use Oracle Cloud type of application-server connection. On first tab provide any name to your connection and select connection-type = Oracle Cloud


4. Next tab provide username/password. NOTE: These are cloud service user not weblogic user. In normal weblogic connection we provide weblogic user and its password but here it should be cloud user and password. If you don't have cloud user details ask cloud admin (who owns identity domain of cloud).



5. Next tab is where you need to select cloud service details [Datacenter, Identity-domain, Service Name]. This is the tab where I see mistakes most of the time. We should be knowing how to get these information. For that login to your cloud my services dashboard.

Datacenter, you always know as that is first thing you select when you want to login to your cloud account. Most of the time for me its us2.

Find identity domain on dashboard



   Select your JCS-SX instance and launch Service Detail page. 
   Get Service-Name as shown below from Service Detail page


   You can also get service name from Java console. Select Java Console from service detail page
   Service Name is mentioned at top of page


Now mention these details on your Jdev connection


Navigate to Test tab and perform a test



Thats all.

Monday, February 15, 2016

Run Groovy from Java

Why do we want to mix Groovy with Java:
One common requirement in java is to keep core logic in groovy and then evaluate it at runtime. This gives a flexibility as groovy can be referred from xml file, property file or database. That way customer can change groovy anytime and without deployment java code can start working with new groovy expression.

One common example could be calculating salary components. We definitely want to give customer a flexibility to write his own logic to determine salary components. We don't want to hard code that logic in java code. In such cases we can store groovy expression in database table and read it at runtime and evaluate it from java. End user can change groovy expressions anytime in database.

Basic requirement from groovy to java integration would be
a. Somehow we should be able to pass java variables to groovy code. These are called environment variables.
b. Somehow we should be able to parse and run groovy from java. We have Groovy apis for that.
c. Somehow values calculated by groovy should be passed back to java.

Below code show how we can do it.

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;

import java.util.HashMap;
import java.util.Map;


public class GroovyUtil {
    public GroovyUtil() {
        super();
    }
   
    public static Map evaluateGroovy(Map paramMap,String scriptText){
       
       System.out.println("Evaluating groovy: " + scriptText);     
        System.out.println("Input Map: " + paramMap);

       //Environment variables passed to groovy using Binding.
        Binding binding = new Binding(paramMap);
        GroovyShell shell = new GroovyShell();       
        Script script = shell.parse(scriptText);
        script.setBinding(binding);
        script.run();

        //bindings.getVariables() returns all variables of groovy including input and other local variables
        System.out.println("Output Map: " + binding.getVariables());      
        return binding.getVariables();
       
    }
   
    public static void main(String[] args){
        String scriptText = "println('Sctipt execution Started');\n" +
        "    sum = a + b;\n" +
        "    println('script finished');";
       
        Map inputMap = new HashMap();
        inputMap.put("a",10);
        inputMap.put("b",20);
        Map outputMap = evaluateGroovy(inputMap,scriptText);
        System.out.println(outputMap);
    }
}












Output looks like
Evaluating groovy: println('Sctipt execution Started');
    sum = a + b;
    println('script finished');
Input Map: {b=20, a=10}
Sctipt execution Started
script finished
Output Map: {b=20, a=10, sum=30}
{b=20, a=10, sum=30}








For such kind of code there must be an understanding between groovy and java code about input and output variable names.

Sunday, February 14, 2016

Taleo: Installing Taleo (TCC) Client

This blog is first in my upcoming blogs of Taleo (TCC). In this I would like to show how we can install Taleo Client TCC.



2. Sign in / Register. (OTN SSO username/password will be used)  
3. Select Product "Oracle Taleo Plateform Cloud Service - Connect" and Plateform Window-32

    Select Continue
4. Read and Accept ‘Terms and Conditions’

5. Download TCC Application Datamodel and TCC Application Installer for windows

6. Once downloaded unzip both zip files. They both contains an exe file each.

7. Install ‘Taleo Connect Client Application Data Model (15.1.0.3) for Microsoft Windows.exe’ first. NOTE: its installation location. It will be required in second installation.

8. Install ‘Taleo Connect Client Application Installer (15.1.0.11) for Microsoft Windows.exe’. Provide pip location as the location of where you installed datamodel.



9. Launch Taleo Client.
10. If you are launching first time, you need to pint Taleo server. Select Product and provide, Host Port (generally 443 for https), username/password