Wednesday, February 15, 2012

Running long running JSP using a thread implementation

This works well in a proxy-ed environment with a session affinity to a JVM from the webtier.

Steps involve creating a worker thread which executes the long running process activity. Create a mechanism to look back on the process at regular intervals from the browser for completion. If the process did not complete kill the thread and report back as "timed out". If there are orphaned process kill them with the help of a maintenance thread initiated by a startup servlet.

Here is the example code samples.

class WorkingThread extends Thread implements Runnable {
String sessionId;
public WorkingThread () {

}

public WorkingThread (String sessionId) {
this.sessionId = sessionId;
}

public void run() {
System.out.println(" Working thread");


try {
synchronized (TestServletWorker.workerMap) {
HashMap threadDetails = (HashMap) TestServletWorker.workerMap.get(sessionId);
threadDetails.put("time", new Long( System.currentTimeMillis()));
}

Thread.sleep(1000 * 60 * 3); // implement the business logic

synchronized (TestServletWorker.workerMap) {
HashMap threadDetails = (HashMap) TestServletWorker.workerMap.get(sessionId);
threadDetails.put("Data", "my Data --> Done");
}


} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void stopThisThread () {

// Stop application functions here

this.interrupt();
try {
this.join ();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Method to call initiate/track/check/retrieve the Application data from a JSP or any action classes.

public class TestServletWorker {

public static HashMap workerMap;

static {
System.out.println("testServletWorker");
workerMap = new HashMap ();
}

public static synchronized String testServletWorkerrunner (String sessionId) {

if (workerMap != null && workerMap.containsKey(sessionId) ) {
HashMap wtHash = (HashMap) workerMap.get(sessionId);
WorkingThread wt = (WorkingThread) wtHash.get("thread");
if ( !wt.isAlive() ) {
System.out.println("not alive ");
String ret = (String) wtHash.get("Data");
workerMap.remove(sessionId);
return ret;
} else if ( wt.isInterrupted() ) {
wtHash.put("Data", "timed out");
workerMap.remove(sessionId);
return "timed out";
}
} else if (workerMap != null && !workerMap.containsKey(sessionId)) {
WorkingThread wt = new WorkingThread (sessionId);
wt.start();
HashMap threadDetails = new HashMap ();
threadDetails.put("thread", wt);
workerMap.put(sessionId, threadDetails);
}

return null;
}


}

Thread to stop any abandoned or orphan threads

public class StopThreadServlet extends HttpServlet implements Servlet {

/**
*
*/
private static final long serialVersionUID = 1L;

public void init() throws ServletException {
System.out.println(": Registering .... ");
threadKiller tk = new threadKiller ();
tk.start();

while ( true ) {
try {
if ( !tk.isAlive() ) {
tk.start();
}
} catch (Exception w) {
w.printStackTrace();
}
}

}
}

class threadKiller extends Thread {

public void run () {
while ( true ) {
try {
Thread.sleep(1000 * 30 * 1); // Run every 1/2 minutes
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

synchronized ( TestServletWorker.workerMap) {
System.out.println( TestServletWorker.workerMap.size() + " current size");

if ( TestServletWorker.workerMap != null && TestServletWorker.workerMap.size() > 0) {
Set s = TestServletWorker.workerMap.keySet();
Iterator it = s.iterator();

while ( it.hasNext()) {
String sessionId = (String) it.next();
System.out.println(sessionId );

HashMap threadDetails = (HashMap)TestServletWorker.workerMap.get(sessionId);
long starttime = ((Long) threadDetails.get("time")).longValue();
long currtime = System.currentTimeMillis();
long diffIntime = currtime - starttime;
if ( diffIntime > 1000 * 60 * 2 ) { // Kill threads > 2 minutes
System.out.println("stop this thread > 2 mins");
WorkingThread thrd = (WorkingThread) threadDetails.get("thread"); // Replace with WorkerThread impl class
threadDetails.put("Data", "timed out");
thrd.stopThisThread(); // Call a stop function in the the Thread implementation class.
System.out.println( TestServletWorker.workerMap.size() + " New current size");
}
}
}
}
}
}
}

Start up servlet configuration in web.xml


<servlet>
<description>Stopthreads running for long duration</description>
<display-name>Stopthreads</display-name>
<servlet-name>Stopthreads</servlet-name>
<servlet-class>StopThreadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

Thursday, February 9, 2012

OSGI best practices IBM link

http://www.ibm.com/developerworks/websphere/techjournal/1007_charters/1007_charters.html

Sample Hibenrnate Spring configuration


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/properties/db.properties
</value>
</list>
</property>

<bean id="hibernateConnProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.connection.driver_class">${driverClassName}
</prop>
<prop key="hibernate.connection.username">${username}</prop>
<prop key="hibernate.connection.password">${password}</prop>
<prop key="hibernate.connection.url">${url}
</prop>
<prop key="hibernate.dialect">${hibernate.dialect}
</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.c3p0.minPoolSize">${hibernate.c3p0.minPoolSize}
</prop>
<prop key="hibernate.c3p0.maxPoolSize">${hibernate.c3p0.maxPoolSize}
</prop>
<prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}
</prop>
<prop key="hibernate.c3p0.max_statement">${hibernate.c3p0.max_statement}
</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">${hibernate.c3p0.testConnectionOnCheckout}
</prop>
</props>
</property>
</bean>


<bean id="dataSourceService" class="org.apache.commons.dbcp.BasicDataSource"
init-method="createDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
<!--
<value>classpath*:/hibernate/NamedQueries.hbm.xml</value>
<value>/hibernate/BMC_CM_ORIGINAL_REQ.hbm.xml</value>
-->
<util:list id="ormResources">
<value>classpath*:/hibernate/NamedQueries.hbm.xml</value>
</util:list>

<bean id="mapBean" class="SORMappings">
<property name="mappingResources" ref="ormResources" />
</bean>

<util:property-path id="mappingLocations" path="mapBean.mappingResources" />

<bean id="sorSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceService" />
<property name="hibernateProperties" ref="hibernateConnProperties" />
<property name="mappingLocations" ref="mappingLocations" />
</bean>

<bean id="mydao" class="dao">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>


<context:annotation-config />

</beans>



public class dao extends HibernateDaoSupport {

@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)

}

Work around to insert XML to database Oracle OCI & Hibernate

The workaround is using a PL/SQL embedded in Java

String XmlData = ((String)cr.get("xml")).replace('\'', '`');
StringBuffer xmlSP = new StringBuffer();
xmlSP/*.append("DECLARE ")
.append("\n")
.append(" l_xml CLOB := ?;")
.append("\n")*/
.append(" BEGIN \n")
.append(" INSERT INTO xml_data")
.append("\n")
.append(" (id, xml)")
.append("\n")
.append(" VALUES ")
.append("\n")
.append(" (my_seq.nextval, ?);")
.append("\n")
.append("END;");

logger.info(xmlSP.toString());
Connection con = session.connection();
try {
CallableStatement stmt = con.prepareCall(xmlSP.toString());
Connection poolConn = stmt.getConnection();
//Convert the poolConnection to OracleConnection.
OracleConnection oracleConn= (OracleConnection) ((DelegatingConnection) poolConn).getInnermostDelegate();
//Convert the input request string to XMLTYPE object.
oracle.xdb.XMLType requestXMLTYPE = oracle.xdb.XMLType.createXML(oracleConn, XmlData);
stmt.setObject(1, requestXMLTYPE);
boolean retCode = stmt.execute();
logger.info("Inserted data into bmc_cm_original_req");
} catch (SQLException e) {
logger.error("Sql Exception while inserting into bmc_cm_original_req " + e.getMessage());
} catch (Exception e) {
logger.error("Sql Exception while inserting into bmc_cm_original_req " + e.getMessage());
}

Wednesday, February 8, 2012

Testing maven Generated WSDL2JAVA JAR

Here is a sample test

@Test
public void testAxis14CcpClient () throws ServiceException {

ccpWebServicesImplServiceLocator.setEndpointAddress(
new javax.xml.namespace.QName(
"http://webservices.com",
"XXXServicesImpl"), "http://XXXcom:80/ServicesImpl");

XXXWebServicesImpl_PortType serviceimpl = ccpWebServicesImplServiceLocator
.getXXXWebServicesImpl();

((javax.xml.rpc.Stub) serviceimpl)._setProperty(
"javax.xml.rpc.session.maintain", Boolean.TRUE);
((javax.xml.rpc.Stub) serviceimpl)._setProperty(XXXWebServicesImpl_BindingStub.USERNAME_PROPERTY,"UUUU");
((javax.xml.rpc.Stub) serviceimpl)._setProperty(XXXWebServicesImpl_BindingStub.PASSWORD_PROPERTY,"ddddd");
String o;
try {
o = serviceimpl.myMethod("X");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

Tuesday, February 7, 2012

Generate SOAP WSDL2JAVA using maven

Find the WSDL file for which you need to generate the client stub.
Keep your WSDL in the main/resources directory as a best practice.

http://mojo.codehaus.org/wsdl2java-maven-plugin/howto.html

Prepare the maven pom.xml

Here is an Example
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>soap.wsdlclient</groupId>
<artifactId>soap.wsdlclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>restapp.wsdlclient</name>
<dependencies>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxrpc-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
</dependencies>
<build>
<!-- To define the plugin version in your parent POM -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>1.4</version>
</plugin>
</plugins>
</pluginManagement>
<!-- To use the plugin goals in your POM or parent POM -->
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/resources</sourceDirectory>
</configuration>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>


Run mvn install

This will generate the client code. You may not have to alter the code.
publish this as a jar and use in other java projects.

Using MockStrutsTestCase

Here is how you can test struts action with MockStrutsTest

Create your struts configuration



<struts-config>
<action-mappings>
<action path="/test" type="my.demo.MyAction" >
<forward name="viewCapablity" redirect="false" path="/WEB-INF/jsp/view.jsp"></forward>
<forward name="viewCapablity1" redirect="false" path="/WEB-INF/capability/jsp/viewCapability1.jsp"></forward>
</action>
<action path="/benny" type="com.cisco.cssd.struts.demo.MyAction" >
<forward name="viewCapablity" redirect="false" path="/WEB-INF/jsp/view.jsp"></forward>
<forward name="viewCapablity1" redirect="false" path="/WEB-INF/capability/jsp/viewCapability1.jsp"></forward>
</action>
</action-mappings>
</struts-config>

Develop your struts action classes

package my.struts.demo;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyAction extends Action {

public ActionForward execute(ActionMapping aMapping, ActionForm aForm,
HttpServletRequest aRequest, HttpServletResponse aResponse) {

String type = (String) aRequest.getParameter("type");

System.out.println(type);

return aMapping.findForward("viewCapablity");

}
}


write mock tests
package com.cisco.cssd.struts.demo;

import org.junit.Test;

import servletunit.struts.MockStrutsTestCase;

public class TestMyAction extends MockStrutsTestCase {

public TestMyAction(String testName) {
super(testName);
// TODO Auto-generated constructor stub
}

public void setUp() throws Exception {
super.setUp();
setServletConfigFile("/WEB-INF/web.xml");
setConfigFile("my/struts/demo/struts-config.xml");
setInitParameter("validating", "false");
setRequestPathInfo("/test.do");
}

@Test
public void testing () {
System.out.println("testing ...");
addRequestParameter("type", "MY demo type");
actionPerform ();
verifyForward("viewCapablity");
verifyForwardPath("/WEB-INF/jsp/view.jsp");


}

}


finally integrate with the final product.