Sunday, May 25, 2014

Hi, in this Posts I will be explaining you how to develop the client to access the AXIOM based AXIS2 web service, what we created in part 1 and tested in part 2.

Ok So lets get started


Prerequisites

The service should be developped and deployed in Axis2, this is explained in part 1 of this post series.
I will be using eclipse to create my client.

Architecture of the client

Customers items will be added to the itemsList and all the items will be processes when buying the items (Final Checkout). There won't be any user inputs or interfaces, this is a simple client side application to demonstrate how a service can be accessed in Axis2 via AXIOM So all the inouts will be hard coded in the client application.

Creating the Client

Step 1

  1. Create a new Java Project and lets name it "Axis2_Webservice".
  2. Within "src" directory let's create a package as follows, "televisionshop.client"
  3. To resolve dependency issues add all the jars in the <AXIS2_HOME>/lib directory into your class path. All the jars may not be required, doing this to make things easy :)
  4. Now within the created package create a new java class named "TelevisionShopClient.java" with the following code snippets

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package televisionshop.client;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class TelevisionShopClient {

 private static String namespace = "http://myshop.com/xsd";

 // Customer Items will be added to the itemList
 static HashMap<String, String> itemList = new HashMap<String, String>();

 private static EndpointReference endPointRef = new EndpointReference(
   "http://localhost:8080/axis2/services/TelevisionShopService");

 public static OMElement getProductAXIOMXML(String id) {
  OMFactory fac = OMAbstractFactory.getOMFactory();
  OMNamespace omNs = fac
    .createOMNamespace("http://myshop.com/xsd", "tns");

  OMElement method = fac.createOMElement("getProduct", omNs);
  OMElement value = fac.createOMElement("id", omNs);
  value.addChild(fac.createOMText(value, id));
  method.addChild(value);
  return method;
 }

 public static OMElement setProductAXIOMXML(String id, String model,
   String price, String qty) {
  OMFactory fac = OMAbstractFactory.getOMFactory();
  OMNamespace omNs = fac
    .createOMNamespace("http://myshop.com/xsd", "tns");

  OMElement method = fac.createOMElement("setProduct", omNs);

  OMElement value1 = fac.createOMElement("id", omNs);
  value1.addChild(fac.createOMText(value1, id));
  method.addChild(value1);

  OMElement value2 = fac.createOMElement("model", omNs);
  value2.addChild(fac.createOMText(value2, model));
  method.addChild(value2);

  OMElement value3 = fac.createOMElement("price", omNs);
  value3.addChild(fac.createOMText(value3, price));
  method.addChild(value3);

  OMElement value4 = fac.createOMElement("qty", omNs);
  value4.addChild(fac.createOMText(value4, qty));
  method.addChild(value4);

  return method;
 }

 public static void getProductDetails(String id) throws AxisFault {

  OMElement getPhonePayload = getProductAXIOMXML(id);
  Options options = new Options();
  options.setTo(endPointRef);
  options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

  ServiceClient sender = new ServiceClient();
  sender.setOptions(options);

  OMElement result = sender.sendReceive(getPhonePayload);

  System.out.println("Model : "
    + result.getFirstChildWithName(new QName(namespace, "model"))
      .getText());
  System.out.println("Price  : "
    + result.getFirstChildWithName(new QName(namespace, "price"))
      .getText());
  System.out.println("QTY On Stocks : "
    + result.getFirstChildWithName(new QName(namespace, "qty"))
      .getText());
  System.out.println();

 }

 public static void updateProductDetails(String id, String model,
   String price, String qty) {

  try {
   OMElement updatePhonePayload = setProductAXIOMXML(id, model, price,
     qty);
   Options options = new Options();
   options.setTo(endPointRef);
   options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

   ServiceClient sender = new ServiceClient();
   sender.setOptions(options);

   sender.fireAndForget(updatePhonePayload);

   System.out.println("Updated Product Details of Product : " + model);

  } catch (Exception e) {
   e.printStackTrace();
  }

 }

 public static void buyItems(HashMap itemList) throws AxisFault {

  Iterator it = itemList.entrySet().iterator();
  float total = 0;
  System.out.println("=================================================");
  System.out.println("===========YOUR ORDER DETAILS====================");
  System.out.println("=================================================");

  while (it.hasNext()) {
   Map.Entry entry = (Map.Entry) it.next();
   String key = (String) entry.getKey();
   String val = (String) entry.getValue();

   OMElement getPhonePayload = getProductAXIOMXML(key);
   Options options = new Options();
   options.setTo(endPointRef);
   options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

   ServiceClient sender = new ServiceClient();
   sender.setOptions(options);

   OMElement result = sender.sendReceive(getPhonePayload);

   String model = result.getFirstChildWithName(
     new QName(namespace, "model")).getText();

   if (Integer.parseInt(result.getFirstChildWithName(
     new QName(namespace, "qty")).getText()) <= Integer
     .parseInt(val)) {
    System.out.println("Not Enough Stock for : " + model);
    System.out.println();
    continue;

   }
   float price = Float.parseFloat(result.getFirstChildWithName(
     new QName(namespace, "price")).getText());

   total += price * Float.parseFloat(val);

   System.out.println("Value of your Items : " + model
     + " Television : (No of Units : " + val + " ) = " + price
     * Float.parseFloat(val));

  }
  System.out.println();
  System.out.println("The Total Value of your Items = " + total);
  System.out.println();

 }

 public static void main(String[] args) throws AxisFault {

  // Adding Products to the Service
  updateProductDetails("001", "Samsung", "100", "6");
  updateProductDetails("002", "Philipse", "200", "15");

  // Retrieving information about a product
  getProductDetails("1");

  // Customer adding items to the List --> The first arguement is product
  // ID and Second is no of units
  itemList.put("001", "5");
  itemList.put("002", "3");

  // Checking out
  buyItems(itemList);

 }

}


  1. The final file structure will look like following,

  1. Now right click on the "TelevisionShopClient.java" file and select Run As >>> Java Application.


  1. The following output will be displayed on your output console of the IDE.


We have successfully developed our service and the client by using Axis2 and AXIOM.
Thank you for reading and direct me any queries you have. :)
Hi, this is the part two of the article where we are creating a complete AXIOM based web service with Axis2, If you haven't read the part one, please read it before going through this.

In this Post I will try to cover as much as possible regarding testing your webservice with SoapUI.

I will be using SoapUI 5.0 installed on top of Ubuntu 14.04.

Ok So lets begin.

What is SoapUI


SoapUI is a free tool that can be used to test web services.  SoapUI can test SOAP and REST based web services, JMS, AMF, as well as make any HTTP(S) and JDBC calls. Learn more from here.

Prerequisites


Install SoapUI on your PC, this can be done in two ways, Install SoapUI as a standalone Application or as a IDE plugin, I recommend to install this as a separate application.

Deploy your webservice created in part 1 and check whether it is deployed correctly as mentioned in that post.

Testing Your Service

Step 01

  1. Go to the Axis2 server URL and check whether the service is available. in my case the Axis2 services can be found at "http://localhost:8080/axis2/services/" 
  2. Click on the title of your service and you will be shown the WSDL of your service.


Note : The "wsdl" function following the service name will give you the WSDL of the service.

  1. Copy the url of the WSDL. 

Step 02

  1. Open SoapUI  and go to File >>> New SOAP Project.

  1. Then give an appropriate name to the project and paste the link of the WSDL of your service as shown in the following image and click OK.


  1. Now your project will be created with all service methods of your service. Note that Soap Binding 1.1 and 1.2 are automatically created by SoapUI.


  1. First lets test the "setProduct" method. Select the request which is located under setProduct method in the Soap1.1 Binding option as shown below.

  1. As you can see from the above image the full message or the payload that has to be sent to the service is not auto generated, as denoted by the "?" the necessary content has to placed in the marked position.
 Note that the message that the service expect is as following,


1
2
3
4
5
6
<tns:setProduct xmlns:tns="http://myshop.com/xsd">
   <tns:id>1</tns:id>
   <tns:model>Samsung</tns:model>
   <tns:price>100</tns:price>
   <tns:qty>6</tns:qty>
</tns:setProduct>

So lets add the required content to the correct place. make sure that your namespaces matches the namespaces defined in the service. The final message will look like following.


  1. Now click on the Submit Request button as shown in the above image. Nothing will be shown in the output window. :) Don't worry the service doesn't return anything so check the Axis2 console for any output. The Axis2 Console will show the following message if the request was successful.


The "setProduct" service is working fine now lets test the "getProduct" service.

  1. Now select the request of "getProduct" method and add the following SOAP content to the request. (make sure that you have already added the product you are going to query through setProduct method)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.televisionshop">
   <soapenv:Header/>
   <soapenv:Body>
     
         <!--Optional:-->
          <tns:getProduct xmlns:tns="http://myshop.com/xsd">
           <tns:id>001</tns:id>
          </tns:getProduct>
     
   </soapenv:Body>
</soapenv:Envelope>

Now click on Submit request button and the following output will be shown.



You have Successfully tested the web service you created, So in the next post I'll explain you how to write a simple client to access the service we created.

Thank for reading, and please feel free to drop a message or comment below if you have any issues. :)

Friday, May 23, 2014


Hi, in this series of Posts I will be explaining you how to create a AXIOM based AXIS2 web service.

The full article will contain three parts, the first part will explain how to create the Server component of the Service and how to deploy it, the second part will explain how to test the service using SOAPUI, the final part will explain how to create the client component of the service.


Ok so Lets Get started 


What is Apache Axis2


Axis2 is a engine for web-services, Axis2 allows developers to develop both the client and the server side of a webservice and to host web services. Main communication method Axis2 uses is SOAP messaging and it allows you to do the following,
  • Send SOAP messages 
  • Receive and process SOAP messages 
  • Create a Web service out of a plain Java class 
  • Create implementation classes for both the server and client using WSDL 
  • Easily retrieve the WSDL for a service 
  • Send and receive SOAP messages with attachments 
  • Create or utilize a REST-based Web service 
  • Create or utilize services that take advantage of the WS-Security, WS-ReliableMessaging, WS-Addressing,WS-Coordination, and WS-Atomic Transaction recommendations 
  • Can use Axis2's modular structure to easily add support for new recommendations as they emerge etc.
This artical will not cover Axis2 in detail, to understand Axis2 features and its architecture please refer to Axis2 user manuals.


What is AXIOM


Axiom stands for Axis Object Model. The Apache Axiom library provides an XML Infoset compliant object model implementation which supports on-demand building of the object tree.  AXIOM is the object model for Apache Axis 2,  AXIOM is different from existing XML object models in various ways, the major one being the way it incrementally builds the memory model of an incoming XML source. AXIOM itself does not contain a parser and it depends on StAX (Streaming API for XML) for input and output.

If you want to learn more about AXIOM follow this

Developing Axis2 Web Service



The development will be done without using any additional integration plugins for IDE. For coding I will be using eclipse IDE, you can use any other IDE you like.

Architecture of the service

The sample implementation is a Order Processing service where the service will contain two methods, "Set Product" and "Get Product" methods. The "Set Product" will allow the client to set product details and "Get Product" will allow the client to retrieve information about a specific product.  All the other functionality like handling Customer Orders, Calculating Cost, Customer Item list management will be handled in the client side.


Prerequisites 

  • Downlad, install and configure Apache Axis2, and the installation location of Axis2 will be referred as <AXIS2_HOME> for later references.
  • Setup Java Development environment. 

Developing the Service


Step 1 : Writing the service Class
  1. Create a new Java Project and lets name it "Axis2_Webservice".
  2. Within "src" directory let's create a package as follows, "televisionshop.service"
  3. Within the created package create a new java class named "Television.java", this will be used to store information of each television by creating objects for each television.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package televisionshop.service;

public class television {
 String model = "Dummy";
 String price = "Dummy";
 String availableQuantity = "Dummy";

 public String getModel() {
  return model;
 }

 public void setModel(String model) {
  this.model = model;
 }

 /**
  * @return the price
  */
 public String getPrice() {
  return price;
 }

 /**
  * @param price
  *            the price to set
  */
 public void setPrice(String price) {
  this.price = price;
 }

 /**
  * @return the availableQuantity
  */
 public String getAvailableQuantity() {
  return availableQuantity;
 }

 /**
  * @param availableQuantity
  *            the availableQuantity to set
  */
 public void setAvailableQuantity(String availableQuantity) {
  this.availableQuantity = availableQuantity;
 }

}

  1. Now add the dependencies that are required for the service class as external jars. The requires Jars can be locates at <AXIS2_HOME>/libs directory. Add the following jars to your class path.
  • axiom-api-x.x.xx 
  • axiom-dom.x.x.xx 
  • axiom-impl.x.x.xx 
  1. Create another Class named "TelevisionShopService.java" within the same package with the following code snippets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package televisionshop.service;


import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import javax.xml.stream.XMLStreamException;
import javax.xml.namespace.QName;
import java.util.HashMap;

public class TelevisionShopService {

 private HashMap<String, television> map = new HashMap<String, television>();

 private String namespace = "http://myshop.com/xsd";


 public OMElement getProduct(OMElement element) throws XMLStreamException {

  // build the xml tree using AXIOM
  element.build();
  // detach the node from its parent container
  element.detach();

  // Get First element which is product id
  OMElement idElement = element.getFirstElement();
  String id = idElement.getText();

  // Get the product details from hash map
  String model = map.get(id).getModel();
  String price = map.get(id).getPrice();
  String qty = map.get(id).getAvailableQuantity();

  // Build the response
  OMFactory fac = OMAbstractFactory.getOMFactory();

  // Create name space definition
  OMNamespace omNs = fac.createOMNamespace(namespace, "ns");
  // Create response element
  OMElement method = fac.createOMElement("getProductResponse", omNs);

  // Create element called return
  OMElement value = fac.createOMElement("model", omNs);
  OMElement value1 = fac.createOMElement("price", omNs);
  OMElement value2 = fac.createOMElement("qty", omNs);

  // add elements according to hierarchy
  value.addChild(fac.createOMText(value, model));
  method.addChild(value);
  value1.addChild(fac.createOMText(value1, price));
  method.addChild(value1);
  value2.addChild(fac.createOMText(value2, qty));
  method.addChild(value2);

  return method;
  // return element;

 }

 public void setProduct(OMElement element) throws XMLStreamException {
  television tele = new television();

  element.build();
  element.detach();

  // Get product id from request XML
  OMElement prodIdElement = element.getFirstChildWithName(new QName(
    namespace, "id"));
  String id = prodIdElement.getText();

  OMElement proDetailElement = element.getFirstChildWithName(new QName(
    namespace, "model"));
  String model = proDetailElement.getText();
  tele.setModel(model);

  OMElement proPriceElement = element.getFirstChildWithName(new QName(
    namespace, "price"));
  String price = proPriceElement.getText();
  tele.setPrice(price);

  OMElement qtyElement = element.getFirstChildWithName(new QName(
    namespace, "qty"));
  String qty = qtyElement.getText();
  tele.setAvailableQuantity(qty);
  
  System.out.println("[Product Set] : ID" +id+ " : Name : " +model+ " : Price : "+price+ " : Qualtity : " +qty);

  map.put(id, tele);
 }
}

Note : As you can see above four parameters are parsed to the service class to set product details, namely; id, model, price and quantity.

Step 2 : Writing The Service Descriptor 
  1. Now create the service descriptor file (service.xml) so Axis2 will be able to identify the corresponding classes and methods of the service, to create the service.xml file create a directory named "META-INF" at the root level of your project and place the service.xml file in that folder with the following content.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<service name="TelevisionShopService" scope="application">
 <description>
  TelevisionShopService
 </description>
 <operation name="getProduct">
  <messageReceiver
   class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver" />
 </operation>
 <operation name="setProduct">
  <messageReceiver
   class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver" />
 </operation>
 <parameter name="ServiceClass">televisionshop.service.TelevisionShopService
 </parameter>
</service>
Note : Axis2 has a set of built-in message receivers; some of them can only handle a XML-in, XML-out scenarios and those are called RawXML message receivers. Meanwhile, there are message receivers that can handle any kind of JavaBeans + simple Java types + XML; those are called RPC message receivers. As you can see from the above service Descriptor parameter named "ServiceClass"  specifies the main service class.

After creating all the files the Folder structure of the project will look like this, 



Step 3 : Creating a service Archive file to deploy the service
  1. The service archive type that is supported by Axis2 is .arr (Axis ARchive), the file structure of a .aar file is similar to a .jar file. So in order to create the service archive (.arr file) just export the project to a Jar file and change the extension of the file from .jar to .aar. (FileName.jar to FileName.aar)
  • The file can be exported as a jar file in eclipse by going to the file menu and selecting export command and selecting export type as JAR. 
  • The file can be exported to a jar file in Intellij by following this.
  1. Next place the created .aar file in <AXIS2_HOME>/repository/services directory. Now start the Axis2 server by running the "axis2server.sh" file located in <AXIS2_HOME>/bin directory. Axis2 will automatically deploy the service.
  2. Now go to the URL where AXIS server is running at, in my case the location is "http://localhost:8080/axis2/services/". If you go to this URL you will be able to view the service you created if it is successfully deployed, click on the service to view the WSDL of the service. 


Now you have successfully created the service component and deployed it, In the next post I'll explain how to test the service without a client.

Thank You for reading and Your feedback is highly appreciated. :)



Subscribe to RSS Feed Follow me on Twitter!