[jboss-svn-commits] JBL Code SVN: r36774 - labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Mar 3 09:32:19 EST 2011


Author: kevin.conner at jboss.com
Date: 2011-03-03 09:32:19 -0500 (Thu, 03 Mar 2011)
New Revision: 36774

Modified:
   labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Building_and_Using_Services.xml
   labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Developing_Custom_Actions.xml
Log:
Move annotated actions to custom action section: JBESB-3576

Modified: labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Building_and_Using_Services.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Building_and_Using_Services.xml	2011-03-03 13:56:45 UTC (rev 36773)
+++ labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Building_and_Using_Services.xml	2011-03-03 14:32:19 UTC (rev 36774)
@@ -483,567 +483,6 @@
 			
 		</section>
 		
-		<section>            
-			<title>
-			    Annotated Action Classes
-			</title>
-		
-        		<para>
-					The <application>JBoss Enterprise Service
-					Bus</application> has a set of <firstterm>action
-					annotations</firstterm> that make it easier to create
-					clean <systemitem>action</systemitem> implementations.
-					This hides the complexity associated with implementing
-					interfaces, abstract classes and dealing with the
-					<systemitem>ConfigTree</systemitem> type (the configuration information provided in the <filename>jboss-esb.xml</filename> file).
-				</para>
-				
-    		    <para>
-					These are the annotations:
-				</para>				
-
-<itemizedlist>
-    <listitem>
-        <para>
-        @Process
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @ConfigProperty        
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @Initialize
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @Destroy
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @BodyParam
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @PropertyParam
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @AttachmentParam
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @OnSuccess
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-        @OnException
-        </para>
-    </listitem>
-
-
-</itemizedlist>
-	
-
-
-<section>    
-    <title>
-        @Process
-    </title>  			
-		<para>
-		    The simplest implementation involves creating an action with a 
-		    a basic <firstterm>plain old Java object</firstterm> (POJO)
-		    with a single method, annotated with @Process:
-		</para>
-		
-		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate1.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>
-		
-		<para>
-		    The @Process annotation serves to identify the class as a valid
-		    ESB <systemitem>action</systemitem>.  In cases in which there
-		    are multiple methods in the class, it also identifies the method
-		    which is to be used for processing the message instance (or
-		    some part of the message. This is explained in more depth when
-		    the @BodyParam, @PropertyParam and @AttachmentParam annotations
-		    are discussed.)
-		</para>		
-		
-		<para>
-		    To configure an instance of this
-		    <systemitem>action</systemitem> on a
-		    <systemitem>pipeline</systemitem>, use the same process as that
-		    for low/base level <systemitem>action</systemitem>
-		    implementations (these being those that extend
-		    <classname>AbstractActionPipelineProcessor</classname> or
-		    implement <classname>ActionLifecycle</classname> or one of its
-		    other sub-types or abstract implementations):
-		</para>				
-		
-		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate2.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		
-		
-		<para>
-		    In cases in which multiple methods annotated with @Process are
-		    associated with the <systemitem>action</systemitem>
-		    implementation, use the <property>process</property> attribute
-		    to specify which of them is to be used for processing the
-		    message instance:
-		</para>			
-		
-		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate3.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>				
-	
-</section>
-
-<section>    
-    <title>
-        @Process Method Return Values
-    </title>  		
-		
-       		    <para>
-					@Process methods can be implemented to return:
-				</para>				
-
-<itemizedlist>
-    <listitem>
-        <para>
-            void. This means there will be no return value, as with the
-            logger action implementation above.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            message: This is an ESB message instance.  This 
-            becomes the active/current instance on the <systemitem>action
-            pipeline</systemitem>.    
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            some other type.  If the method does not return an ESB message
-            instance, the object instance that is returned will be set on
-            the current ESB message instance on the <systemitem>action
-            pipeline</systemitem>.  As to where it is set on the message
-            depends on the <property>set-payload-location</property>
-            &lt;action&gt; configuration property, which default according
-            to the normal <classname>MessagePayloadProxy</classname> rules.
-        </para>
-    </listitem>
-</itemizedlist>		
-</section>
-<section>    
-    <title>
-        @Process Method Parameters
-    </title>  		
-    		    <para>
-					Use @Process methods to specify parameters in a range of
-					different ways. One can:
-				</para>				
-
-<orderedlist>
-    <listitem>
-        <para>
-            specify the ESB message instance as a method parameter.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            specify one or more arbitrary parameter types.  The Enterprise
-            Service Bus framework will search for data of that type in the
-            active/current pipeline Message instance. Firstly, it will
-            search the message body, then properties, then attachments and
-            pass this data as the values for those parameters (or
-            <code>null</code> if not found.)
-        </para>
-    </listitem>
-</orderedlist>		
-	
-       <para>
-            An example of the first option was depicted above in the logger
-            action.  Here is an example of the second option:
-        </para>	
-	
-		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate4.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
-		
-       <para>
-            In this example, the @Process method is relying on a previous
-            action in the <systemitem>pipeline</systemitem> to create the
-            <code>OrderHeader</code> and <code>OrderItem</code> object
-            instances and attach them to the current message.  (Perhaps a
-            more realistic implementation would have a generic action
-            implementation that decodes an XML or EDI payload to an order
-            instance, which it would then returns. The
-            <classname>OrderPersister</classname> would then take an order
-            instance as its sole parameter.) Here is an example:
-        </para>			
-		
-		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate5.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
-		
-		
-       <para>
-             Chain the two actions together in the service configuration:
-        </para>			
-		
-		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate6.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>					
-		
-       <para>
-             The code is easier to read in Option #2 because there are less
-             annotations, but it carries a risk because the process of
-             run-time "hunting" through the message for the appropriate
-             parameter values is not completely
-             <firstterm>deterministic</firstterm>.  Due to this, Red Hat
-             supports the @BodyParam, @PropertyParam and @AttachmentParam
-             annotations.
-        </para>		
-        
-        <para>
-             Use these @Process method parameter annotations to explicitly
-             define from where in the message an individual parameter value
-             for the @Process method is to be retrieved. As their names
-             suggest, each of these annotations allow one to specify a
-             named location (in the message body, properties or
-             attachments) for a specific parameter:
-        </para>					
-        			
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate7.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		        			
-		
-        <para>
-             If the message location specified does not contain a value,
-             then null will be passed for this parameter (the @Process
-             method instance can decide how to handle this.) If, on the
-             other hand, the specified location contains a value of the
-             wrong type, a
-             <exceptionname>MessageDeliverException</exceptionname> will be
-             thrown.
-        </para>		
-</section>
-
-<section>    
-    <title>
-        @ConfigProperty
-    </title>           
-    
-        <para>
-             Most actions require some degree of custom configuration.  
-             In the ESB action configuration, the properties are
-             supplied as &lt;property&gt; sub-elements of the
-             &lt;action&gt; element:
-        </para>		        		
-		
-		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate8.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
-		
-        <para>
-            In order to utilise these properties, one must use the low/base level
-            action implementations (do so by extending
-            <classname>AbstractActionPipelineProcessor</classname> or by
-            implementing <classname>ActionLifecycle</classname>.) This
-            involves working with the <classname>ConfigTree</classname>
-            class, (which is supplied to the action via its constructor.)
-            In order to implement an action, follow these steps:
-        </para>		       		
-		
-<orderedlist>
-    <listitem>
-        <para>
-            Define a constructor on the action class that supplies the
-            <classname>ConfigTree</classname> instance.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            Obtain all of the relevant action configuration properties from
-            the <classname>ConfigTree</classname> instance.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            Check for mandatory action properties and raise exceptions in
-            those places where they are not specified on the &lt;action&gt;
-            configuration.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            Decode all property values from strings (as supplied on the
-            <classname>ConfigTree</classname>) to their appropriate types
-            as used by the action implementation. For example, decide
-            <code>java.lang.String</code> to <code>java.io.File</code>,
-            <code>java.lang.String</code> to Boolean,
-            <code>java.lang.String</code> to long and so forth.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-                Raise exceptions at those places where the configured value
-                cannot be decoded to the target property type.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-                Implement <firstterm>unit tests</firstterm> on all the
-                different configuration possibilities to ensure that the
-                tasks listed above were completed properly.
-        </para>
-    </listitem>
-</orderedlist>
-		
-       <para>
-                Whilst the tasks above are generally not difficult to
-                undertake, they can be laborious, error-prone and
-                lead to inconsistencies across actions with regard to how
-                configuration mistakes are handled.  One may also be
-                required to add quite a lot of code, with a net result of
-                less overall clarity.
-        </para>		
-        
-      <para>
-               The annotated action addresses these problems via
-               @ConfigProperty. Expand the MyLogActions implementation,
-               which has two mandatory configuration properties:
-               <property>logFile</property> and
-               <property>logLevel</property>:
-        </para>		        
-        
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate9.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>	   
-	
-        <note>	
-            <para>
-               One can also define the @ConfigProperty annotation on
-               "setter" methods (as opposed to on the field.)
-            </para>		     
-        </note>	     
-	     
-        <para>
-                That is all that needs to be done. When the Enterprise
-                Service Bus deploys the action, it examines both the
-                implementation and the maps found within the decoded value
-                (including any support for enums, as with the LogLevel enum
-                above.) It finds the action fields possessing the
-                @ConfigProperty annotation. The developer is not
-                required to deal with the <classname>ConfigTree</classname>
-                class at all or develop any extra code. 
-        </para>		 
-        
-        <para>
-               By default, every class field possessing the @ConfigProperty
-               annotation is mandatory.  Non-mandatory fields are handled
-               in one of these two ways:
-        </para>		             
-	     
-<orderedlist>
-    <listitem>
-        <para>
-            by specifying <code>use = Use.OPTIONAL</code> on the field's @ConfigProperty
-            annotation.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            by specifying a <property>defaultVal</property> on the field's
-            @ConfigProperty annotation. (This is optional.)
-        </para>
-    </listitem>	     
-</orderedlist>	     
-
-        <para>
-               To make the log action's properties optional only, 
-               implement the action like this:
-        </para>		     
-	     
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate10.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>	   	     
-	     
-        <para>
-              The @ConfigProperty annotation supports two additional
-              fields:
-        </para>		             
-	     
-<orderedlist>
-    <listitem>
-        <para>
-            <property>name</property>: use this to explicitly specify the
-            name of the action configuration property to be used to
-            populate the field of that name on the action instance.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            <property>choice</property>: use this field to constrain the
-            configuration values allowed for itself.  This can also be
-            achieved using an enumeration type (as with the
-            <property>LogLevel</property>.)
-        </para>
-    </listitem>	     
-</orderedlist>	     	     
-	     
-        <para>
-              The name field might be used in various situations such as
-              when migrating an old action (that uses the low/base level
-              implementation type) to the newer annotation-based
-              implementation, only to find that the old configuration name
-              for a property (which cannot be changed for
-              backward-compatibility reasons) does not map to a valid Java
-              field name. Taking the log action as an example, imagine that
-              this was the old configuration for the log action:
-        </para>		     
-	     
-		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate11.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		  
-		
-        <para>
-             The property names here do not map to valid Java field names,
-             so specify the name on the @ConfigProperty annotation:
-        </para>		     		
-		   
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate12.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   
-
-</section>
-<section>    
-    <title>
-        Decoding Property Values
-    </title>       
-		   
-        <para>
-              The bean configuration's property values are decoded from
-              their string values. To then match them against the
-              appropriate POJO bean property type, these simple rules are
-              used:
-        </para>		             
-	     
-<orderedlist>
-    <listitem>
-        <para>
-            If the property type has a single-argument string constructor, use that.
-        </para>
-    </listitem>
-
-    <listitem>
-        <para>
-            If it is a "primitive," use its object type's single-argument string
-            constructor. For example, if it is an int, use the Integer
-            object.
-        </para>
-    </listitem>	  
-
-    <listitem>
-        <para>
-            If it is an enum, use <code>Enum.valueOf</code> to convert the
-            configuration string to its enumeration value.
-        </para>
-    </listitem>	                                  
-</orderedlist>	  		   
-
-</section>
-<section>    
-    <title>
-        @Initialize and @Destroy
-    </title>        
-		   
-        <para>
-              Sometimes action implementations need to perform
-              initialization tasks at deployment time. They may also need to
-              perform a clean-up whilst being undeployed.  For these
-              reasons, there are @Initialize and @Destroy method
-              annotations.
-        </para>		    
-
-        <para>
-              To illustrate, here are some examples. At the time of
-              deployment, the logging action may need to perform some
-              checks (that, for example, files and directories exist.) It
-              may also want to perform some initialization tasks (such as
-              opening the log file for writing.) When it is undeployed, the
-              action may need to perform some clean-up tasks (such as
-              closing the file). Here is the code to perform these tasks:
-        </para>		            		   
-		   
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate13.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   
-		 
-    <note>		   
-        <para>
-              All of the @ConfigProperty annotations will have been processed by the
-              time the ESB deployer invokes the @Initialize methods.
-              Therefore, the @Initialize methods can rely on these fields
-              being ready before they execute the customised 
-              initialization.
-        </para>		    
-    </note>		   
-    
-    <note>		       
-        <para>
-              There is no need to always use both of these annotations to specify
-              methods.  Only specify them if there is a need; in other
-              words, if a method only needs initialization, only use the
-              @Initialize annotation (one does not have to supply a
-              "matching" method annotated with the @Destroy annotation.)
-        </para>		       		   
-    </note>		   		   
-    
-    <note>		       
-        <para>
-              It is possible to specify a single method and annotate it
-             with both @Initialize and @Destroy. 
-        </para>		       		   
-    </note>		
-    
-    <note>		       
-        <para>
-              One can optionally specify a
-              <classname>ConfigTree</classname> parameter on @Initialize
-              methods. Do this to have access to the actions which underlie that 
-              <classname>ConfigTree</classname> instance.
-        </para>		       		   
-    </note>		  
-</section>
-
-<section>    
-    <title>
-        @OnSuccess and @OnException
-    </title>
-            
-        <para>
-              Use these annotations to specify those methods to be executed
-              on a successful or failed execution, respectively, of that 
-              <systemitem>pipeline</systemitem> in which the action
-              is configured:
-        </para>	          
-		   
-	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate14.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   		   
-		
-        <para>
-              In the cases of both of these annotations, the parameters
-              passed to the methods are optional. One has the choice of supplying 
-              none, some or all of the parameters shown above.  The Enterprise Service Bus'                
-              framework resolves the relevant parameters in each case.
-        </para>	      		
-
-    </section>		   
-</section>		
-		
-		
-		
 		<section>
 
 			<title>

Modified: labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Developing_Custom_Actions.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Developing_Custom_Actions.xml	2011-03-03 13:56:45 UTC (rev 36773)
+++ labs/jbossesb/branches/JBESB_4_9_CP/product/docs/Programmers_Guide/en-US/Developing_Custom_Actions.xml	2011-03-03 14:32:19 UTC (rev 36774)
@@ -105,4 +105,562 @@
 
 	</section>
 
+		<section>            
+			<title>
+			    Annotated Action Classes
+			</title>
+		
+        		<para>
+					The <application>JBoss Enterprise Service
+					Bus</application> has a set of <firstterm>action
+					annotations</firstterm> that make it easier to create
+					clean <systemitem>action</systemitem> implementations.
+					This hides the complexity associated with implementing
+					interfaces, abstract classes and dealing with the
+					<systemitem>ConfigTree</systemitem> type (the configuration information provided in the <filename>jboss-esb.xml</filename> file).
+				</para>
+				
+    		    <para>
+					These are the annotations:
+				</para>				
+
+<itemizedlist>
+    <listitem>
+        <para>
+        @Process
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @ConfigProperty        
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @Initialize
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @Destroy
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @BodyParam
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @PropertyParam
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @AttachmentParam
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @OnSuccess
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+        @OnException
+        </para>
+    </listitem>
+
+
+</itemizedlist>
+	
+
+
+<section>    
+    <title>
+        @Process
+    </title>  			
+		<para>
+		    The simplest implementation involves creating an action with a 
+		    a basic <firstterm>plain old Java object</firstterm> (POJO)
+		    with a single method, annotated with @Process:
+		</para>
+		
+		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate1.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>
+		
+		<para>
+		    The @Process annotation serves to identify the class as a valid
+		    ESB <systemitem>action</systemitem>.  In cases in which there
+		    are multiple methods in the class, it also identifies the method
+		    which is to be used for processing the message instance (or
+		    some part of the message. This is explained in more depth when
+		    the @BodyParam, @PropertyParam and @AttachmentParam annotations
+		    are discussed.)
+		</para>		
+		
+		<para>
+		    To configure an instance of this
+		    <systemitem>action</systemitem> on a
+		    <systemitem>pipeline</systemitem>, use the same process as that
+		    for low/base level <systemitem>action</systemitem>
+		    implementations (these being those that extend
+		    <classname>AbstractActionPipelineProcessor</classname> or
+		    implement <classname>ActionLifecycle</classname> or one of its
+		    other sub-types or abstract implementations):
+		</para>				
+		
+		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate2.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		
+		
+		<para>
+		    In cases in which multiple methods annotated with @Process are
+		    associated with the <systemitem>action</systemitem>
+		    implementation, use the <property>process</property> attribute
+		    to specify which of them is to be used for processing the
+		    message instance:
+		</para>			
+		
+		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate3.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>				
+	
+</section>
+
+<section>    
+    <title>
+        @Process Method Return Values
+    </title>  		
+		
+       		    <para>
+					@Process methods can be implemented to return:
+				</para>				
+
+<itemizedlist>
+    <listitem>
+        <para>
+            void. This means there will be no return value, as with the
+            logger action implementation above.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            message: This is an ESB message instance.  This 
+            becomes the active/current instance on the <systemitem>action
+            pipeline</systemitem>.    
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            some other type.  If the method does not return an ESB message
+            instance, the object instance that is returned will be set on
+            the current ESB message instance on the <systemitem>action
+            pipeline</systemitem>.  As to where it is set on the message
+            depends on the <property>set-payload-location</property>
+            &lt;action&gt; configuration property, which default according
+            to the normal <classname>MessagePayloadProxy</classname> rules.
+        </para>
+    </listitem>
+</itemizedlist>		
+</section>
+<section>    
+    <title>
+        @Process Method Parameters
+    </title>  		
+    		    <para>
+					Use @Process methods to specify parameters in a range of
+					different ways. One can:
+				</para>				
+
+<orderedlist>
+    <listitem>
+        <para>
+            specify the ESB message instance as a method parameter.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            specify one or more arbitrary parameter types.  The Enterprise
+            Service Bus framework will search for data of that type in the
+            active/current pipeline Message instance. Firstly, it will
+            search the message body, then properties, then attachments and
+            pass this data as the values for those parameters (or
+            <code>null</code> if not found.)
+        </para>
+    </listitem>
+</orderedlist>		
+	
+       <para>
+            An example of the first option was depicted above in the logger
+            action.  Here is an example of the second option:
+        </para>	
+	
+		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate4.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
+		
+       <para>
+            In this example, the @Process method is relying on a previous
+            action in the <systemitem>pipeline</systemitem> to create the
+            <code>OrderHeader</code> and <code>OrderItem</code> object
+            instances and attach them to the current message.  (Perhaps a
+            more realistic implementation would have a generic action
+            implementation that decodes an XML or EDI payload to an order
+            instance, which it would then returns. The
+            <classname>OrderPersister</classname> would then take an order
+            instance as its sole parameter.) Here is an example:
+        </para>			
+		
+		<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate5.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
+		
+		
+       <para>
+             Chain the two actions together in the service configuration:
+        </para>			
+		
+		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate6.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>					
+		
+       <para>
+             The code is easier to read in Option #2 because there are less
+             annotations, but it carries a risk because the process of
+             run-time "hunting" through the message for the appropriate
+             parameter values is not completely
+             <firstterm>deterministic</firstterm>.  Due to this, Red Hat
+             supports the @BodyParam, @PropertyParam and @AttachmentParam
+             annotations.
+        </para>		
+        
+        <para>
+             Use these @Process method parameter annotations to explicitly
+             define from where in the message an individual parameter value
+             for the @Process method is to be retrieved. As their names
+             suggest, each of these annotations allow one to specify a
+             named location (in the message body, properties or
+             attachments) for a specific parameter:
+        </para>					
+        			
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate7.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		        			
+		
+        <para>
+             If the message location specified does not contain a value,
+             then null will be passed for this parameter (the @Process
+             method instance can decide how to handle this.) If, on the
+             other hand, the specified location contains a value of the
+             wrong type, a
+             <exceptionname>MessageDeliverException</exceptionname> will be
+             thrown.
+        </para>		
+</section>
+
+<section>    
+    <title>
+        @ConfigProperty
+    </title>           
+    
+        <para>
+             Most actions require some degree of custom configuration.  
+             In the ESB action configuration, the properties are
+             supplied as &lt;property&gt; sub-elements of the
+             &lt;action&gt; element:
+        </para>		        		
+		
+		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate8.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>			
+		
+        <para>
+            In order to utilise these properties, one must use the low/base level
+            action implementations (do so by extending
+            <classname>AbstractActionPipelineProcessor</classname> or by
+            implementing <classname>ActionLifecycle</classname>.) This
+            involves working with the <classname>ConfigTree</classname>
+            class, (which is supplied to the action via its constructor.)
+            In order to implement an action, follow these steps:
+        </para>		       		
+		
+<orderedlist>
+    <listitem>
+        <para>
+            Define a constructor on the action class that supplies the
+            <classname>ConfigTree</classname> instance.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            Obtain all of the relevant action configuration properties from
+            the <classname>ConfigTree</classname> instance.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            Check for mandatory action properties and raise exceptions in
+            those places where they are not specified on the &lt;action&gt;
+            configuration.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            Decode all property values from strings (as supplied on the
+            <classname>ConfigTree</classname>) to their appropriate types
+            as used by the action implementation. For example, decide
+            <code>java.lang.String</code> to <code>java.io.File</code>,
+            <code>java.lang.String</code> to Boolean,
+            <code>java.lang.String</code> to long and so forth.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+                Raise exceptions at those places where the configured value
+                cannot be decoded to the target property type.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+                Implement <firstterm>unit tests</firstterm> on all the
+                different configuration possibilities to ensure that the
+                tasks listed above were completed properly.
+        </para>
+    </listitem>
+</orderedlist>
+		
+       <para>
+                Whilst the tasks above are generally not difficult to
+                undertake, they can be laborious, error-prone and
+                lead to inconsistencies across actions with regard to how
+                configuration mistakes are handled.  One may also be
+                required to add quite a lot of code, with a net result of
+                less overall clarity.
+        </para>		
+        
+      <para>
+               The annotated action addresses these problems via
+               @ConfigProperty. Expand the MyLogActions implementation,
+               which has two mandatory configuration properties:
+               <property>logFile</property> and
+               <property>logLevel</property>:
+        </para>		        
+        
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate9.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>	   
+	
+        <note>	
+            <para>
+               One can also define the @ConfigProperty annotation on
+               "setter" methods (as opposed to on the field.)
+            </para>		     
+        </note>	     
+	     
+        <para>
+                That is all that needs to be done. When the Enterprise
+                Service Bus deploys the action, it examines both the
+                implementation and the maps found within the decoded value
+                (including any support for enums, as with the LogLevel enum
+                above.) It finds the action fields possessing the
+                @ConfigProperty annotation. The developer is not
+                required to deal with the <classname>ConfigTree</classname>
+                class at all or develop any extra code. 
+        </para>		 
+        
+        <para>
+               By default, every class field possessing the @ConfigProperty
+               annotation is mandatory.  Non-mandatory fields are handled
+               in one of these two ways:
+        </para>		             
+	     
+<orderedlist>
+    <listitem>
+        <para>
+            by specifying <code>use = Use.OPTIONAL</code> on the field's @ConfigProperty
+            annotation.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            by specifying a <property>defaultVal</property> on the field's
+            @ConfigProperty annotation. (This is optional.)
+        </para>
+    </listitem>	     
+</orderedlist>	     
+
+        <para>
+               To make the log action's properties optional only, 
+               implement the action like this:
+        </para>		     
+	     
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate10.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>	   	     
+	     
+        <para>
+              The @ConfigProperty annotation supports two additional
+              fields:
+        </para>		             
+	     
+<orderedlist>
+    <listitem>
+        <para>
+            <property>name</property>: use this to explicitly specify the
+            name of the action configuration property to be used to
+            populate the field of that name on the action instance.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            <property>choice</property>: use this field to constrain the
+            configuration values allowed for itself.  This can also be
+            achieved using an enumeration type (as with the
+            <property>LogLevel</property>.)
+        </para>
+    </listitem>	     
+</orderedlist>	     	     
+	     
+        <para>
+              The name field might be used in various situations such as
+              when migrating an old action (that uses the low/base level
+              implementation type) to the newer annotation-based
+              implementation, only to find that the old configuration name
+              for a property (which cannot be changed for
+              backward-compatibility reasons) does not map to a valid Java
+              field name. Taking the log action as an example, imagine that
+              this was the old configuration for the log action:
+        </para>		     
+	     
+		<programlisting language="XML" role="XML"><xi:include href="extras/building_and_using_services/annotate11.xmlt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		  
+		
+        <para>
+             The property names here do not map to valid Java field names,
+             so specify the name on the @ConfigProperty annotation:
+        </para>		     		
+		   
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate12.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   
+
+</section>
+<section>    
+    <title>
+        Decoding Property Values
+    </title>       
+		   
+        <para>
+              The bean configuration's property values are decoded from
+              their string values. To then match them against the
+              appropriate POJO bean property type, these simple rules are
+              used:
+        </para>		             
+	     
+<orderedlist>
+    <listitem>
+        <para>
+            If the property type has a single-argument string constructor, use that.
+        </para>
+    </listitem>
+
+    <listitem>
+        <para>
+            If it is a "primitive," use its object type's single-argument string
+            constructor. For example, if it is an int, use the Integer
+            object.
+        </para>
+    </listitem>	  
+
+    <listitem>
+        <para>
+            If it is an enum, use <code>Enum.valueOf</code> to convert the
+            configuration string to its enumeration value.
+        </para>
+    </listitem>	                                  
+</orderedlist>	  		   
+
+</section>
+<section>    
+    <title>
+        @Initialize and @Destroy
+    </title>        
+		   
+        <para>
+              Sometimes action implementations need to perform
+              initialization tasks at deployment time. They may also need to
+              perform a clean-up whilst being undeployed.  For these
+              reasons, there are @Initialize and @Destroy method
+              annotations.
+        </para>		    
+
+        <para>
+              To illustrate, here are some examples. At the time of
+              deployment, the logging action may need to perform some
+              checks (that, for example, files and directories exist.) It
+              may also want to perform some initialization tasks (such as
+              opening the log file for writing.) When it is undeployed, the
+              action may need to perform some clean-up tasks (such as
+              closing the file). Here is the code to perform these tasks:
+        </para>		            		   
+		   
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate13.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   
+		 
+    <note>		   
+        <para>
+              All of the @ConfigProperty annotations will have been processed by the
+              time the ESB deployer invokes the @Initialize methods.
+              Therefore, the @Initialize methods can rely on these fields
+              being ready before they execute the customised 
+              initialization.
+        </para>		    
+    </note>		   
+    
+    <note>		       
+        <para>
+              There is no need to always use both of these annotations to specify
+              methods.  Only specify them if there is a need; in other
+              words, if a method only needs initialization, only use the
+              @Initialize annotation (one does not have to supply a
+              "matching" method annotated with the @Destroy annotation.)
+        </para>		       		   
+    </note>		   		   
+    
+    <note>		       
+        <para>
+              It is possible to specify a single method and annotate it
+             with both @Initialize and @Destroy. 
+        </para>		       		   
+    </note>		
+    
+    <note>		       
+        <para>
+              One can optionally specify a
+              <classname>ConfigTree</classname> parameter on @Initialize
+              methods. Do this to have access to the actions which underlie that 
+              <classname>ConfigTree</classname> instance.
+        </para>		       		   
+    </note>		  
+</section>
+
+<section>    
+    <title>
+        @OnSuccess and @OnException
+    </title>
+            
+        <para>
+              Use these annotations to specify those methods to be executed
+              on a successful or failed execution, respectively, of that 
+              <systemitem>pipeline</systemitem> in which the action
+              is configured:
+        </para>	          
+		   
+	<programlisting language="Java" role="JAVA"><xi:include href="extras/building_and_using_services/annotate14.java" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include></programlisting>		   		   
+		
+        <para>
+              In the cases of both of these annotations, the parameters
+              passed to the methods are optional. One has the choice of supplying 
+              none, some or all of the parameters shown above.  The Enterprise Service Bus'                
+              framework resolves the relevant parameters in each case.
+        </para>	      		
+
+    </section>		   
+</section>		
 </chapter>



More information about the jboss-svn-commits mailing list