There are several best practices for composing and developing WLI applications. They are described in the following sections:
For more information on this section, see Guide to Building Business Processes and Using Oracle WebLogic Integration Controls.
When you develop WLI applications, you should follow a uniform and consistent naming standard for various WLI artifacts such as JPDs, task plans, controls, projects, and files. All controls, processes, methods, variables, and other WLI object names should follow standard object oriented and Java naming standards.
In WLI, JPD, control, and data-transformation files have common .java extensions. You should add a suffix to each artifact so that they can be easily identified. Table 4-1 contains an example of naming controls, the related suffix for each artifact, and their locations.
If you have to define a large process, it is always a good practice to make it modular. A modular JPD meets a specific business objective. A few examples of modular JPDs are:
You can divide a large JPD into number of smaller JPDs or sub-processes. Sub-processes can be invoked using a central or main JPD. You can use process control to communicate between a JPD and a sub-process (another JPD). You can also loosely couple two JPDs using Message Broker or publish and subscribe architecture. See Communication Between JPDs and Core Implementation Patterns for a JPD for more details.
Every JPD has a start node and uses a XML document to start. Ensure that the XML document is modular and small for better performance. It is a good practice to have separate XSDs for each type of document. For example, you should have a separate XSDs for a Purchase Order and Invoice, instead of one single large schema for both the Purchase Order and the Invoice.
The modularity of a JPD and its associated document is a relative concept. If a JPD is too modular, it may be counter productive. You should take a balanced decision on modularity depending upon the specific scenario.
The JPD provides a parallel node. Before you use this node, it is recommended that you understand how this node works. Parallel nodes can be used for managing multiple tasks which are related but not dependent. Parallel nodes are meant for business level parallelism. The actual execution does not take place in parallel.
At any given time, execution can start in one branch without any execution in other branches. For example, the branch executing a task may request for a quote from a partner and wait for a response. While this branch is waiting for a response, execution may start in another branch thus achieving business level parallelism.
There are two forms of parallel nodes – AND and OR mode. In the AND mode, all parallel paths should complete their execution, before the business process can proceed further. In the OR mode, the path that completes execution first is the winner. The processing of other path is stopped and the business process proceeds further.
The branches of a parallel node are isolated by transaction (default behavior). You can override this behavior to improve the performance of parallel nodes. Set the continueTransaction
property to true
in the source for each parallel element as follows:
<parallel continueTransaction=
"true
">
You can define exceptions and exception handlers in JPDs at nodes, groups, or process-levels. Exception handlers are executed in the following order:
It is a good practice at the process-level to have a catch all
process-level exception handler.
Exceptions that are not handled can cause process failure. You can set a freezeOnfailure
property to avoid this scenario. If this property is set, any exceptions that are not handled cause the process to freeze. The process then rolls back to the last committed point and the administrator can restart the process from the last committed state.
Table 4-2 contains a list of high-level design guidelines which you can follow while working on a JPD exception.
An Event Choice node group in a business process represents a point at which the business process waits to receive one or more events. The first node on each branch of an event choice node group handles the receipt of an event. You can design the other nodes within an event choice node group to handle the incoming events. Each branch works as event handler for the event or message.
You must create an event choice node at a point in a business process at which it waits to receive multiple events. If you use an Event Choice node to start a business process, it can contain Client Request, Client Request with Return, and Subscription nodes. An Event Choice node which is located at a point other than the start node in a business process can contain Client Request nodes and Control Receive nodes. You can also add a timer branch to your Event Choice node to start that branch after a specified time out.
OnMessage
event handler. OnMessage
event handler
OnMessage
and OnTimeout
events handlers allow interruption of process by outside events. Events handlers allow outside events to interrupt the process using OnMessage
and OnTimeout
event handlers. OnMessage
event handlers can accept client requests.
Figure 4-1 shows an example of how an OnMessage
and OnTimeout
event handler is used.
The following sections describe the best practices for various JPD transactions and compensation management:
Processes in WLI are transactional in nature. Every step of a process is executed within the context of a Java Transaction API (JTA) transaction. When you are building a process, implicit transaction boundaries are formed based upon the location of blocking elements such as a Control Receive or a Client Send. As you add process nodes, the transaction boundaries within a process keep changing.
You can also create explicit transaction boundaries. To do this, select contiguous nodes and declare them in a separate transaction to distinguish between them and the implicit nodes that the application creates. The transaction may also contain resources accessed by a process, depending on the nature of the resource and the control that provides the access.
A stateless process is executed either in a client transaction or when a new transaction is started. Using JPD proxy, a Java client can invoke a JPD over RMI. In this scenario, the client transactions are propagated to the JPD. The caller transaction is not propagated when a JPD is invoked as a web service. The caller transaction is not propagated to a JPD for asynchronous processes as well.
Transaction controls are of three types:
If all controls used within a process are transactional and XA compliant, then the transaction of the process can be used to commit or terminate the underlying transaction branches. The process needs exception handlers to catch any issues and make the necessary transaction decisions. The developer needs to be aware where the transaction was started as any abort or rollback takes the control back to the starting point and this may not be within the process where the exception occurred.
XA is a protocol used to manage distributed transactions. WLI extends XA to allow non-XA resources to participate in distributed transactions, with the limitation that in a given transaction, only one transactional resource can be non-XA compliant. Therefore, if more than one transactional non-XA resource needs to be accessed in a process, then the access to these resources should be encapsulated in separate JPD sub-processes, which should be called asynchronously by the original process. Asynchronous invocation is necessary because synchronously called subprocesses run in the same transaction as the calling process. See Using Integration Controls for more details.
Non-transactional controls such as email controls do not support transactions. In the case of non-transactional controls, you need to have a strategy for exception handling. Use automatic rollback where controls are transactional. Use a caught exception for non-transactional controls to handle the error based on the business problem.
In addition to providing support for Atomicity Consistency Isolation and Durability (ACID) and XA transaction, JPDs also provide support for compensation. You should ensure that the transaction block for which you want to provide compensation, is not marked for rollback only
. Define an exception handler path for the transaction block and enable the execute on rollback
exception handler property. In such a situation, when a transaction fails, the exception handler path is executed first. You can define your undo or compensation logic in such a path. Figure 4-2 shows an example of non-transactional controls.
Table 4-3 contains a list of high-level guidelines to decide the transaction characteristic for your JPD.
A stateless JPD is a process executed in memory only. Its state does not persist. All stateless processes are compiled into a stateless session bean. Stateless processes are intended to support business scenarios that involve short-running logic and have high performance requirements.
As the JPD does not persist its state to a database, it is optimized for lower-latency and higher-performance execution.
Table 4-4 contains a list of high-level guidelines that you should follow, when working on stateless processes.
A stateful process is a process that runs within the scope of more than one transaction. The process persists its state in the database. The state of the JPD survives even if the server crashes. The stateful JPD process is compiled into an entity bean. Stateful processes are intended to support business scenarios that involve complex, and long-running logic.
Stateful processes, in general, are slower than stateless processes. Use stateless processes, especially in scenarios where a state does not need to persist. In certain situations, you can split a stateful process into several stateless processes. Figure 4-3 shows how you can split a stateful process into a stateless process.
WLI has a version feature that helps you change your business process without interrupting any instances of the process that are currently running. When you create a version of a business process, you are actually creating a child version of a business process that shares the same public interface as the parent business process. At runtime, the version of the process that is marked active, is the process that external clients access using the public URI. Through the regular development cycle, new process versions are deployed with new versions of the application.
When the new version of a JPD is deployed, the existing instances run to completion on the same version of the JPD that they started with. You can version business processes, but not the individual controls associated with that process, or other business process related components such as schemas and transformations. When you version a business process, you must also version the sub-processes of that process, as they are not assigned a version automatically along with their parent process.
Table 4-5 contains a list of high-level guidelines that you can follow to set versions for JPDs.
A JPD can subscribe to a message broker channel in two ways: Static or Dynamic.
If a process subscribes to a channel at the start node, this is called a static subscription. The subscription is known at the time the application is compiled and remains through the life time of the application.
When a process subscribes to a message broker channel during its flow using the message broker control, this is known as a dynamic subscription. The subscription starts and ends at runtime. A static subscription to a message broker channel can be specified as suppressible if you set the suppressible attribute for the subscription in the business process. The accepted values for the suppressible attribute are true and false (false is the default value).
A singleton JPD has only one instance of the JPD running at any time. The singleton JPD can be re-run only after the previous instance is complete. The messages in the queue that are received when one instance of the singleton JPD is running are rejected.
To create a singleton JPD, first define a JPD with a static subscription and set the suppressible attribute to True. In this situation, the first message on the channel invokes the JPD and creates an instance of the JPD. Subsequent messages on the static channel do not lead to the creation of a new JPD instance. Singleton JPDs created in this way can continue to receive messages using dynamic subscription.
A race condition is possible when you use the message broker with a dynamic subscription. A message is lost if it is sent before the subscription is complete. This problem is evident when processes start waiting indefinitely for a response, coupled with messages appearing in the dead-letter channel.
If the request message is non-transactional, for example, in the case of a web service call, the message is sent immediately, whereas the subscription to the response occurs only when the transaction is committed. If the subscription appears before the message is sent in the process flow, it might occur later. In this case, ensure that the transaction is committed (for example, add an empty explicit transaction) after the subscription node and before the request message is sent.
If a message is sent to a channel without a subscriber after the filtering process is complete, the message goes to the dead-letter channel. Subscribe to the dead-letter channel to check if messages are published there, because in most cases, this is not a desired behavior.
You need to take special steps to implement at-least-once
or once-only
Quality of Service. If these steps are not taken, the default is the at-least-once
Quality of Service. The steps for the different process types are as follows:
Note: | You cannot ensure the successful completion of every computer program, but a high Quality of Service means that the error is always recoverable. |
A Service Level Agreement (SLA) specifies the performance target for a JPD. An internal or external commitment shows that a JPD is executed within a specified period of time. To help you achieve the SLA for a process, the Oracle WebLogic Integration Administration Console allows you to set the following thresholds (Figure 4-4):
The process status that is relative to these thresholds is tracked for each process instance as follows:
When the elapsed time for a process instance reaches the warning threshold, a warning is displayed on the Process Instance Summary and Detail pages of the WLI Administration Console. The amount of time remaining until the SLA threshold is reached is also displayed. When the elapsed time exceeds the SLA, a red flag is displayed on the WLI Administration Console. The time limit by which the SLA threshold has been exceeded is also displayed. However, there is no event fired and you do not receive a separate notification for the SLA exceeding the threshold other than the warning on the WLI Administration Console.
This ability to set SLA thresholds allows you to easily identify processes that do not execute within the target time frame. You can then make the required changes to meet agreements between suppliers and customers, or to achieve your own performance goals.
You can track a process at various levels. The system contains a default tracking level and then each process can override this. The WLI Administration Console and underlying MBeans provide a monitoring interface to running instances and their variable values. Although variable values cannot be changed, it is possible to query the process using the instance ID or process label. You can set the process label in the instance by calling the JPD context setProcessLabel. Table 4-6 contains a list of high-level design guidelines to monitor JPDs.
You can define the security policy for a JPD. The security policy controls the identity that the JPD uses to access external or backend systems. It allows the administrator to configure whether a JPD accesses an external system as the invoking application, or as an application that calls into the process later. For example, if a process subscribes to a channel and then waits for a client request, the administrator can set the execution policy and use the identity from the client request while accessing backend resources.
The JPD security policy has four main components:
The policy also ascertains if a single principal is required or not. If a single principal is required, all incoming client requests must come from the same user.
You can expose a JPD as a Java Web Service (JWS). There are limitations to developing interoperable JPDs, which include:
Figure 4-5 shows the recommended architecture, keeping the interoperability limitations in mind.
A business process can be exposed as a web service (JWS) as follows:
A WLI application contains several JPDs that communicate with each other. A JPD that is invoked by other JPDs is called a sub-process. Table 4-7 lists the high-level guidelines that you can follow for JPD to JPD communication.
Controls are an integral part of a JPD. WLI controls are based upon open Apache Beehive standards. They support annotations based on JSR-175 standards. Controls are reusable and provide easy access to enterprise resources. Controls can be used within a process definition to make calls to a backend system. For example, the database control allows a process to send SQL to an RDBMS using a JDBC connection pool. Table 4-8 lists the high-level guidelines that you can follow for using controls.
In many cases, control attributes are statically defined using annotations. However, some controls provide a Java API to dynamically change attributes. Dynamic controls, such as service broker and process controls provide the means to dynamically set control attributes. A dynamic or late binding process is used wherein attributes are determined at runtime using a combination of lookup rules and values. Controls that support dynamic binding are called dynamic controls.
Look-up rules are defined during design time. Look-up values can be defined by changing the DynamicProperties.XML file containing the look-up rules and values during runtime via the WLI Administration Console. It contains mappings between values from the message payload (the look-up key) and the corresponding control properties. This file is a domain-wide file shared by all WLI applications in the domain and managed using the WLI Administration Console. This feature allows the complete de-coupling of control attributes from the application. This file allows you to administer dynamic properties while an application is running, and you do not need to redeploy the application for the changes to take effect. The file is located in a subdirectory of the domain root called wliconfig.
To achieve the dynamic binding of properties, use:
Use the getProperties()
method to retrieve the current property settings. You can also use the XML Meta Data Cache control to improve the performance of dynamic data look-up at run time.
When you call web service controls asynchronously from business processes, it is recommended that you buffer the asynchronous call to ensure that the message sent from the business process to the web service is enqueued. An asynchronous call to a resource marks the boundary of a transaction in your business process. A call to a resource is not enqueued until the transaction is committed.
By buffering the call to the resource, you ensure that the transaction is committed before there is any response from the resource. If you do not buffer the call, your business process must wait for the HTTP acknowledgement before the transaction is committed. In this situation, the resource may attempt to respond to the business process before the HTTP acknowledgement.
The control factory feature of a control enables a JPD to interact with a multiple instances of the same JPD. You can implement File, e-mail, WLI JMS, Trading Partner Management, Service, and Worklist controls as control factories. For example, if a JPD is required to send a document, such as loan application, to multiple service providers, it can use a control factory to create multiple instances of the service control, and dispatch requests to the service control instances in parallel. If the control uses callbacks, a single parameterized callback handler in the calling JPD, can manage the callbacks received from all the control instances.
Data transformation and manipulation is an integrated part of a business process. Service consumers and providers require varied data format and types. WLI provides the following tools for data transformation:
Note: | WLI supports the runtime execution of XQuery 2002 for the purpose of backward compatibility with WLI 8.1. |
It is recommended that you create a canonical data model for your application. A canonical data model maps the data to an agreed standard form. If correctly implemented, such a data model provides the services with an Enterprise Information System (EIS) neutral interface. It specifies how you can map the reference, static, and identifier data from an EIS data format to a standard format, de-coupling the data model of the host and the data model of the recipient. You should first create standards for the service interface, that in turn, enforces a common representation of data types and entities within the enterprise. You must maintain a consistent method of representing dates, numbers, post codes, and addresses.
A dynamic transformation control enables a business process to dynamically select and execute a transformation during runtime. It allows you to choose the XQuery, XSLT, or MFL file that is invoked at runtime. For example, if you have an integration hub that receives documents from various regional offices, you can use the dynamic transformation control to perform different transformations based on the area code of each regional office. Table 4-9 lists the high-level design guidelines for data transformation.
WLI worklist has several features as follows:
You can use the task plan to manage exceptions in a JPD. Users can work on a task plan that is invoked when an exception occurs.
Use the task plan event service to integrate your custom logic with the task plan.
To subscribe to task plan events, write your own custom event listeners and register them with the task plan. You can write custom code in your listener class. This custom code is executed when task plan events invoke the respective event listeners associated with the task.
You can use a custom assignment handler in the custom logic to change the default task assignment at runtime.
See Using the Worklist for detailed information.