Friday, March 20, 2015

How to call JBPM6's RESTFul API with athentication details

In JBPM 6 the inbuilt RESTFul API is a great feature which makes our lives easier.
In order to use these APIs, you have to provide authentication details with the request in request header.
First join the username and the password with a colon and encode it using Base64 encoder. Then append the word "Basic " (note the space) and put as "Autorization" header.
Ex:-
  "Basic " + Base64Encode(<username> + ":" + <password>)

See below working complete code written in java to get the task list of krisv.
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public class JBPMRest {
  public static void getTaskSummaryList() throws Exception {
    String status = "Reserved";
    String actor = "krisv";

    String addr = "http://localhost:8080/jbpm-console/rest/task/query?status=" + status + "&potentialOwner=" + actor;
    try {
      HttpClient client = HttpClientBuilder.create().build();
      HttpGet get = new HttpGet(addr);

      String authData = "krisv" + ":" + "krisv";
      String encoded = new sun.misc.BASE64Encoder().encode(authData.getBytes());
      get.setHeader("Authorization", "Basic " + encoded);
      get.setHeader("Content-Type", "application/json");
      get.setHeader("ACCEPT", "application/xml");

      HttpResponse cgResponse = client.execute(get);
      String content = EntityUtils.toString(cgResponse.getEntity());
      System.out.println(content);
    } catch (Exception e) {
      throw new Exception("Error consuming service.", e);
    }
  }
}

Thursday, March 19, 2015

How to pass parameters to a Quartz job

In your Job class(implementation of org.quartz.Job interface) you don't have a way to set external parameters. What you can do is putting parameters in to the SchedulerContext when scheduling the job and get them back in the execute() method of the job.
See below example.

This is your main class where you set the scheduler.
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class TestQuartz {

  public static void main(String[] args) throws Exception {
    JobBuilder jobBuilder = JobBuilder.newJob(MyJob.class);
    JobDetail job = jobBuilder.withIdentity("myJob", "group1").build();
    Date sheduleTime = new Date(new Date().getTime() + 5000);
    Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(sheduleTime).build();
    Scheduler scheduler = new StdSchedulerFactory().getScheduler();
    //Below line sets a variable named myContextVar in SchedulerContext.
    //Not only strings, you can set any type of object here.
    scheduler.getContext().put("myContextVar", "Hello, this text is from context.");
    scheduler.start();
    scheduler.scheduleJob(job, trigger);
  }
}

Now in your Job class you can get that variable from the SchedulerContext as below.
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerContext;
import org.quartz.SchedulerException;

public class MyJob implements Job {

  @Override
  public void execute(JobExecutionContext arg0) throws JobExecutionException {
    try {
      SchedulerContext schedulerContext = arg0.getScheduler().getContext();
      //Below line gets the value from context.
      //Just get it and cast it in to correct type
      String objectFromContext = (String) schedulerContext.get("myContextVar");
      System.out.println(objectFromContext);
    } catch (SchedulerException e1) {
      e1.printStackTrace();
    }
  }
}

Tuesday, March 17, 2015

Creating a web service client using apache Cxf

In this tutorial you will see how to create a web service client(synchronous) using apache Cxf.
First download the apache cxf  binary distribution from cxf download page.
http://cxf.apache.org/download.html
Extract the downloaded archieve and it will create a folder named like apache-cxf-x.x.x.

Now create a new Java project. I name it as CXFClient.
In this tutorial I am going to write a client to consume cdyne.com's Weather service.
This is the WSDL for that service.
http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL

Now you can create the stub for the above web service as below.
Open command window and point to apache-cxf-x.x.x\bin.
Below command will generate the stub for the above web service in to a folder named mystub inside bin folder.

wsdl2java -ant -client -p com.example.stub -d mystub http://wsf.cdyne.com/Weather.asmx?WSDL

You will see the stub is generated inside the apache-cxf-x.x.x\bin\mystub folder. Open the stub folder and copy the content in to the src(java source) folder of your project.
Now I am going to create my client class to consume the web service. Create a new java class in com.example.client package and name it as WeatherClient.

If you are using eclipse, your project structure will look like this now.


























This is my client class to invoke the weather service. Run this class and you will see the the data is retrieved through the web service.
package com.example.client;

import java.util.List;
import com.example.stub.ArrayOfWeatherDescription;
import com.example.stub.Weather;
import com.example.stub.WeatherDescription;
import com.example.stub.WeatherSoap;

public class WeatherClient {
  public static void main(String[] args) {
    try {
      Weather weatherService = new Weather();
      WeatherSoap weatherSoap = weatherService.getWeatherSoap();
      ArrayOfWeatherDescription forecastReturn = weatherSoap.getWeatherInformation();
      List forecasts = forecastReturn.getWeatherDescription();
      for (WeatherDescription forecast : forecasts) {
        short weatherID = forecast.getWeatherID();
        String description = forecast.getDescription();
        System.out.println("weatherID : " + weatherID);
        System.out.println("description : " + description);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Spring HelloWorld Example

Create new Maven project. These are my configurations.
groupId : com.example
artifactId : SpringHello
packaging : war

Edit the pom.xml file and add Spring dependencies.This is my pom.xml file.
<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>prageeth.example</groupId>
<artifactId>SpringHello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<springRealeaseVersion>4.1.3.RELEASE</springRealeaseVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springRealeaseVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springRealeaseVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springRealeaseVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springRealeaseVersion}</version>
</dependency>
</dependencies>
</project>

Create a new Java class "SayHello" in com.example package. This is my SayHello class. This is the class which I am going to convert a Spring bean.

package com.example;

public class SayHello {
  public String getHelloMessage(String username) {
    return "Hello " + username;
  }
}

Now I want to make this class a Spring bean. To do that I need to have a beans xml file.
Create a new folder in src/main/webapp folder and name it as WEB-INF. Create new xml file in this newly created WEB-INF folder. I name the file as context.xml.
You can use any name for it. This is your beans xml file in which you are going to define your Spring beans.
I define my com.example.SayHello as a Spring bean in this file. This is my context.xml file.

<?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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> 
    
<bean id="helloBean" class="com.example.SayHello"/>
</beans>

Now what you need to do is tell Spring what your beans xml file is. You can do it in web.xml file. This is my web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/context.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>com.example.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
  </servlet-mapping>
</web-app>

That is all. Now my bean is configured and I can use it in my application. For an example assume that I want to invoke a method of helloBean in a servlet.
I can do it like this.

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    SayHello helloBean =(SayHello)ContextLoader.getCurrentWebApplicationContext().getBean("helloBean");
    String message = helloBean.getHelloMessage("John");
    System.out.println(message);
}

Note 1:-
If your Spring application is not a web application, you cannot the configure contextConfigLocation and ContextLoaderListener in a web xml.
In this case you can directly load the context xml by code as below.
First create the context xml file in the src folder. Then load the file and invoke the method like this.

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
    SayHello helloBean = (SayHello) context.getBean("helloBean");
    String message = helloBean.getHelloMessage("John");
    System.out.println(message);
}

Note 2:-
You have to design your project to prevent loading the context xml file multiple times. You can easily do this by implementing the singleton design patten.

Monday, March 2, 2015

SOAP web service using Spring and Axis2 - Simple Example

Create new Maven project in eclipse. These are my project settings.
groupId : com.example
artifactId : SpringService
packaging : war

Add axis2m, axis2 and Spring dependencies in to the pom.xml. This is my pom.xml.

<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>com.example</groupId>
<artifactId>SpringService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>org.axis2m</groupId>
<artifactId>axis2m-spring</artifactId>
<version>1.0M2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
</project>

Now I create a new java class. This is the class where I am going to write my service methods. I add getHello() method as below.

public class HelloService {
  public String getMessage(String username) {
    return "Hello " + username + "! from spring web service.";
  }
}

Now I have to register this class as a Spring bean. So we need to create a beans xml file.
Create new xml file in src/main/webapp/WEB-INF folder. I name it as context.xml. This is the content of my context.xml file.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
<bean id="myService" class="org.axis2m.spring.beans.ServiceBean">
<property name="serviceName" value="TestService" />
<property name="serviceBean" ref="myServiceClass" />
<property name="targetNameSpace" value="com.hello"/>
</bean>

<bean id="myServiceClass" class="services.HelloService" />
</beans>

The line <bean id="myServiceClass" class="com.beans.HelloWorld" /> registers this class as a SpringBean named as 'myServiceClass'.
The block <bean id="testService".... exposes above bean as a web service via axis.

Finally I add the context xml file and axis servlet in to the web xml. This is my web.xml.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/context.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>org.axis2m.spring.servlet.SpringAxis2Servlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
</web-app>


Now run the project in tomcat server. After the application is deployed open the web browser and point to below wsdl location.(My tomcat runs on port 8080)
http://localhost:8080/SpringService/services/TestService?wsdl

Wow! The wsdl for my web service is opened. It means my web service has been successfully published.
Look at the wsdl path again. It can be described as below.


















I use SOAP-UI to test the service. These are my request and the response received.























Note:
All the public methods written in HelloService class are exposed as web services. If you want any public method in this class not to be exposed as a service you just can mention it in context.xml file as below. For an example if you have a public method myHiddenMethod() in HelloService class, you can avoid it being exposed via web service like this.

<bean id="myService" class="org.axis2m.spring.beans.ServiceBean">
    <property name="serviceName" value="TestService" />
    <property name="serviceBean" ref="myServiceClass" />
    <property name="targetNameSpace" value="com.hello"/>
    <property name="excludeOperationsNames" value="myHiddenMethod"/>
</bean>