blob: 12974c633ebcdbc043f074b6cab0f80920bfd9f5 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>Axis2 User's Guide</title>
<meta name="generator" content="amaya 9.2.1, see http://www.w3.org/Amaya/">
</head>
<body lang="en-US" dir="ltr">
<h4><a name="Axis2_User's_Guide">Axis2 User's Guide</a></h4>
<p><i>Version 0.94</i></p>
<i>User Feedback: <a
href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a></i>
<p align="right">Pages: <a href="userguide.html">Content</a>, <a
href="userguide1.html">1</a>, <a href="userguide2.html">2</a>, <a
href="userguide3.html">3</a>, <b>4</b>, <a href="userguide5.html">5</a></p>
<p><b><font size="4">Note (on samples):</font></b> All the user's guide samples
are located in the <b>"samples/userguide/src"</b> directory of the binary
distribution.</p>
<h2><a name="Modules"></a>Modules</h2>
<p>Axis2 provides an extended support for modules (See <a
href="Axis2ArchitectureGuide.html" target="_blank">Architecture Guide</a> for
more details about modules in Axis2). Let's create a custom module and deploy
it to the MyService which we created earlier. Following steps shows the
actions that need to be performed to deploy a custom module for a given Web
Service:</p>
<ol>
<li><p style="margin-bottom: 0in">Create the Module Implementation</p>
</li>
<li><p style="margin-bottom: 0in">Create the Handlers</p>
</li>
<li><p style="margin-bottom: 0in">Create the module.xml</p>
</li>
<li><p style="margin-bottom: 0in">Modify the "axis2.xml" (if you need
custom phases)</p>
</li>
<li><p style="margin-bottom: 0in">Modify the "services.xml" to engage
modules at the deployment time.</p>
</li>
<li><p style="margin-bottom: 0in">Package in a ".mar" (Module Archive)</p>
</li>
<li><p>Deploy the module in Axis2</p>
</li>
</ol>
<h3><a name="MyService_with_a_Logging_Module">MyService with a Logging
Module</a></h3>
<p>Let's write a simple logging module for our sample. This module contains
one handler that just logs the message that is passed through it. Axis2 uses
."mar" (Module Archive) to deploy modules in Axis2. Following diagram shows
the file structure inside that needs to be there in the ".mar" archive. Let's
create all these and see how it works.</p>
<p><img src="images/userguide/ModuleView.jpg" name="Graphic5" align="bottom"
width="185" height="120" border="0"></p>
<h4><a name="Step1_:_LoggingModule_Class">Step1 : LoggingModule Class</a></h4>
<p>LoggingModule is the implementation class of the Axis2 module. Axis2
modules should implement the "org.apache.axis2.modules.Module" interface with
the following methods.</p>
<pre>public void init(AxisConfiguration axisSystem) throws AxisFault;//Initialize the module
public void shutdown(AxisConfiguration axisSystem) throws AxisFault;//End of module processing</pre>
<p>These methods can be used to control the module initialization and the
termination. With the input parameter AxisConfiguration user is provided with
the complete configuration hierarchy. This can be used to fine-tune the
module behavior using the module writers. For the simple logging service we
can keep these methods blank in our implementation class.</p>
<h4><a name="Step2_:_LogHandler">Step2 : LogHandler</a></h4>
<p>A module in Axis2 can contain, one or more handlers that perform various
SOAP header processing at different phases. (See<a
href="Axis2ArchitectureGuide.html" target="_blank"> Architecture Guide</a>
for more information about phases). For the logging module we will write a
handle with the following methods. "public void invoke(MessageContext ctx);"
is the method that is called by Axis2 engine when the control is passed to
the handler. "public void revoke(MessageContext ctx);" is called when the
handlers are revoked by the Axis2 engine.</p>
<pre>public class LogHandler extends AbstractHandler implements Handler {
private Log log = LogFactory.getLog(getClass());
private QName name;
public QName getName() {
return name;
}
public void invoke(MessageContext msgContext) throws AxisFault {
log.info(msgContext.getEnvelope().toString());
}
public void revoke(MessageContext msgContext) {
log.info(msgContext.getEnvelope().toString());
}
public void setName(QName name) {
this.name = name;
}
}</pre>
<h4><a name="Step3_:_module_xml">Step3 : module.xml</a></h4>
<p>"module.xml" contains the deployment configurations for a particular
module. It contains details such as Implementation class of the module (in
this example it is the "LoggingModule" class and various handlers that will
run in different phases). "module.xml" for the logging module will be as
follows:</p>
<pre>&lt;module name="logging" class="userguide.loggingmodule.LoggingModule "&gt;
&lt;inflow&gt;
&lt;handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase" /&gt;
&lt;/handler&gt;
&lt;/inflow&gt;
&lt;outflow&gt;
&lt;handler name="OutFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/outflow&gt;
&lt;Outfaultflow&gt;
&lt;handler name="FaultOutFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/Outfaultflow&gt;
&lt;INfaultflow&gt;
&lt;handler name="FaultInFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/INfaultflow&gt;
&lt;/module&gt;</pre>
<p>As it can be seen there are four phases defined in this "module.xml"</p>
<ol>
<li>inflow               - Represents the handler chain that will run when
a message is coming in. </li>
<li><p style="margin-bottom: 0in">outflow             - Represents the
handler chain that will run when the message is going out. </p>
</li>
<li><p style="margin-bottom: 0in">Outfaultflow      - Represents the
handler chain that will run when there is a fault and the fault is going
out </p>
</li>
<li><p>INfaultflow       - Represents the handler chain that will run when
there is a fault and the fault is coming in </p>
</li>
</ol>
<p>Following set of tags describe the name of the handler, handler class and
the phase in which this handler is going to run. "InFlowLogHandler" is the
name given for the particular instance of this handler. The value of class
attribute is the actual implementation class for this handler. Since we are
writing logging handler, we can reuse the same handler in all these phases.
However this may not be the same for all the modules. "&lt;order
phase="loggingPhase" /&gt;" describes the phase in which this handler
runs.</p>
<pre>&lt;handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase" /&gt;
&lt;/handler&gt;</pre>
<p>To learn more on Phase rules, click on <a
href="http://www.developer.com/java/web/article.php/3529321"
target="_blank">here</a></p>
<h4><a name="Step_4:_Modify_the_&#34;axis2_xml&#34;">Step 4: Modify the
"axis2.xml"</a></h4>
<p>In this handler the phase "loggingPhase" is defined by the module writer.
It is not a pre-defined handler phase, hence the module writer should
introduce it to the "axis2.xml" (NOT the services.xml) so that Axis2 engine
knows where to place the handler in different "flows" ( InFlow, OutFlow,
etc.). Following xml lines show the respective changes made to the
"axis2.xml" in order to deploy this logging module in Axis2 engine. This is
an extract of the phase section of the "axis2.xml".</p>
<pre>&lt;!-- ================================================= --&gt;
&lt;!-- Phases --&gt;
&lt;!-- ================================================= --&gt;
&lt;phaseOrder type="inflow"&gt;
&lt;!-- System pre defined phases --&gt;
&lt;phase name="TransportIn"/&gt;
&lt;phase name="PreDispatch"/&gt;
&lt;phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"&gt;
&lt;handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher"&gt;
&lt;order phase="PostDispatch"/&gt;
&lt;/handler&gt;
&lt;/phase&gt;
&lt;!-- System pre defined phases --&gt;
&lt;!-- After Postdispatch phase module author or or service author can add any phase he want --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="outflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;!--system predefined phase--&gt;
&lt;!--these phase will run irrespective of the service--&gt;
&lt;phase name="PolicyDetermination"/&gt;
&lt;phase name="MessageOut"/&gt;
&lt;/phaseOrder/&gt;
&lt;phaseOrder type="INfaultflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="Outfaultflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;phase name="PolicyDetermination"/&gt;
&lt;phase name="MessageOut"/&gt;
&lt;/phaseOrder&gt;
</pre>
<p>Shown in green, the custom phase "loggingPhase" is placed in all the
flows, hence that phase will be called in all the message flows in the
engine. Since our module is associated with this phase, the LogHandler inside
the module now will be executed in this phase.</p>
<h4><a name="Step5_:_Modify_the_&#34;services_xml&#34;">Step5 : Modify the
"services.xml"</a></h4>
<p>Up to this point we have created the required classes and configuration
descriptions for the logging module and by changing the "axis2.xml" we have
created the required phases for the logging module. Next step is to
"<b>engage</b>" (use) this module in one of our services. For this, let's use
the same Web Service that we have used throughout the user's guide,
MyService. However, since we need to modify the "services.xml" of MyService
in order to engage this module, we use a separate Web Service, but with the
similar operations. The code for this service can be found in the
"Axis2Home/samples/userguide/src/userguide/example2" directory. The simple
changes that we have done to "services.xml' are shown in green in the
following lines of xml.</p>
<pre>&lt;service name="<font color="#33cc00">MyServiceWithModule</font>"&gt;
&lt;description&gt;
This is a sample Web Service with a logging module engaged.
&lt;/description&gt;
<font color="#33cc00">&lt;module ref="logging"/&gt;</font>
&lt;parameter name="ServiceClass" locked="xsd:false"&gt;userguide.example2.MyService&lt;/parameter&gt;
&lt;operation name="echo"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;operation name="ping"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;/service&gt;</pre>
<p>In this example we have changed the service name (the implementation class
is very similar to what we have used earlier although it is in a different
package). In addition we have added the line <b>"&lt;module
ref="logging"/&gt;"</b> to "services.xml". This informs the Axis2 engine that
the module "logging" should be engaged for this service. The handler inside
the module will be executed in their respective phases as described by the
"module.xml".</p>
<p><b><a name="Step6_:_Packaging">Step6 : Packaging</a></b></p>
<p>Before deploying the module we need to create the ".mar" file for this
module. This can be done, using the "jar" command and then renaming the
created jar file. Or you can find the "Logging.mar" that is already created
for you in the "Axis2Home/samples/userguide" directory.</p>
<h4><a name="Step7_:_Deploy_the_Module_in_Axis2">Step7 : Deploy the Module in
Axis2</a></h4>
<p>Deploying a module in Axis2 require the user to create a directory with
the name "modules" in the "webapps/axis2/WEB-INF" directory of their servlet
container and then copying the ".mar" file to that directory. So let's first
create the "modules" directory and drop the "LoggingModule.mar" in to this
directory.</p>
<p>Although the required changes to the "services.xml" is very little, we
have created a separate service archive (MyServiceWithModule.aar) for users
to deploy and see. Deploy this service using the <a
href="userguide2.html#Step4_:Deploy_the_Web_Service">same steps that you used
to deploy "MyService"</a> and copy the "LoggingModule.mar" file to the
"modules" directory. Then run using the "TestWebServiceWithModuleClient.bat"
or "TestWebServiceWithModuleClient.sh" in the
"Axis2Home/samples/userguide/src/userguide/clients/bin" directory.</p>
<p>Note: To see the logs, the user needs to modify the "log4j.properties" to
log INFO. The property file is located in "webapps\axis2\WEB-INF\classes" of
your servlet container. Change the line "log4j.rootCategory= ERROR, LOGFILE"
to "log4j.rootCategory=INFO, ERROR, LOGFILE".</p>
<p align="right"><a href="userguide3.html"><img src="images/arrow_left.gif">
Previous</a> | <a href="userguide5.html">Next <img
src="images/arrow_right.gif"></a></p>
<p>Pages: <a href="userguide.html">Content</a>, <a
href="userguide1.html">1</a>, <a href="userguide2.html">2</a>,<a
href="userguide3.html"> 3</a>, <b>4</b>, <a href="userguide5.html">5</a></p>
</body>
</html>