Develop Generic VCL Call
Contents
Description
A VCL Generic Call is a facility to enable the use of custom Java libraries in GreenVulcano® ESB. The plug-in must implement the CallOperation interface and can be configured in GV Console® or VulCon® through a simple configuration interface.
Configure the Eclipse workspace
To develop the plug-in is needed to reference some GreenVulcano® ESB libraries: in GV_HOME/application/deploy/gvesb-javaee5-*.ear/lib
- gvbase-*.jar
- gvcore-*.jar
- gvvcl-*.jar
in JBOSS_HOME/commons/lib
- log4j.jar
The simplest mode is to define a User Libaries set, named "GVESB", as show in the image.
The create an Eclipse Java project (ex.GenericVCLCall
) and add the GVESB User Libraries set to the project's classpath.
Generic VCL Call life cycle
A Generic VCL Call life cycle is the same as every VCL plug-in:
- VCL plug-in instances are pooled
- the
init
method is called at instance creation time - the
perform
method is called at every service invocation - the
cleanUp
method is called after every perform invocation - the
destroy
method is called at instance destruction time
Create a Generic VCL Call class
In the Eclipse project create a class with the parameters as illustrated in the image:
The example plug-in is a simple class that perform a toupper|tolowe|echo operation on a String input or optionally to cancel the input data.
Basic development guidelines
Following some guidelines useful to develop a GreenVulcano® ESB VCL plug-in.
Package name
Using a package name that starts with it.greenvulcano.gvesb.virtual.
automatically enable the logging in the GVVCL log file.
Logging
To enable the logging in GreenVulcano® ESB plug-in import the following class anche defines the logger
instance as illustraded:
import it.greenvulcano.log.GVLogger;
import org.apache.log4j.Logger;
public class TestGenericCall implements CallOperation {
private static final Logger logger = GVLogger.getLogger(TestGenericCall.class);
The GVLogger
class enable the logger reconfiguration at runtime.
VCL internal methods
Some methods defined by the CallOperation interface must be coded in a standard mode, as indicated in the following code:
protected OperationKey key = null;
....
public OperationKey getKey() {
return key;
}
public void setKey(OperationKey key) {
this.key = key;
}
public String getServiceAlias(GVBuffer gvBuffer) {
return gvBuffer.getService();
}
The indicated methods are used internally by the VCL framework.
Plug-in initialization code
To read the plug-in's configuration parameters must be used the XMLConfig utility class.
For the Generic VCL Call the XML node describing the configuration parameters is the following:
<generic-call class="it.greenvulcano.gvesb.virtual.test.TestGenericCall"
name="test-call" type="call">
<call-parameter name="operation" value="toupper" type="param"/>
<!-- optional -->
<call-parameter name="cancelData" value="false" type="param"/>
</generic-call>
The following code illustrate the plug-in initialization:
private String operation = null;
private boolean cancelData = false;
....
public void init(Node cfg) throws InitializationException {
try {
// reads the 'operation' configuration parameter as String
operation = XMLConfig.get(cfg, "call-parameter[@name='operation']/@value");
// reads the 'cancelData' configuration parameter as boolean, setting 'false' as default value
cancelData = XMLConfig.getBoolean(cfg, "call-parameter[@name='cancelData']/@value", false);
// check the 'operation' parameter value
if ((operation == null) || !(operation.equals("toupper") || operation.equals("tolower") || operation.equals("echo"))) {
logger.error("Invalid 'operation' value:" + operation);
throw new InitializationException("GVVCL_XML_CONFIG_ERROR", new String[][]{{"exc", "Invalid 'operation' value:" + operation},
{"key", key.toString()}});
}
logger.debug("Initialized TestGenericCall: operation[" + operation + "] cancelData["
+ cancelData + "]");
}
catch (InitializationException exc) {
throw exc;
}
catch (Exception exc) {
logger.error("An error occurred reading configuration data.", exc);
throw new InitializationException("GVVCL_XML_CONFIG_ERROR", new String[][]{{"exc", exc.toString()},
{"key", key.toString()}}, exc);
}
}
Plug-in execution code
The following code illustrate the plug-in logic execution:
public GVBuffer perform(GVBuffer gvBuffer) throws ConnectionException, CallException, InvalidDataException {
try {
String input = getInputString(gvBuffer);
logger.debug("TestGenericCall input: " + input);
String output = null;
if (!cancelData) {
if (operation.equals("toupper")) {
output = input.toUpperCase();
}
else if (operation.equals("tolower")) {
output = input.toLowerCase();
}
else {
output = input;
}
}
logger.debug("TestGenericCall output: " + output);
gvBuffer.setObject(output);
return gvBuffer;
}
catch (Exception exc) {
throw new CallException("GVVCL_CALL_SERVICE_ERROR", new String[][]{{"service", gvBuffer.getService()},
{"system", gvBuffer.getSystem()}, {"id", gvBuffer.getId().toString()},
{"message", exc.getMessage()}}, exc);
}
}
private String getInputString(GVBuffer gvBuffer) throws Exception
{
String str = null;
Object currentObject = gvBuffer.getObject();
if (currentObject instanceof String) {
str = (String) currentObject;
}
else if (currentObject instanceof byte[]) {
str = new String((byte[]) currentObject);
}
else {
str = currentObject.toString();
}
return str;
}
The following code illustrate the plug-in clean-up, executed after every logic execution, in this case the code don't perform anything:
public void cleanUp() {
// do nothing
}
The following code illustrate the plug-in destroy, in this case the code don't perform anything:
public void destroy() {
// do nothing
}
Plug-in deployment
Export the Eclipse project as a jar file:
Generate the jar in GV_HOME/application/deploy/gvesb-javaee5-*.ear/lib, named, as example, test-vclcall.jar:
Plug-in configuration and testing
In a VulCon® project insert a new generic-call operation and the required parameters:
Attribute | Value |
---|---|
class | it.greenvulcano.gvesb.virtual.test.TestGenericCall |
name | test-call |
Its two call-parameter sub-elements are:
Name | Value |
---|---|
operation | toupper|tolower|echo |
cancelData | true|false |
Create a simple service named TestGenericCall
(ex. through the Vulcon's Wizard New Service) that use the configured test-call operation:
then start GreenVulcano® ESB server and deploy the service using the GV Console®.
Reload the GVCore.xml configuration file and invoke the deployed service TestGenericCall
setting as input a lower-case string:
invoke the RequestReply
operation:
Follows a GVVCL log file fragment illustrating the initialization, execution/cleanup and destroy phases:
[15 mag 2012 15:31:57,016][.....] - Initializing the Operation Manager Pool. [it.greenvulcano.gvesb.virtual.pool.OperationManagerPool] [15 mag 2012 15:31:57,019][.....] - OperationManagerPool - not found instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPool] [15 mag 2012 15:31:57,020][.....] - OperationManagerPoolElement created for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:31:57,020][.....] - OperationManagerPoolElement - CHECK - not found Operation instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:31:57,022][.....] - BEGIN creating 'call' operation: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.OperationFactory] [15 mag 2012 15:31:57,022][.....] - Class name: it.greenvulcano.gvesb.virtual.test.TestGenericCall [it.greenvulcano.gvesb.virtual.OperationFactory] [15 mag 2012 15:31:57,026][.....] - BEGIN INITIALIZATION: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,026][.....] - Initialized TestGenericCall: operation[toupper] cancelData[false] [it.greenvulcano.gvesb.virtual.test.TestGenericCall] [15 mag 2012 15:31:57,027][.....] - BEGIN - Build Alias Map [it.greenvulcano.gvesb.virtual.ServiceAlias] [15 mag 2012 15:31:57,027][.....] - END - Build Alias Map [it.greenvulcano.gvesb.virtual.ServiceAlias] [15 mag 2012 15:31:57,027][.....] - END INITIALIZATION: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,027][.....] - END creating 'call' operation: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.OperationFactory] [15 mag 2012 15:31:57,036][.....] - OperationManagerPool - found instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPool] [15 mag 2012 15:31:57,036][.....] - OperationManagerPoolElement - GET - found Operation instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:31:57,036][.....] - BEGIN PERFORM: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,036][.....] - TestGenericCall input: test generic vcl call [it.greenvulcano.gvesb.virtual.test.TestGenericCall] [15 mag 2012 15:31:57,036][.....] - TestGenericCall output: TEST GENERIC VCL CALL [it.greenvulcano.gvesb.virtual.test.TestGenericCall] [15 mag 2012 15:31:57,036][.....] - END PERFORM: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,037][.....] - BEGIN CLEANUP: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,037][.....] - END CLEANUP: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:31:57,037][.....] - OperationManagerPool - releasing instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPool] [15 mag 2012 15:31:57,037][.....] - OperationManagerPoolElement - releasing instance in pool for key: class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:47:00,580][.....] - BEGIN discarding class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:47:00,580][.....] - Destroy: it.greenvulcano.gvesb.virtual.CallOperationWrapper@38cbb303 [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement] [15 mag 2012 15:47:00,580][.....] - BEGIN DESTROY: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:47:00,580][.....] - END DESTROY: type=call, key=class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.CallOperationWrapper] [15 mag 2012 15:47:00,580][.....] - END discarding class it.greenvulcano.gvesb.core.flow.GVCoreOperationKey[key = 'GVSystems.xml:/GVSystems[1]/Systems[1]/System[2]/Channel[6]/generic-call[1]'] [it.greenvulcano.gvesb.virtual.pool.OperationManagerPoolElement]
Resources
Download the Eclipse projects: