Official Documentation (ws Apache Org) - Axis2 - Part 2

  • Uploaded by: Fede
  • 0
  • 0
  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Official Documentation (ws Apache Org) - Axis2 - Part 2 as PDF for free.

More details

  • Words: 16,596
  • Pages: 80
AXIS 2 Índice de contenido AXIS 2..................................................................................................................................................1 Apache Axis2 Modules.........................................................................................................................4 Axis2 - WS-Addressing Implementation.........................................................................................4 Using the SOAP Monitor.................................................................................................................4 Welcome to Apache Sandesha2.......................................................................................................6 Resources:...................................................................................................................................6 Securing SOAP Messages with Rampart.........................................................................................7 Content........................................................................................................................................7 Introduction.................................................................................................................................7 Rampart-1.1 Configuration.........................................................................................................7 Rampart Specific Assertions..................................................................................................7 Service Configration...............................................................................................................8 Client Confiuration.................................................................................................................8 Rampart-1.0 Configuration.........................................................................................................8 OutflowSecurity Parameter....................................................................................................8 InflowSecurity Parameter.......................................................................................................9 References.................................................................................................................................10 Examples...................................................................................................................................10 Web Services Policy Support In Apache Axis2..................................................................................12 Content...........................................................................................................................................12 What is Web Services (WS) Policy?..............................................................................................12 Client Side WS-Policy Support.....................................................................................................12 How it works:.................................................................................................................................12 Phase 1: At PolicyEvaluator......................................................................................................12 Phase 2: At AxisServiceBasedMultiLanguageClientEmitter....................................................13 Phase 3: Runtime......................................................................................................................13 Server Side WS-Policy Support.....................................................................................................13 Resources.......................................................................................................................................14 RESTful Web Services Support..........................................................................................................14 Content...........................................................................................................................................14 Introduction....................................................................................................................................14 REST Web Services with HTTP POST.........................................................................................15 Sample REST - HTTP POST Client.........................................................................................15 Access a REST Web Service via HTTP GET................................................................................16 Resources.......................................................................................................................................17 JSON Support in Axis2......................................................................................................................17 What is JSON?...............................................................................................................................17 Why JSON Support for Axis2?......................................................................................................17 How to use JSON in Axis2............................................................................................................18 Step 1.........................................................................................................................................18 Step 2.........................................................................................................................................19 Step 3.........................................................................................................................................19 Tests and Samples..........................................................................................................................19 Integration Test..........................................................................................................................19 Yahoo-JSON Sample.................................................................................................................20 1

Guide to using EJB Provider for Axis2..............................................................................................20 1. Creating a Simple Stateless Session EJB...................................................................................20 2. Creating the Axis2 Service Archive...........................................................................................22 Using the SOAP Monitor...................................................................................................................24 Axis2 Reference Guide.......................................................................................................................27 WSDL2Java Reference..................................................................................................................27 Java2WSDL Reference..................................................................................................................27 Apache Axis2 Tools............................................................................................................................28 Code Generator Tool Guide for Command Line and Ant Task.....................................................29 Content......................................................................................................................................29 Introduction...............................................................................................................................29 Command Line Version.............................................................................................................29 Option Reference..................................................................................................................29 Ant Task....................................................................................................................................30 Ant Task Reference..............................................................................................................30 Example Build File Using the Custom Ant Task..................................................................32 Invoking the Code Generator From Ant...............................................................................33 Appendix...................................................................................................................................40 Service Archive Generator Wizard Guide for Eclipse Plug-in......................................................40 Content......................................................................................................................................40 Introduction...............................................................................................................................40 Installation.................................................................................................................................41 Operation...................................................................................................................................41 Appendix...................................................................................................................................48 Code Generator Wizard Guide for Eclipse Plug-in.......................................................................49 Content......................................................................................................................................49 Introduction...............................................................................................................................49 Installation.................................................................................................................................49 Operation - WSDL2Java...........................................................................................................49 Operation - Java2WSDL...........................................................................................................55 Appendix...................................................................................................................................58 Maven2 AAR Plug-in Guide..........................................................................................................59 Introduction...............................................................................................................................59 Goals.........................................................................................................................................59 Configuration............................................................................................................................59 The aar Goal..............................................................................................................................59 File Sets.....................................................................................................................................60 Maven2 Java2WSDL Plug-in Guide.............................................................................................60 Introduction...............................................................................................................................60 Goals.........................................................................................................................................61 The Java2WSDL Goal..............................................................................................................61 Configuration............................................................................................................................61 Maven2 WSDL2Code Plug-in Guide............................................................................................62 Introduction...............................................................................................................................62 Goals.........................................................................................................................................62 The WSDL2Code Goal.............................................................................................................63 Configuration............................................................................................................................63 Migrating from Apache Axis 1.x to Axis2..........................................................................................64 Content...........................................................................................................................................64 Compatibility.................................................................................................................................64 2

Getting Started...............................................................................................................................65 Custom Deployment of Services, Handlers, and Modules............................................................66 Transports for HTTP Connection..................................................................................................69 Data Binding Support....................................................................................................................69 Best Usage.....................................................................................................................................76 Design Notes......................................................................................................................................76 Axis2 RPC Support........................................................................................................................76 Introduction...............................................................................................................................76 Step 1 - Converting RPC Style WSDL's into Doc/Lit Style WSDL....................................76 Step 2 - Unwrapping the Schema.........................................................................................78 Step 3 - Populate Type Information......................................................................................78 Step 4 - Generate Code with Unwrapped Parameters..........................................................79 Bringing the Parameters Together and Exploding Them..........................................................80 Conclusion................................................................................................................................80

3

Apache Axis2 Modules Axis2 - WS-Addressing Implementation This is an implementation of WS-Addressing submission version (2004-08) and WSAddressing 2005-08 versions. Complete WS-Addressing Final version will be available, once the specification itself gets finalized. Axis2 engine contains addressing support by default. So you may need not put this module, unless you specifically want to use a particular release of this module.

Using the SOAP Monitor Web service developers often want to see the SOAP messages that are being used to invoke the Web services, along with the results of those messages. The goal of the SOAP Monitor utility is to provide a way for the developers to monitor these SOAP messages without requiring any special configuration or restarting the server. In this utility, a handler has been written and added to the global handler chain. As SOAP requests and responses are received, the SOAP message information is forwarded to a SOAP monitor service where it can be displayed using a Web browser interface. The SOAP message information is accessed by a Web browser by going to http://localhost:8080/axis2/SOAPMonitor (where 8080 is the port number where the application server is running). The SOAP message information is displayed through a Web browser by using an applet that opens a socket connection to the SOAP monitor service. This applet requires a Java plug-in 1.3 or higher to be installed in your browser. If you do not have a correct plug-in, the browser will prompt you to install one. The port used by the SOAP monitor service to communicate with applets is configurable. Edit the web.xml file to change the port used by the Axis2 Web application. The SOAP Monitor module (soapmonitor.mar) is available in the axis2.war but it is not engaged by default. The SOAP Monitor is NOT enabled by default for security reasons. The SOAP Monitor can be engaged by inserting the following in the axis2.xml file. ●

<module ref="soapmonitor"/>

In the axis2.xml file, define your phase orders for the 'soapmonitorPhase' referenced in the module.xml of soapmonitor.mars. Below is an example which should NOT be copied exactly, since the default phases change occasionally. The important point here is that 'soapmonitorPhase' should be placed under the 'user can add his own phases to this area' comment in the 'inflow', 'outflow', 'INfaultflow', and 'Outfaultflow' sections.

4

To configure the servlet to communicate with the applet, add the following code to the web.xml (The SOAPMonitorPort is configurable.):

5

<servlet> <servlet-name>SOAPMonitorService SOAPMonitorService <servlet-class> org.apache.axis2.soapmonitor.servlet.SOAPMonitorService <param-name>SOAPMonitorPort <param-value>5001 1 <servlet-mapping> <servlet-name>SOAPMonitorService /SOAPMonitor

Finally, compile the applet classes and place them at the root (eg: /webapps/axis2/) of the extracted WAR file. You can find the SOAPMonitorApplet.java in the source distribution. To compile, use the following command: ●

javac -classpath axis2-soapmonitor.jar SOAPMonitorApplet.java

Alternatively, you can directly get the compiled applet classes from the WEBINF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2soapmonitor-*.jar file, simply execute the command, jar -xf axis2-soapmonitor-*.jar and place the compiled applet classes in the root directory of the extracted WAR, for example, in /webapps/axis2/. Using a Web browser, go to http[s]://host[:port][/webapp]/SOAPMonitor (e.g.http://localhost:8080/axis2/SOAPMonitor) substituting the correct values for your Web application. This will show the SOAP Monitor applet used to view the service requests and responses. Any requests to services that have been configured and deployed correctly should show up in the applet. The SOAPMonitor with attachments currently serializes themselves as base64 characters. It is therefore recommended to use the TCPMon tool to correctly capture MTOM and SWA messages as an multipart mime where the binary data is an attachment.

Welcome to Apache Sandesha2 Sandesha2 is an implementation of WS-ReliableMessaging specification published by IBM, Microsoft, BEA and TIBCO. Sandesha2 was built on top of Axis2. Therefore by using Sandesha2 you can add reliable messaging capability to the web services hosted using Axis2. Sandesha2 can also be used with Axis2 client to interact with already hosted web services in a reliable manner. Please see sandesha2 user guide for more information on using Sandesha2. Read Sandesha2 Architecture guide to see how Sandesha2 work internally.

Resources: Official Page: ●

http://ws.apache.org/sandesha/sandesha2/index.html

WS-ReliableMessaging specification: ftp://www6.software.ibm.com/software/developer/library/wsreliablemessaging200502.pdf



6

Securing SOAP Messages with Rampart Axis2 comes with a module based on Apache WSS4J [1] to provide WS-Security features, called "Rampart". This document explains how to engage and configure Rampart module.

Content •

Introduction



Rampart-1.1 Configuration





Rampart Specific Assertions



Service Configration



Client Confiuration

Rampart-1.0 Configuration •

OutflowSecurity Parameter



InflowSecurity Parameter



References



Examples

Introduction Since rampart module inserts handlers in the system specific security phase, it must be engaged globally. These handlers can be configured using WS-SecurityPolicy[2] and Rampart specific policy assertions. Rampart-1.0 used two axis2 parameters for configuration and these are still supported in the 1.1 release as well. The rampart-1.1 release is available here: ●

http://www.apache.org/dyn/closer.cgi/ws/rampart/1_1

First it should be engaged by inserting the following in the axis2.xml file. ●

<module ref="rampart"/>

The web admin interface can be used when Axis2 is deployed in a servlet container such as Apache Tomcat. At the server it is possible to provide security on a per service basis. The configuration parameters should be set in the service.xml file of the service. The client side config parameters should be set in the axis2.xml of the client's Axis2 repository.

Rampart-1.1 Configuration Rampart Specific Assertions Rampart uses the standard WS-SecurityPolicy[2] assertions and also defines its own assertions to be able capture the configuration information that is not provided in WSSecurityPolicy. The Rampart specific assertion's xsd can be found here: ●

http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/rampart-config.xsd

The ramp:RampartConfig assertion must be available as a one of the top level assertions of the policy as shown here: ●

http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/sample-policy.xml

7

Service Configration To configure the service one will simply have to add the policy element into the sevices.xml file. A sample service.xml file is available here: ●

http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/sample-services.xml

Client Confiuration On the client side, a policy object should be created and loaded into options. Creating the policy object can be done using a "policy.xml" file as follows. //Creating the object StAXOMBuilder builder = new StAXOMBuilder(pathToPolicyfile); Policy clientPolicy = PolicyEngine.getPolicy(builder.getDocumentElement()); //setting the object Options options = new Options(); options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, clientPolicy);

Rampart-1.0 Configuration Rampart module uses two parameters: •

OutflowSecurity



InflowSecurity

The configuration that can go in each of these parameters are described below:

OutflowSecurity Parameter This parameter is used to configure the outflow security handler. The outflow invoked more than once in the outflow one can provide configuration for invocations. The 'action' element describes one of these configurations. 'OutflowSecurity' parameter can contain more than one 'action' elements. The 'action' element is available here: ●

handler can be each of these Therefore the schema of this

http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/out-action.xsd

An outflow configuration to add a timestamp, sign and encrypt the message once, is shown in Example 1 and Example 2 shows how to sign the message twice by chaining the outflow handler (using two 'action' elements) Following is a description of the elements that can go in an 'action' element of the OutflowSecurity parameter Parameter

Description

Example

items

Add a Timestamp, Sign the SOAP body and Encrypt the SOAP body Security actions for the inflow Timestamp Signature Encrypt

user

The user's name

Set alias of the key to be used to sign <user> bob

passwordCallback Callback class used to provide <passwordCallbackClass> Class the password required to org.apache.axis2.security.PWCallback
8

create the UsernameToken or wordCallbackClass> to sign the message property file used to get the signature parameters such as signaturePropFile crypto provider, keystore and its password

Set example.properties file as the signature property file <signaturePropFile> example.properties

Key identifier to be used in signatureKeyIdent referring the key in the ifier signature

Use the serial number of the certificate <signatureKeyIdentifier> IssuerSerial

Key identifier to be used in encryptionKeyIde referring the key in ntifier encryption

Use the serial number of the certificate <encryptionKeyIdentifier>IssuerSerial

encryptionUser

The user's name for encryption.

<encryptionUser>alice

encryptionSymAlg Symmetric algorithm to be orithm used for encryption

Use AES-128 <encryptionSymAlgorithm> http://www.w3.org/2001/04/xmlenc#aes12 8-cbc

encryptionKeyTran Key encryption algorithm sportAlgorithm

Use RSA-OAEP <parameter name="encryptionSymAlgorithm"> http://www.w3.org/2001/04/xmlenc#rsaoaep-mgf1p Sign Foo and Bar elements qualified by "http://app.ns/ns" <signatureParts> {Element}{http://app.ns/ns}Foo;{Element} {http://app.ns/ns}Bar

signatureParts

Sign multiple parts in the SOAP message

optimizeParts

Optimize the CipherValue MTOM Optimize the elements specified by the XPath query //xenc:EncryptedData/xenc:CipherData/xen c:CipherValue

InflowSecurity Parameter This parameter is used to configure the inflow security handler. The 'action' element is used to encapsulate the configuration elements here as well. The schema of the 'action' element is available here. Example 3 shows the configuration to decrypt, verify signature and validate timestamp. Parameter

Description

Example

items

first the incoming message should be decrypted and then the signatures should be verified and should be checked for the Security actions for the inflow availability of the Timestamp Timestamp Signature Encrypt

Callback class used to obtain passwordCallback password for decryption and Class UsernameToken verification signaturePropFile

Property file used for signature verification

<passwordCallbackClass> org.apache.axis2.security.PWCallback <signaturePropFile> sig.properties

9

decryptionPropFile

Property file used for decryption

<decryptionPropFile> dec.properties

Please note that the '.properties' files used in properties such as OutSignaturePropFile are the same property files that are using in the WSS4J project. Following shows the properties defined in a sample property file org.apache.ws.security.crypto.provider=org.apache.ws.security.components .crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=pkcs12 org.apache.ws.security.crypto.merlin.keystore.password=security org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458fabf5-2f875f74882e org.apache.ws.security.crypto.merlin.alias.password=security org.apache.ws.security.crypto.merlin.file=keys/x509.PFX.MSFT org.apache.ws.security.crypto.provider defines the implementation of the org.apache.ws.security.components.crypto.Crypto interface to provide the crypto information required by WSS4J. The other properties defined are the configuration properties used by the implementation class (org.apache.ws.security.components.crypto.Merlin).

References 1. Apache WSS4J: ○

http://ws.apache.org/wss4j

2. ws-securitypolicy.pdf: ○

http://specs.xmlsoap.org/ws/2005/07/securitypolicy/ws-securitypolicy.pdf

Examples Example 1: An outflow configuration to add a timestamp, sign and encrypt the message once

10

Example 2: An outflow configuration to sign the message twice and add a timestamp

Example 3: An inflow configuration to decrypt, verify signature and validate timestamp

11

Web Services Policy Support In Apache Axis2 This document gives you an introduction to the role of Web services policy in Apache Axis2. Send your feedback to: [email protected]. (Subscription details are available on the Axis2 site.) Kindly prefix every email subject with [Axis2].

Content •

What is Web Services (WS) Policy?



Client Side WS-Policy Support



Server Side WS-Policy Support



Resources

What is Web Services (WS) Policy? To consume non trivial web services you must fully understand its XML contract (WSDL) along with any other additional requirements, capabilities, or preferences that translate to the configuration of the service and essentially becomes the policies of the service. WS Policy framework provides a way to express the policies of a service in a machinereadable way. A Web services infrastructure can be enhanced to understand and enforce policies at runtime. For instance, a service author might write a policy requiring a digital signature and encryption, while service consumers can use the policy information to reason out whether they can adhere to this policy information to use the service. Furthermore, Web service infrastructure can be enhanced to enforce those requirements without requiring the service author to write even a single line of code.

Client Side WS-Policy Support This release fully supports WS Policy at client-side. It means that when you codegen a stub against a WSLD which contains policies, the stub will contain the capability to engage the required modules with the appropriate configurations, plus it will generate additional methods in the stub where the user can set certain properties. For instance, if there is a security policy attached to a binding, the generated stub will engage the security module for that service with the appropriate security configurations with some addtional methods that the user can use to set properties in the generated stub.

How it works: Phase 1: At PolicyEvaluator The Codegen engine runs a few of its registered extensions before it generates the stub. When the PolicyEvalutor (which is a registered Codegen extension) is initialized, it populates a registry of QNames of supported policy assertions to PolicyExtensions. For instance, module Foo might have a mapping of assertion {http://test.com/foo, foo} which means any assertion that has this name will be processed by this module. The Foo module might implement the ModulePolicyExtension interface through which the PolicyExtension object can be obtained. A PolicyExtension is the access point for a module to add any additional methods to the

12

stub. For instance a Reliable Messaging module can add startSequence() and endSequence() methods to the stub, that the user must call to start and end an RM sequence. Then at the engagement of the PolicyEvaluator, the effective policy of each message of every operation is calculated based on policy information declared in the WSDL document. Here we assume that the effective policy of an operation contains a single alternative (Multiple policy alternatives are not supported). Then we split that policy as follows into few other policies such that, each policy will contain assertions that can be processed by a single module. <wsp:Policy>

=>

<wsp:Policy>

<wsp:Policy>





Then each policy is given the appropriate PolicyExtension with an org.w3c.Element type object to which the module can append any other elements/attributes it wishes. Those attributes/elements should resolve to meaningful stub functions through the Custom PolicyExtensionTemplate.xsl at a latter point of time. For instance, depending on the policy, the Security module can append <username>, <passwd> elements to the given element as children, which are later resolved into setUsername(..), setPasswd(..), functions of the stub. This way a module can include additional methods to the stub that can be used to get specific propreties from the user. These methods store any user input in the ServiceClient properties (ServiceClient.getOptions().putProperty(...)) which can later be accessed by the module.

Phase 2: At AxisServiceBasedMultiLanguageClientEmitter Further, policies (based on the WSDL) at appropriate levels (service level, operation level) are stored as policy strings in the stub. If there are a few policies at a given level, they are merged together and represented as a single policy in the stub. Few more generic methods are also added to the stub which are used to evaluate and process the policies at runtime.

Phase 3: Runtime When a new stub object is created, the policy strings in the stub are converted into policy objects and are set in the AxisDescription hierarchy that is used in the stub. In other words, any policy information available in the WSDL will be preserved in the AxisService object that is used in the stub. Then based on its policy, each AxisDescription is engaged to a set of modules. Modules can do a prior calculation of configurations if needed at the engagement. When the stub method is invoked, those modules which are engaged to that AxisDescription, access the policy for that operation via the AxisDescription object. It can get the other required information from the MessageContext, which is stored by stub methods that the module has added to the stub earlier, through the ModulePolicyExtension implementation. The modules are required to load their configurations according to the effective policy, which is set at AxisDescription, and the properties they get via MessageContext.

Server Side WS-Policy Support In this current release, the Apache Axis2 framework uses the WS-Commons/Neethi framework to manipulate policy documents. All its description builders store the policy information included in description documents (services.xml, axis2.xml, .. etc) in the appropriate description classes. This information is available at both deployment and run time

13

via these description classes. When generating WSDL dynamically for each service, policy information in the description classes is included. For instance, if you declare a policy in axis2.xml, then that policy is reflected in the service elements of the WSDL of every service. If a policy is declared in a services.xml, it is shown in the service element of WSDL for that particular service. Further, when a service is deployed, an arbitary policy alternative is selected and set for each AxisOperation and AxisMessages of the AxisService. If the selected Policy alternative cannot be supported by any modules that are capable of processing the selective alternative, then the service is considered as a faulty service. Else, the set of modules is engaged at appropriate levels to support the requirments and capabilities that are defined in the Policies associated with the AxisDescription. It is evident that there is some work left to make Apache Axis2 a fully fledged ws-policy supported Web service infrastructure. However, it is encouraging to note that we've taken the first steps towards this goal. We appreciate any suggestions, patches, etc., you send us in this regard. Keep on contributing!

Resources Apache Neethi (WS Policy Implementation) official site: ●

http://ws.apache.org/commons/neethi/index.html

Sanka Samaranayake, March 2006. Web services Policy - Why, What & How: ●

http://wso2.org/library/23

WS-commons/policy SVN: ●

http://svn.apache.org/viewvc/webservices/commons/trunk/modules/neethi/

Web Services Policy Framework (WS-Policy): ●

http://specs.xmlsoap.org/ws/2004/09/policy/ws-policy.pdf

RESTful Web Services Support This document presents an introduction on REST and REST with HTTP POST and GET.

Content •

Introduction



Doing REST Web Services with HTTP POST •



Sample REST - HTTP POST Client

Access a REST Web Service via HTTP GET

Introduction WSDL 2.0 HTTP Binding defines a way to implement REST (Representational State Transfer) with Web services. Axis2 implements the most defined HTTP binding specification. REST Web services are a reduced subset of the usual Web service stack. The Axis2 REST implementation assumes the following properties: 1. REST Web services are Synchronous and Request Response in nature. 2. When REST Web services are accessed via GET, the service and the operations are identified based on the URL. The parameters are assumed as parameters of the Web

14

service. In this case, the GET based REST Web services support only simple types as arguments and it should adhere to the IRI style. 3. POST based Web services do not need a SOAP Envelope or a SOAP Body. REST Web Services do not have Headers and the payload is sent directly. Axis2 can be configured as a REST Container and can be used to send and receive RESTful Web service requests and responses. REST Web services can be accessed using HTTP GET and POST.

REST Web Services with HTTP POST If REST is enabled, the Axis2 server will act as both a REST endpoint and a SOAP endpoint. When a message is received, if the content type is text/xml and if the SOAPAction Header is missing, then the message is treated as a RESTful Message, if not it is treated as a usual SOAP Message. On sending a message, whether the message is RESTful or not, can be decided from the client API. Set a property in the client API. ... Options options = new Options(); options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE); ...

Sample REST - HTTP POST Client There is an example named, userguide.clients.RESTClient.java found in AXIS2_HOME/samples/userguide/src/userguide/clients which demonstrates the usage of the above. It uses the "echo" operation of the userguide.example1.MyServiceof the AXIS2_HOME/samples/userguide/src/userguide/example1. The class source will be as follows: public class RESTClient { private static String toEpr = "http://localhost:8080/axis2/services/MyService"; public static void main(String[] args) throws AxisFault { Options options = new Options(); options.setTo(new EndpointReference(toEpr)); options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE); ServiceClient sender = new ServiceClient(); sender.engageModule(new QName(Constants.MODULE_ADDRESSING)); sender.setOptions(options); OMElement result = sender.sendReceive(getPayload()); try { XMLStreamWriter writer = XMLOutputFactory.newInstance() .createXMLStreamWriter(System.out); result.serialize(writer); writer.flush(); }

15

catch (XMLStreamException e) { e.printStackTrace(); } catch (FactoryConfigurationError e) { e.printStackTrace(); }

} private static OMElement getPayload() { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace( "http://example1.org/example1", "example1"); OMElement method = fac.createOMElement("echo", omNs); OMElement value = fac.createOMElement("Text", omNs); value.addChild(fac.createOMText(value, "Axis2 Echo String ")); method.addChild(value); return method; }

}

Access a REST Web Service via HTTP GET Axis2 allows users to access Web services that have simple type parameters via HTTP GET. For example, the following URL requests the Version Service via HTTP GET. However, the Web service arriving via GET assumes REST. Other parameters are converted into XML and put into the SOAP body. ●

http://127.0.0.1:8080/axis2/services/Version/getVersion

The result can be shown in the browser as follows:

For example, the following request, ●

http://127.0.0.1:8080/axis2/services/Version/getVersion

will be converted into the following SOAP message for processing by Axis2.

16

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body>

Resources How I Explained REST to My Wife, By Ryan Tomayko: ●

http://naeblis.cx/articles/2004/12/12/rest-to-my-wife

Building Web Services the REST Way, By Roger L. Costello: ●

http://www.xfront.com/REST-Web-Services.html

Resource-oriented vs. activity-oriented Web services, By James Snell: ●

http://www-128.ibm.com/developerworks/webservices/library/ws-restvsoap/

JSON Support in Axis2 This document explains the JSON support implementation in Axis2. It includes an introduction to JSON, an outline as to why JSON support is useful to Axis2 and how to it should be used. Document also provides details on test cases and samples.

What is JSON? JSON (Java Script Object Notation) is another data exchangeable format like XML, but it is more lightweight and easily readable. It is based on a subset of JavaScript language. Therefore, JavaScript can understand JSON, and it can make JavaScript objects by using JSON strings. JSON is based on key-value pairs and it uses colons to separate keys and values. JSON doesn't use end tags, and it uses braces (curly brackets) to enclose JSON Objects. json object == {?root??:{?test??:??json object??}} When it comes to converting XML to JSON and vice versa, there are two major conventions, one named "Badgerfish" and the other, ?Mapped??. The main difference between these two conventions exists in the way they map XML namespaces into JSON. <xsl:root xmlns:xsl="http://foo.com">my json string This XML string can be converted into JSON as follows. Using ?Badgerfish?? {"xsl:root":{"@xmlns":{"xsl":"http://foo.com"},"data":{"$":"my json string"}}} Using ?Mapped?? If we use the namespace mapping as http://foo.com -> foo {"foo.root":{"data":"my json string"}} JSON support implementation is a new feature in Apache Axis2/Java. It will become a crucial improvement in the future with applications like JavaScript Web services.

Why JSON Support for Axis2? Apache Axis2 is a Web services stack that delivers incoming messages into target applications. In most cases, these messages are SOAP messages. In addition, it is also

17

possible to send REST messages through Axis2. Both types of messages use XML as their data exchangeable format. So if we can use XML as a format, why not use JSON as another format? There are many advantages of implementing JSON support in Axis2. Mainly, it helps the JavaScript users (services and clients written in JavaScript) to deal with Axis2. When the service or the client is in JavaScript, it can use the JSON string and directly build JavaScript objects to retrieve information, without having to build the object model (OMElement in Axis2). Also, JavaScript services can return the response through Axis2, just as a JSON string can be shipped in a JSONDataSource. Other than for that, there are some extra advantages of using JSON in comparison to XML. Although the conversation ?XML or JSON??? is still a hot topic, many people accept the fact that JSON can be passed and built easily by machines than in the case of XML. For more details of this implementation architecture, refer to the article "JSON Support for Apache Axis2"

How to use JSON in Axis2 At the moment JSON doesn't have a standard and unique content type. ?application/json?? (this is the content type which is approved in the JSON RFC ), ?text/javascript?? and ? text/json?? are some of the commonly used content types of JSON. Due to this problem, in Axis2, the user has been given the freedom of selecting the content type.

Step 1 Map the appropriate MessageFormatter and OMBuilder with the content type you are using in the axis2.xml file. e.g.1: If you are using the ?Mapped?? convention with the content type ?application/json?? <messageFormatters> <messageFormatter contentType="application/json" class="org.apache.axis2.json.JSONMessageFormatter"/> <messageBuilders> <messageBuilder contentType="application/json" class="org.apache.axis2.json.JSONOMBuilder"/> e.g.2: If you text/javascript??

are

using

the

?Badgerfish??

convention

with

the

<messageFormatters> <messageFormatter contentType="text/javascript" class="org.apache.axis2.json.JSONBadgerfishMessageFormatter"/> <messageBuilders> <messageBuilder contentType="text/javascript" class="org.apache.axis2.json.JSONBadgerfishOMBuilder"/>

18

content

type

?

Step 2 On the client side, make the ConfigurationContext by reading the axis2.xml in which the correct mappings are given. File configFile = new File("test-resources/axis2.xml"); configurationContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(nul l, configFile.getAbsolutePath()); .......... ServiceClient sender = new ServiceClient(configurationContext, null);

Step 3 Set the MESSAGE_TYPE option with exactly the same content type you used in the axis2.xml. e.g. If you use the content type ?application/json??, Options options = new Options(); options.setProperty(Constants.Configuration.MESSAGE_TYPE, ? application/json??); //more options //................... ServiceClient sender = new ServiceClient(configurationContext, null); sender.setOptions(options); If you are sending a request to a remote service, you have to know the exact JSON content type that is used by that service, and you have to use that content type in your client as well. HTTP POST method is used as the default to send JSON messages through Axis2, if the HTTP method is not set by the user. But if you want to send JSON in HTTP GET method as a parameter, you can do that by just setting an option on the client side. options.setProperty(Constants.Configuration.HTTP_METHOD, Constants.Configuration.HTTP_METHOD_GET); Here, the Axis2 receiving side (JSONOMBuilder) builds the OMElement by reading the JSON string which is sent as a parameter. The request can be made even through the browser. e.g. Sample JSON request through HTTP GET. The JSON message is encoded and sent.

GET /axis2/services/EchoXMLService/echoOM?query=%7B%22echoOM%22:%7B%22data%2 2:%5B%22my%20json%20string%22,%22my%20second%20json%20string%22%5D%7D%7D HTTP/1.1

Tests and Samples Integration Test The JSON integration test is available under ?test?? in the ?json?? module of Axis2. It uses the SimpleHTTPServer to deploy the service. A simple echo service is used to return the

19

incoming OMSourcedElementImpl object, which contains the JSONDataSource. There are two test cases for two different conventions and another one test case to send the request in GET.

Yahoo-JSON Sample This sample is available in the ?samples?? module of Axis2. It is a client which calls the Yahoo search API using the GET method, with the parameter ?output=json??. The Yahoo search service sends the response as a ?Mapped?? formatted JSON string with the content type ?text/javascript??. This content type is mapped with the JSONOMBuilder in the axis2.xml. All the results are shown in a GUI. To run the sample, execute the ant script. These two applications are good examples of using JSON support for Axis2. You can understand the architecture of JSON support implementation in Axis2 by looking at these samples.

Guide to using EJB Provider for Axis2 The EJB message receiver allows one to access stateless session EJBs (Enterprise JavaBeans) through Web services. The example used in this guide illustrates how to use EJB provider that ships with axis2 to access EJBs deployed on a J2EE server such as Geronimo or Jboss. This example explains how to use Geronimo 1.1 and Jboss 4.0.4.GA as application server. The following steps will take you through the example through which we will explain how to use an EJB provider in Axis2

1. Creating a Simple Stateless Session EJB First, we need to create a stateless session EJB. Use the following files to make an EJB for testing: Remote interface (Hello.java) package my.ejb; import javax.ejb.EJBObject; public interface Hello extends EJBObject, HelloBusiness { } The following interface defines the business methods available in 1.HelloBusiness.java package my.ejb; import java.rmi.RemoteException; public interface HelloBusiness { public String sayHello(String name) throws RemoteException; } 2, Remote home interface - HelloHome.java package my.ejb; import javax.ejb.EJBHome; import javax.ejb.CreateException; import java.rmi.RemoteException; public interface HelloHome extends EJBHome { public Hello create() throws CreateException, RemoteException; }

20

3. Bean class - HelloBean.java package my.ejb; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.ejb.EJBException; import javax.ejb.CreateException; public class HelloBean implements SessionBean { public void setSessionContext(SessionContext sessionContext) throws EJBException {}

}

public void ejbRemove() throws EJBException {} public void ejbActivate() throws EJBException {} public void ejbPassivate() throws EJBException {} public void ejbCreate() throws CreateException {} public String sayHello(String name) { return "Hello " + name + ", Have a nice day!"; }

4. Deployment descriptor - ejb-jar.xml <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1"> <enterprise-beans> <session> <ejb-name>Hello my.ejb.HelloHome my.ejb.Hello <ejb-class>my.ejb.HelloBean <session-type>Stateless Bean <method> <ejb-name>Hello <method-name>* Required Now we have to write application server specific deployment descriptor(s) for the Hello EJB. Following listing shows an example Geronimo/OpenEJB deployment descriptor (openejbjar.xml)

21

<enterprise-beans> <session> <ejb-name>Hello <jndi-name>my/ejb/HelloBean If you want to test on JBoss, use the following JBoss deployment descriptor (jboss.xml) <jboss> <enterprise-beans> <session> <ejb-name>Hello <jndi-name>my/ejb/HelloBean Compile the above java classes and bundle the compiled classes and the XML files into a jar file (HelloEJB.jar) as shown below. HelloEJB.jar | +--META-INF | +--ejb-jar.xml | +--jboss.xml [If you want to deploy on Jboss] | +--openejb-jar.xml [If you want to deploy on Geronimo/Openejb] | +--my +--ejb | +--Hello.class +--HelloBean.class +--HelloBusiness.class +--HelloHome.class Deploy HelloEJB.jar on appropriate J2EE application server.

2. Creating the Axis2 Service Archive Now we need to make the services.xml file.

22

<serviceGroup> <service name="HelloBeanService"> <description>Hello! web service <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.ejb.EJBInOnlyMessageReceiver"/> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.ejb.EJBMessageReceiver"/> <parameter name="ServiceClass" locked="false"> my.ejb.HelloBusiness <parameter name="remoteInterfaceName">my.ejb.Hello <parameter name="homeInterfaceName">my.ejb.HelloHome <parameter name="beanJndiName">my/ejb/HelloBean <parameter name="providerUrl">[URL] <parameter name="jndiContextClass"> [Context Factory Class Name] In the above services.xml file, replace the [URL] and [Context Factory Class Name] with valid values as follows: i.e. If the EJB is deployed on Geronimo: Replace [URL] by 127.0.0.1:4201 Replace [Context Factory Class Name] by org.openejb.client.JNDIContext For Jboss: Replace [URL] by jnp://localhost:1099 Replace [Context Factory Class Name] by org.jnp.interfaces.NamingContextFactory Bundle the HelloBeanService.wsdl, services.xml, remote interface class and home interface class as illustrated below: HelloBeanService.aar | +--META-INF | +--services.xml | +--lib | +--[jars used by the ejb client eg.initial context factory classes] | +--my +--ejb +--Hello.class +--HelloBusiness.class +--HelloHome.class The lib directory of HelloBeanService.aar must contain all the libraries needed to access the EJB. If the EJB is deployed on Geronimo, add the following jar files to the lib directory. •

cglib-nodep-2.1_3.jar



geronimo-ejb_2.1_spec-1.0.1.jar



geronimo-j2ee-jacc_1.0_spec-1.0.1.jar

23



geronimo-kernel-1.1.jar



geronimo-security-1.1.jar



openejb-core-2.1.jar

For JBoss add the following jar files. •

jnp-client.jar



jboss-client.jar



jboss-common-client.jar



jboss-remoting.jar



jboss-serialization.jar



jboss-transaction-client.jar



concurrent.jar



jbosssx-client.jar



jboss-j2ee.jar

Deploy HelloBeanService.aar on an Axis2 server. Now you can access the Hello EJB through Web services. Since our EJB message receivers extend RPC message receivers, org.apache.axis2.rpc.client.RPCServiceClient can be used to invoke the service as illustrated in the following code fragment.

... RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/HelloBeanService "); options.setTo(targetEPR); QName hello = new QName("http://ejb.my/xsd", "sayHello"); Object[] helloArgs = new Object[] {"John"}; System.out.println(serviceClient.invokeBlocking(hello, helloArgs).getFirstElement().getText()); ...

Using the SOAP Monitor Web service developers often want to see the SOAP messages that are being used to invoke the Web services, along with the results of those messages. The goal of the SOAP Monitor utility is to provide a way for the developers to monitor these SOAP messages without requiring any special configuration or restarting the server. In this utility, a handler has been written and added to the global handler chain. As SOAP requests and responses are received, the SOAP message information is forwarded to a SOAP monitor service where it can be displayed using a Web browser interface. The SOAP message information is accessed by a Web browser by going to http://localhost:8080/axis2/SOAPMonitor (where 8080 is the port number where the application server is running). The SOAP message information is displayed through a Web browser by using an applet that opens a socket connection to the SOAP monitor service. This applet requires a Java plug-in 1.3 or higher to be installed in your browser. If you do not have a correct plug-in, the browser will prompt you to install one. The port used by the SOAP

24

monitor service to communicate with applets is configurable. Edit the web.xml file to change the port used by the Axis2 Web application. The SOAP Monitor module (soapmonitor.mar) is available in the axis2.war but it is not engaged by default. The SOAP Monitor is NOT enabled by default for security reasons. The SOAP Monitor can be engaged by inserting the following in the axis2.xml file. <module ref="soapmonitor"/> In the axis2.xml file, define your phase orders for the 'soapmonitorPhase' referenced in the module.xml of soapmonitor.mars. Below is an example which should NOT be copied exactly, since the default phases change occasionally. The important point here is that 'soapmonitorPhase' should be placed under the 'user can add his own phases to this area' comment in the 'inflow', 'outflow', 'INfaultflow', and 'Outfaultflow' sections.

25

To configure the servlet to communicate with the applet, add the following code to the web.xml (The SOAPMonitorPort is configurable.): <servlet> <servlet-name>SOAPMonitorService SOAPMonitorService <servlet-class> org.apache.axis2.soapmonitor.servlet.SOAPMonitorService <param-name>SOAPMonitorPort <param-value>5001 1 <servlet-mapping> <servlet-name>SOAPMonitorService /SOAPMonitor Finally, compile the applet classes and place them at the root (eg: /webapps/axis2/) of the extracted WAR file. You can find the SOAPMonitorApplet.java in the source distribution. To compile, use the following command: javac -classpath axis2-soapmonitor.jar SOAPMonitorApplet.java Alternatively, you can directly get the compiled applet classes from the WEBINF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2soapmonitor-*.jar file, simply execute the command, jar -xf axis2-soapmonitor-*.jar and place the compiled applet classes in the root directory of the extracted WAR, for example, in /webapps/axis2/. Using a Web browser, go to: ●

http[s]://host[:port]/[webapp]/SOAPMonitor(http://localhost:8080/axis2/SOAPMonitor)

substituting the correct values for your Web application. This will show the SOAP Monitor applet used to view the service requests and responses. Any requests to services that have been configured and deployed correctly should show up in the applet. The SOAPMonitor with attachments currently serializes themselves as base64 characters. It is therefore recommended to use the TCPMon tool to correctly capture MTOM and SWA messages as an multipart mime where the binary data is an attachment.

26

Axis2 Reference Guide WSDL2Java Reference NAME wsdl2java.sh or wsdl2java.bat - Generates java code according to a given WSDL file to handle Web service invocation. These scripts can be found under the bin directory of the Axis2 distribution. SYNOPSIS wsdl2java.sh [OPTION]... -uri DESCRIPTION Given a WSDL file, this generates java code to handle Web service invocations. -o : output file location -a : Generate async style code only. Default is off -s : Generate sync style code only. Default is off. takes precedence over -a -p <package name> : set custom package name -l : valid languages are java and csharp. Default is java -t : Generate TestCase to test the generated code -ss : Generate server side code (i.e. skeletons). Default is off -sd : Generate service descriptor (i.e. services.xml). Default is off. Valid with -ss -d : valid databinding(s) are adb, xmlbeans and jaxme. Default is adb -g : Generates all the classes. valid only with the -ss (This will generate client and server codes) -pn <port_name> : name of port in the presence of multiple ports -sn <service_name> : name of service in the presence of multiple services -u : unpacks the databinding classes -r : path of the repository against which code is generated -ns2p ns1=pkg1,ns2=pkg2 : Specify a custom package name for each namespace specified in the wsdl's schema -ssi : Generate an interface for the service implementation (Default: off) -em : Specify an external mapping file -wv : WSDL Version. Valid Options : 2, 2.0, 1.1 -f : Generate the source output folder without the src directory -uw : Switch on un-wrapping. -S : Generated source folder name. (Default: src) -R : Generated resources folder name. (Default: resources) EXAMPLES wsdl2java.sh wsdl2java.sh wsdl2java.sh ../samples -p

-uri ../samples/wsdl/Axis2SampleDocLit.wsdl -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -d xmlbeans -o org.apache.axis2.userguide

Java2WSDL Reference NAME Java2WSDL.sh or Java2WSDL.bat - Generates the appropriate WSDL file for a given java class. These scripts can be found under the bin directory of the Axis2 distribution. SYNOPSIS Java2WSDL.sh [OPTION]... -cn DESCRIPTION

27

Given a java class generates a WSDL file for the given java class. -o : output file location -cp : list of classpath entries - (urls) -tp : target namespace prefix -stn <schema target namespace> : target namespace for schema -stp <schema target namespace prefix> : target namespace prefix for schema -sn <service name> : service name -of : output file name for the WSDL -st : style for the WSDL -u : use for the WSDL -l <soap address> : address of the port for the WSDL -efd : Setting for elementFormDefault (defaults to qualified) -afd : Setting for attributeFormDefault (defaults to qualified) -xc <extra class> : Extra class for which schematype must be generated. Use as : -xc class1 -xc class2 ... EXAMPLES Java2WSDL.sh -cn ../samples/test/searchTool.Search Java2WSDL.sh -cn ../samples/test/searchTool.Search -sn search Java2WSDL.sh -cn ../samples/test/searchTool.Search -u -sn search Java2WSDL.sh -cn ../samples/test/searchTool.Search -sn search -o ../samples/test/wsdl

Apache Axis2 Tools Axis2 is bundled with a set of tools in order to make users' life easier. This page is maintained to keep track of the tools supported by Axis2. Name

Description

Code Tool consists of a command line version and an Ant Task. It is implemented by Generator Tool- the WSDL2Code class and WSDL2Java class. One can choose to run the main Command Line classes directly or use one of the scripts to run the WSDL2Code and & Ant Task WSDL2Java appropriately. Service Archive As part of the Axis2 tool set, the service archive generator is an important tool Wizard that allows the generation of service archives ("aar" file or a "jar" files) that Eclipse Plug-in can be deployed as a Web services to the Axis2. Code Axis2 code generator comes built-in with an eclipse plug-in. This can be used Generator to generate a WSDL file from a java class (Java2WSDL) and/or a java class file Wizard from a WSDL (WSDL2Java) Eclipse Plug-in Code Generator Wizard IntelliJ IDEA Plug-in

Using this tool one can create service archives that can be deployed as a Web services to the Axis2, and also generate a java class file from a WSDL file (WSDL2Java).

Maven2 AAR Plug-in

This plugin generates an Axis2 service file (AAR file).

Maven2 Java2WSDL Plug-in

This plugin takes as input a Java class and generates a WSDL, which describes a Web service for invoking the classes methods.

Maven2 WSDL2Code Plug-in

This plugin takes as input a WSDL and generates client and server stubs for calling or implementing a Web service matching the WSDL.

28

Code Generator Tool Guide for Command Line and Ant Task The Code Generator tool consists of a command line version and an Ant Task. This document will list the command line references and Ant task references. Also in detail, this document shows how to build file using custom Ant task and invoking the Code Generator from Ant. This tool is bundled with the Axis2 Binary Distribution.

Content •

Introduction



Command Line Version •





Option Reference

Ant Task •

Ant Task Reference



Example Build File Using the Custom Ant Task



Invoking the Code Generator From Ant

Appendix

Introduction This basic tool is implemented by the WSDL2Code class and just for the convenience in the case of Java (which would be the majority) there is another WSDL2Java class. One can choose to run the main classes directly or use one of the scripts to run the WSDL2Code and WSDL2Java appropriately. (the scripts are found in the bin directory of the Standard Binary Distribution)

Command Line Version For those users who wish to use the command line version of the tool, this section will be of value.

Option Reference Usage WSDL2Code E.g. :- WSDL2Code -uri Short Option

Long Option

Description

-uri

WSDL file location. This should point to a WSDL file in the local file system.

-o

--output

Output file location. This is where the files would be copied once the code generation is done. If this option is omitted the generated files would be copied to the working directory.

-l

--language

Output language. Currently the code generator can generate code in Java but it has the ability to be extended to support other languages.

-p <package name>

The target package name. If omitted, a default package --package (formed using the target namespace of the WSDL) will <package name> be used.

29

--async

Generate code only for async style. When this option is used the generated stubs will have only the asynchronous invocation methods. Switched off by default.

-s

--sync

Generate code only for sync style . When this option is used the generated stubs will have only the synchronous invocation methods. Switched off by default. When used with the -a option, this takes precedence.

-t

--test-case

Generates a test case. In the case of Java it would be a JUnit test case.

-ss

--server-side

Generates server side code (i.e. skeletons). Default is off.

-sd

--servicedescription

Generates the service descriptor (i.e. server.xml). Default is off. Only valid with -ss, the server side code generation option.

-d

--databindingmethod

Specifies the Databinding framework. Valid values are xmlbeans, adb, jibx, and none. Default is adb.

-g

--generate-all

Generates all the classes. This option is valid only with the -ss (server side code generation) option. When on, the client code (stubs) will also be generated along with the skeleton.

-u

--unpack-classes

Unpack classes. This option specifies whether to unpack the classes and generate separate classes for the databinders.

-sn <service name>

--service-name <service name>

Specifies the service name to be code generated. If the service name is not specified, then the first service will be picked.

-pn <port name>

Specifies the port name to be code generated. If the --port-name <port port name is not specified, then the first port (of the name> selected service) will be picked.

-ns2p

Specifies a comma separated list of namespaces and -packages where the given package will be used in the namespace2packa place of the auto generated package for the relevant ge namespace. The list will be the format of ns1=pkg1,ns2=pkg2.

-ssi

--serversideinterface

-a

Generate an interface for the service skeleton.

Apart from these mentioned options one can pass extra options by prefixing them with -E (uppercase). These extra options will be processed by the extensions. The extra options that can be passed are documented separately with the extensions documentation (For example with ADB).

Ant Task The code generator also comes bundled with an Ant task. The ant task is implemented by the org.apache.axis2.tool.ant.AntCodegenTask class. Following are the ant task attributes.

Ant Task Reference wsdlfilename

WSDL file location. Maps to the -uri option of the command line tool.

30

output

Output file location. This is where the files would be copied once the code generation is done. If this option is omitted the generated files would be copied to the working directory. Maps to the -o option of the command line tool.

language

Output language. Currently the code generator can generate code in Java. Maps to the -l option of the command line tool.

packageName

The target package name. If omitted, a default package (formed using the target namespace of the WSDL) will be used. Maps to the -p option of the command line tool.

databindingName

Data binding framework name. Maps to the -d option of the command line tool. Possible values include "adb", "xmlbeans", "jibx".

serviceName

The name of the service in the case of multiple services. Maps to -sn options of the command line tool.

portName

The name of the port in the presence of multiple ports. Maps to -pn options of the command line tool.

asyncOnly

Generate code only for async style. When this option is used the generated stubs will have only the asynchronous invocation methods. Defaults to false if omitted. Only true and false are applicable as values. Maps to the -a option of the command line tool.

syncOnly

Generate code only for sync style. When this option is used the generated stubs will have only the synchronous invocation methods. Defaults to false if omitted. Only true and false are applicable as values. Maps to the -s option of the command line tool.

serverSide

Generates server side code (i.e. skeletons). Only true and false are applicable as values. Default is false. Maps to the -ss option of the command line tool.

testcase

Generates a test case. Possible values are true and false. Maps to the -t options of the command line tool.

generateServiceXml

Generates server side code (i.e. skeletons). Only true and false are applicable as values. Default is false. Maps to the -sd option of the command line tool.

unpackClasses

Unpacks the generated classes. This forces the databinding classes to be generated separately, which otherwise would have been generated as inner classes.

generateAllClasses

Generates all the classes including client and server side code. Maps to the -g option of the command line tool.

namespaceToPackages

A list of namespace to package mappings.

serverSideInterface

Flag stating whether to generate an interface for the server side skeleton.

repositoryPath

Sets the repository path to be used. Maps to the -r option of the command line tool.

wsdlVersion

Sets the version of the wsdl that is being used during codegeneration. This deafults to 1.1 and one can set this to 2, when trying to work with a WSDL 2.0 document. Maps to the -wv option of the command line tool.

externalMapping

Location of the external mapping file to be used. Maps to the -em option of the command line tool.

targetSourceFolderLocation

Rather than dumping all the code in the same location, one has the option to make the sources to be generated in a

31

different location, given using this option. Maps to the -S option of the command line tool. Rather than dumping all the code in the same location, one has the option to make the resources to be generated in a targetResourcesFolderLocation different location, given using this option. Maps to the -R option of the command line tool. unwrap

This will select between wrapped and unwrapped during code generation. Default is set to false. Maps to the -uw option of the command line tool.

Example Build File Using the Custom Ant Task Following is an example ant build file that uses the custom Ant task. You can use any wsdl file to test the example. Replace the "CombinedService.wsdl" with the name of your wsdl file in the following script. 1 2 <project name="CodegenExample" default="main" basedir="."> 3 4 <path id="example.classpath"> 5 6 7 8 9 10 11 14 15 16 17 18 23 24 25 In the above build script, from line 4 to 8 it sets the classpath and includes all the .jar files (which are listed below) into the classpath. From line 10 to 15 it creates a target to declare a task called "codegen" and sets the appropriate class (org.apache.axis2.tool.ant.AntCodegenTask) within the classpath in line 12. From line 17 to 23 it creates the "main" target to generate the code from the given wsdl. There are some arguments set form line 19 to 22. Here in line 19 it sets the location of the wsdl. In line 20 it sets the output directory in which the code is generated. Line 21 indicates that this build generates the server side code(skeleton) and line 22 indicates that the services.xml is also generated. Notice the main target that uses the "codegen" task which will use the org.apache.axis2.tool.ant.AntCodegenTask class and run the code generation tool internally while passing the relevant arguments and do the proper generation. If a user types >ant or >ant main it will generate the server side code and services.xml for the given WSDL file

32

(C:\test\wsdl\CombinedService.wsdl -in the above instance) and the generated code will be written to the specified output path (C:\output - in the above instance). For this Ant task to work the following jars need to be in the class path. •

axis2-*.jar (from the Axis2 distribution)

wsdl4j-1.6.2.jar or higher (The WSDL4J implementation jar. Bundled with the Axis2 distribution) •

stax-api-1.0.1.jar (The StAX API's that contain the javax.xml.namespace.QName class. This jar may be replaced by any other jar that contains the javax.xml.namespace.QName implementation. However Axis2 uses this class from the stax-api-1.0.1.jar which comes bundled with the Axis2 distribution) •

commons-logging-1.1.jar, neethi-2.0.jar and XmlSchema-1.2.jar (from the Axis2 distribution) • •

axiom-api-1.2.1.jar and axiom-impl-1.2.1.jar (from the Axis2 distribution)



activation-1.1.jar (from the Axis2 distribution)



wstx-asl-3.1.0.jar (from the Axis2 distribution)

Invoking the Code Generator From Ant Since the users may find altering their ant class path a bit daunting they can also follow an easier technique. The code generator main class can be invoked directly through the build file. Below is an example of a full build.xml needed to run WSDL2Java and generate the Java source files, compile the sources, and build an AAR file ready for deployment (These are done one by one, by calling the targets in the build file separately): <project name="wsdl2java-example" default="usage" basedir="."> <property name="project-name" value="wsdl2java-example"/> <property file="build.properties"/> <property name="build" value="build"/> <property name="src" value="src"/> <property name="build.classes" value="build/classes" /> <path id="axis.classpath"> <pathelement location="build/classes" /> <pathelement location="${build.classes}" /> <path id="axis_client.classpath"> <pathelement location="build/classes" /> <pathelement location="${build.classes}" />

33

<echo message=" " /> <echo message="${project-name} " /> <echo message="-------------------------------------------------" /> <echo message=" " /> <echo message="Available Targets:" /> <echo message=" " /> <echo message=" Compiling:" /> <echo message=" compile - Compiles the WSDL2Java source code" /> <echo message=" " /> <echo message=" Compiling client:" /> <echo message=" compile_client - Compiles the client source code" /> <echo message=" " /> <echo message=" Cleaning up:" /> <echo message=" clean - Delete class files" /> <echo message=" " /> <echo message=" WSDL:" /> <echo message=" wsdl2java - Generate source from WSDL" /> <echo message=" " /> <echo message=" AAR:" /> <echo message=" aar - Generate an .aar for deployment into WEBINF/services" /> <echo message=" " /> <echo message=" Executing:" /> <echo message=" runLogin - Execute the runLogin client" /> <mkdir dir="${build.classes}" /> <delete dir="${build}" /> <delete dir="${dist}" /> <echo message="Compiling wsdl2 files"/> <javac srcdir="output" destdir="${build.classes}" deprecation="true" failonerror="true" debug="true">

34

<delete dir="output" /> <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true"> <arg value="-d"/> <arg value="xmlbeans"/> <arg value="-uri"/> <arg file="wsdl/LoginEndpoint.wsdl"/> <arg value="-ss"/> <arg value="-g"/> <arg value="-sd"/> <arg value="-o"/> <arg file="output"/> <arg value="-p"/> <arg value="org.example.types"/> <move todir="${build.classes}"> <jar jarfile="lib/axis2_example_wsdl.jar" > <delete dir="${build.classes}/META-INF" /> <mkdir dir="${build.classes}/META-INF" /> <jar jarfile="dist/LoginEndpoint.aar" > <echo message="Compiling client files"/> <javac srcdir="src" destdir="${build.classes}" deprecation="true" failonerror="true" debug="true">

35

<java classname="org.client.LoginClient" >

Place the above build.xml file in the 'bin' directory of the axis2 binary distribution. Then create a build.properties file in the same directory and specify the axis.home path pointing to the axis2 binary distribution E.g. :- axis.home=C://Axis2//axis2-1.1-bin The above build.xml example also assumes three empty directories exist, 'dist', 'lib', and 'src'. Below is a validated WSDL Document following the Document/Literal Style. The name of this file matches the name used in the WSDL2Java ant task above, LoginEndpoint.wsdl. <definitions name="LoginService" targetNamespace="http://login" xmlns:tns="http://login" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://login/types"> <schema targetNamespace="http://login/types" xmlns:tns="http://login/types" xmlns:soap11enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="returnWebLoginElement"> <sequence> <element ref="tns:soap_session_idElement"/> <element ref="tns:web_user_nameElement"/> <element name="webLoginElement"> <sequence> <element ref="tns:user_nameElement"/> <element ref="tns:user_passwordElement"/> <element name="user_nameElement" type="xsd:string"/> <element name="user_passwordElement" type="xsd:string"/> <element name="soap_session_idElement" type="xsd:string"/> <element name="web_user_nameElement" type="xsd:string"/> <message name="LoginEndpoint_webLogin"> <part name="parameters" element="ns2:webLoginElement"/> <message name="LoginEndpoint_webLoginResponse"> <part name="result" element="ns2:returnWebLoginElement"/>

36

<portType name="LoginEndpoint"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <soap:operation soapAction="webLogin"/> <soap:body use="literal"/> <soap:body use="literal"/> <service name="LoginService"> <port name="LoginEndpointPort" binding="tns:LoginEndpointBinding"> <soap:address location="http://localhost:8080/axis2/services/LoginService"/> Place the above file, named LoginEndpoint.wsdl, in the directory 'wsdl' which is also inside the 'bin' directory. Run the wsdl2java command via the ant task defined above (>ant wsdl2java), and there will be a directory called 'output' created. This directory contains the WSDL2Java generated source. An important detail is that an XMLBean class file is also generated by WSDL2Java, TypeSystemHolder.class. That file is placed into build/classes by the above ant task and will be needed to compile the generated sources. A frequent problem is users get an error such as: ClassNotFoundException : Cannot load SchemaTypeSystem. Unable to load class with name schemaorg_apache_xmlbeans.system.s68C41DB812F52C975439BA10FE4FEE54.TypeS ystemHolder. Make sure the generated binary files are on the classpath. The TypeSystemHolder.class generated by WSDL2Java must be placed in your classpath in order to avoid this error. The next step is to modify the generated Skeleton Java Source file - the Web service. This file as generated returns null and needs to be updated to contain the business logic. After the WSDL2Java command runs the file LoginEndpoint.wsdl, edit the following file: output/src/org/example/types/LoginServiceSkeleton.java. You should see the following code: /** * LoginServiceSkeleton.java * This file was auto-generated from WSDL */ package org.example.types;

37

/** * LoginServiceSkeleton java skeleton for the axisService */ public class LoginServiceSkeleton { /** * Auto generated method signature * @param param0 */ public login.types.ReturnWebLoginElementDocument webLogin (login.types.WebLoginElementDocument param0 ) { //Todo fill this with the necessary business logic throw new java.lang.UnsupportedOperationException(); } } Replace the contents of this file with the following, which uses the complex types generated by WSDL2Java and the example wsdl file: /** * LoginServiceSkeleton.java * This file was auto-generated from WSDL * by the Apache Axis2 version: 1.0-RC4 Apr 28, 2006 (05:23:23 IST) */ package org.example.types; import login.types.ReturnWebLoginElementDocument; import login.types.ReturnWebLoginElementDocument.*; import login.types.WebLoginElementDocument; import login.types.WebLoginElementDocument.*; /** * Auto generated java skeleton by the Axis code generator */ public class LoginServiceSkeleton { /** * Auto generated method signature * @param webLoginElementDocument changed from param0 */ public ReturnWebLoginElementDocument webLogin(WebLoginElementDocument webLoginElementDocument){ //Todo fill this with the necessary business logic System.out.println("LoginServiceSkeleton.webLogin reached successfully!"); // Get parameters passed in WebLoginElement webLoginElement = webLoginElementDocument.getWebLoginElement(); String userName = webLoginElement.getUserNameElement(); String password = webLoginElement.getUserPasswordElement(); System.out.println("LoginServiceSkeleton.webLogin userName: " + userName); System.out.println("LoginServiceSkeleton.webLogin password: " + password); // input paramaters would be used here // prepare output ReturnWebLoginElementDocument retDoc = ReturnWebLoginElementDocument.Factory.newInstance(); ReturnWebLoginElement retElement = ReturnWebLoginElement.Factory.newInstance();

38

retElement.setWebUserNameElement("joe sixpack"); retElement.setSoapSessionIdElement("some_random_string"); System.out.println("validate retElement: " + retElement.validate()); retDoc.setReturnWebLoginElement(retElement); System.out.println("validate retDoc: " + retDoc.validate()); System.out.println("LoginServiceSkeleton.webLogin returning..."); return retDoc; }

}

The next steps assume the axis2.war has been deployed and has expanded in a servlet container. Run the 'jar_wsdl' ant task from the example build.xml (>ant jar_wsdl), which generates a jar file axis2_example_wsdl.jar in the 'bin/lib' directory. This jar will be used to compile the client, and also will be placed in the servlet container. Next, run the 'aar' ant task from the example build.xml (>ant aar), which generates the deployable axis2 Web service. Place dist/LoginEndpoint.aar into axis2/WEB-INF/services . Place lib/axis2_example_wsdl.jar into axis2/WEB-INF/lib . Verify the happy axis page loaded the services correctly - there should be the service 'LoginEndpoint' with the available operation 'webLogin' displayed. The last step is to create and run the client. In the src directory create the file org.client.LoginClient.java, with the contents below: package org.client; import import import import import import

org.apache.axis2.AxisFault; login.types.ReturnWebLoginElementDocument; login.types.ReturnWebLoginElementDocument.*; login.types.WebLoginElementDocument; login.types.WebLoginElementDocument.*; org.example.types.LoginServiceStub;

//Login. public class LoginClient { public static void main(String[] args) { try { System.out.println("webLogin, firing..."); LoginServiceStub stub = new LoginServiceStub(); WebLoginElementDocument webLoginElementDocument = WebLoginElementDocument.Factory.newInstance(); WebLoginElement webLoginElement = WebLoginElement.Factory.newInstance(); webLoginElement.setUserNameElement("joe"); webLoginElement.setUserPasswordElement("sixpack"); webLoginElementDocument.setWebLoginElement(webLoginElement); System.out.println("validate: " + webLoginElement.validate()); stub.webLogin(webLoginElementDocument); ReturnWebLoginElementDocument returnWebLoginElementDocument = stub.webLogin(webLoginElementDocument); System.out.println("Client returned");

39

ReturnWebLoginElementDocument.ReturnWebLoginElement retElement = returnWebLoginElementDocument.getReturnWebLoginElement(); System.out.println("WebUserName: " + retElement.getWebUserNameElement()); System.out.println("SOAPSessionId: " + retElement.getSoapSessionIdElement()); System.out.println("webLogin, completed!!!");

}

} catch (AxisFault axisFault) { axisFault.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); }

} Now run the ant task 'runLogin' (>ant runLogin). The following output should appear: runLogin: [echo] [java] [java] [java] [java] [java] [java]

running the webLogin client webLogin, firing... validate: true Client returned WebUserName: joe sixpack SOAPSessionId: some_random_string webLogin, completed!!!

Appendix •

Eclipse reference - http://www.eclipse.org/



Custom Ant Tasks - http://ant.apache.org/manual/develop.html

Service Archive Generator Wizard Guide for Eclipse Plug-in This document will guide you through the installation and usage of the archive generator Eclipse plug-in. Download Plugin Tool: ●

http://ws.apache.org/axis2/tools/index.html

Content •

Introduction



Installation



Operation

Introduction As part of the Axis2 tool set, the service archive generator is an important tool that allows the generation of service archives ("aar" file or a "jar" files) that can be deployed as a web services to the Axis2.

40

Installation One can easily download (http://ws.apache.org/axis2/tools/index.html) the plugin. If one needs to build the plug-in from source, Maven2 and Ant builds arevailabe. Please refer the readme.txt located at module/tools on Axis2 source. Once you've obtained the plug-in just unzip the content of the plug-in archive to the Eclipse plug-in directory (if it is the zipped-binary version) or copy the necessary folders to the Eclipse plug-in directory and restart Eclipse. NOTE : This plug-in works on Eclipse version 3.1 and upwards, also the java version should be 1.4 or higher. The provided screen shots may slightly differ with what the user would actually see but the functionality has not been changed.

Operation If the plug-in is properly installed you should see a new wizard under the "New" section. (Use the File -> New -> Other or Ctrl + N )

Selecting the wizard and pressing the "Next" button will start the service generator wizard. Following is the first page of the wizard. Page 1:

41

Once the class file folder (which should be a folder in the file system) is browsed and selected, the "Next" button will be enabled and you can move to the next page. Note that you have the option of either including all the files or the class files only of the folder on page 1. Page 2: Page 2 of the wizard as seen below requires you to locate/browse the WSDL file. If you do not wish to add a WSDL file to the service archive, select skip WSDL, else you can select the location of the WSDL file by selecting the select WSDL option.

42

Page 3: Select the services.xml file on this wizard page by browsing or select the option of generating service xml automatically, after which you can click "Next" button to go to the next page. Notice how the browsing option disables when the "Generate service xml automatically" check box is ticked.

Page 4: The next step is to add the libraries. The library addition page looks like this:

43

The library name (with full path) can be either typed on the text box or browsed for using the "Browse" button.

Once there is a library name with full path on the text box, hit the "Add" button to add the library to the list. Added libraries should be displayed in the "Added libraries" list box. This way you can add as many external libraries as you wish. See the screen shots below.

44

If any added library needs to be removed, highlight it or in other words, select it from the "Added libraries" list and hit on the "Remove" button as shown below. Click on the "Next" button to proceed to the last page of the wizard if the user did not select to auto generate the services.xml file. If user select to auto generate the services.xml file then the services.xml option page will be displayed.

Page 5: This page only appears if the user select to generate the services.xml at page 3 of the wizard. If the user have selected a services.xml then the user will be directed to the last page of the wizard. After entering the correct service name and valid fully qualified class name, try to load the

45

existing methods of that class by clicking the load button.

If successfully loaded the user will be presented with a table at the bottom of the page with the details of the loaded class. By checking and unchecking the user can select the necessary methods to include in the services.xml

By clicking on the search declared method only check box, the user can remove the inherited methods from the class. Click on the "Next" button to proceed to the last page of the wizard

46

Page 6: The last page of the wizard asks for the output file location and the output archive file name. To be able to finish the wizard, user must enter valid output file location and output file name.

Once all the parameters are filled, hit the "Finish" button to complete the wizard and generate the service archive.

47

If you see the above message, then you've successfully generated the service archive! This service archive can be hot deployed (deployed at run time) to the axis2

Appendix •

Eclipse reference - http://www.eclipse.org/



Custom Ant Tasks - http://ant.apache.org/manual/develop.html

48

Code Generator Wizard Guide for Eclipse Plug-in This document explains the usage of this code generator plug-in for Eclipse. In other words, this document will guide you through the operations of generating a WSDL file from a Java class and/or generating a Java class file from a WSDL file.Download Plugin Tool: ●

http://ws.apache.org/axis2/tools/index.html

Content •

Introduction



Installation



Operation - WSDL2Java



Operation - Java2WSDL

Introduction The Axis2 code generator comes built-in with an Eclipse plug-in. This plug-in can be used to generate a WSDL file from a java class (Java2WSDL) and/or a java class file from a WSDL (WSDL2Java). First you need to install the plug-in. The instructions for the installation process are given below.

Installation One can easily download the plugin If one needs to build the plug-in from source, Maven2 and Ant builds arevailabe. Please refer the readme.txt located at module/tools on Axis2 source. Once you've obtained the plug-in just unzip the content of the plug-in archive to the Eclipse plug-in directory (if it is the zipped-binary version) or copy the necessary folders to the Eclipse plug-in directory and restart Eclipse. NOTE : This plug-in works on Eclipse version 3.1 and upwards, also the java version should be 1.4 or higher. The provided screen shots may slightly differ with what the user would actually see but the functionality has not been changed.

Operation - WSDL2Java If the plug-in is properly installed you should see a new wizard under the "New" section.(use the File -> New -> Other or Ctrl + N )

49

Selecting the wizard and pressing the "Next" button will start the code generator wizard. Following is the first wizard page. Page 1:

50

Selecting the "Generate Java source code from WSDL file" option and clicking "Next" leads to the following page. WSDL2Java Page 2 :

To move on to the next page the WSDL file location must be given. The "Browse" button can be used to easily browse for a file rather than typing the whole path. WSDL2Java Page 3 : Once the WSDL file is selected, the next page will take you to the page from where codegen options are to be selected. By far this is the most important page in this wizard. This page determines the characteristics of the code being generated. Novices need not worry about these options since the most common options are defaulted, but advanced users will find it very easy to turn the knobs using these options.

51

What advanced users can do is select custom from the select codegen options drop down list and then change/edit the fields that you need.

52

Once the options are selected, only the final step of the code generation is left which is the selection of the output file location. WSDL2Java Page 4 : Here you can select the output file path by typing or browsing using the "Browse" button. You have the option of browsing only eclipse workspace projects by selecting the "Add the source to a project on current eclipse workspace" radio button. Or else you have the option to save the codegen resutls to file system

53

Here also you have the option to add some value to the codegen results. If you have enabled the check box "Add Axis2 libraries to the codegen result project" then all other controls below will get enabled. What you can do is point the downloaded Axis2_HOME location via the "Browse" button. Then you can verify the availability of the Axis2 libs by clicking on the "Check Libs" button. If all goes well then you can add the axis 2 libs to the codegen results location. Another option is available to generate a jar file if the user needs to add the codegen results to a project as a compiled jar file to the selected locations lib directory.

54

When the output file location is selected, the "Finish" button will be enabled. Clicking the "Finish" button will generate the code and a message box will pop up acknowledging the success. Well Done! You've successfully completed Axis2 code generation.

Operation - Java2WSDL Page 1: For this operation you need to select the option which says "Generate a WSDL from a Java source file"

55

Then click the "Next" button which will lead to the next page below. Java2WSDL Page 2:

56

In this page one needs to select the class to be exposed and the relevant jar files /classes to be loaded as the classpath. After the libraries have been set, the "Test Class Loading" button must be clicked in order to test whether the class is loadable. Unless the class loading is successful proceeding to the "Next" button will not be enabled. Once the classloading is successful and "Next" button is clicked the page below will appear. Java2WSDL Page 3: This page allows the parameters to be modified by setting the options for the generator.

Java2WSDL Page 4: Here you can select the output file path by typing or browsing using the "Browse" button. You have the option of browsing only Eclipse workspace projects by selecting the "Add the source to a project on current eclipse workspace" radio button . Or else you have the option to save the codegen resutls to file system. Once the output file location and the output WSDL file name is added you can click the "Finish" button to complete generation.

57

If a message box pops up acknowledging the success, then you've successfully completed the Java2WSDL code generation.

Appendix •

Eclipse reference - http://www.eclipse.org/



Custom Ant Tasks - http://ant.apache.org/manual/develop.html

58

Maven2 AAR Plug-in Guide Introduction This plugin generates an Axis 2 service file (AAR file). Download Plugin Tool: ●

http://ws.apache.org/axis2/tools/index.html

Goals The AAR plugin allows the packaging of an Axis 2 service aar in 3 different modes: 1. aar (default): generates the aar artifact 2. inplace : package the aar in the source tree 3. exploded : package an exploded aar application Each mode is materialized by a goal. For instance, to generate an exploded aar from the current project, one would type mvn aar:exploded

Configuration All AAR plugin goals takes the following configuration parameters as input: Parameter Name

Default Value

Description

aarDirectory

${project.build.directory}/aar

Directory where the aar file is built

classesDirectory ${project.build.outputDirectory}

Directory with compiled classes and resources

fileSets

Additional file sets, which are being added to the archive. See "File Sets" below for an example

servicesXmlFile

Location of the services.xml file. By default, it is assumed that the file is already present in classesDirectory/META-INF and no special processing is required

wsdlFile

Location of the WSDL file. By default, it is assumed that the file is already present in classesDirectory/META-INF and no special processing is required

wsdlFileName

Name, to which the WSDL file should be mapped

service.wsdl

The aar Goal The aar goal allows the following additional parameters: Parameter Name

Default Value

Description

outputDirectory ${project.build.directory} Directory where to generate the AAR file aarName

${project.build.finalName} The generated AAR files name

59

archive

A Maven archive configuration. This allows, for example, to configure the MANIFEST.MF file

classifier

A classifier, which should be added to the generated AAR files name. Setting this parameter has the side effect, that the artifact is treated as an attachment and not as the projects primary artifact

primaryArtifact true

Setting this property to false disables installation or deployment of the artifact as the projects primary artifact

File Sets Additional file sets may be configured for inclusion into the AAR file. A file set looks as follows: src/aar/files META-INF/docs **/*.html src/aar/files META-INF/etc <excludes> <exclude>**/*.html The example specifies, that the contents of the directory src/aar/files shall be added to the AAR file. HTML files will go into META-INF/docs, all other files to META-INF/etc. A file set is configured through the following configuration parameters: Parameter Name

Description

directory

The directory, from which to read the file set. This parameter is required

outputDirectory

The target directory within the AAR file. Defaults to the AAR files root directory

includes

Configures the set of files, which shall be included into the AAR file. Defaults to **/*

excludes

Configures a set of files, which shall be excluded from the file set. Defaults to the Maven default excludes (**/*~, **/cvs/**/*, **/.svn/**/*, etc.)

skipDefaultExcludes If this parameter is set to true, then no default excludes are being used

Maven2 Java2WSDL Plug-in Guide Introduction This plugin takes as input a Java class and generates a WSDL, which describes a Web service for invoking the classes methods. Download Plugin Tool:

60



http://ws.apache.org/axis2/tools/index.html

Goals The Java2WSDL plugin offers a single goal: java2wsdl (default): Reads a java class and generates a WSDL for invoking the classes methods as a Web service. •

To run the plugin, add the following section to your POM (Project Object Model): org.apache.axis2.maven2 <artifactId>axis2-java2wsdl-maven-plugin com.foo.myservice.MyHandler <executions> <execution> java2wsdl The plugin will be invoked automatically in the generate-resources phase. You can also invoke it directly from the command line by running the command: mvn java2wsdl:java2wsdl

The Java2WSDL Goal By default, the plugin reads the given Java class and creates a file target/generatedresources/java2wsdl/service.xml. The Java class is given by the configuration element className above.

Configuration The Java2WSDL goal takes the following parameters as input. All parameters can be set from the command line by using properties. For example, the parameter "className" may be set using the property "axis2.java2wsdl.className". If the parameter isn't set via property or in the POM, then a default value applies. Parameter name Command line property

Description

className

${axis2.java2wsdl.className}

Fully qualified name of the class, which is being read and transformed into a WSDL

outputFileName

${axis2.java2wsdl.outputFileName Path of the generated } service file.

schemaTargetName ${axis2.java2wsdl.schemaTargetN Target namespace of the space amespace} generated schema.

61

Default value

Prefix, which is being schemaTargetName ${axis2.java2wsdl.schemaTargetN associated with the spacePrefix amespacePrefix} schemas target namespace. Unqualifie d name Name of the generated Web of the service. input class.

serviceName

${axis2.java2wsdl.serviceName}

targetNamespace

${axis2.java2wsdl.targetNamespa Target namespace of the ce} generated WSDL

Default namespac e

Prefix, which is being targetNamespacePr ${axis2.java2wsdl.targetNamespa associated with the target efix cePrefix} namespace

Maven2 WSDL2Code Plug-in Guide Introduction This plugin takes as input a WSDL and generates client and server stubs for calling or implementing a Web service matching the WSDL.Download Plugin Tool: ●

http://ws.apache.org/axis2/tools/index.html

Goals The WSDl2Code offers a single goal: •

wsdl2code (default): Reads the WSDL and generates code.

To run the plugin, add the following section to your POM (Project Object Model): org.apache.axis2.maven2 <artifactId>axis2-wsdl2code-maven-plugin <executions> <execution> wsdl2code <packageName>com.foo.myservice The plugin will be invoked automatically in the generate-sources phase. You can also invoke it directly from the command line by running the command mvn wsdl2code:wsdl2code

62

The WSDL2Code Goal By default, the plugin reads the file src/main/axis2/service.wsdl. Sources for the Java programming language and the ADB data binding are generated into target/generatedsources/axis2/wsdl2code. Note the configuration element packageName above, which sets the package name, thus a subdirectory.

Configuration The WSDL2Code goal takes the following parameters as input. All parameters can be set from the command line by using properties. For example, the parameter "generateServerSide" may be set using the property "axis2.wsdl2code.generateServerSide". If the parameter isn't set via property or in the POM, then a default value applies. Parameter Name

Command Line Property

Description

Default Value

databindingName

Data binding framework, which is ${axis2.wsdl2code.data being used by the generated adb bindingName} sources.

generateAllClasses

Whether to generate simply all ${axis2.wsdl2code.gene classes. This is only valid in rateAllClasses} conjunction with "generateServerSide".

false

generateServerSide

${axis2.wsdl2code.gene Whether server side sources are rateServerSide} being generated.

false

${axis2.wsdl2code.gene generateServerSideInte Whether to generate the server rateServerSideInterface rface side interface. }

false

generateServicesXml

${axis2.wsdl2code.gene Whether a "services.xml" file is rateServicesXml} being generated.

false

generateTestcase

${axis2.wsdl2code.gene Whether a test case is being rateTestCase} generated.

false

language

${axis2.wsdl2code.lang Programming language of the uage} generated sources.

java

namespaceToPackages

Map of namespace URI to packages in the format uri1=package1,uri2=package2,... Using this parameter is ${axis2.wsdl2code.nam discouraged. In general, you espaceToPackages} should use the namespaceUris parameter. However, the latter cannot be set on the command line. Map of namespace URI to packages. Example: uri1 <package>package1 ........

namespaceURIs

outputDirectory

Target directory, where sources ${axis2.wsdl2code.targe are being target/generatedt} sources/axis2/wsdl2code

63

generated. packageName

${axis2.wsdl2code.pack Package name of the generated age} sources.

portName

Port name, for which sources are ${axis2.wsdl2code.port being generated. By default, Name} sources are generated for all ports.

serviceName

Service name, for which sources ${axis2.wsdl2code.servi are being generated. By default, ceName} sources are generated for all services.

syncMode

Sync mode, for which sources are ${axis2.wsdl2code.sync being generated; either of "sync", both Mode} "async", or "both" (default).

unpackClasses

${axis2.wsdl2code.unpa Whether to unpack classes. ckClasses}

wsdlFile

${axis2.wsdl2code.wsdl Location of the WSDL file, which } is read as input

src/main /axis2/s ervice.w sdl

Migrating from Apache Axis 1.x to Axis2 For all those users who are familiar with Axis 1.x series will be assisted through this document to switch to Axis2 series. We begin by listing the improvements in Axis2 in comparison with Axis1. This is followed by guidelines for the migration. Send your feedback or questions to: [email protected]. (Subscription details are available on the Axis2 site.) Kindly prefix subject with [Axis2].

Content •

Compatibility



Getting Started



Custom Deployment of Services, Handlers and Modules



Transports for HTTP Connection



Data Binding Support



Best Usage

Compatibility Axis1.x and Axis2 have evolved from different architectures. Speed - Axis2 is based on StAX API, which gives greater speed than SAX event based parsing that has been used in Axis1.x. Stability - Axis2 has fixed phases as well as user-defined phases for extensions. This allows far more stability as well as flexibility than Axis1.x. Transport framework - Simple abstraction in the designing of transports (i.e., senders and listeners for SOAP over various protocols such as SMTP, etc), allows far more flexibility and the core of the engine is completely transport-independent. WSDL support - Axis2 supports versions 1.1 and 2.0, which allow you to create stubs and

64

skeletons to manipulate the web services arena. Component - oriented architecture - The components are .mar and .aar archives . Easily reusable components such as handlers and modules allow pattern processing for your applications or distribution to partners. Axis2 is more concerned on the "Module" concept rather the "Handler" concept. Modules contain handlers that have been ordered through the phase rules. These are ordered to specific service(s).

Getting Started Let's look at a simple example of echoing at client API. Axis 1.x import org.apache.axis.client.Call; import org.apache.axis.client.Service; import javax.xml.namespace.QName; public class TestClient { public static void main(String [] args) { try { String endpoint ="http://ws.apache.org:5049/axis/services/echo"; Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress( new java.net.URL(endpoint) ); call.setOperationName(new QName("http://soapinterop.org/", echoString")); String ret = (String) call.invoke( new Object[] { "Hello!" } ); System.out.println("Sent 'Hello!', got '" + ret + "'"); } catch (Exception e) { System.err.println(e.toString()); } } } Axis 2 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.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; public class EchoBlockingClient { private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService"); public static void main(String[] args) { try { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace ns = fac.createOMNamespace("http://soapinterop.org/", "ns1"); OMElement payload = fac.createOMElement("echoString", ns); payload.setText("Hello!"); Options options = new Options(); ServiceClient client = new ServiceClient(); options.setTo(targetEPR); //Blocking invocation OMElement result = client.sendReceive(payload); } catch (AxisFault axisFault) { axisFault.printStackTrace(); } } }

65

It has been clearly depicted that the invocation in Axis2 is dealt with the SOAP body element itself. Here the invocation is synchronous, but Axis2 can handle asynchronous invocations as well. The "payload" variable above contains the SOAP body element which should go in the SOAP envelope. Once the service is called through the stub in Axis2, the "payload" will be according to the data binding framework that will be used. So the extra work of "payload" will vanish. Apart from synchronous invocation, Axis2 also supports asynchronous invocation through sendReceiveNonblocking(). Synchronous/Asynchronous invocations can handle both single and double HTTP connections. With this advanced architecture, Axis2 is capable of handling megabytes of requests and responses, which is far from the capabilities of Axis1.x.

Custom Deployment of Services, Handlers, and Modules In Axis 1.x, the deployment of services was via WSDD, which in my opinion was highly cumbersome. Service deployment in Axis2 is straight forward and dynamic. Dynamic behavior is from the "Administrator" facility given by the development in the server side. It's just a matter of creating the .aar file and deploying it. More details regarding this is given in the Axis2 user guide. Axis2 has moved away from the "Handler concept" and is more into the "Module concept". Abstractly speaking, the module concept is a collection of handlers with rules that govern which modules are created as .mar files. It has module.xml, which is the brain behind manipulating the handlers. When a service is called through a handler, it is just a matter of giving a reference to the module that includes the handler in the services.xml (using <module ref="foo/>"). Services are hot deployable in Axis2, but modules are not. This is one feature which is unique to Axis2. Let's take a detailed look at what it takes to migrate the Axis 1.x handlers to the Axis 2 modules via the "SOAP Monitor". The SOAP monitor is really a combination of three components: An applet which displays responses/requests, a servlet which binds to a default port of 5001 and connects to the applet, and a handler chain used to intercept the SOAP messages. Here we'll focus on the handler. Axis 1.x required two WSDD's to use the SOAP Monitor. First, the SOAP Monitor Handler itself: <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <parameter name="wsdlURL" value="/wzs/SOAPMonitorService-impl.wsdl"/> <parameter name="namespace" value="http://tempuri.org/wsdl/2001/12/SOAPMonitorService-impl.wsdl"/> <parameter name="serviceName" value="SOAPMonitorService"/> <parameter name="portName" value="Demo"/> <service name="SOAPMonitorService" provider="java:RPC"> <parameter name="allowedMethods" value="publishMessage"/> <parameter name="className" value="org.apache.axis.monitor.SOAPMonitorService"/> <parameter name="scope" value="Application"/>

66

Axis 1.x requires a reference to the handler in the user's WSDD that defines their Web Service: <deployment name="example" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="urn:myService" provider="java:RPC"> <parameter name="className" value="org.MyService"/> <parameter name="allowedMethods" value="*"/> <requestFlow> Axis 2 requires a module.xml, placed inside a jar with a .mar extension under WEB-INF/modules, to define a Handler: <module name="soapmonitor" class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorModule"> The SOAPMonitorModule referenced above simply implements the org.apache.axis2.modules.Module, and is used for any additional tasks needed to initialize the module and shutdown the module. In this situation, nothing is needed and the implemented interface methods have blank bodies. Furthermore, the 'soapmonitorPhase' will be used later (below) in the axis2.xml .

67

Axis 1.x the SOAPMonitorHandler has the class signature as: ●

public class SOAPMonitorHandler extends BasicHandler

Axis 2 the SOAPMonitorHandler has the class signature as: ●

public class SOAPMonitorHandler extends AbstractHandler

In Axis2, you need to reference the module that contains the handler chain that you want to use inside your services.xml: <service name="ExampleService"> <module ref="soapmonitor"/> <description> This service has the SOAP Monitor wired in <parameter name="ServiceClass" locked="false">org.ExampleService <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> Finally, Axis2 requires you to make some changes to axis2.xml. Start by adding a global module: ●

<module ref="soapmonitor"/>

Then define your phase orders for the 'soapmonitorPhase' referenced in the module.xml:

68



-->

-->

See the user guide for more information on Axis2 modules.

Transports for HTTP Connection Axis2 comes with the CommonsHTTPTransportSender which is based on commonshttpclient. It should be noted that axis2.xml should be configured to call the commons transports with the statement, ... <parameter name="PROTOCOL" locked="false">HTTP/1.1 <parameter name="Transfer-Encoding" locked="false">chunked ...

Data Binding Support ADB is used to provide data binding support. In Axis2, XML is manipulated via AXIOM, which is based on the StAX API. XML gives full schema support. Thus, serialization and deserialization of XML is handled in Axis2 via the xml-data binding framework.

69

Below is an example of migrating an WSDL based Axis 1.x Web Service to Axis2. First, let's take a look at a simple document/literal style WSDL used in an Axis 1.x Web Service. This example assumes the name simple.wsdl for the WSDL below: <definitions name="SimpleService" targetNamespace="http://simpleNS" xmlns:tns="http://simpleNS" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://simpleNS/types"> <schema targetNamespace="http://simpleNS/types" xmlns:tns="http://simpleNS/types" xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="simpleLogin"> <sequence> <element name="user_name" type="xsd:string"/> <element name="user_password" type="xsd:string"/> <element name="simpleLoginResponse"> <sequence> <element name="soap_session_id" type="xsd:string"/> <element name="web_user_name" type="xsd:string"/> <message name="SimpleEndpoint_simpleLogin"> <part name="parameters" element="ns2:simpleLogin"/> <message name="SimpleEndpoint_simpleLoginResponse"> <part name="result" element="ns2:simpleLoginResponse"/> <portType name="SimpleEndpoint">

70

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <soap:operation soapAction="simpleLogin"/> <soap:body use="literal"/> <soap:body use="literal"/> <service name="SimpleService"> <port name="SimpleEndpointPort" binding="tns:SimpleEndpointBinding"> <soap:address location="http://localhost:8080/axis/services/SimpleEndpointPort"/> The next step is to run WSDL2Java on the wsdl. For axis 1.x, this example uses the following Ant task: <delete dir="output" /> <mkdir dir="output" /> The Axis 1.x Ant task above takes the simple.wsdl under the directory 'wsdl' , and from that creates files under the directory 'output'. The files created are shown below: output/ output/simpleNS output/simpleNS/types output/simpleNS/types/SimpleLoginResponse.java output/simpleNS/types/SimpleLogin.java output/simpleNS/SimpleEndpoint.java output/simpleNS/SimpleEndpointBindingStub.java output/simpleNS/SimpleEndpointBindingSkeleton.java output/simpleNS/SimpleEndpointBindingImpl.java output/simpleNS/SimpleService.java output/simpleNS/SimpleServiceLocator.java output/simpleNS/deploy.wsdd output/simpleNS/undeploy.wsdd Now let's run WSDL2Java with Axis2. In this example, the only change to simple.wsdl required for Axis2 is that 'soap:address location' be changed to:

71

<soap:address location="http://localhost:8080/axis2/services/SimpleEndpoint"/> In Axis2, the default databinding uses ADB. However, XMLBeans and JaxMe are also supported. This example uses XMLBeans. For Axis2, our example uses the following Ant task: <delete dir="output" /> <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true"> <arg value="-d"/> <arg value="xmlbeans"/> <arg value="-uri"/> <arg file="wsdl/simple.wsdl"/> <arg value="-ss"/> <arg value="-g"/> <arg value="-sd"/> <arg value="-o"/> <arg file="output"/> <arg value="-p"/> <arg value="org.simple.endpoint"/> <move todir="${build.classes}"> For an explanation of the Axis2 WSDL2Java Ant task and its options, see the CodegenToolReference Guide. A feature of XMLBeans is that there is one class file created with WSDL2java, and a series of .xsb files. They must be referenced when compiling, and as the example shows, these files are moved to a build directory. The Axis2 WSDL2Java example also takes the simple.wsdl, which is under the directory 'wsdl', and creates files under the directory 'output'. The relevant non-xmlbean files created are shown below:

72

output/resources/services.xml output/src/org/simple output/src/org/simple/endpoint output/src/org/simple/endpoint/SimpleEndpointSkeleton.java output/src/org/simple/endpoint/SimpleEndpointMessageReceiverInOut.java output/src/org/simple/endpoint/SimpleEndpointCallbackHandler.java output/src/org/simple/endpoint/SimpleEndpointStub.java output/src/simplens output/src/simplens/types output/src/simplens/types/SimpleLoginDocument.java output/src/simplens/types/impl output/src/simplens/types/impl/SimpleLoginDocumentImpl.java output/src/simplens/types/impl/SimpleLoginResponseDocumentImpl.java output/src/simplens/types/SimpleLoginResponseDocument.java The first important distinction is that while the Axis 1.x example generated deploy.wsdd and undeploy.wsdd, the Axis2 example created a services.xml. The files deploy.wsdd and services.xml are a breed apart, coming from different architectures. There is no direct parallel between them. See the Axis2 user guide for an explanation about services.xml Now we're ready to code. We'll start with Axis 1.x on the service side. To implement the business logic, we'll change simpleNS/SimpleEndpointBindingImpl.java from: package simpleNS; public class SimpleEndpointBindingImpl implements simpleNS.SimpleEndpoint{ public simpleNS.types.SimpleLoginResponse simpleLogin(simpleNS.types.SimpleLogin parameters) throws java.rmi.RemoteException { return null; } } To: package simpleNS; public class SimpleEndpointBindingImpl implements simpleNS.SimpleEndpoint{ public simpleNS.types.SimpleLoginResponse simpleLogin(simpleNS.types.SimpleLogin parameters) throws java.rmi.RemoteException { String userName = parameters.getUser_name(); String password = parameters.getUser_password(); // do something with those vars... return new simpleNS.types.SimpleLoginResponse("mySessionID", "username"); } } In Axis 1.x, the next step is to compile the classes and put them in the Axis.war, and then run the admin client with the generated deploy.wsdd. You then look at the happy axis page to verify that the service has been installed correctly. Now let's code Axis2. In Axis 1.x, while the Ant task shown in the example created a skeleton, a peek inside shows that the skeleton calls the binding implementation class. In

73

Axis2, we work with the skeleton directly. To implement the business logic in the generated Axis2 classes, we'll change org/simple/endpoint/SimpleEndpointSkeleton.java from: package org.simple.endpoint; /** * SimpleEndpointSkeleton java skeleton for the axisService */ public class SimpleEndpointSkeleton { /** * Auto generated method signature * @param param0 */ public simplens.types.SimpleLoginResponseDocument simpleLogin(simplens.types.SimpleLoginDocument param0 ) throws Exception { //Todo fill this with the necessary business logic throw new java.lang.UnsupportedOperationException(); } } To: package org.simple.endpoint; import simplens.types.*; import simplens.types.SimpleLoginResponseDocument.*; import simplens.types.SimpleLoginDocument.*; /** * SimpleEndpointSkeleton java skeleton for the axisService */ public class SimpleEndpointSkeleton { /** * Modified * @param simpleLoginDocument */ public SimpleLoginResponseDocument simpleLogin(simplens.types.SimpleLoginDocument simpleLoginDocument){ //Todo fill this with the necessary business logic SimpleLoginResponseDocument retDoc = SimpleLoginResponseDocument.Factory.newInstance(); SimpleLoginResponse retElement = SimpleLoginResponse.Factory.newInstance(); // Get parameters passed in SimpleLogin simpleLogin = simpleLoginDocument.getSimpleLogin(); String userName = simpleLogin.getUserName(); String password = simpleLogin.getUserPassword(); // do something with those variables... retElement.setWebUserName(userName); retElement.setSoapSessionId("my random string"); retDoc.setSimpleLoginResponse(retElement); return retDoc; }

}

74

In Axis2, the next step is to compile the classes, put them along with the generated services.xml in an AAR, and then hot deploy the AAR by placing it in the Axis2.war under WEBINF/services. Point a browser to http://localhost:8080/axis2/listServices, and you should see the service 'SimpleService' ready for action. See the Axis2 user guide for more info. The last step is the client. Our Axis 1.x client for this example is: package org; import simpleNS.*; import simpleNS.types.*; public class Tester { public static void main(String [] args) throws Exception { // Make a service SimpleService service = new SimpleServiceLocator(); // Now use the service to get a stub which implements the SDI. SimpleEndpoint port = service.getSimpleEndpointPort(); // set the params SimpleLogin parameters = new SimpleLogin("username","password"); // Make the actual call SimpleLoginResponse simpleLoginResponse = port.simpleLogin(parameters); String session = simpleLoginResponse.getSoap_session_id(); String user = simpleLoginResponse.getWeb_user_name(); System.out.println("simpleLoginResponse, session: " + session + ", user: " + user); } } Finally, our Axis2 client for this example is: package org; import simplens.types.*; import simplens.types.SimpleLoginDocument.*; import simplens.types.SimpleLoginResponseDocument.*; import simplens.types.impl.*; import org.simple.endpoint.*; public class Tester { public static void main(String [] args) throws Exception { // you may not need to pass in the url to the constructor // try the default no arg one SimpleEndpointStub stub = new SimpleEndpointStub(null, "http://localhost:8080/axis2/services/SimpleService"); SimpleLogin simpleLogin = SimpleLogin.Factory.newInstance(); simpleLogin.setUserName("userName"); simpleLogin.setUserPassword("password"); SimpleLoginDocument simpleLoginDocument = SimpleLoginDocument.Factory.newInstance(); simpleLoginDocument.setSimpleLogin(simpleLogin);

75

SimpleLoginResponseDocument simpleLoginResponseDocument = stub.simpleLogin(simpleLoginDocument); SimpleLoginResponse simpleLoginResponse = simpleLoginResponseDocument.getSimpleLoginResponse(); String session = simpleLoginResponse.getSoapSessionId(); String user = simpleLoginResponse.getWebUserName(); System.out.println("simpleLoginResponse, session: " + session + ", user: " + user); }

}

Axis2 clients also have asynchronous options via a Callback and alternatively a 'Fire and forget'. See the user guide for more details.

Best Usage Axis1.x and Axis2 have different ways of seeing the SOAP stack. So the best way to migrate is to follow the User's Guide and the Architecture Guide of Axis2 properly. Axis2 is very straight forward and friendly to use than its predecessor.

Design Notes Axis2 RPC Support This document describes Axis2's Remote Procedure Call support in a set of easy to understand implementation steps.

Introduction Axis2 Remote Procedure Call (RPC) support may seem somewhat tricky and confusing at first glance. However, Axis2 RPC strategy is based on a set of well defined rules. This document aims to drill down to the details of the strategy and resolve most of the unknown bits and pieces. Note that Axis2 currently does not support the rpc/encoded style fully. Its main support is for the rpc/lit style. We will discuss the Axis2 RPC strategy in the following steps

Step 1 - Converting RPC Style WSDL's into Doc/Lit Style WSDL This is probably the most confusing part of the RPC strategy. Since the Axis2 code generator is based on pure doc/lit style, the first step of the code generation process is to generate a wrapper schema. This wrapper generation can be easily explained by using an example. Take the following piece of WSDL

76

..... < message name="requestMessage"> <part name="part1" type="xs:string"/> <part name="part2" type="xs:int"/> <message name="responseMessage"> <part name="part1" type="xs:string"/> <portType name="echoPortType">

<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <soap:operation soapAction="echo"/> <soap:body use="literal"/> <soap:body use="literal"/> ..... The binding says its got to be rpc/lit and in this case the message parts need wrapping in the following order. 1. The first element needs to have the operation name as the local name and the operation namespace. (This happens to be the namespace of the porttype - in this case the targetnamespace of the WSDL.) 2. The children of this element are non namespace qualified elements with the part names as local names (referred to as part element) 3. In case the part refers to a standard type like the example WSDL, the content of the part element would be of that type. If the part refers to a complex type defined in the schema, the content of the part element becomes of that type. Having an element reference in the part when the binding is rpc is invalid. For example, the input wire message for the echo operation mentioned in the above WSDL fragment would look like this: <>Hello World <>123 Note that the element name is in bold. The first one is the operation name, the second and third are part names. It can be seen that it is possible to generate a schema representing this structure, and then treat the whole service as a pure doc/lit service. In this case, the following piece of schema is generated to make the rpc to doc conversion. Note that in this case the wire message stays unchanged. It is only a different WSDL authoring style

77

<xs:element name="echo"> <xs:complexType> <xs:sequence> <xs:element name="part1" type="xs:string" /> <xs:element name="part2" type="xs:int" /> What the Axis2 code generator does is exactly this. By looking at the binding style, it generates a wrapper schema in places required before handing over the Axis* hierarchy to the code generator engine. In every case (even when the schema needs to be unwrapped) this wrapping part will take place!

Step 2 - Unwrapping the Schema If the schema needs to be unwrapped, it brings up a few issues. This is mainly because the only thing that the emitters rely on when generating code is a mapping table. 1. When the schema is unwrapped, where will the unwrapping information remain? There has to be a store to keep the information seperated. The Axis * hierarchy ca be used for this. It has nicely separated information holders and a parameter store that can hold an information bean. 2. How do we maintain uniqueness among message part names? Part names are only unique across a message and not globally. However, due to the fact that we have a global mapping table, we need a way to differentiate between parts of different messages. The technique used here is to generate a QName that has the operation name as a namespace and a suffix (like _input) appended to the local name. Given these solutions, the first step in unwrapping is to walk the schema and figure out the unwrappable items. The key player of the unwrapping process is the unwrapping extension. It walks a given schema and figure out the unwrappable parts if there are any. The current unwrapper looks for the following patterns and fails if it is not found! <element> <sequence> <element/> Once this pattern is detected, the unwrapper details will be added to the relevant AxisMessage component.

Step 3 - Populate Type Information The next step is to populate the Type information for the parts. This has to be explicitly done by the data binding extensions, and currently the ADB and XMLbeans extensions populate the relevant AxisMessage by looking up their generated type systems. This type information goes into the AxisMessage inside a MessagePartInformationHolder instance. The following code fragment from the ADB extension shows how the AxisMessages get populated with the relevant type information. The code is almost the same for the XMLBeans extension. Note the items in bold.

78

if (message.getParameter(Constants.UNWRAPPED_KEY) != null) { XmlSchemaType schemaType = message.getSchemaElement().getSchemaType(); if (schemaType instanceof XmlSchemaComplexType) { XmlSchemaComplexType cmplxType = (XmlSchemaComplexType) schemaType; XmlSchemaParticle particle = cmplxType.getParticle(); if (particle instanceof XmlSchemaSequence) { XmlSchemaObjectCollection items = ((XmlSchemaSequence) particle).getItems(); for (Iterator i = items.getIterator(); i.hasNext();) { Object item = i.next(); if (item instanceof XmlSchemaElement) { XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) item; XmlSchemaType eltSchemaType = xmlSchemaElement.getSchemaType(); if (eltSchemaType != null) { } else if (xmlSchemaElement.getSchemaTypeName() != null) { eltSchemaType = findSchemaType(schemaMap, xmlSchemaElement.getSchemaTypeName()); if (eltSchemaType!=null){ populateClassName(eltSchemaType,mapper,opName,xmlSchemaEle ment.getName()); } } } } } } } The populateClassName looks like this

private static void populateClassName(XmlSchemaType eltSchemaType, TypeMapper typeMap, String opName, String partName) { Map metaInfoMap = eltSchemaType.getMetaInfoMap(); if (metaInfoMap != null) { if(Boolean.TRUE.equals(metaInfoMap.get( SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_PRIMITVE_KEY))){ //this type is primitive - add that to the type mapper status //for now lets add a boolean typeMap.addTypeMappingStatus(partQName,Boolean.TRUE); } } }

Step 4 - Generate Code with Unwrapped Parameters The next step is generating the actual code. The AxisServiceBasedMultiLanguageEmitter has a method that generates the XML model for the input parameters, and that method includes the relevant part parameters inside the relavant top level input parameter element. The relevant part of the XML model looks like this. Note that this intermediate XML model is the one that is parsed against the Stylesheets to generate the code.

79

<param name="param4" type="com.example.www.ServiceNameStub.Echo" shorttype="Echo" value="null" location="body" opname="echo"> <param name="param5" type="java.lang.String" shorttype="String" value="null" location="body" opname="echo" partname="Part1" primitive="yes"/> <param name="param6" type="int" shorttype="int" value="0" location="body" opname="echo" partname="Part2" primitive="yes"/> The next part is handled by the template. Basically, the template looks after the generation of multiple parameters into the method signatures, and then the generating of the relevant serialization and deserialization code for the parameters.

Bringing the Parameters Together and Exploding Them This is a somewhat controversial area. The current Axis2 code generator does the wrapping and unwrapping at the object level and not the XML level. In short, the exploded parameters are only a convenience and the explosion does not run down to the XML level. The following example of generated source code makes this clear: private org.apache.axiom.soap.SOAPEnvelope toEnvelope(org.apache.axiom.soap.SOAPFactory factory, String param1, int param2, boolean optimizeContent) { rg.apache.axiom.soap.SOAPEnvelope emptyEnvelope = factory.getDefaultEnvelope(); emptyEnvelope.getBody().addChild(wrappedType.getOMElement(com.example. www.ServiceNameStub.Echo.MY_QNAME, factory)); return emptyEnvelope; } Note the lines in bold. The wrapped class will anyway be instantiated and used at the end, but what the user sees is different. Exploding the parameters happens in a similar way!

Conclusion Axis2 RPC support is sort of a misty area, but it is based on a well defined set of rules which makes it not that misty after all!

80

Related Documents


More Documents from ""