This chapter will explain how to virtualize the building blocks of your SOA environment the clients and the endpoints.
Both for the clients and the endpoints what we've to reproduce are locations, formats and contents.
This is done with three key technologies:
XML virtualization consist in creating xml templates that act for any potential value of interest of a xml document.
In a xml document anything is a node but only some makes change our elaboration flow and we will call them decision nodes.
For example in the following fragment the action element is a decision node that changes the flow.
<book>
<id>8</id>
<action>add</action>
<book>
The flow will change depending if action will be add or delete.
In the following paragraphs we will see how to virtualize it, first describing how we can generate dynamically the values then how to use the SoaBox template engine or velocity.
The SoaBox one is suggested for simple virtualization because it's easier, for more complex needs use Velocity.
Their path on the menu is Virtualization > Values.
SoaBox provide an easy way to generate values with values generators. Their role is to generate values for the templates, for example taking them from a list or from a database.
A lá carte we got the following value generators:
The SoaBox built in template engine will be used on the files with the following extensions:
To use it create your Value bean and then place the name of the bean in gullwings, so if the value bean name is actionValue the syntax will be {actionValue}.
A complete example follows:
<book>
<id>8</id>
<action>{actionValue}</action>
<book>
You can also add multiple Value beans inside an element declaration for example the following is valid:
<book>
<id>8</id>
<action>{actionValue}</action>
<author>{nameValue}-{surnameValue}</author>
<book>
The build in xml engine supports also three statements:
To access the context information use the following syntax:
{ctx("http.param.userId")}
An example complete with xml follows.
<user>
<id>{ctx("http.param.userId")}</id>
</user>
The table that follows states the context information that can be accessed.
| Scope | Syntax | Example |
|---|---|---|
| System enviroment | env.variable | env.user.dir |
| HTTP request body | req.body | |
| HTTP request param | http.param.paramname | http.param.userId |
| The splitted uri | http.uri.x | http.param.1 |
| HTTP request header | http.header | http.header.soapaction |
To get an xml node on a request you the following syntax:
{xpath(//c:customer/c:name)}
If you have to define namespaces the syntax is:
{xpath({a=namespace1, b=namespace2}xpathexpression)}
An example follows:
{xpath({c=http://example.com/example, d=http://example.com/ex}//c:customer/c:name)}</p>
An example:
<updated>
<customer>
{xpath("{c=http://example.com/example}//c:customer/c:name")}
</customer>
</updated>
With the incude statement you can include an external template as follows:
{include(contained.vm)}
A xml example:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>{include(contained.vm)}
</soap:Body>
</soap:Envelope>
The position of the file will be relative to the parent, so if you want to include a file in a subdirectory you can you the following sintax:
{include(subdir/contained.vm)}
The include statement supports also system variable declarations, so you can write also declarations as:
{include({USER_HOME}contained.vm)}
SoaBox integrates also Velocity as template engine, to use it the file must have as extension .vm
You can use all the syntax of Velocity and use the Value beans via the replacer object with the syntax $replacer.replace("NameListValue"), where NameListValue is the value bean name.
A complete example follows:
#foreach ($i in [0..5])
$i $replacer.replace("UIDValue") $replacer.replace("RandomNumberValue")
#end
This will build a five row CSV file.
To the Velocity template also a context object is given named ctx.
This permits to have to context information like system's variables, HTTP headers, HTTP paremeters, the request body
To have access to the context use the following syntax:
$ctx.get("env.java.home")
To print all the context in the log use the following syntax:
$ctx.print()
To access the context information the following standard is used.
| Scope | Syntax | Example |
|---|---|---|
| System enviroment | env.variable | env.user.dir |
| HTTP request body | req.body | |
| HTTP request param | http.param.paramname | http.param.userId |
| The splitted uri | http.uri.x | http.param.1 |
| HTTP request header | http.header | http.header.soapaction |
Server side it's also possibile to execute xpaths on the received xml.
To do that call xpath on the ctx's req.body object as follows:
$ctx.get("req.body").xpath("//c:customer/c:name")
If you need also to include the namespace definitions an example is:
$ctx.get("req.body").xpath("{soap=http://www.w3.org/2001/12/soap-envelope,c=http://example.com/example}//c:customer/c:name")
A example including also xml:
<updated>
<customer>
$ctx.get("req.body").xpath("{soap=http://www.w3.org/2001/12/soap-envelope,
c=http://example.com/example}//c:customer/c:name")
</customer>
</updated>
For more info on the Velocity language refer to the Apache Velocity website:
http://velocity.apache.org/
To virtualize the clients means to call a destination or to publish selected content on a location, activating the elaboration flow.
The location/destination are defined with the destinations.
The content are files, created or not with the xml virtualization and the selection is done with the selectors.
The job aggregates all those beans and the publishing can be started immediately or scheduled with a trigger.
The selector has as role to select which files or templates to publish.
There is also a special type of selector called Quantity that just select a quantity with no content.
This is the proper Selector if you want, for example, to just call an HTTP get without sending some content.
To work with the selectors the menu is Virtualization > Client > Selectors
Actually five types of selectors are implemented:
<bean name="getHotelDetailSelector"
class="com.blacksoa.box.selectors.SingleFileSelector">
<property name="inputFile">
${jboss.server.home.dir}/deploy/soaBox/virtualClient.sar/input/dir/file.soap
</property>
<property name="quantity">1</property>
</bean>
With the quantity you select how many times the file or files will be selected when the job will be run.
A destination is where the content will be pubblished or a location that will be called.
To work with the destinations the menu is Virtualization > Client > Destinations
The following destination are available:
All the destination have the name property that is used for proper logging, the other attributes are different depending on the needs to know which attribute you can configure refer to the appendix.
The destinations can also be chained, to do that you have to pass a reference (the BID) of the destination to the next one with the Next field.
An example of configuration file with chaining follows:
<bean name="getHotelDetailRequest"
class="com.blacksoa.box.destinations.Soap">
<property name="name">http://localhost:8680/virtual/somepath</property>
<property name="next">AnotherDestinationBID</property>
<property name="log">false</property>
<property name="url">http://localhost:8680/virtual/somepath</property>
<property name="contentType">application/soap+xml</property>
<property name="connTimeout">5000</property>
<property name="contentCharset">UTF-8</property>
<property name="threads">3</property>
</bean>
For the HTTP destinations (Http, Soap, Get, Post, Put, Create, Delete), it's possibile to virtualize the URLs.
This can be done using the Value beans inside the URL.
If we got a Value bean called IdValue, that returns an incrementing id, we can use it inside the URL as follows:
http://localhost:xxxx/virtual/rest/get/{IdValue}
The {IdValue} will be replaced by the IdValue bean. Generating for every request a new URL like:
A job is an aggregation of the following elements:
If no trigger is given the job will be run only one time, else based on the trigger.
To create the other parts use the "Add new" button on the Virtual Client tab in the Console.
For the details see the relative paragraphs.
The list of jobs is accessible also with the menu Virtualization > Client > Configuration
An example of job's configuration file follows.
<bean name="TriggeredJob" class="com.blacksoa.box.job.Job">
<property name="name">Triggered</property>
<property name="threads">1</property>
<property name="group">Flows</property>
<property name="trigger">
<value-factory bean="EveryMinuteTrigger" method="createBean"/>
</property>
<property name="selector">
<inject bean="DefaultFileSelector" state="Instantiated"/>
</property>
<property name="destination">
<inject bean="DefaultWSDestination"/>
</property>
<install state="configured" method="addJob" bean="VirtualClientService">
<parameter>
<this/>
</parameter>
</install>
</bean>

On the menu the path to the server virtualization is Virtualization > Server > Configuration.
The work that the Virtual Server performs is to return an HTTP response, if needed also using virtualized content, depending of the result of chaining matchers and rules and if needed to start a Virtual Client job.
In this way you can make it act exactly as the endpoints your application will be calling for real.
The server virtualization is based on a servlet registered on the URL:
http://locahost:8060/virtual
Everything that comes after the context /virtual will be used to make the match against the provided regular expression.
So as example for http://localhost:8060/virtual/example/anything the match will be on the URI /example/anything
The first step is to select or create a configuration file on the server field and then build the matchers and rules chain for the URLs.
The chain of URLs, matchers and rules permits to return different content depending on a lot of conditions.
We must think this chain as a pipeline from which we return a HTTP response (a response code and if needed a file) when there is a match.
When the specified Request regular expression matches the URI of a configuration one, the matching starts passing the rules to the current matcher and checking the validity of the given rule expression against the matcher.
The first step is to define a Request regular expression. The goal of the Request is to start the Matchers and Rules evaluation only on certains URLs.
As written the regular expression will be executed agains the part of the url after
http://domain:port/virtual.
So for example to match exactly http://localhost:8060/virtual/example/anything use as Request configuration ^(/example/anything)$
Or another example to match both http://localhost:8060/virtual//rest/get/1 and http://localhost:8060/virtual//rest/get/2 use as request configuration (/rest/get/)(.*)
In the appendix you will find many example of regular expression, that should be usefull in most cases.
When a Request regular expression matches, the evaluation of the Matchers starts.
A Matcher is a class that has the role to apply the Rules on the request and check if there is a match.
The Rule class is the container of the rule to be used by the Matcher, and the HTTP response to provide when the rule is valid.
The HTTP response consists in the response code, the content type, and the response file when needed.
For the reponse file you can use both velocity and the SoaBox xml template engine, for more info refer to the xml virtualization chapter.
On the Rule is also possibile to define a Virtual Client Job to start.
If no match is found the process proceed with the next, if all fails the default HTTP response is served.
The available matchers are:
| Matcher | Description |
|---|---|
| XPATH | matches against the request content, selecting a node with the given xpath and comparing the value with the given regular expression |
| HTTP_PARAM | check for HTTP parameters |
| HTTP_HEADER | check for HTTP headers |
| REGEX | check if the request content matches the given regular expression |
| PERCENTAGE | match on a percentage basis |
The syntax of the matchers follows:
| Matcher | Description |
|---|---|
| XPATH | {ns=http://namespace1.com, ns1=http://namespace1.com...}xpath=somevalue |
| HTTP_PARAM | param (checks simply if the param exist), param=value (checks the the param equals the value) |
| HTTP_HEADER | aheader (checks simply if the aheader exist), aheader=value (checks the the aheader equals the value) |
| REGEX | reqex. The regular expression will be run against the request content, the used regular expression engine is the Java one |
| PERCENTAGE | an int between 0 and 100 |
In the following screenshot shows an example:

The flow of this example will start when a call to http://localhost8086/virtual/examples/matchers will be made and will act as follows:
SoaBox can create the Virtual Server and Virtual Client jobs starting from a WSDL.
To do that simply go to the menu File > Import > WSDL...
The following page will be displayed.

If you want to load the WSDL from a file press the "choose" button else insert the URL of the WSDL in WSDL/URL.
Select what you want to be generated Virtual Client, Virtual Server or both.
Select if you want to convert the soap destinations URLs to the Virtual Server ones. If yes the Virtual Client destination URL will point to http://localhost:XXXX/virtual/originalURI/
Click Upload.
The WSDL will be imported and one ore more jobs, selectors and destinations will be created and the console page will be displayed with the new created jobs.
Using the file manager you can see that in the Virtual Client input folder the xml/soap files has been created and under Virtualization > Client in the various submenus (Configuration, Destinations, Selectors) you'll find the created jobs, destinations and selectors.
If you have selected to create the Virtual Server also the server configuration and files will be created. To se the configuration go to the menu Virtualization > Server > Configuration. You will not see any entry in the Console's Virtual Server tab untill some request is made.
Now you can start fine tuning the created configurations.
The trigger are based on quartz, both simple and cron triggers can be created.
To have an exhaustive guide on creating triggers you can refer to the Quartz documentation at the address:
http://www.opensymphony.com/quartz
The most commonly used trigger is CronTrigger, a trigger based on a cron expression.
<beanfactory name="EveryMinuteTrigger" class="org.quartz.CronTrigger"> <property name="name"> EveryMinuteService1Trigger </property> <property name="cronExpression">0 * * * * ?</property> </beanfactory>
When we virtualize we can need to setup the environment or to keep it clean or to perform other activities, for this SoaBox provides the possibility to define and use tasks.
To work with the tasks the menu is Virtualization > Tasks > Destinations
The following tasks are available:
The task can be triggered or not. If it's not triggered the task will be run immediately and at every box restart.
The destinations can also be chained, to that you have to pass a reference of the destination to the next one with the Next field
An example of configuration file with chaning follows:
<bean name="CleanOutDirTask" class="com.blacksoa.box.tasks.DeleteFiles">
<property name="name">OutDirCleaner</property>
<property name="group">Cleaners</property>
<property name="trigger">
<value-factory bean="EveryMinuteTrigger" method="createBean"/>
</property>
<property name="file">
${jboss.server.home.dir}/deploy/virtualClient.sar/output
</property>
<install state="configured" method="addTask" bean="TaskService">
<parameter>
<this/>
</parameter>
</install>
</bean>