JEE Custom Search Portals

Sunday, June 26, 2011

Spring-WS: Implementing Contract First Web services

Spring Web Services (Spring-WS) is a product of the Spring community focused on creating document driven web services. There are 2 common development styles of creating web services -
  1. Contract First - This means we will define the contract first (WSDL - Web services definition language) and use this WSDL to generate the java code to implement the web services. 
  2. Contract Last - This means we will define the java code first and use the java code to generate the WSDL. For example, web services stacks like AXIS, CXF support this style of web service implementation.
Spring-WS only supports Contract First approach. The following are the reasons for following this approach.
  1. This is based on the WS-I (Web services interoperability) specification. WS-I provides the interoperability guidance for core web services specifications such as SOAP, WSDL and UDDI. Since Spring web services are created following this specification, it allows other technologies [Java, .NET, Python] to easily integrate with each other.
  2. Fragility - Contract First web services is based on having the contract (WSDL) written up first and then generate the java classes. If there are a large number of clients using this web service, it is better to go in this approach because this will avoid the different clients to change their client implementations. This is one of the major advantages of implementing Contract First web services.
  3. Re-usability - For contract first web services, we need to write up the WSDL first and also define the different elements in the WSDL (which becomes the part of the WSDL message). In such cases, if we define the schema in a separate schema definition file (XSD), we can re-use this in different schemas and WSDLs using an import statement.
  4. Contract First web services provides loose coupling between the contract and implementation.
In this blog, I will concentrating on demonstrating with simple guaranteed steps to implement a web service using Spring-WS.

The following are the pre-requisites for this demo - 
  • SpringSource Tool Suite  [STS - 32bit/64bit]. 
  • Spring Framework [v3.1.0.M1] 
  • Spring-WS [v2.0.2]
  • Apache Tomcat [v7.0]
  • JDK 6 [32bit/64bit]One thing to note here is that if you are running the application on a 64 bit machine, make sure you install the 64 bit STS and 64 bit JDK 6. Otherwise you will end up in getting issues while launching the STS. 
  • Soap-UI Tool [v4.0.0]
Before starting STS, I modified the STS.ini file in the springsource tool suite home directory as highlighted below. This will help in setting up the JDK in eclipse by default instead of JRE.

The first step is to create a new dynamic web project as shown below.

The next step is to provide a name for the project. For our example, I am giving the name as SpringWS. Click on New Runtime and add the 'Apache Tomcat v7.0' runtime and click 'Next'.
Browse to the Tomcat's installation directory and also select the JDK as shown below and Click 'Finish'
Click 'Next' and set the 'Default output folder' as the 'WebContent/WEB-INF/classes' and click 'Next'.
Select the 'Generate the web.xml deployment descriptor' option and click 'Finish'. Once the project is created, copy the following jars in the WebContent/WEB-INF/lib folder.
  • commons-logging-1.1.1.jar
  • org.springframework.aop-3.1.0.M1.jar
  • org.springframework.asm-3.1.0.M1.jar
  • org.springframework.beans-3.1.0.M1.jar
  • org.springframework.context.support-3.1.0.M1.jar
  • org.springframework.context-3.1.0.M1.jar
  • org.springframework.core-3.1.0.M1.jar
  • org.springframework.expression-3.1.0.M1.jar
  • org.springframework.oxm-3.1.0.M1.jar
  • org.springframework.web.servlet-3.1.0.M1.jar
  • org.springframework.web-3.1.0.M1.jar
  • spring-ws-core-2.0.2.RELEASE.jar
  • spring-ws-security-2.0.2.RELEASE.jar
  • spring-ws-support-2.0.2.RELEASE.jar
  • spring-xml-2.0.2.RELEASE.jar
  • wsdl4j-1.6.1.jar
Once it is copied, the project structure will show up as in the below screenshot 
We will now focus on implementing a MoviesBrowser service. This would be a simple service which would list all movies based on the genre of the movie.

Since we are implementing a contract first web service, we should first define the contract - which in our case would be the WSDL. First we will define the request and response elements for the Movies browser service by writing a schema definition file (XSD). For this, we will create a new MoviesBrowser.xsd under WEB-INF/resources. This is a very simple schema definition which defines an request element MoviesRequest which has a child element - genre. I have added a restriction for genre element by accepting only the following enumerated values - Action, Comedy and Cartoon. Also there is a response element MoviesResponse which has child elements - id and name. The contents of the schema is as shown below.
Next we will define the contract which is the WSDL as shown below. There are different tools which we can use to generate this WSDL. Now again there are ways to create and publish the WSDL dynamically using Spring-WS. I will show that later in this tutorial, but for now, we will concentrate on creating the WSDL and publishing it.
Now lets understand the WSDL. There are 5 main elements in a WSDL:
  • types - This defines the data types that will be used by the web service. Here in our case, I have defined the types in a schema definition file (XSD) and then imported it in here.
  • message - This defines the data elements of an operation.  Each message can have one or more parts. The parts can be considered as parameters in a method call. In our case, the request is MoviesRequest and response is MoviesResponse. 
  • portType - This describes the web service, operations that can be performed and also the messages that are involved in an operation. In our case, the portType MoviesBrowser defines an operation 'DisplayMovies' which takes in MoviesRequest as input parameter and returns a MoviesResponse.
  • binding - This defines the message format and the protocol details for each port. 
    • A binding element has 2 attributes - name and type. Name can be any name that defines the name of the binding. The type attribute refers to the port for the binding. In our case, it is mapped to MoviesBrowser portType.
    • soap:binding element - It has 2 attributes - style and transport. The style attribute can have values 'document' or 'rpc'. In our case, it is document. The transport attribute defines the SOAP protocol to use. In this case, it is HTTP.
    • operation element - It defines each operation that the port exposes. For each operation, we have to define the SOAP action. We must also specify the encoding for the input and output. In our case, it is 'literal'.
  • service - This defines the different services enclosed within the WSDL document.
    • The name attribute just needs to be a unique name for the service.
    • port - used to specify the location of the service. It has 2 attributes: name and binding. Name can be any name but binding should refer to an already defined binding in the WSDL. In our case, it refers to the MoviesBrowserBinding.
    • soap:address - Since this is a soap service, we use the soap:address to specify the location of the service. In our case, I will give it as http://localhost:8080/SpringWS/
Now let's create the classes that refer the elements in the schema. This can be done in a number of ways. One way is the traditional way of hand coding the classes. The other one is by using some binding architectures. For example - JAXB or JiBX. 

In our example, I will be using JAXB as this is the easiest one which we can use. Also the JAXB distribution is now part of the JDK and also the compiler XJC (which is used for compiling the schema to generate java classes) is available with JDK. To generate the classes, type the following command in the command prompt - 

C:\>xjc WebContent/WEB-INF/resources/MoviesBrowser.xsd -d src -p com.blogspot.javaclickonline.springws.moviesbrowser



Note: The pre-requisites for running this command are the following -
  • Set the JAVA_HOME property to the JDK directory. It can be done as shown below -
    • C:\>set JAVA_HOME=<JDK Home Directory>; 
  • Set the path to the Java's bin directory be added to the system path. It can be done as shown below - 
    • C:\>set path=%path%;<JDK Home Directory>\bin;
This will generate the classes as shown below.

Next we will need to implement the Endpoint that is used to handle incoming messages. A endpoint is created by annotating a class with @Endpoint annotation. In our case, the MoviesBrowserEndPoint is annotated with @Endpoint annotation. Also we will implement a method -

public MoviesResponse getMovies(@RequestPayload MoviesRequest request) {
  ...  }

A complete example is as shown below.

There are several annotations on this method - 
  • @PayloadRoot - This annotation is used to indicate which sort of messages can be handled by the getMovies(...) method. There are 2 properties to this annotation - 
    • namespace - This should map to the namespace of the MoviesBrowser definition
    • localPart - This should map to the MoviesRequest local part.
  • @ResponsePayload - If this method returns a response, we need to have this annotation. In our case, this will map to the MoviesResponse object.
  • @RequestPayload - This will map to the request payload. In this case, it will map to the MoviesRequest object.
I have created an interface MoviesBrowserService. This is being referenced from the Endpoint for get all movies by genre.
The class below provides a simple implementation of the MoviesBrowserService as shown below.
Next step is to define the MessageDispatcherServlet in the WEB-INF/web.xml. The servlet is mapped to the URL pattern '/*'.
In addition to the web.xml, we will need a Spring-WS specific configuration file (WEB-INF/spring-ws-servlet.xml). The name of the file is derived from the servlet-name 'spring-ws' appended with '-servlet.xml'. This file will contain the definition of endpoints, interceptors, etc. The spring-ws-servlet.xml is as shown below.
 Let's understand the mappings in the above spring configuration file.
  • context:component-scan - This is used to detect all the classes with @Endpoint annotation.
  • sws:annotation-driven - We are instructing Spring-WS to use annotation driven end points. This will enable the detection of @PayloadRoot, @RequestPayload and @ResponsePayload annotations. 
  • sws:interceptors - Here I am adding one validating interceptor to validate the request and response pay load. This will help in validating the request or response payload and providing with user friendly error messages for the consumer of the web service.
    • schema - This tells the interceptor that request/response pay load has to be validated against the schema definition file (XSD)
    • validateRequest - This can be true/false. If true, the interceptor intercepts the request and validates it, otherwise, it will not validate it.
    • validateResponse - This can be true/false. If true, the interceptor intercepts the response and validates it, otherwise, it will not validate it.
  • moviesRequest bean definition - This is used to publish the MoviesBrowser.wsdl so that we can access the WSDL using the URL in our case - http://localhost:8080/SpringWS/moviesRequest.wsdl
  •  Apart from all this, I have also wired up the moviesBrowserService which is being used in the MoviesBrowserEndpoint. This currently provides the implementation of the getMoviesByGenre(...) method.
Now that we have completed the coding of the service. The next step is to deploy the web service and then test it with a client. I will be using the Soap-UI tool to test the web service.

For deploying the application, right click on the 'Tomcat v7.0 Server' in the Servers view and select 'Add and Remove...' option. Next add the project SpringWS on the server. Start the server and this will deploy the application on the server. Once deployed, we can check if the web service is deployed correctly by accessing the following URL.

http://localhost:8080/SpringWS/moviesRequest.wsdl

To test the web service, we can use the soap-ui tool. For this we need to first create a new soapUI project. Provide a project name and browse to the path of the WSDL file and click OK. Expand the project -> MoviesBrowserBinding -> DisplayMovies -> Request 1. See below for the testing done by the soapUI tool.



Now some of the extra things we can configure in the application are the following - 
  • transformWsdlLocations - We can add an init-param for the servlet which says transformWsdlLocations as true. This will take care of changing the location of the web service to change relative to the application URL.

  • Dynamically create and publish the WSDL. For this, we can add the following configuration in the spring configuration file.

To summarize, we learned how to write a contract first web service, deploy it and test it. In case you want to read more on this topic, please go to the Spring's documentation

    Sunday, January 30, 2011

    PGP - Pretty Good Privacy [Why, What and How]

    In this blog, I will be discussing about a common technique used for encryption and decryption.

    First of all, we will discuss on the importance of encryption and decryption. Encryption is the method of disguising plain text in such a way as to hide its substance from everyone and just provide the key/code/algorithm for people who need the access to the content. Decryption is the opposite of Encryption. The process of reverting the encrypted cypher text to read the original contents is known as Decryption.

    There are many different ways of encrypting/decrypting content. Some of them are given below.
    1. Using different cryptographic algorithms to encrypt the content and then decrypt the content using the reverse algorithm. For example, RSA is one of the most commonly used algorithm.
    2. Using secret-key or symmetric key algorithm for encrypting/decrypting the content. Here in this case, we use the same key for both encryption and decryption. For example, DES is one of the most commonly used symmetric key algorithm.
    3. Using secure hash algorithms to hash an arbitrary length bytestring in to a 128 bit value. For example, MD5 is an example of one such algorithm.
    PGP [Pretty Good Privacy] is an example of a public key encryption technique. This was written by Phil Zimmermann in 1991. Over the past few years, PGP has got thousands of adherent supporters all over the globe and has become a de-facto standard for encryption of email on the Internet. Also the PGP corporation is now acquired by Symantec and now the software is distributed under the PGP Software License Agreement.

    For our demonstration, I will be downloading the version [PGP v6.5.8] which is part of the PGPi project. The PGPi project is a non-profit initiative, whose purpose is to make PGP freely and legally available worldwide. The project is largely based on unpaid, voluntary effort by security and privacy minded individuals.

    To install the PGP, we have to first unzip the downloaded distribution into a directory. The next step is to run the setup.exe under the distribution <pgp_directory>. This will install PGP. To check if it got installed correctly, just type in the following command in the command line as shown below.


    There are 3 major commands line arguments for PGP.
    • pgp -h: This is used for getting the usage summary and help on how to use the commands for getting the right results. If you type in this command in the command prompt, you will see as shown below.
    • pgp -k: This is used for getting the key management functions. This can be used to create/generate our own public/private key pair, or to extract a copy from the public or secret key pair, or to sign someone else's public key on our public key ring. If you type in this command in the command prompt, you will see as shown below.
    • pgp -g: This is used for using the group management functions. This command can be used for adding keys to a group, view the contents of a group. If you type in this command in the command prompt, you will see as shown below.

    As a next step, we will see on how to generate a private/public key pair and then use that for encrypting a file and later decrypt it to see if it is actually working. Also we will see how to extract the public key from the key ring for distribution to outside vendors so that they can use it for encrypting the file and send it to us for decrypting it using our private key.

    Type the following command in the command for starting the process to generate a public/private key pair.

    cmd> pgp -kg

    The next step is to select one of the public key algorithms. Here we have the following options:

    1) DSS/DH (a.k.a. DSA/ElGamal) (default)
    2) RSA
    Choose 1 or 2
    :
    I will be selecting option 2 to select the RSA public key algorithm.

    The next step required to pick the RSA key size. Here we have the following options:

    1)  1024 bits- High commercial grade, secure for many years
    2)  2048 bits- "Military" grade, secure for forseeable future
    Choose 1, 2, or enter desired number of bits:
    I will be selecting option 1 to select 1024 bits.

    The next step is to provide a user id for our public key. This key is important because this key is what we use for encryption and also to extract the public key for distribution.

    You need a user ID for your public key.  The desired form for this user ID is your name, followed by your E-mail address enclosed in <angle brackets>, if you have an E-mail address.
    For example:  John Q. Smith <
    jqsmith@nai.com>
    Enter a user ID for your public key:
    I will be providing a user id as 'javaclickonline.blogspot.com'.

    The next step is to enter the validity period of your signing key.

    Enter the validity period of your signing key in days from 0 - 10950
    0 is forever (the default is 0):
    0

    The next step is add a pass phrase to protect our RSA secret key. A passphrase is a longer version of a password, and in theory, a more secure one. Typically composed of multiple words, a passphrase is more secure against standard dictionary attacks, wherein the attacker tries all the words in the dictionary in an attempt to determine your password. The best passphrases are relatively long and complex and contain a combination of upper and lowercase letters, numeric and punctuation characters.

    You need a pass phrase to protect your RSA secret key.
    Your pass phrase can be any sentence or phrase and may have many words, spaces, punctuation, or any other printable characters.
    Enter pass phrase: I will be providing a pass phrase as 'pgp-javaclickonline secret key'.
    Enter same pass phrase: Re-enter the same pass phrase entered above.

    The next step is make this key the default signing key or not. Here in our scenario, I am selecting 'Y' to make it the default signing key.

    With this the key generation is completed. See the below screenshot to demonstrate all the steps dicussed above for generating the public/private key pair.


    The next step is to extract the public key from the key ring and then send it to any outside public. This key can be used for encrypting a file. For extracting the public key, we need to type the following command.

    cmd>pgp -kx <user id>

    We have to type the same user id we used while generating the key pair. If it finds any key in the key ring for the specified user id, we have to provide a file path for exporting the key. Here in our case, I have given the file path as 'C:\pgp\pgpjavaclickonline'.

    See below screenshot for the above mentioned steps.


    The next step is to encrypt a file from one machine [to show that it is a different vendor] using the public key and then decrypt the file from another machine using our private key.

    To encrypt the file, we need to import the public key file [pgpjavaclickonline.pgp] on the vendor machine.

    For importing the public key, type the following command in the command prompt and select 'Y' to add the key to the key ring.

    cmd>pgp +force -ka <path to exported public key>

    See below for the screenshot showing how to import the public key. The user id for the public key will be displayed as an output. This user id is required while performing encryption.

    PS: See the ipconfig I have included on the top of the picture. This was done to show that it is running in a different machine.

    The next step is to encrypt the file. For encrypting a file we need to create a simple plain text file as shown below.


    Now in order to encrypt the file, type the following command onto the command prompt.

    cmd>pgp +force -ea <file to encrypt> <user id> -o <file path to encrypted output file>


    The contents of the encrypted file is a cypher text and is gibberish. It looks as shown below.


    Now that we have encrypted the file. We can go to the other machine and see if we can decrypt the file.

    For decrypting the file, we need to type the following command on to the command prompt.

    cmd>pgp +force <pgp encrypted file> -z <user id> -o <file path to decrypted output file>

    PS: See the ipconfig I have included on the top of the picture. This was done to show that it is running in a different machine.

    The contents of the decrypted file is a plain text as shown below.


    To summarize, we learned how to generate a public/private key pair. We also learned on how to extract the public key and then import it on a different machine. And finally we learned how to encrypt and decrypt a file using PGP.

    If you want to read more on PGP, you can go to the following web site. This is the International PGP Home page - http://www.pgpi.org/doc

    Apache Geronimo - Java EE 5 Application Server [Administrative Console functionalities - Setting up datasource]

    In the previous blog [Apache Geronimo - Java EE 5 Application Server [Installing, Running and Deploying Application]], I have explained on how to install, run and deploy applications to Apache Geronimo server. In this blog, I will be detailing the steps required for setting up a datasource. In this example, we will be creating a mysql datasource. 

    The following are the pre-requisites for this tutorial -
    To create a mysql datasource, we need to have the mysql connector jar in the Geronimo repository. To add a jar to the Geronimo repository, we have to navigate to the Geronimo repository view by selecting Server > Repository on the console navigation menu. See screenshot below for the Geronimo Repository viewer.

    The following are the mandatory fields that need to be entered.
    • File: Actual location of the archive
    • Group: Group identifier which is the name of the open source project, or directory tree matching the Java package prefix of the organization that supplies the library.
    • Artifact: File name prefix of the library.
    • Version: Version identifier of the library in the file.
    • Type: Type is the type of the file. eg: jar

    If the mysql connector jar is added successfully, you can find the jar in the repository viewer as shown below.


    Now in order to create a mysql datasource, click on the Services > Database Pools and then click on the link 'Using the Geronimo database pool wizard'. Select the name of database pool and database type and click 'Next' as displayed in screenshot below.


    Next step is create and deploy the datasource. The Basic Connection Properties need to be configured for setting up the datasource.
    • Database Name: The name of the database
    • User Name: The user credential for the db
    • Password: The password credential for the db
    • Confirm Password: Re-enter the password
    • Server Name: The server on which the db is installed. In our case, mysql server is running in my local and hence 127.0.0.1 or localhost
    • Port Number: The database port number

    After entering the basic connection properties and then click the 'Deploy' button. See in the below screenshot the datasource has been created successfully.


    Now in order to check if the datasource was created successfully, we can select the newly created datasource and write a sql in the Run SQL section and click 'Run SQL' button. This should be done as given below.


    Now as a next step we will create an application that uses this newly added datasource. For this, we will follow the same steps we followed for creating a simple web application in my previous blog [Apache Geronimo - Java EE 5 Application Server [Installing, Running and Deploying Application]]. In our application, I will only be concentrating on how to use the datasource in our application instead of focussing on the best practices or frameworks on using datasources.

    As the first step, I will create a table and insert some rows into the table as shown below.


    The next step is to create a servlet and add a resource reference to the datasource in the web.xml as shown below.


    Also we need to add a resource reference in the geronimo's specific web.xml [geronimo-web.xml]. It should be displayed as shown below.


    The point to be noted is that the <res-ref-name> in the web.xml should match to <name:ref-name> in geronimo-web.xml.

    Next step is to initialize the servlet by overriding the init method. In this method, we will set the datasource by looking up the datasource.


    Once the datasource is set, the next step is to override the doPost method as given below.


    ProductDTO in the above method is a simple pojo with the following fields and its corresponding getters and setters.


    Finally create a page [results.jsp] as given below.


    PS: I added the jstl-1.2.jar under the WEB-INF/lib folder. You can find the jar in the geronimo distribution directory [<geronimo>/repository\javax\servlet\jstl\1.2].

    Create the war file and deploy it as described in the previous blog. Once deployed you can access the application using the following URL - http://localhost:8080/GeronimoWeb/GeronimoAppServlet


    To summarize, we have looked at how to create a datasource in the server and also how to use it in our application. In the next blog, I will be coming up with another interesting topic.

    Tuesday, January 25, 2011


    Apache Geronimo - Java EE 5 Application Server [Installing, Running and Deploying Application]

    In the previous blog Apache Geronimo - Java EE 5 Application Server [General Overview], I just gave a general overview of the Application server, its integrated components and its advantages. In this blog, I will show how we can get started with working with Apache Geronimo. In this, I will be detailing about the installation, running and also about the admin console functionalities.

    The following are the pre-requisites for this tutorial -
    To install Apache Geronimo, download and unzip the Geronimo distribution [C:\Installed-Softwares\geronimo-tomcat6-javaee5-2.2.1].

    To start Apache Geronimo, just type the following command on to the command line. [Note: On Windows, type 'cmd' in Start > Run to open up the command line]

    Then navigate to the unzipped bin directory under the <geronimo_home/bin> [C:\Installed-Softwares\geronimo-tomcat6-javaee5-2.2.1\bin] and type the following command.

    <geronimo_home/bin> geronimo start

    See the screenshot below -


    If the server started successfully, it will display as screenshot below


    Once started, you can access the admin console using the link - http://localhost:8080/console.



    Login to the admin console with the following credentials to access the administrative functionalities.

    User Name: system
    Password: manager


    Next step is to create a simple web application and try deploying it to the Apache Geronimo application server. For this, we will be creating a simple web project. I will be concentrating on the specific files that need to be created for this example and not focus on each and every step of creating a dynamic web project.

    A simple jsp - index.jsp is as given below. This file needs to be copied into <app_home> directory.


    The following screenshot shows a common web.xml. This needs to be copied into the <app_home>/WEB-INF directory.


    Next we need a geronimo specific file - geronimo-web.xml. This file needs to be copied under <app_home>/WEB-INF.


    Once these steps are done, create a war file using the following command.

    <app_home> java -jar <app_name>.war

    The next step is to deploy the application into Apache Geronimo server. For this, select Applications > Deployer under the console navigation menu. Select the war file and click Install.
    If you select the checkbox 'Start application after installation', then once the application is deployed and the application will be started.


    To see the status of the deployed application, go to the Applications > Web App WARs under the left console navigation menu. This will display all the applications that are currently deployed to the server. If the application is deployed correctly, you can see the app as shown below.


    There is also provision to stop, restart or uninstall the application from the above mentioned page.

    To access the application, type in the following URL -


    To stop the server, type the following command.

    <geronimo_home/bin> geronimo stop

    To summarize, we have learned how to install the Application server, start and stop the server and also deploy applications on the server using the administrative console. In the next blog post, I will be concentrating on the different Admin Console functionalities.