FeaturesThis service engine allows to create a Petals service from an annotated Java class.
|
Table of contents
Contributors
|
Creating an hard-coded service
This section explains how to create a hard-coded service, that will run on the JSR-181 component.
JSR-181 proposes an easy way to define the service you want to expose via Java annotations.
Service-Unit content
A service-unit for this component must contain:
- One or several JAR files, containing at least one Java annotated class.
- A WSDL definition, that is coherent with the Java class. The best way to ensure that is to generate the WSDL from the annotated class.
- A JBI descriptor.
The directory structure of a SU for the Petals-SE-Jsr81 looks like this:
su-jsr181-ServiceName-provide.zip + META-INF - jbi.xml + Service.wsdl + ServiceImplementation.jar (one or several)
The Service implementation
The service is implemented by Java class which must be annotated with JSR-181 annotations (@WebService to be exact).
Every parameter must be a Java bean, with a public zero-argument constructor.
The important thing to take care is the way objects will be marshalled and unmarshalled, i.e. the transformation between the XML messages than come from and to Petals, and the Java objects the service implementation will deal with. This is why all your parameters should respect the Java bean conventions.
The service operation will be the class methods.
You are strongly encouraged to annotate every element of the class, so that the generated WSDL is easy to read.
The WSDL should be generated from the annotated class. Tools like wsgen make this task easy (or you can use Petals Studio too).
Here is a sample annotated class:
package org.ow2.petals.usecase.jsr181; import java.text.SimpleDateFormat; import java.util.Date; import jakarta.jws.WebMethod; import jakarta.jws.WebService; /** * @author Christophe Hamerling - EBM WebSourcing */ @WebService(serviceName = "Hello", name = "MyService", targetNamespace = "http://petals.ow2.org") public class TestService { /** * Say hello to the world! */ @WebMethod public String sayHello( String str ) { System.out.println( "Hey! This is the sayHello operation." ); return "You told me: " + str; } /** * Gets a person from its id only to test 'complex' data binding. * * @param id * @return */ @WebMethod public Person getPerson( int id ) { System.out.println( "Get person " + id ); return new Person( id, "Christophe", "Hamerling", 29, "France" ); } /** * * @return */ @WebMethod public String getTime() { System.out.println( "Get time" ); return new SimpleDateFormat().format( new Date( System.currentTimeMillis())); } /** * NOP */ @WebMethod public void voidvoid() { System.out.println( "The Void operation" ); } /** * The final WSDL operation will be 'specializedOperation' */ @WebMethod(operationName = "specializedOperation") public void operation() { System.out.println( "The specialized operation" ); } /** * * @throws Exception */ @WebMethod public String iAmThrowingAnException() throws Exception { System.out.println( "throw exception" ); throw new Exception( "This is a server side Exception" ); } /** * Gets a list of persons. */ @WebMethod public List<Person> getPersons() { ... } }
The main annotations you may use are:
- The @WebService annotation is mandatory and is used by the Axis2 engine to build the service. You can specialize the service name, target namespace and more with the annotation parameter.
- The @WebMethod annotation is used to delare the that the method will be seen as a JBI operation. You can specialize the operation name and more with the annotation parameters.
- The @WebParam annotation is used to configure an operation parameter.
![]() | If one your method returns a collection of beans, do not forget to annotate the fields of the bean class with @XmlAttribute. Otherwise, the WSDL generation will be incomplete (missing elements in the XML schemas). |
public class Person { public enum Sex { F ("Female"),M("Male"); private String textToDisplay; Sex(String text) { this.textToDisplay = text; } @Override public String toString() { return this.textToDisplay; } } @XmlElement private String firstName; @XmlElement private String surname; @XmlElement private Calendar birthday; @XmlElement private Sex sex; public Person() { this.firstName = null; this.surname = null; this.birthday = null; this.sex = null; } public String getFirstName() { return firstName; } public String getSurname() { return surname; } public Calendar getBirthday() { return birthday; } public Sex getSex() { return sex; } }
There are many more annotations to use with JAX-WS.
More information is available on the Apache Axis2 page.
In fact, for each annotated class, the Petals Jsr181 component creates an Axis2 service.
The messages that are received from the bus are then forwarded to the right Axis2 service the component holds.
Before forwarding the JBI message to the Axis2 service, the service engine checks that :
- The requested operation exists in the Axis2 service. If not, an error will be returned in the JBI message exchange.
- The JBI Message Exchange Pattern (MEP) is compatible with the target operation. For example, in the previous code snippet, an InOut MEP is not compatible with the 'voidvoid' operation and an error would be returned in the JBI message exchange.
It is not possible to only provide the Java class.
The component needs the annotated class, the associated WSDL and a JBI descriptor.
This descriptor references WSDL elements. You mandatory need to have generated the WSDL.
Service-Unit descriptor
The service-unit descriptor file (jbi.xml) looks like this:
<?xml version="1.0" encoding="UTF-8"?> <jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5" xmlns:helloworld="http://petals.ow2.org/helloworld" xmlns:jsr181="http://petals.ow2.org/components/jsr181/version-1"> <jbi:services binding-component="false"> <jbi:provides interface-name="helloworld:Helloworld" service-name="helloworld:HelloworldService" endpoint-name="HelloworldEndpoint"> <petalsCDK:wsdl>Service.wsdl</petalsCDK:wsdl> <jsr181:class>org.ow2.petals.usecase.jsr181.TestService</jsr181:class> </jbi:provides> </jbi:services> </jbi:jbi>
Placeholder
A placeholder is a specific value that is resolved at runtime against a property available in the property file set at component level. It is mainly used in the service unit JBI descriptor to be able to configure your service providers and/or your service consumers.
<service-unit-parameter>${dgfip.quotient-familial.base-url}</service-unit-parameter>
Its syntax is: '${placeholder-name[:default-value]}',
- if no property with name 'placeholder-name' exists in the component property file, the default value 'default-value' is used. If no default value is defined, the literal value '${placeholder-name}' is used,
- if a placeholder name must contain the character ':' (colon), it must be escaped by the character '\', example: ${placeholder-name-with-\:-colon:default-value}',
- if a placeholder default value must contain the character ':' (colon), it must be escaped by the character '\', example: ${placeholder-name:default-value-with-\:-colon}'.
- the escape character can be escaped by itself.
Placeholders are not supported for each service unit parameter, check your documentation before to use them.
It is also possible to change a placeholder value at runtime reloading the component property file. It is not sufficient, the parameter associated to the placeholder must be changeable at runtime. So check component documentation to know that.
CDK parameters defining service provider implementation
The following parameters correspond to the CDK configuration of the service provider implementation.
The service provider is defined into the section 'provides' of the JBI descriptor, containing:
CDK parameters driving interceptors
The following parameters drive interceptors at CDK layer.
Interceptors can be defined to inject some post or pre-processing in the service provider processing or service consumer processing.
Using interceptor is very sensitive and must be manipulated only by power users. A non properly coded interceptor engaged in a component can lead to uncontrolled behaviors, out of the standard process.
Example of an interceptor configuration:
<?xml version="1.0" encoding="UTF-8"?> <jbi:jbi xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5"> <jbi:services> <jbi:provides|consumes> <!--...--> <petalsCDK:su-interceptors> <petalsCDK:send> <petalsCDK:interceptor name="myInterceptorName"> <petalsCDK:param name="myParamName">myParamValue</petalsCDK:param> <petalsCDK:param name="myParamName2">myParamValue2</petalsCDK:param> </petalsCDK:interceptor> </petalsCDK:send> <petalsCDK:accept> <petalsCDK:interceptor name="myInterceptorName"> <petalsCDK:param name="myParamName">myParamValue</petalsCDK:param> </petalsCDK:interceptor> </petalsCDK:accept> <petalsCDK:send-response> <petalsCDK:Interceptor name="myInterceptorName"> <petalsCDK:param name="myParamName">myParamValue</petalsCDK:param> </petalsCDK:Interceptor> </petalsCDK:send-response> <petalsCDK:accept-response> <petalsCDK:Interceptor name="myInterceptorName"> <petalsCDK:param name="myParamName">myParamValue</petalsCDK:param> </petalsCDK:Interceptor> </petalsCDK:accept-response> </petalsCDK:su-interceptors> <!--...--> </jbi:provides|consumes> <!--...--> </jbi:services> </jbi:jbi>
Interceptors configuration for SU (CDK)
Parameter | Description | Default | Required |
---|---|---|---|
send | Interceptor dedicated to send phase, for an exchange sent by a consumer | - | No |
accept | Interceptor dedicated to receive phase, for an exchange received by a provider | - | No |
send-response | Interceptor dedicated to send phase, for an exchange (a response) received by a consumer | - | No |
accept-response | Interceptor dedicated to receive phase, for an exchange sent (a response) by a provider | - | No |
interceptor - name | Logical name of the interceptor instance defined at component level, see CDK Component Interceptor configuration. | - | Yes |
param[] - name | The name of the parameter to use for the interceptor for this SU | - | No |
param[] | The value of the parameter to use for the interceptor for this SU | - | No |
Dedicated configuration
Attribute | Description | Default Value | Required |
---|---|---|---|
class | The JSR-181 annotated class which will provide the Service. This class must be available in the Service-Unit class loader. | -
|
Yes
|
Data-binding
The data-binding is the process that transforms XML messages into Java objects, and vice-versa.
The Jsr181 component delegates this task to Axis2.
As an example, invoking the sayHello operation of the previous service, with a message payload like:
<sayHello> <param0>Hey!!!</param0> </sayHello>
... would result in a response like:
<dlwmin:sayHelloResponse xmlns:dlwmin="http://petals.ow2.org" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <return>You told me: Hey!!!</return> </dlwmin:sayHelloResponse>
Obviously, we assume the operation was invoked with the right MEP (InOut here).
Configuring the component
The component can be configured through the parameters of its JBI descriptor file. These parameters are divided in following groups:
- JBI parameters that have not to be changed otherwise the component will not work,
- CDK parameters that are parameters driving the processing of the CDK layer,
- Dedicated parameters that are parameters specific to this component.
CDK parameters
The component configuration includes the configuration of the CDK. The following parameters correspond to the CDK configuration.
Parameter | Description | Default | Scope* |
---|---|---|---|
acceptor-pool-size | The size of the thread pool used to accept Message Exchanges from the NMR. Once a message is accepted, its processing is delegated to the processor pool thread. | 1 |
Runtime |
acceptor-retry-number | Number of tries to submit a message exchange to a processor for processing before to declare that it cannot be processed. | 40 |
Installation |
acceptor-retry-wait | Base duration, in milliseconds, to wait between two processing submission tries. At each try, the new duration is the previous one plus this base duration. | 250 |
Installation |
acceptor-stop-max-wait | The max duration (in milliseconds) before, on component stop, each acceptor is stopped by force. | 500 |
Runtime |
processor-pool-size | The size of the thread pool used to process Message Exchanges. Once a message is accepted, its processing is delegated to one of the thread of this pool. | 10 | Runtime |
processor-max-pool-size | The maximum size of the thread pool used to process Message Exchanges. The difference between this size and the processor-pool-size represents the dynamic threads that can be created and destroyed during overhead processing time. |
50 |
Runtime |
processor-keep-alive-time | When the number of processors is greater than the core, this is the maximum time that excess idle processors will wait for new tasks before terminating, in seconds. |
300 |
Runtime |
processor-stop-max-wait | The max duration (in milliseconds) of message exchange processing on stop phase (for all processors). |
15000 |
Runtime |
time-beetween-async-cleaner-runs | The time (in milliseconds) between two runs of the asynchronous message exchange cleaner. |
2000 |
Installation |
properties-file | Name of the file containing properties used as reference by other parameters. Parameters reference the property name using a placeholder in the following pattern ${myPropertyName}. At runtime, the expression is replaced by the value of the property. The properties file can be reloaded using the JMX API of the component. The runtime configuration MBean provides an operation to reload these place holders. Check the service unit parameters that support this reloading. The value of this parameter is :
|
- | Installation |
monitoring-sampling-period | Period, in seconds, of a sample used by response time probes of the monitoring feature. | 300 | Installation |
activate-flow-tracing | Enable ('true') or disable ('false') the flow tracing. This value can be overridden at service consumer or service provider level, or at exchange level. | true | Runtime |
propagate-flow-tracing-activation | Control whether the flow tracing activation state must be propagated to next flow steps or not. If 'true', the flow tracing activation state is propagated. This value can be overridden at service consumer level. | true | Runtime |
component-interceptors | Component interceptor configuration. See CDK Component interceptor configuration. | - | See Maven Petals plugin to known how to inject component interceptor configuration in component configuration |
* Definition of CDK parameter scopes:
- Installation: The parameter can be set during the installation of the component, by using the installation MBean (see JBI specifications for details about the installation sequence). If the parameter is optional and has not been defined during the development of the component, it is not available at installation time.
- Runtime: The paramater can be set during the installation of the component and during runtime. The runtime configuration can be changed using the CDK custom MBean named RuntimeConfiguration. If the parameter is optional and has not been defined during the development of the component, it is not available at installation and runtime times.
Interception configuration
Interceptors can be defined to inject some post or pre-processing in the component during service processing.
Using interceptor is very sensitive and must be manipulated only by power users. A non properly coded interceptor engaged in a component can lead to uncontrolled behaviors, out of the standard process.
Example of an interceptor configuration:
<?xml version="1.0" encoding="UTF-8"?> <jbi:jbi xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5" ...> <jbi:component> <!--...--> <petalsCDK:component-interceptors> <petalsCDK:interceptor active="true" class="org.ow2.petals.myInterceptor" name="myInterceptorName"> <petalsCDK:param name="myParamName">myParamValue</petalsCDK:param> <petalsCDK:param name="myParamName2">myParamValue2</petalsCDK:param> </petalsCDK:interceptor> </petalsCDK:component-interceptors> <!--...--> </jbi:component> </jbi:jbi>
Interceptors configuration for Component (CDK)
Parameter | Description | Default | Required |
---|---|---|---|
interceptor - class | Name of the interceptor class to implement. This class must extend the abstract class org.ow2.petals.component.common.interceptor.Interceptor. This class must be loadable from the component classloader, or in a dependent Shared Library classloader. | - | Yes |
interceptor - name | Logical name of the interceptor instance. It is referenced at service unit level to register this interceptor for services of the service unit. See SU Interceptor configuration. | - | Yes |
interceptor - active | If true, the Interceptor instance is activated for every SU deployed on the component. If false, the Interceptor can be activated: -by the InterceptorManager Mbean at runtime, to activate the interceptor for every deployed SU. -by a SU configuration |
- | Yes |
param[] - name | The name of the parameter to use for the interceptor. | - | No |
param[] | The value of the parameter to use for the interceptor. | - | No |
Dedicated configuration
No dedicated configuration parameter is available.
Monitoring the component
Using metrics
Several probes providing metrics are included in the component, and are available through the JMX MBean 'org.ow2.petals:type=custom,name=monitoring_<component-id>', where <component-id> is the unique JBI identifier of the component.
Common metrics
The following metrics are provided through the Petals CDK, and are common to all components:
Metrics, as MBean attribute | Description | Detail of the value | Configurable |
---|---|---|---|
MessageExchangeAcceptorThreadPoolMaxSize | The maximum number of threads of the message exchange acceptor thread pool | integer value, since the last startup of the component | yes, through acceptor-pool-size |
MessageExchangeAcceptorThreadPoolCurrentSize | The current number of threads of the message exchange acceptor thread pool. Should be always equals to MessageExchangeAcceptorThreadPoolMaxSize. | instant integer value | no |
MessageExchangeAcceptorCurrentWorking | The current number of working message exchange acceptors. | instant long value | no |
MessageExchangeAcceptorMaxWorking | The max number of working message exchange acceptors. | long value, since the last startup of the component | no |
MessageExchangeAcceptorAbsoluteDurations | The aggregated durations of the working message exchange acceptors since the last startup of the component. | n-tuple value containing, in nanosecond:
|
no |
MessageExchangeAcceptorRelativeDurations | The aggregated durations of the working message exchange acceptors on the last sample. | n-tuple value containing, in nanosecond:
|
no |
MessageExchangeProcessorAbsoluteDurations | The aggregated durations of the working message exchange processor since the last startup of the component. | n-tuple value containing, in milliseconds:
|
no |
MessageExchangeProcessorRelativeDurations | The aggregated durations of the working message exchange processor on the last sample. | n-tuple value containing, in milliseconds:
|
no |
MessageExchangeProcessorThreadPoolActiveThreadsCurrent | The current number of active threads of the message exchange processor thread pool | instant integer value | no |
MessageExchangeProcessorThreadPoolActiveThreadsMax | The maximum number of threads of the message exchange processor thread pool that was active | integer value, since the last startup of the component | no |
MessageExchangeProcessorThreadPoolIdleThreadsCurrent | The current number of idle threads of the message exchange processor thread pool | instant integer value | no |
MessageExchangeProcessorThreadPoolIdleThreadsMax | The maximum number of threads of the message exchange processor thread pool that was idle | integer value, since the last startup of the component | no |
MessageExchangeProcessorThreadPoolMaxSize | The maximum size, in threads, of the message exchange processor thread pool | instant integer value | yes, through http-thread-pool-size-max |
MessageExchangeProcessorThreadPoolMinSize | The minimum size, in threads, of the message exchange processor thread pool | instant integer value | yes, through http-thread-pool-size-min |
MessageExchangeProcessorThreadPoolQueuedRequestsCurrent | The current number of enqueued requests waiting to be processed by the message exchange processor thread pool | instant integer value | no |
MessageExchangeProcessorThreadPoolQueuedRequestsMax | The maximum number of enqueued requests waiting to be processed by the message exchange processor thread pool since the last startup of the component | instant integer value | no |
ServiceProviderInvocations | The number of service provider invocations grouped by:
|
integer counter value since the last startup of the component | no |
ServiceProviderInvocationsResponseTimeAbs | The aggregated response times of the service provider invocations since the last startup of the component grouped by:
|
n-tuple value containing, in millisecond:
|
no |
ServiceProviderInvocationsResponseTimeRel | The aggregated response times of the service provider invocations on the last sample, grouped by:
|
n-tuple value containing, in millisecond:
|
no |
Dedicated metrics
No dedicated metric is available.
Receiving alerts
Several alerts are notified by the component through notification of the JMX MBean 'org.ow2.petals:type=custom,name=monitoring_<component-id>', where <component-id> is the unique JBI identifier of the component.
![]() | To integrate these alerts with Nagios, see Receiving Petals ESB defects in Nagios. |
Common alerts
Defect | JMX Notification |
---|---|
A message exchange acceptor thread is dead |
|
No more thread is available in the message exchange acceptor thread pool |
|
No more thread is available to run a message exchange processor |
|
Dedicated alerts
No dedicated alert is available.
Business monitoring
MONIT traces
Each service provider implemented is able to log MONIT traces with following information:
- on service provider invocation, when receiving an incoming request, with following attributes:
- traceCode set to provideFlowStepBegin,
- flowInstanceId set to the flow instance identifier retrieved from the incoming request,
- flowStepId set to an UUID value,
- flowStepInterfaceName set to the service provider interface name,
- flowStepServiceName set to the service provider service name,
- flowStepOperationName set to the operation of the invoked service provider,
- flowStepEndpointName set to the service provider endpoint name,
- flowPreviousStepId set to the step identifier of the previous step, retrieved from the incoming request.
- on service provider termination, when returning the outgoing response, with following attributes:
- traceCode set to provideFlowStepEnd or provideFlowStepFailure,
- flowInstanceId set to the flow instance identifier retrieved from the incoming request,
- flowStepId set to the flow step identifier defined on incoming request receipt.
Flow tracing activation
The flow tracing (ie. MONIT traces generation) is defined according to the property 'org.ow2.petals.monitoring.business.activate-flow-tracing' of the incoming JBI request. If the property does not exist, the parameter activate-flow-tracing of the service provider definition will be inspected. If no parameter is defined at service provider level, the component configuration parameter 'activate-flow-tracing' is used. Finally, by default, the flow tracing is enabled.
Flow tracing propagation
The flow tracing propagation from a service provider implemented with this component to another service provider is driven by the parameter propagate-flow-tracing-activation of the service consumer definition. If no parameter is defined at service consumer level, the component configuration parameter 'propagate-flow-tracing-activation' is used. Finally, by default, the flow tracing propagation is enabled.