-
Language:
English
-
Language:
English
Red Hat Training
A Red Hat training course is available for Red Hat Fuse
Chapter 9. Service Implementations
9.1. Bean
9.1.1. Bean Service Component
9.1.2. Bean Services
9.1.3. Create a Bean Service
Prerequisites
- Name: the name of the Java class for your bean service.
- Service Name: the name of the service your bean provides.
- Interface: the contract for the service being provided. Java is the only valid interface type for bean services.
Procedure 9.1. Task
- Create a new Bean Service Class in the SwitchYard Editor JBoss Developer Studio plug-in.
Note
If you provide the interface value first, it automatically generates default names for Name and Service Name.Figure 9.1. Creating a New Bean Service
The example above showsExampleBean
as the name of the class andcom.example.switchyard.docs.Example
as the interface. - Click Finish.Your new class looks like this:
package com.example.switchyard.docs; import org.switchyard.component.bean.Service; @Service(Example.class) public class ExampleBean implements Example { }
The @Service annotation allows the SwitchYard CDI Extension to discover your bean at runtime and register it as a service. The value of the annotation (Example.class
in the above example) represents the service contract for the service. Every bean service must have an @Service annotation with a value identifying the service interface for the service. - After creating a bean service, complete the service definition by adding one or more operations to the service interface and a corresponding implementation in your bean:
package com.example.switchyard.docs; import org.switchyard.component.bean.Service; @Service(Example.class) public class ExampleBean implements Example { public void greet(Person person) { // implement service logic here for greet operation } }
9.1.4. Providing a Service
Procedure 9.2. Task
- In order to provide a service with the Bean component, add an @Service annotation to your bean:
@Service(SimpleService.class) public class SimpleServiceBean implements SimpleService { public String sayHello(String message) { System.out.println("*** Hello message received: " + message); return "Hi there!!"; } } public interface SimpleService { String sayHello(String message); }
TheSimpleService
interface represents the Service Interface that defines the service operations exposed by SwitchYard.
9.1.5. @Service
META-INF/beans.xml
file in your deployed application tells the JBoss application server to look for beans in this application and to activate the CDI. The SwitchYardCDIServiceDiscovery
CDI extension picks up the @Service beans and makes them available to the application deployer. The service can now be invoked from other services within SwitchYard or bound to a wire protocol through SwitchYard gateways.
9.1.6. Consuming a Service
Procedure 9.3. Task
- In order to consume a SwitchYard service from within a CDI bean, add a @Reference annotation to your bean:
@Service(ConsumerService.class) public class ConsumerServiceBean implements ConsumerService { @Inject @Reference private SimpleService service; public void consumeSomeService() { service.sayHello("Hello"); } } public interface ConsumerService { void consumeSomeService(); }
By default, SwitchYard expects a service reference to be declared with a name which matches the Java type used for the reference. In the above example, the SimpleService type expects a service reference called "SimpleService" in your SwitchYard configuration. However, the @Reference annotation also accepts a service name if the service reference name does not match the Java type name of the contract. For example:@Reference("urn:myservices:purchasing:OrderService") private OrderService orders;
9.1.7. @Reference
9.1.8. ReferenceInvoker
Message
and Context
interfaces.
Note
@Inject @Reference("SimpleService") private ReferenceInvoker service; public void consumeSomeService(String consumerName) { service.newInvocation("sayHello") .setProperty("myHeader", "myValue") .invoke(consumerName); }
9.1.9. Invocation Properties
9.1.10. Accessing Invocation Properties
Procedure 9.4. Task
- To enable access to the invocation properties, add a
Context
property to your bean and annotate it with the CDI @Inject annotation:package com.example.switchyard.docs; import javax.inject.Inject; import org.switchyard.Context; import org.switchyard.component.bean.Service; @Service(SimpleService.class) public class SimpleServiceBean implements SimpleService { @Inject private Context context; public String sayHello(String message) { System.out.println("*** Funky Context Property Value: " + context.getPropertyValue("funkyContextProperty")); return "Hi there!!"; } }
Here, the Context interface allows your bean logic to get and set properties in the context.Note
You can invoke the Context instance only within the scope of one of the Service Operation methods. If you invoke it outside this scope, it results in an UnsupportedOperationException error.
9.1.11. @Inject
9.1.12. Implementation Properties
switchyard.xml
) for your bean implementation.
9.1.13. Accessing Implementation Properties
switchyard.xml
) for your bean implementation. Implementation properties in SwitchYard are the properties that you can configure on a specific service implementation. That is, you can make the property value available to service logic executing inside an implementation container. Here is an example:
<sca:component name="SimpleServiceBean"> <bean:implementation.bean class="com.example.switchyard.switchyard_example.SimpleServiceBean"/> <sca:service name="SimpleService"> <sca:interface.java interface="com.example.switchyard.switchyard_example.SimpleService"> <properties> <property name="userName" value="${user.name}"/> </properties> </sca:interface.java> </sca:service> </sca:component>
Procedure 9.5. Task
- To access the Implementation Properties, add an @Property annotation to your bean class identifying the property you want to inject:
package com.example.switchyard.docs; import org.switchyard.component.bean.Property; import org.switchyard.component.bean.Service; @Service(SimpleService.class) public class SimpleServiceBean implements SimpleService { @Property(name="userName") private String name; @Override public String sayHello(String message) { return "Hello " + name + ", I got a message: " + message; } }
Here, the @Property annotation is used for injecting theuser.name
property.
9.1.14. @Property
9.2. BPM
9.2.1. BPM Component
9.2.2. Create a BPM Service
Prerequisites
- File Name: The file name of the new BPMN 2 Process definition.
- Interface Type: The contract for the service provided by your bean. BPM supports Java and WSDL contract types.
- Service Name: The name of the service provided by your bean.
Procedure 9.6. Task
- Create a new BPMN file in the SwitchYard Editor JBoss Developer Studio plug-in.
- Input the values into the SwitchYard Editor's New SwitchYard BPMN File Screen.
Figure 9.2. New SwitchYard BPMN File Screen
- Click Finish.This creates a new service component definition for your process service and an empty BPMN process definition.
- After creating a new BPM Service, create the BPMN 2 process definition and configure the BPM service component to interact with that process definition.
9.2.3. Process Interaction
package org.switchyard.userguide; public interface MyService { public void start(String data); public void signal(String data); public void stop(String data); }
- START_PROCESS
- Operations configured with the START_PROCESS action type start new process instances.When you start your process (actually, any interaction with a service whose implementation is bpm), the processInstanceId is put into the SwitchYard context at Scope.EXCHANGE and is fed back to your client in a binding-specific way. For SOAP, it is in the form of a SOAP header in the SOAP response envelope:
<soap:Header> <bpm:processInstanceId xmlns:bpm="urn:switchyard-component-bpm:bpm:1.0">1</bpm:processInstanceId> </soap:Header>
In future process interactions, you need to send back that same processInstanceId, so that the correlation is done properly. For SOAP, that means including the same SOAP header that was returned in the response to be sent back with subsequent requests.Important
If you are using persistence, the sessionId is also available in the Context, and must be fed back as well. It looks the same as the processInstanceId in the SOAP header. - SIGNAL_EVENT
- Operations configured with the SIGNAL_EVENT action type have to signal the associated process instance. The processInstanceId must be available in the Context so the correct process instance is correlated.There are two other pieces of information that are needed when signaling an event:
- The "id". In BPMN2 lexicon, this is known as the "signal id", but in jBPM can also be known as the "event type". This is set as the id of the annotation.
Note
In BPMN2, a signal looks like this:<signal id="foo" value="bar"/>
In jBPM, it is the signal id that is respected, not the name. This might require you to tweak a tooling-generated id if you want to customize its name. - The "event object". This is the data representing the event itself. There are two ways to pass in the event object:
- The first way is through a Context object. The way in which this is passed is similar to the processInstanceId, and it is known as "signalEvent". If you use this, you are limited to a String type.
- The second way is through the Message content object itself (that is, your payload). If the signalEvent Context property is absent, the content of the Message is used as the event object.
- ABORT_PROCESS_INSTANCE
- If an operation is configured with the ABORT_PROCESS_INSTANCE action type, associated process instances are aborted. Note that the processInstanceId must be available in the Context so the correct process instance is correlated.
9.2.4. Use Process Variables
Prerequisites
- JBoss Developer Studio jBPM Plug-In
Procedure 9.7. Use Process Variables
- Click on the white space around a process or on any of your process nodes.
- Access the Properties view.
- Declare the variablenames at the process level and in the Parameter Mapping (and possibly Result Mapping).
9.2.5. Mappings
- Global mappings are used to provide data that is applicable to the entire action, and is often used in classic in/out param (or data-holder/provider) fashion. An example of a global mapping is a global variable specified within a Drools Rule Language (DRL) file.
- Input mappings are used to provide data that represents parameters being fed into an action. An example of an input mapping for BPM is a process variable used while starting a business process. For Rules, it could be a fact to insert into a rules engine session.
- Output mappings are used to return data from an action. An example of an output mapping is a BPM process variable that you want to set as the outgoing (response) message’s content.
Note
9.2.6. expressionType Properties
- exchange
- The current org.switchyard.Exchange.
- context
- The current org.switchyard.Context.
- message
- The current org.switchyard.Message.
expression="message.content"
message.getContent()
.
expression="context[‘foo’]" scope="IN"
context.getProperty("foo", Scope.IN).getValue()
in a null-safe manner.
Note
<mapping expression="theExpression" expressionType="MVEL" scope="IN" variable="theVariable"/>
9.2.7. Consuming a Service
- By invoking the BPM implementation through a gateway binding. Since the BPM component exposes a Java interface fronting the business process, you can use any of the bindings provided by SwitchYard. (You could, for example, use either a SOAP Binding or a Camel Binding.)
- By invoking other SwitchYard Services from inside a BPM process itself. To do this, you can use the SwitchYardServiceWorkItemHandler, which is provided out-of-the-box. (To make authoring BPMN2 processes easier, SwitchYard provides a widget for the Eclipse BPMN2 Modeler visual editor palette.)
9.2.8. SwitchYard Service Task Properties
- ServiceName
- This is the name of the SwitchYard service to invoke. It is a mandatory property
- ServiceOperationName
- This is the name of the operation within the SwitchYard service to invoke. It is an optional property. (The default behavior is to use the single method name in the service interface, if there is just one.)
- ContentInputName
- This is the process variable into which the message content is placed. It is an optional property. The default value is contentInput.
- ContentOutputName
- The process variable from which the message content is obtained. It is an optional property. The default value is contentOutput.
- FaultResultName
- This is the name of the output parameter (in other words, the result variable) under which the exception is stored. It is optional.
- FaultSignalId
- This is the bpmn signal id (or event type) that is used to signal an event in the same process instance. The event object is the exception. This is an optional property.
- FaultWorkItemAction
- This property determines what happens after a fault occurs. If it is set to null, nothing is done. If set to complete, the current work item (that is, the SwitchYard service task) is completed. If it is set to abort, the current work item is aborted. (The default setting is null.) This property is optional.
9.2.9. SwitchYard Service Fault Handling
SwitchYardServiceWorkItemHandler
class is used for fault handling in the Switchyard Service tasks during process execution. It executes service references according to the SwitchYard's fault-handling properties that you have configured. The SwitchYard's fault-handling properties define the behavior of the SwitchYardServiceWorkItemHandler
class when a fault is encountered during the execution of the service reference.
SwitchYardServiceWorkItemHandler
class for fault handling in the following scenarios:
- If you want to have a split gateway in your process flow, to inspect a process variable for any occurrence of a fault. To achieve this, you need to set the following fault-handling properties in your SwitchYard Service task:
- FaultResultName: Specifying the FaultResultName property enables the
SwitchYardServiceWorkItemHandler
class to make the fault available as an output parameter of the task. You can then associate it with a process variable, and inspect for existence in your split gateway. - FaultWorkItemAction: Specifying the FaultWorkItemAction property to complete enables the process to continue on to your split gateway.
- If you want to have a single shared path of fault-handling in your process flow. To achieve this, you need to set the following fault-handling properties in your SwitchYard Service task:
- FaultSignalId: Specifying the FaultSignalId property same as the Signal ID you specified in your bpmn2 process definition, enables you to add an event node in your process that is triggered with this signal id. The flow starting from this event node is your fault handling path. The
SwitchYardServiceWorkItemHandler
class then signals the proper event with the configured ID.
9.2.10. Using The Standard BPMN2 Service Task
- The
<serviceTask>
attribute invokes SwitchYard when it has animplementation="##SwitchYard"
attribute. - The ServiceName is derived from the BPMN2 interfaceImplementationRef.
- The ServiceOperationName is derived from the BPMN2 operationImplementationRef.
- The ContentInputName is always called Parameter.
- The ContentOutputName is always called Result.
9.2.11. Resources
9.2.12. WorkItemHandler Interface
org.kie.runtime.process.WorkItemHandler
interface and add a handler definition to your BPM service component.
9.3. BPEL
9.3.1. BPEL Component
9.3.2. Providing a Service with the BPEL Component
Procedure 9.8.
- Define your process using WS-BPEL within JBoss Developer Studio (with JBoss Integration and SOA Development tooling installed).
- Define a WSDL interface for the BPEL service.
- Define a Deployment Descriptor using the ODE Deployment Descriptor editor bundled with JBoss Tools.
- Add the component containing the implementation and service interface to the SwitchYard configuration.
9.3.3. Example of BPEL Component Configuration
<sca:component name="SayHelloService"> <bpel:implementation.bpel process="sh:SayHello"/> <sca:service name="SayHelloService"> <sca:interface.wsdl interface="SayHelloArtifacts.wsdl#wsdl.porttype(SayHello)"/> </sca:service> </sca:component>
implementation.bpel
element that identifies the fully qualified name of the BPEL process. This component may also contain one or more service elements defining the WSDL port types through which the BPEL process can be accessed.
deploy.xml
). Here is an example of the deployment descriptor for the BPEL process referenced above:
<deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03" xmlns:examples="http://www.jboss.org/bpel/examples"> <process name="examples:SayHello"> <active>true</active> <retired>false</retired> <process-events generate="all"/> <provide partnerLink="client"> <service name="examples:SayHelloService" port="SayHelloPort"/> </provide> </process> </deploy>
9.3.4. Consuming a Service from a BPEL Process
deploy.xml
file:
<process name="ls:loanApprovalProcess"> <active>true</active> <process-events generate="all"/> <provide partnerLink="customer"> <service name="ls:loanService" port="loanService_Port"/> </provide> <invoke partnerLink="assessor" usePeer2Peer="false"> <service name="ra:riskAssessor" port="riskAssessor_Port"/> </invoke> </process>
usePeer2Peer
property informs the BPEL engine not to use internal communications for sending messages between BPEL processes that may be executing within the same engine, and instead pass messages through the SwitchYard infrastructure.
switchyard.xml
file below:
<sca:component name="loanService"> <bpel:implementation.bpel process="ls:loanApprovalProcess" /> <sca:service name="loanService"> <sca:interface.wsdl interface="loanServicePT.wsdl#wsdl.porttype(loanServicePT)"/> </sca:service> <sca:reference name="riskAssessor"> <sca:interface.wsdl interface="riskAssessmentPT.wsdl#wsdl.porttype(riskAssessmentPT)"/> </sca:reference> </sca:component>
9.3.5. Property Injection into a BPEL Process
SwitchYardPropertyFunction.resolveProperty()
XPath custom function. The bpel:copy
section copies Greeting property value into the ReplySayHelloVar
variable in example shown below:
<bpel:copy> <bpel:from xmlns:property="java:org.switchyard.component.bpel.riftsaw.SwitchYardPropertyFunction" expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"> <![CDATA[concat(property:resolveProperty('Greeting'), $ReceiveSayHelloVar.parameters/tns:input)]]> </bpel:from> <bpel:to part="parameters" variable="ReplySayHelloVar"> <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:result]]></bpel:query> </bpel:to> </bpel:copy>
9.3.6. Maintaining Multiple Versions of a BPEL Process
HelloWorld.bpel
file, then you can simply add a hyphen followed by the version number, such as HelloWorld-32.bpel
. This indicates that this is the thirty second version of this BPEL process. Whenever you define a new version of the BPEL process, package it in the SwitchYard application along side the previous versions of the BPEL process. It is important that the older version of the BPEL process remain in the SwitchYard application until there are no longer any active process instances associated with that version. You need to then re-deploy the SwitchYard application, without undeploying the previous version. If you undeploy the previous version of the SwitchYard application, the BPEL engine deletes all outstanding active instances associated with the deleted process definitions.
9.3.7. Structure of a SwitchYard BPEL Application
src/main/resources
folder are structured differently. The switchyard.xml
configuration file is located in the META-INF folder. However, the BPEL deployment descriptor (deploy.xml
), and the BPEL process definition are located in the root folder. You can locate the WSDL interface definitions, and any accompanying XSD schemas in the sub-folders. You must ensure that the BPEL process and SwitchYard BPEL component configuration define the correct relative path for the artifacts.
say_hello src/main/java src/main/resources META-INF switchyard.xml deploy.xml SayHello.bpel SayHelloArtifacts.wsdl JRE System Library [JavaSE-1.6] src pom.xml
9.4. Camel
9.4.1. Camel Services
9.4.2. Create a Camel Service
Prerequisites
- Name: the name of the Java class or XML file for your bean service.
- Service Name: the name of the service your bean provides.
- Interface: the contract for the service being provided. Camel supports Java and WSDL contract types.
Procedure 9.9. Create a Camel Service
- Create a new Camel Route file resource in the SwitchYard Editor JBoss Developer Studio plug-in.
- Decide whether to use DSL or XML dialect for the route. (Functionally, they are more or less equivalent, the choice is determined by how you want to express your routing logic.)
- If you want create a Java DSL route, select the "Camel (Java)" implementation type. For XML, use the "Camel (XML)" type.
- Input the values into the SwitchYard Editor's New Route File Screen.
- Click Finish.
9.4.3. Guidelines of Camel Route
- There is only one route per service.
- The consumer or "from" endpoint in a route is always a "switchyard" endpoint and the endpoint name must equal the service name. This is default behavior in the tooling.
- To consume other services from within your route, only use "switchyard" consumer (in other words "to") endpoints. This keeps your routing logic independent of the binding details for consumed services.
9.4.4. Java DSL Route
RouteBuilder
class. As there can be only one route per service, you can have only one RouteBuilder
class for each Camel routing service in your application. You can then add logic to your routing service in the configure()
method as shown below:
package com.example.switchyard.docs; import org.apache.camel.builder.RouteBuilder; public class CamelServiceRoute extends RouteBuilder { /** * The Camel route is configured through this method. The from: * endpoint is required to be a SwitchYard service. */ public void configure() { // TODO Auto-generated method stub from("switchyard://Example").log( "Received message for 'Example' : ${body}"); } }
9.4.5. XML Route
<route>
tag with the namespace "http://camel.apache.org/schema/spring" as shown below:
<?xml version="1.0" encoding="ASCII"?> <route xmlns="http://camel.apache.org/schema/spring"> <from uri="switchyard://Example"/> <log message="Example - message received: ${body}"/> </route>
9.4.6. Consuming Services From Camel Routes
switchyard://
) within your route as shown below:
switchyard://[service-name]?operationName=[operation-name]
- service-name: Name of the SwitchYard service. This value should match the name of a service reference defined on the service component for the route.
- operation-name: Name of the service operation you want to invoke. This is only used on references and is optional if the target service only has a single operation.
<?xml version="1.0" encoding="ASCII"?> <route xmlns="http://camel.apache.org/schema/spring"> <from uri="switchyard://Example"/> <log message="Example - message received: ${body}"/> <!-- Invoke hasItem operation on WarehouseService --> <to uri="switchyard://WarehouseService?operationName=hasItem"/> </route>
9.4.7. Using Scripting Languages
- You can use them to create a predicate in a message filter as shown below:
public class ScriptingBuilder extends RouteBuilder { public void configure() { from("switchyard://Inbound").filter().javaScript("request.getHeader('myHeader') != null").to("switchyard://Outbound"); } }
- You can use them to implement your service using
transform
element as shown below:public class ScriptingImplementationBuilder extends RouteBuilder { public void configure() { from("switchyard://Inbound").transform().groovy("classpath:script.groovy"); // classpath resource from("switchyard://InboundBsh").transform().language("beanshell", "file:script.bsh"); // file system resource } }
9.4.8. Supported Scripting Languages
- BeanShell
- JavaScript
- Groovy
- Ruby
- Python
9.4.9. Using CDI Beans in Camel Routes
@Named("StringSupport") @ApplicationScoped public class StringUtil { public String trim(String string) { return string.trim(); } }The SwitchYard Camel Route logic implemented with this CDI bean looks like this:
public class ExampleBuilder extends RouteBuilder { public void configure() { from("switchyard://ExampleBuilder") .split(body(String.class).tokenize("\n")) .filter(body(String.class).startsWith("sally:")) .to("bean:StringSupport"); } }Any Java class annotated with
@Named
annotation in your application is available through Camel's Bean registry.
9.4.10. Injecting Implementation Properties in Camel Routes
{{propertyName}}
expression, where propertyName
is the name of the property.
user.name
property to be injected in the last <Log>
statement:
<route xmlns="http://camel.apache.org/schema/spring" id="CamelTestRoute"> <log message="ItemId [${body}]"/> <to uri="switchyard://WarehouseService?operationName=hasItem"/> <log message="Title Name [${body}]"/> <log message="Properties [{{user.name}}]"/> </route>
9.5. Rules
9.5.1. Rules Component
9.5.2. Create a Rules Service
Prerequisites
- File Name: the name of the file that is used to create a new template rules definition.
- Service Name: the name of the service that your rules provide.
- Interface Type: the contract for the service being provided. Rules services support Java and WSDL contract types.
- Package Name: package name used for the new Rules file.
Procedure 9.10. Create a Rules Service
- Create a new SwitchYard Rules file in the SwitchYard Editor JBoss Developer Studio plug-in.
- The MyService interface can be as simple as this, with no SwitchYard-specific imports:
package com.example.switchyard.docs; public interface Example { public void process(MyData data); }
- The generated rule template looks like this:
package com.example.switchyard.docs import org.switchyard.Message global Message message rule "RulesExample" when // insert conditional here then // insert consequence here System.out.println("service: ExampleService, payload: " + message.getContent()); end
- Input the values into the SwitchYard Editor's SwitchYard Rules File screen.
- Click Finish.
9.5.3. Stateless and Stateful Rules Executions
By default, service method invocation creates a new Drools knowledge session, execute it given the passed-in domain data and then be disposed cleanly.
FIRE_ALL_RULES
action type instead of EXECUTE
.
INSERT
action type.
9.5.4. Stateless Knowledge Session
- Validation
- Is this person eligible for a mortgage?
- Calculation
- Compute a mortgage premium.
- Routing and Filtering
- Filter incoming messages, such as emails, into folders.Send incoming messages to a destination.
9.5.5. Stateful Knowledge Session
the dispose()
method must be called afterwards to ensure there are no memory leaks, as the Knowledge Base contains references to Stateful Knowledge Sessions when they are created. StatefulKnowledgeSession also supports the BatchExecutor
interface, like StatelessKnowledgeSession, the only difference being that the FireAllRules
command is not automatically called at the end for a Stateful Session.
- Monitoring
- Stock market monitoring and analysis for semi-automatic buying.
- Diagnostics
- Fault finding and medical diagnostics
- Logistics
- Parcel tracking and delivery provisioning
- Compliance
- Validation of legality for market trades.
9.5.6. Mapping Global Variables
- To map the variables, hover the mouse over the Rules component in
switchyard.xml
and click Properties icon.Figure 9.3. Properties dialog for Rules Component
- In the Properties dialog, click Implementation. From the right hand side panel, click Operations tab to view Operation Mapping tooling window.
Figure 9.4. Operations Mapping
9.5.7. Map Global Variables
- Configure the rules implementation.
Note
Your expression can use the variables exchange (org.switchyard.Exchange
), context (org.switchyard.Context
) or message (org.switchyard.Message
).Context can be accessed in the expression as a java.util.Map. When accessing it as such, the default properties Scope is IN. This can be overridden using the contextScope attribute by changing it to OUT or EXCHANGE - Use these global variables in your JBoss Rules Drools Rule Language file:
package example global java.lang.String service global java.lang.String messageId global com.example.Payload payload rule "Example" when ... then ... System.out.println("service: " + service + ", messageId: " + messageId + ", payload: " + payload); end
Note
In a more realistic scenario, the payload would be accessed in rule firing because it was inserted into the session directly by the RulesExchangeHandler, and thus evaluated (rather than being accessed as a global).
9.5.8. Mapping Facts
9.5.9. Notes About Mapping Facts
- If you specify your own fact mappings, the SwitchYard message's content is not inserted as a fact. You can add a fact mapping with an expression of "message.content" if you want to still include it.
- There is no point in specifying the "variable" attribute of the mappings (as done for global mappings), as the result of each expression is inserted as a nameless fact.For stateless execution, the full list of facts is passed to the StatelessKnowledgeSessions'
execute(Iterable)
method.For stateful execution, each fact is individually inserted into the StatefulKnowledgeSession. - If the result of the mapping expression implements Iterable (for example, a Collection), then the result is iterated over, and each iteration is inserted as a separate fact, rather than the parent Iterable itself being inserted. This is not recursive behavior (because it is only done once).
9.5.10. Auditing a Service
9.5.11. Consuming a Service from the Rules Component
9.6. Knowledge Services
9.6.1. Knowledge Services
9.6.2. Actions
myOperation
, it may result in execution of actions like execute some business rules or start a business process. Here is an example of Actions attribute illustrating myOperation
method and an action of type ACTION_TYPE
:
<actions> <action id="myId" operation="myOperation" type="ACTION_TYPE"> <globals> <mapping/> </globals> <inputs> <mapping/> </inputs> <outputs> <mapping/> </outputs> </action> </actions>Here, the placeholder
ACTION_TYPE
can hold values for the actual ActionTypes
specific to the BPM or Rules components.
9.6.3. Mappings
- Global Mappings: Use the global mappings to provide data that is applicable to the entire action. You can use them in an in/out parameter or a data-holder/provider structure. An example of a global mapping is a global variable specified within a Drools Rule Language (DRL) file.
- Input Mappings: Use the input mappings to provide data that represents parameters provided to an action. An example of an input mapping for BPM is a process variable used while starting a business process. An example of an input mapping for Rules is a fact to insert into a rules engine session.
- Output Mappings: Use the output mappings to return data out of an action. An example of an output mapping is a BPM process variable that you want to set as the outgoing (response) message’s content.
9.6.4. MVEL expressionType
expressionType
called MVEL. You can use following variables with MVEL:
- exchange: The current
org.switchyard.Exchange
. - context: The current
org.switchyard.Context
. - message: The current
org.switchyard.Message
.
expression="message.content" - This is the same as message.getContent(). expression="context[‘foo’]" scope="IN" - This is the same as context.getProperty("foo", Scope.IN).getValue(), in a null-safe manner.
Note
Scope.EXCHANGE
for global mappings, Scope.IN
for input mappings, and Scope.OUT
for output mappings.
<mapping expression="theExpression" expressionType="MVEL" scope="IN" variable="theVariable"/>
9.6.5. Channels
org.kie.runtime.Channel
. Here is an example illustrating the use of channels in a method:
package com.example rule "example rule" when $f : Foo ( bar > 10 ) then channels["Bar"].send( $f.getBar() ); endThe following example illustrates use of channels in XML:
<channels> <channel class="com.example.BarChannel" name="Bar"/> </channels>
9.6.6. SwitchYard Service Channel
<channel name="HelloWorld" reference="HelloWorld" operation="greet"/>Here,
- class: The channel implementation class. Default value is SwitchYardServiceChannel.
- name: The channel name.
- reference: The service reference qualified name.
- operation: The service reference operation name.
- input: The service reference operation input name.
9.6.7. Listeners
java.util.EventListener
.
KIE/Drools/jBPM Listener
interfaces. For example:
org.drools.event.WorkingMemoryEventListener
org.drools.event.AgendaEventListener
org.kie.event.process.ProcessEventListener
<listeners><listener class="org.drools.event.DebugProcessEventListener"/> <listener class="org.kie.event.rule.DebugWorkingMemoryEventListener"/> <listener class="com.example.MyListener"/> </listeners>
9.6.8. Loggers
<loggers> <logger interval="2000" log="myLog" type="THREADED_FILE"/> <logger type="CONSOLE/> </loggers>
9.7. Manifest
9.7.1. Manifest
9.7.2. Ways of Configuring the Manifest
Note
com/example/MyRules.drl
.
- with a KIE Container. (This relies upon the existence of a
META-INF/kmodule.xml
configuration file.)Here is the sampleMETA-INF/kmodule.xml
file:<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="com.example"> <ksession name="my-session"/> </kbase> </kmodule>
Here is the sample XML file:<manifest> <container sessionName="my-session"/> </manifest>
In addition to the sessionName attribute, you can also specify baseName and releaseId, if you desire.To enable it to scan for updates, simply setscan="true"
and, optionally,scanInterval=<# of milliseconds>
- with a manually defined list of resources.Here is the sample XML file:
<manifest> <resources> <resource location="com/example/MyProcess.bpmn" type="BPMN2"/> <resource location="com/example/MyRules.drl" type="DRL"/> </resources> </manifest>
Important
9.8. Properties
9.8.1. Properties
9.8.2. Add a Property
Procedure 9.11. Add a Property
- Launch the JBoss Developer Studio's SwitchYard Editor.
- Open a Type Hierarchy that has a root of
org.kie.conf.Option
. - Here you can see the full list. Here is one example:
<properties> <property name="drools.clockType" value="pseudo"/> <property name="drools.eventProcessingMode" value="stream"/> </properties>