Wednesday 15 November 2017

Convert WSDL to POJO

We can convert WSDL files into Java POJO class in an easy way with wsimport command

Command :

wsimport -keep -s <directory> -p <pkg> -verbose WSDLfile

Example

wsimport -keep -s /home/ubuntu/example -p com.example.org -verbose http://example.org/helloservice?wsdl

For help use wsimport --help which will provide you the list of option

Sunday 12 November 2017

Compare Operation with Camel Spring DSL

We can use Camel simple expression to compare values.The following things will help to compare values while using simple

Operator
Description
==
Equals.
=~
equals ignore case (will ignore case when comparing values String).
>
Greater than.
>=
Greater than or equals.
<
Less than.
<=
Less than or equals.
!=
Not equals.

Example :

<route id="HELLO-WORLD">
<from uri="direct:hello.world" />
  <setHeader headerName="status">
<simple>SUCCESS</simple>
 </setHeader>
  <choice>
    <when>
      <simple>${headers.status} =~ 'success'</simple>
      <to uri="bean:helloWorld?method=process" />
    </when>
  </choice>
</route>
The above ${headers.status} =~ 'success' will return true . Because =~ compare the values with equals ignore case.

Application Logging With JBOSS Logger

Log4j is well known Logger to log all info ,debug related information of application.

While Using Application along with JBoss server we can use JBOSS Logger.

Steps To integrate JBOSS logger to Application

1.Need to include jboss-logging jar in our application.We are using maven project then simply  include the following dependency in POM.

<dependency>
   <groupId>org.jboss.logging</groupId>
   <artifactId>jboss-logging</artifactId>
   <version>3.0.0.CR1</version>
   <scope>provided</scope>
</dependency>
2.Import the following jboss logger package into our class.

import org.jboss.logging.Logger;
3.Create logger object
private static final Logger LOGGER = Logger.getLogger(HelloWorld.class);

4.Finally we can user LOGGER like Log4J

LOGGER.debug(Object message)
LOGGER.info(Object message)
LOGGER.error(Object message)
LOGGER.trace(Object message)
LOGGER.fatal(Object message)


Adding Classes to the JAR File's Classpath

You may need to reference classes in other JAR files from within a JAR file.

You specify classes to include in the Class-Path header field in the manifest file of an applet or application. The Class-Path header takes the following form:

Class-Path: jar1 jar2 directory-name/jar3

By using the Class-Path header in the manifest, you can avoid having to specify a long -classpath flag when invoking Java to run the your application.

Example :

create jar file using

jar cfm HelloWorld.jar modifyManifest.txt MyPackage/*.class

The modifyManifest.txt contains the following info

Main-Class: HelloWorld
Class-Path: jar1 jar2 directory-name/jar3

After creating jar, the MANIFEST.MF will have the added content

Manifest-Version: 1.0
Created-By: 1.7.0_80 (Oracle Corporation)
Main-Class: HelloWorld
Class-Path: jar1 jar2 directory-name/jar3

The classes in jar1,jar2, directory-name/jar3 are now loaded into the class path when you run HelloWorld.jar.

Modifying a Manifest File

You use the m command-line option to add custom information to the manifest during creation of a JAR file. 

The Jar tool automatically puts a default manifest with the pathname META-INF/MANIFEST.MF into any JAR file you create. You can enable special JAR file functionality, such as package sealing, by modifying the default manifest. Typically, modifying the default manifest involves adding special-purpose headers to the manifest that allow the JAR file to perform a particular desired function.

To modify the manifest, create a text file containing the information you wish to add to the manifest. You then use the Jar tool's m option to add the information in your file to the manifest.

jar cfm jar-file manifest-addition input-file(s)

The m indicates that you want to merge information from an existing file into the manifest file of the JAR file you're creating.

Example :

create jar file using

jar cfm modifyManifest.txt HelloWorld.jar HelloWorld

The modifyManifest.txt contains the following info

Main-Class: HelloWorld

After creating jar, it looks like 



And the MANIFEST.MF will have the added content

Manifest-Version: 1.0
Created-By: 1.7.0_80 (Oracle Corporation)

Main-Class: HelloWorld

Create and Run a JAR File Using Java Class

We can create a jar file form java class in simple way.If we have a more than one java class, we can combine all the files in single jar.

The command to create jar

jar cf jar-file input-file(s)

The option indicates

c - Create a JAR file.
f - The output to go to a file rather than to stdout.
jar-file is the name that you want the resulting JAR file to have.
The input-file(s) argument is a space-separated list of one or more files that you want to include in your JAR file.

The created Jar looks like

The META-INF/MANIFEST.MF contains meta info about jar

Manifest-Version: 1.0
Created-By: 1.7.0_80 (Oracle Corporation)

Command to run jar file

java -jar HelloWorld.jar

To run the jar file we need to mention Main class in MANIFEST.MF file
other wise will get error Error: Could not find or load main class

Adding main class in MANIFEST.MF
Main-Class: HelloWorld

Important no space between Main-Class and :


SOAP Custom Header

The interceptor-based solution provides a very flexible way of configuring custom Header for Apache CXF based SOAP clients.For custom Header configuration per operation(Methods defined inside WSDL), will use an interceptor that sets a custom header at request.

Java Interceptor : 


com.interceptor;

import java.util.List;

import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.headers.Header.Direction;
import org.apache.cxf.interceptor.MessageSenderInterceptor;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.phase.Phase;
import org.springframework.beans.factory.annotation.Value;

import com.temp.THeader;

public class SOAPCustomHeaderInterceptor extends AbstractSoapInterceptor {

  public SOAPCustomHeaderInterceptor(String phase) {
    super(phase);
    addBefore(MessageSenderInterceptor.class.getName());
  }

  public SOAPCustomHeaderInterceptor() {
    this(Phase.PREPARE_SEND);
  }

  /**
   * Setting Custom Headers
   * 
   * @param message
   */
  @Override
  public void handleMessage(SoapMessage message) {
    List<Header> headers = message.getHeaders();
    THeader theader = new THeader();
    theader.setCountry("IN");
    theader.setState("TN");
    SoapHeader newHeader;
    try {
      newHeader = new SoapHeader(new QName("ns2:subHeader"), theader, new JAXBDataBinding(THeader.class));
      newHeader.setDirection(Direction.DIRECTION_IN);
      headers.add(newHeader);
    } catch (JAXBException exception) {
       exception.printStackTrace();
    }
  }
}

This handleMessage method takes a soap message and set header with it

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:cxf="http://camel.apache.org/schema/cxf"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd 
http://cxf.apache.org/transports/http/configuration 
http://cxf.apache.org/schemas/configuration/http-conf.xsd">

<cxf:cxfEndpoint id="bookService"
address="http://locathost:8080/someServiceName"
serviceClass="someServiceClass" />
<cxf:outInterceptors>
<ref bean="customSOAPHeader" />
</cxf:outInterceptors>
</cxf:cxfEndpoint>

<bean  id="customSOAPHeader" class="sample.camel.SOAPCustomHeaderInterceptor"
</bean>
</key>
</entry>
</map>
</property>
</bean>   

</beans>

Above configuration defines custom header per operation wise.

Sample Example output of above things for custom SOAP header :


<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header>
      <ns2:subHeader xmlns:ns2="http://www.test.com">
      <ns2:Country>IN</ns2:Country>
      <ns2:State>TN</ns2:State>
      </ns2:subHeader>
   </soap:Header>
   <soap:Body>
      <ns2:changeName xmlns:ns2="http://book.com/">
         <arg0>
            <name>Rockey</name>
         </arg0>
      </ns2:changeName>
   </soap:Body>
</soap:Envelope>