[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>
- <action> 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 <property> sub-elements of the
- <action> 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 <action>
- 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>
+ <action> 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 <property> sub-elements of the
+ <action> 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 <action>
+ 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