mercredi 9 décembre 2009

Memo : Weblogic JDBC Persistent Store

Script to use for table creation of a JDBC persistent store :

CREATE TABLE TABLE_NAME (
id int not null primary key,
type int not null,
handle int not null,
record blob not null
);

The table name is computed with the prefix name defined at persistent store configuration with the appended string WLSTORE. So for exemple if prefix name is MYAPPLI, the table name will be MYAPPLIWLSTORE.

The command line to create the table could be :

java utils.Schema url JDBC_driver [options] DDL_file


options could be :
  • -u for database connection username
  • -p for the user password
  • -s for the database SID


You will find hereunder is an example of the installation command line :

java utils.Schema jdbc:weblogic:oracle:DEMO weblogic.jdbc.oci.Driver -u user1 -p password1 -verbose createTab.ddl

Command line to use the Jconsole to connect on Weblogic 10.3.1

This is the command line that is usefull for the connection of the jconsole on a Weblogic server 10.3.1

%JAVA_HOME%\bin\jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;%JAVA_HOME%\lib\tools.jar;%BEA_HOME%\server\lib\wljmxclient.jar -J-Djmx.remote.protocole.provider.pkgs=weblogic.management.remote -J-Dcom.sun.management.jmxremote

where JAVA_HOME references the jdk and BEA_HOME the installation directory of the weblogic server

mercredi 18 mars 2009

Dynamic web service invocation

The main goal of this section is to show you how to invoke a web service using the dynamic web service invocation api (DII).

There is two ways to invoke the web service dynamically :
  • Using the Jax-Rpc's dynamic call api (jax.xml.rpc.Call)
  • Using the Jax-Ws dynamic Dispatch api

First of all, you will find here under the code of a simple web service we will use in the sample :

package test;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@Stateless
@WebService(name="DynamicWs",
serviceName="DynamicWsService",
portName="DynamicWsPort",
targetNamespace="http://test"
)
public class DynamicWs {
@WebMethod(operationName="hello")
@WebResult(name="result",
targetNamespace="http://test")
public String hello( @WebParam(name="name", targetNamespace="http://test") String name)
{
return "hello " + name;
}
}

This sample exposes the hello method which receives a string in parameter and returns a string in response to the client.


Dynamic invocation using jax.xml.rpc.Call api

The client code for dynamic method invocation using the rpc Call api :

package client;

import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.XMLType;

import org.junit.Test;


public class TestDynamicWs {
private static final String END_POINT = "http://localhost:8080/DynamicWsService/DynamicWs";
private static final String TNS = "http://test";

@Test
public void testDynamicInvocation() throws ServiceException, RemoteException
{
Service service = ServiceFactory.newInstance().createService (
new QName( TNS, "DynamicWsService")
);
Call call = service.createCall ();
call.setTargetEndpointAddress ( END_POINT);
// Set call properties
call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY, "");
call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY , "");
call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc");

// Set the name of the operation to call
call.setOperationName( new QName( TNS, "hello"));
// Define and add the parameter value
call.addParameter(
"name", // parameter name
XMLType.XSD_STRING, // parameter XML type QName
String.class, // parameter Java type class
ParameterMode.IN); // parameter mode

// Define the type of the result returned by the method
call.setReturnType(XMLType.XSD_STRING);

// Call the method with parameters
String response = (String) call.invoke(new String[] {"franck"});

System.out.println ("Response is '" + response + "'");
}
}


Fist of all, we have to create the service using the javax.xml.rpc.ServiceFactory and instanciate the javax.xml.rpc.Call object.
This Call object will be configured using some properties :
  • Call.SOAPACTION_USE_PROPERTY : this property indicates whether or not SOAPAction is to be used. We set it to TRUE.
  • Call.OPERATION_STYLE_PROPERTY : this property is set to "rpc" to indicates that the operation will be accessed by rpc.
Once configured, we defined the operation to invoke
call.setOperationName( new QName( TNS, "hello"));


and the type of input and output parameters
        // Define and add the parameter value
call.addParameter(
"name", // parameter name
XMLType.XSD_STRING, // parameter XML type QName
String.class, // parameter Java type class
ParameterMode.IN); // parameter mode

// Define the type of the result returned by the method
call.setReturnType(XMLType.XSD_STRING);

The XMLType class contains all QName that defines the type of parameters we could use.

Now, it's time to invoke the remote method using rpc call and encoding
        // Call the method with parameters
String response = (String) call.invoke(new String[] {"franck"});


Remark : Just note that the client never recovered the wsdl file on the server !

The message that has been sent by the client code :

<env:envelope enc="http://schemas.xmlsoap.org/soap/encoding/" env="http://schemas.xmlsoap.org/soap/envelope/" ns0="http://test" xsd="http://www.w3.org/2001/XMLSchema" xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:body>
<ns0:hello>
<name>franck</name>
</ns0:hello>
</env:body>
</env:envelope>


The response received by the client :

<s:envelope s="http://schemas.xmlsoap.org/soap/envelope/">
<s:body>
<helloresponse xmlns="http://test">
<result>hello franck</result>
</helloresponse>
</s:body>
</s:envelope>


Dynamic call using the jax-ws dynamic Dispatch api
In this level we will the Dispatch api of the jax-ws api to create a SOAP envelop and invoke the web service.
You will find here under the source code to invoke the hello method through the Dispatch api :

package client;

import java.net.URL;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.Text;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;

import org.junit.Test;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class TestDynamicWs2 {
private static final String TNS = "http://test";
private static final String WSDL = "http://localhost:8080/DynamicWsService/DynamicWs?wsdl";

@Test
public void testDynamicInvocation() throws Exception
{
/* wsdl url you can get from link provided by glassfish server.*/
URL url = new URL( WSDL);

/* service name & port name as mentioned in wsdl, which can also be viewed in glassfish */
QName serviceName = new QName( TNS, "DynamicWsService");
QName portName = new QName( TNS, "DynamicWsPort");
Service service = Service.create(url, serviceName);

/** Create a Dispatch instance from a service.**/
Dispatch dispatch = service.createDispatch( portName,
SOAPMessage.class,
Service.Mode.MESSAGE
);

MessageFactory mf;
try {
mf = MessageFactory.newInstance(SOAPConstants.DEFAULT_SOAP_PROTOCOL);

// Create a message. This example works with the SOAPPART.
SOAPMessage req = mf.createMessage();
SOAPPart part = req.getSOAPPart();

// Obtain the SOAPEnvelope and header and body elements.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();

// Construct the message payload.
SOAPElement operation = body.addChildElement( "hello", "ns", TNS);
SOAPElement value = operation.addChildElement( "name", "ns", TNS);
value.addTextNode( "franck");
req.saveChanges();

// Invoke the service using the soap request
SOAPMessage res = (SOAPMessage)dispatch.invoke(req);

SOAPPart soapPart = res.getSOAPPart();
NodeList list = soapPart.getElementsByTagNameNS (TNS, "result");
// Read the first node
Node node = list.item ( 0);

// Display the result
System.out.println ( "Server say : " + node.getTextContent ());

} catch (Exception ex) {
ex.printStackTrace ();
throw ex;
}

}


First of all, we have to connect to server to retrieve the wsdl file and the port associated to the service :

/* wsdl url you can get from link provided by glassfish server.*/
URL url = new URL( WSDL);

/* service name & port name as mentioned in wsdl, which can also be viewed in glassfish */
QName serviceName = new QName( TNS, "DynamicWsService");
QName portName = new QName( TNS, "DynamicWsPort");
Service service = Service.create(url, serviceName);

The wsdl file will contains the end point definition to find the right service deployed on the right server.

After we create a Dispatch object on the port and indicates that we want to deal with soap message :

/** Create a Dispatch instance from a service.**/
Dispatch dispatch = service.createDispatch( portName,
SOAPMessage.class,
Service.Mode.MESSAGE
);


It is now the time to create a soap message and fill it with invocation parameters :

MessageFactory mf = MessageFactory.newInstance(SOAPConstants.DEFAULT_SOAP_PROTOCOL);

// Create a message. This example works with the SOAPPART.
SOAPMessage req = mf.createMessage();


The api used to set attributs in the soap envelop are very similar to the DOM api used in xml parsing.

SOAPElement operation = body.addChildElement( "hello", "ns", TNS);
SOAPElement value = operation.addChildElement( "name", "ns", TNS);
value.addTextNode( "franck");
req.saveChanges(); // Save the changes made on the soap envelop


Now invoke you service :
            // Invoke the service using the soap request
SOAPMessage res = (SOAPMessage)dispatch.invoke(req);


And retrieve your result :

SOAPPart soapPart = res.getSOAPPart();
NodeList list = soapPart.getElementsByTagNameNS (TNS, "result");
// Parse the node list here...