Difference between revisions of "GVJade"

From GreenVulcano Wiki
Jump to: navigation, search
(Description)
(Examples of messaging through GVJADE)
 
(24 intermediate revisions by the same user not shown)
Line 8: Line 8:
 
==Description==
 
==Description==
  
ATM, GVJADE allows to run different flow scenarios, involving internal (JADEd) and external (GV's) contexts.
+
ATM, GVJADE allows to run different flow scenarios, involving internal (JADEd, using ACL messages) and external (GV's, using JMS queues) contexts.
 +
These scenarios are a direct proof of true bridging between a JADE platform and GV context:
  
Scenario 1 : '''Messaging communication started from the external (simulation of an external request to the inner agent):'''
+
Scenario 1 : '''Messaging communication started from an external service/application (simulation of an external request to the inner agent):'''
  
 
* Through a simple JMS queue an external context may send an XML message, containing usual ACL message components such as: sender, receivers, action and content. (See section '''Example of messaging through JADE''' for a viable example)
 
* Through a simple JMS queue an external context may send an XML message, containing usual ACL message components such as: sender, receivers, action and content. (See section '''Example of messaging through JADE''' for a viable example)
Line 21: Line 22:
 
Scenario 2 : '''Messaging communication started from inside the JADE platform agent (simulation of an inner update to deliver to the external context):'''
 
Scenario 2 : '''Messaging communication started from inside the JADE platform agent (simulation of an inner update to deliver to the external context):'''
  
* An internal business agent, with an system update ready to be posted to the external application, sends it to the bridging agent
+
* An internal business agent, with a system update ready to be posted to the external application, sends it to the bridging agent
 
* The agent enroutes it to a proper queue, translated in XML code
 
* The agent enroutes it to a proper queue, translated in XML code
* External application, waiting for the update, finds it and uses it, also preparing a proper response in XML and sending it to another queue
+
* External application, waiting for the update, finds and uses it, also preparing a proper response in XML and sending it to another queue
 
* Bridging agent pops the message from the queue and sends it back to originating business agent, in ACL format
 
* Bridging agent pops the message from the queue and sends it back to originating business agent, in ACL format
 +
 +
 +
Scenario 3 : '''GV messaging service running on a ditributed GV cluster'''
 +
 +
* With an XML registration message, a GV service can register through the proxy agent, which is meant to centralize communications
 +
* Once the service registration appliance is accepted, the GV "route" is stored and the service can be reached from others GV instances/services simply contacting the proxy agent
  
  
Line 37: Line 44:
  
 
     <GCJADEAdapterConfiguration>
 
     <GCJADEAdapterConfiguration>
    <Engine main="true" local-port="1500" gui="false" dump-options="true" no-display="true" platform-id="Main_GV_Container" nomtp="false">
+
    <Engine main="true" local-port="1500" gui="false" dump-options="true" no-display="true" platform-id="Main_GV_Container" nomtp="false"></Engine>
    </Engine>
 
 
    <Agents>
 
    <Agents>
 
    <Agent name="PingAgent" class="examples.PingAgent.PingAgent"/>
 
    <Agent name="PingAgent" class="examples.PingAgent.PingAgent"/>
Line 99: Line 105:
  
  
==Example of messaging through JADE==
+
==Examples of messaging through GVJADE==
  
 +
*Applying scenario 1
 
Configure a process to send a JMS message to the "''GV_JADE_Response_Queue''" queue, serviced under GV, with the following XML code:
 
Configure a process to send a JMS message to the "''GV_JADE_Response_Queue''" queue, serviced under GV, with the following XML code:
  
     <XMLMessage><sender>GVapp1</sender><receivers><receiver><name>PingAgent@Main_GV_Container</name></receiver></receivers><comm action=\"REQUEST\"/><content>ping</content></XMLMessage>
+
     <XMLMessage><sender>GVapp1</sender><receivers><receiver><name>PingAgent@Main_GV_Container</name></receiver></receivers><comm action="REQUEST"/><content>ping</content></XMLMessage>
  
 
This, as previously shown in case scenario 1, will trigger GVJADE processing the message to the inner JADE agent ("''PingAgent''").
 
This, as previously shown in case scenario 1, will trigger GVJADE processing the message to the inner JADE agent ("''PingAgent''").
The expected result to the "REQUEST:ping" message can be received through the "''GV_JADE_Request_Queue''" queue, which will be an "INFORM:pong" action.
+
The expected result to the ''REQUEST'':"''ping''" message can be received through the "''GV_JADE_Request_Queue''" queue, which will be an ''INFORM'':"''pong''" action.
 
 
 
 
 
 
 
 
This example shows how {{GVESB}} receipts and processes emails. The workflow consists in two services: ProcessSVCEmails which receives the messages and for each one calls service ProcessSingleSVCEmail that processes it.
 
 
 
ProcessSVCEmails service executes the following operations:
 
* Checks if there are new service messages
 
* For each one invokes a processing service
 
 
 
ProcessSingleSVCEmails service executes the following operations:
 
* Receives data from an email
 
* Reads the subject and verifies if it is well formatted
 
* If subject is well formatted invokes the respective service for the request. If don't, sends a preconfigured email.
 
 
 
The request service can be:
 
* A PDF report
 
* An Excel report
 
* A BIRT report
 
containing data about persons and credit cards.
 
 
 
=={{VULCON}} Configuration==
 
 
 
The preferred mode for creating a Service (at least its skeleton) is through the Service Wizard. Before using it you must first configure the VCL adapters and plugins needed.  To do that, go to the {{L_VULCON}} Adapter view.
 
 
 
===GVAdapters Configuration===
 
 
 
When emails will be read by the ProcessSingleSVCEmail, the [[GVBuffer]] of output will contain a XML with the available data. To read these data you will need a [[CollectionDataProvider]].
 
 
 
To insert a new CollectionDataProvider execute the following steps:
 
* From the {{VULCON}} Core view, expand the element GVDataProviderManager
 
* Right click the element DataProviders -> Insert After (Insert before)-> CollectionDataProvider
 
* Click the element just created and set the following parameters as:
 
: name="CREDIT::SVCEmailListDataProvider"
 
: source-selector="object"
 
: '''Field''':
 
:: direction="INOUT"
 
:: key="buffer"
 
:: '''Expression''':
 
::: type="xpath"
 
::: Expression: /MailMessages/Message
 
 
 
When a service requires the generation of a BIRT report, it is necessary to configure the [[GVDataHandlerConfiguration]] and [[GVBIRTReportConfiguration]] Adapters.
 
 
 
'''GVDataHandlerConfiguration'''
 
 
 
Inside of element [[GVDataHandlerConfiguration]] visualized from the {{L_VULCON}} Core view, insert a new [[DBOBuilder]] and set its attributes as:
 
* jdbc-connection-name="ds.gv_test"
 
* name="ListPersons"
 
Insert into ''ListPersons'' a new item DBOSelect with the property:
 
* name="ListPersons"
 
and containing an element statement with:
 
* id="1"
 
* type="select"
 
select ' ', 'NULL' from dual union all
 
select p.NAME, p.NAME from PERSON p
 
order by 1
 
 
 
'''GVBIRTReportConfiguration'''
 
 
 
Inside of elements [[GVBIRTReportConfiguration]] / [[GVBIRTReportConfiguration#ReportGroups|ReportGroups]], create a new ReportGroup (by right clicking element ReportGroups -> Insert After -> ReportGroup). Name it TestGRP.
 
 
 
Inside of ''TestGRP'', insert a new Report. Set its attributes as:
 
* config: "CreditCards.rptdesign"
 
* name: "Credit Cards"
 
Inside of Report ''Credit Cards'' insert an element ''Parameters'' containing the item ''Parameter'' setted as follow:
 
* control-type: "SELECT"
 
* label: "Nome"
 
* name: "NAME"
 
Inside of ''NAME'' put an element DHSource with the attributes:
 
* service: "ListPersons"
 
* sort: "true"
 
* use-string-map: "true"
 
 
 
Now you might define a new [[Group]], [[System]] and [[Channel]], if you do not want to use those already present, and then start the Wizard.
 
 
 
===GVCore Configurations===
 
 
 
When the request concerns the generation of a PDF Report, you also need a FOP transformation.
 
 
 
{{GVESB}} gives the function [[XSLFOPTransformation]] for configure it.
 
 
 
In this example, we use the file [[SearchPerson2FO.xsl]] and save it into $GV_HOME/gvdte/datasource/xsl/DataHandler/CREDIT folder.
 
 
 
From the {{VULCON}} core view, insert a new [[XSLFOPTransformation]]:
 
* Expand the element [[GVDataTransformation]]
 
* Right click the element Transformation -> Insert After -> [[XSLFOPTransformation]]
 
* Click the new [[XSLFOPTransformation]] element and set its attributes as follow:
 
: DataSourceSet="Default"
 
: XSLMapName="DataHandler/CREDIT/SearchPerson2FO.xsl"
 
: name="UserDataAsPDF"
 
 
 
====Defining System, Channel and Operations====
 
 
 
To define a System, go to {{VULCON}} core view and, into Systems element, insert the System CREDIT if it is not already present.
 
From there create the Channel CHANNEL_CREDIT_MAIL in which the following operations will be configured:
 
 
 
{|class="gvtable"
 
! Attribute/Sub-element !! Value
 
|-
 
| [[pop-call]] || name="ReceiveSVCEmail" <br/>delete-messages="true"  <br/>expunge="true" <br/>jndi-name="gvesb.mailServer"
 
|-
 
| [[smtp-call]] || name="SendEmailSVCResponse" <br/>jndi-name="gvesb.mailServer"  <br/>'''mail-message''':
 
: content-type="text-plain"
 
: high-priority="false"
 
: sender-display-name="GV ESB"
 
: subject="RE: ${property['SUBJECT']}"
 
: '''message-body''':
 
:: gvBuffer-dump="false"
 
:: '''message-text''':
 
::: Persons data
 
: '''attachments''':
 
:: '''gvBuffer''':
 
::: name="PersonsData_${@it.greenvulcano.util.txt.DateUtils@nowToString('yyyyMMddHHmmss')}.<br/>${property['FILE_EXT']}"
 
|-
 
| [[smtp-call]] || name="SendEmailNoSVC" <br/>jndi-name="gvesb.mailServer"  <br/>'''mail-message''':
 
: content-type="text-plain"
 
: high-priority="true"
 
: sender-display-name="GV ESB"
 
: subject="RE: ${property['SUBJECT']}"
 
: '''message-body''':
 
:: gvBuffer-dump="false"
 
:: '''message-text''':
 
::: Invalid service request. Available Services:
 
:::: SVC=LIST_EXCEL[!NAME=.....]
 
:::: SVC=LIST_PDF[!NAME=.....]
 
:::: SVC=LIST_BIRT[!TYPE=EXCEL or PDF(default)][!NAME=.....]
 
|- 
 
| [[excel-call]] || name="listPerson" <br/>'''GVExcelReport''':
 
: format="default"
 
: group="CREDIT"
 
: jdbc-connection="ds.gv_test"
 
: name="listPerson"
 
: '''Sheet''':
 
:: id="1"
 
:: name="Person List"
 
:: title="Person List - <nowiki>timestamp{{dd/MM/yyyy HH:mm:ss}}</nowiki>"
 
:: '''statement''':
 
::: type="select"
 
select p.NAME as Name, p.BIRTHDATE as BirthDate, c.NAME as City
 
from PERSON p, CITY c
 
where p.ID_CITY = c.ID
 
<nowiki>decode{{@{{NAME}}::NULL::::and p.NAME='@{{NAME}}'}}</nowiki>
 
order by c.NAME, p.NAME
 
: '''Sheet''':
 
:: id="2"
 
:: name="Credit Card List"
 
:: title="Credit Card List - <nowiki>timestamp{{dd/MM/yyyy HH:mm:ss}}"</nowiki>
 
:: '''statement''':
 
::: type="select"
 
select p.NAME as Name, cc.CNUMBER as CardNumber, cc.CREDIT as Credit,
 
decode(cc.ENABLED, 'Y', 'Yes', 'No') as Active
 
from PERSON p, CREDIT_CARD cc
 
where p.ID = cc.ID_OWNER
 
<nowiki>decode{{@{{NAME}}::NULL::::and p.NAME='@{{NAME}}'}}</nowiki>
 
order by p.NAME
 
|-
 
| [[birt-report-call]] || groupName="TestGRP" <br/>name="CreditCards" <br/>reportName="Credit Cards" <br/> reportType="excel"
 
|-
 
| [[dh-call]] || name="UserDataAsPDF"<br/> '''DBOBuilder''':
 
: jdbc-connection-name="ds.gv_test"
 
: name="UserDataAsPDF"
 
: '''DHVariables''':
 
:: DHVariable name="decimal-separator" value="."
 
:: DHVariable name="grouping-separator" value=","
 
:: DHVariable name="format" value="#0.00"
 
:: DHVariable name="NAME" value="NULL"
 
: '''DBOSelect''':
 
:: name="UserDataAsPDF"
 
:: transformation="UserDataAsPDF"
 
:: '''statement''':
 
::: id="1"
 
::: keys="1,2,3"
 
::: type="select"
 
select p.NAME, p.BIRTHDATE, c.NAME, cc.CNUMBER, cc.CREDIT, cc.ENABLED
 
from PERSON p, CITY c, CREDIT_CARD cc
 
where p.ID_CITY = c.ID
 
and p.ID = cc.ID_OWNER
 
<nowiki>decode{{@{{NAME}}::NULL::::and p.NAME like '%@{{NAME}}'}}</nowiki>
 
order by c.NAME, p.NAME
 
|}
 
 
 
{{GVESB}} includes the [[HSQLDB support database]], where the schema GV_TEST is already configured.
 
 
 
===Flow implementation===
 
 
 
For creating a new service using the Wizard execute the following steps:
 
# From the Core View of {{VULCON}}. Right click the element Services -> Wizard New Service
 
# A new window will be open where you can set the name of the Service you want to create, in this case we name it ProcessSCVEmails, and as Group, we use CREDIT_GRP. You can also select the scenario, for this example it will be [[Paradigms_of_communication#synchronous-synchronous|synchronous-synchronous]]. Click next.
 
# Set System as CREDIT, Channel as CHANNEL_CREDIT_MAIL and select the Operation ReceiveSVCEmails. Then finish.
 
 
 
[[File:GVExamples_ProcessSCVEmails.jpg|thumb|ProcessSCVEmails Service]]As you can see from the core view, inside the Services element, a new Service named ProcessSCVEmails has been created. The editor will be opened automatically, showing a workflow that must be modified successively as seen in the picture.
 
 
 
First of all, change the Operation name to Request. This is done by clicking the element Operation and setting the attribute name present in the Property view.
 
 
 
Insert a [[Conditions|Condition]] which will test if there are new emails to be processed. This is done from the {{VULCON}} Core view inserting into Flow a new element Conditions (right clicking the element Flow). Inside of it insert a [[GVBufferCondition]] and set its attributes and subelements as follow:
 
* Condition: EmailPresent
 
* [[GVBufferCondition]]/Property:
 
:* name: POP_MESSAGE_COUNT
 
:* operator: greater
 
:* value: 0
 
:* value-type: integer
 
 
 
Expand the [[Palette]] if it is not already visible from the Editor View. This can be done by clicking into a little arrow head present into the Editor right top corner. The steps to modify the workflow are:
 
* Click the [[GVOperationNode]] "request" and set its attributes as follow:
 
: dump-in-out="false"
 
: id="check_pop"
 
: id-system="CREDIT"
 
: input="input"
 
: next-node-id="check_status"
 
: operation-name="ReceiveSVCEmail"
 
: output="emails"
 
* Insert a [[GVIteratorOperationNode]] ( drag and drop an [[Iterations|Iterator Call node]] from the [[palette]] into the Editor). Click this new element and set its attributes as follow:
 
: collection-dp="CREDIT::SVCEmailListDataProvider"
 
: id="process"
 
: input="emails"
 
: next-node-id="end"
 
: output="processed"
 
* From the {{VULCON}} Core view, insert an element CoreCall inside of the [[GVIteratorOperationNode]] already created. This is done expanding the [[GVIteratorOperationNode]] element, right clicking the element proxy-call created automatically -> Change to -> CoreCall. Set its attributes as:
 
: change-log-context="true"
 
: dynamic="false"
 
: id-service="ProcessSingleSVCEmail"
 
: id-system="CREDIT"
 
: operation="Request"
 
: ref-dp="stringSerializeNodeDataProvider"
 
* Insert a GVEndNode (drag and drop an EndNode into the editor) and set its attributes as:
 
: end-business-process="yes"
 
: id="end"
 
: output="processed"
 
* Click on the ''return_status'' End Node and change its attributes as:
 
: end-business-process="yes"
 
: id="end-noemail"
 
: output="emails"
 
: [[GVEndNode]]/ChangeGVBuffer:
 
:: clear-data="true"
 
* Click on the ''return_error'' End Node and change its attributes as:
 
: end-business-process="yes"
 
: id="end-poperror"
 
: output="emails"
 
: [[GVEndNode]]/ChangeGVBuffer:
 
:: clear-data="true"
 
* Create the [[Palette|Connections]]
 
: From the [[Palette]], select a [[Palette|Routing Connection]] (blue arrow) and create a connection between ''check_status'' and ''process''. A new windows will be open for selecting the Condition. Select EmailPresent and click OK.
 
: Select a Default Connection (black arrow) and create a connection between ''process'' and ''end''.
 
* Save the editor clicking on the apposite Eclipse icon and close it.
 
 
 
 
 
Repeat these steps for the ProcessSingleSVCEmail, beginning from the Wizard to create this new Service with the parameters:
 
: Service name: ProcessSingleSVCEmail
 
: Group: CREDIT_GRP
 
: Scenario: synchronous-synchronous
 
: System: CREDIT
 
: Channel: CHANNEL_CREDIT_MAIL
 
: Operation: SendEmailNoSVC
 
 
 
[[File:GVExamples_ProcessSingleSCVEmail.jpg|thumb|ProcessSingleSCVEmail Service]]Service ProcessSingleSCVEmail will be created, containing a RequestReply Operation. The editor will be opened automatically, showing a workflow that must be modified successively as seen in the picture.
 
  
The first step to be follow is to create three new operations, one for each possible report type:
 
# Operation with attributes forward-name="LIST_BIRT" name="Forward" operation-activation="on" out-check-type="sys-svc-id"
 
# Operation with attributes forward-name="LIST_EXCEL" name="Forward" operation-activation="on" out-check-type="sys-svc-id"
 
# Operation with attributes forward-name="LIST_PDF" name="Forward" operation-activation="on" out-check-type="sys-svc-id"
 
  
For creating a new Operation you can use the Wizard, setting the same Service name, or directly from the {{L_VULCON}} Core view right clicking the element Service -> Insert After (or Insert Before) -> Operation. In both case you will set its parameters as described before.
+
*Applying scenario 2
 +
In order to trigger scenario 2 shown above a JADE platform must be run (via terminal console or IDE such as Eclipse).
 +
Through the platform run a simple agent with send/response capabilities (such as default ''DummyAgent'').  
 +
Prepare a message to send with:
  
These operations will extract data from the DB, save it into a file, and will send and email with this file as attachment. Each operation will have a Participant with id-channel="CHANNEL_CREDIT_MAIL" and id-system="CREDIT", and its first node will be ''extract_data''.
+
- address to reach as the GVJADE address/agent (address is the platform one readable from the GVJADE output, while the agent name is the bridging one: "'''JadeToGvAgent'''")
  
The following table shows how configure it:
+
- communicative act configured as ''REQUEST''
{|class="gvtable"
 
! Node/Subelement !! LIST_BIRT !! LIST_EXCEL !! LIST_PDF
 
|-
 
| [[GVOperationNode]] ||
 
: dump-in-out="false"
 
: id="extract_data"
 
: id-system="CREDIT"
 
: input="to_process"
 
: next-node-id="add_ext"
 
: operation-name="CreditCards"
 
: output="data"
 
||
 
: dump-in-out="false"
 
: id="extract_data"
 
: id-system="CREDIT"
 
: input="to_process"
 
: next-node-id="add_ext"
 
: operation-name="listPerson"
 
: output="data"
 
||
 
: dump-in-out="false"
 
: id="extract_data"
 
: id-system="CREDIT"
 
: input="to_process"
 
: next-node-id="add_ext"
 
: operation-name="UserDataAsPDF"
 
: output="data"
 
|-
 
| [[GVOperationNode]]/InputServices/ognl-script-service
 
||
 
||
 
||
 
: critical="yes" internal="yes"
 
|-
 
| [[GVOperationNode]]/InputServices/ognl-script-service/ognl-script-call
 
||
 
||
 
||
 
: name="setDBService"
 
: '''OGNLScript'''
 
: setProperty('DH_SERVICE_NAME', 'UserDataAsPDF')
 
|-
 
| [[ChangeGVBufferNode]]
 
||
 
: dump-in-out="false"
 
: id="add_ext"
 
: input="data"
 
: next-node-id="send_email"
 
: op-type="change GVBuffer" 
 
||
 
: dump-in-out="false"
 
: id="add_ext"
 
: input="data"
 
: next-node-id="send_email"
 
: op-type="change GVBuffer"
 
||
 
: dump-in-out="false"
 
: id="add_ext"
 
: input="data"
 
: next-node-id="send_email"
 
: op-type="change GVBuffer"
 
|-
 
| [[ChangeGVBufferNode]]/ChangeGVBuffer
 
||
 
: clear-data="false"
 
||
 
: clear-data="false"
 
||
 
: clear-data="false"
 
|-
 
| [[ChangeGVBufferNode]]/ChangeGVBuffer/PropertyDef
 
||
 
: name="FILE_EXT"
 
: value="decode{{ognl{{property<br/>['BIRT_REPORT_TYPE']}}::<br/>excel::xls::pdf}}"
 
||
 
: name="FILE_EXT"
 
: value="xsl"
 
||
 
: name="FILE_EXT"
 
: value="pdf"
 
|-
 
| [[GVOperationNode]]
 
||
 
: dump-in-out="false"
 
: id="send_email"
 
: id-system="CREDIT"
 
: input="data"
 
: next-node-id="end"
 
: operation-name="SendEmailSVCResponse"
 
: output="data" 
 
||
 
: dump-in-out="false"
 
: id="send_email"
 
: id-system="CREDIT"
 
: input="data"
 
: next-node-id="end"
 
: operation-name="SendEmailSVCResponse"
 
: output="data" 
 
||
 
: dump-in-out="false"
 
: id="send_email"
 
: id-system="CREDIT"
 
: input="data"
 
: next-node-id="end"
 
: operation-name="SendEmailSVCResponse"
 
: output="data"
 
|-
 
| [[GVEndNode]]
 
||
 
: end-business-process="yes" id="end"
 
: output="data"
 
||
 
: end-business-process="yes" id="end"
 
: output="data"
 
||
 
: end-business-process="yes" id="end"
 
: output="data"
 
|-
 
| [[GVEndNode]]/ChangeGVBuffer
 
||
 
: clear-data="true"
 
||
 
: clear-data="true"
 
||
 
: clear-data="true"
 
|}
 
                   
 
Now turn to the RequestReply Operation, created with the Wizard configuration of Service ProcessSingleSVCEmails:
 
* Change its attributes as:
 
: name="Request" operation-activation="on" out-check-type="none"
 
* Insert a [[Conditions|Condition]] which will control the request service type
 
: right click Flow element -> Insert before -> Conditions
 
: right click Conditions element -> Insert after -> [[JavaScriptCondition]]
 
: click [[JavaScriptCondition]] element and set the parameters ''condition'' as "CheckServiceName" and ''scope-name'' as "gvesb"
 
: insert a Script element with the attribute script as
 
:: var services = {'LIST_EXCEL':'1', 'LIST_PDF':'1', 'LIST_BIRT':'1'};
 
:: var data = environment.get(dataName);
 
:: var svc = data.getProperty('SVC');
 
:: ('1' == services[svc]);
 
* Insert the nodes and set their attributes as described by the following table:
 
{|class="gvtable"
 
! Node/Subelement !! Atributes
 
|-
 
| [[ChangeGVBufferNode]] ||
 
: dump-in-out="true" id="prepare" input="input"
 
: next-node-id="check_service" output="prepared"
 
|-
 
| [[ChangeGVBufferNode]]/ChangeGVBuffer ||
 
: clear-data="false" scope-name="gvesb"
 
|-
 
| [[ChangeGVBufferNode]]/ChangeGVBuffer/Script ||
 
: var doc=XMLUtils.parseDOM_S(new java.lang.String(data.getObject()),false,true);
 
: var subject = XMLConfig.get(doc,'/Message/Subject', 'NULL');
 
: data.setProperty("SUBJECT",subject);
 
: var to = XMLConfig.get(doc,'/Message/ReplyTo', 'NULL');
 
: data.setProperty("GV_SMTP_TO",to);
 
: var cc = XMLConfig.get(doc,'/Message/Cc', 'NULL');
 
::  if (cc != 'NULL') {
 
::  data.setProperty("GV_SMTP_CC",cc);
 
::  };
 
: data.setProperty('NAME', 'NULL');
 
: data.setProperty('TYPE', 'PDF');
 
: var items = subject.trim().split("!");
 
:: for (i=0; i < items.length; i++) {
 
::: var  item = items[i].trim().split("=");
 
::: if (item.length > 1) {
 
:::: var name = item[0].trim();
 
:::: var value = item[1].trim();
 
:::: data.setProperty(name,value);
 
::::  }
 
:::  };
 
: data.setProperty('BIRT_REPORT_TYPE', data.getProperty('TYPE').toLowerCase());
 
|-
 
| [[GVNodeCheck]] ||
 
: default-id="send_nosvc_email"
 
: id="check_service"
 
: input="prepared"
 
: on-exception-id="end-exc"
 
|-
 
| [[GVNodeCheck]]/GVRouting ||
 
: condition="CheckServiceName"
 
: next-node-id="send_user_data"
 
|-
 
| [[GVCoreCallNode]] ||
 
: change-log-context="true"
 
: dynamic="true"
 
: id="send_user_data"
 
: id-service="ProcessSingleSVCEmail"
 
: id-system="CREDIT"
 
: input="prepared"
 
: next-node-id="check_status"
 
: operation="ognl{{#object.getProperty('SVC')}}"
 
: output="output"
 
: overwrite-sys-svc="true"
 
|-
 
| [[GVOperationNode]] ||
 
: dump-in-out="false"
 
: id="send_nosvc_email"
 
: id-system="CREDIT"
 
: input="prepared"
 
: next-node-id="check_status"
 
: operation-name="SendEmailNoSVC"
 
: output="output"
 
|-
 
| [[GVNodeCheck]] ||
 
: default-id="end"
 
: id="check_status"
 
: input="output"
 
: on-exception-id="end-exc"
 
|-
 
| [[GVEndNode]] ||
 
: end-business-process="yes"
 
: id="end-exc"
 
: output="output"
 
|-
 
| [[GVEndNode]]/ChangeGVBuffer ||
 
: clear-data="true"
 
|-
 
| [[GVEndNode]] ||
 
: end-business-process="yes"
 
: id="end"
 
: output="output"
 
|-
 
| [[GVEndNode]]/ChangeGVBuffer ||
 
:clear-data="true"
 
|}
 
  
=={{GVCONSOLE}} Configuration==
+
- content edited a simple "''ping''" (a simple content to update the internal status to the outside world)
  
It is time to deploy and test your new Service.  
+
Then press to send the message.
  
Let's send a service email. The first step is to configure a new email account with the properties:<br/>
+
An ''INFORM'':"''pong''" message will be received from the original sender agent, reporting sort of a "course of action" to follow about the initial update.
Server SMTP/POP3
 
* SMTP : localhost:3025
 
* POP3: localhost:3110
 
* Server mailbox: gv1@gv.com (gv1/gv1)
 
* Client mailbox:  gv2@gv.com (gv2/gv2)<br/>gv3@gv.com (gv3/gv3)
 
  
Send an email to Server (gv1@gv.com) with the subject SVC=LIST_BIRT or SVC=LIST_EXCEL or SVC=LIST_PDF, depending on the service you want to request, that is, the generation of a BIRT, EXCEL or PDF report.
 
You might also generate a report for a specific person. This is done adding into the email subject a "!" and the Username after the request service. For example: SVC=LIST_PDF!NAME=UserName.
 
In case of BIRT report, you can also select the type (EXCEL or PDF). For example SVC=LIST_BIRT!TYPE=EXCEL!NAME=Username. The default BIRT report type is PDF.
 
  
[[File:GVCONSOLEDeploy.jpg|thumb|Deploy new Service]]To deploy the new Service follow this steps:
+
*Applying scenario 3
# [[Starting|Start {{GVESB}}]]
+
In order to gain accessibility to cluster based messaging between different GV instances a REGISTRATION kind of message needs to be sent to the ingoing queue from a certain GVserv1 service:
# [[GV_Console#Access|Access to the {{GVCONSOLE}}]].
 
# In the Deploy New Service section click Browse and select the .zip file where you saved the {{VULCON}} configuration.
 
# Click Submit.
 
  
The section [[Deploy_Service|Deploy Services]] will be open. In this section you can select the services you want to deploy.
+
    <XMLMessage><sender><name>GVserv1</name></sender><receivers><receiver><name>''ProxyAgent@Proxy_GV_Container''</name></receiver></receivers><comm action="REQUEST"/><content>'''[REGISTRATION]'''</content>   
# Clicking on service ProcessSVCEmails a new view will be shown containing the files GVCore.xml present in local and on server side.
+
    </XMLMessage>
# Click Deploy. Now you can save the document and write some notes about it.
 
# Save the Document. By saving you will return to the [[Deploy Service]] section.
 
# Repeat steps 1 to 3 for service ProcessSingleSVCEmail.
 
  
[[File:GVConsoleUtilityReload1.jpg|thumb|{{GVCONSOLE}} Utility section]]Now pass to the {{GVCONSOLE}} section [[Utility]].
+
Once its registration process is done, GVserv1 will be reachable through the GV clustering.
# Click on [[Reload_Configuration|Reload configuration]]
+
For instance, a GVserv2 (which has been previously been registered) can message GVserv1 by sending a simple XML message, formatted as before:
# Select GVCore.xml and GVAdapters.xml and then Reload. A new windows will be open to confirm the operation
 
# Click OK.
 
  
[[File:GVExamplesProcessSVCEmailsOutput.jpg|thumb|Testing ProcessSVCEmails]]Go to the {{L_GVCONSOLE}} section [[Testing]]. In this section you can finally test your new services:
+
    <XMLMessage><sender><name>GVserv2</name></sender><receivers><receiver><name>''GVserv1''</name></receiver></receivers><comm action="REQUEST"/><content>'''Hi, im a service like you. Pleased to meet you. :-)'''</content>   
# Into the Service voice select ProcessSVCEmails
+
    </XMLMessage>
# Into the System voice select CREDIT (optional)
 
# Click Request
 
  
The Testing View will be expanded and it is also possible to view the [[GVBuffer]] Output panel. There is present the property POP_MESSAGES_COUNT setted to 1, representing the number of emails received.  
+
The Proxy agent will recognize the receiver name previously registered, and will be able to use it with the properly stored route (which is a simple pair : ''gateway/bridging agent'' + ''http GV machine address'').
 +
Once received, GVserv1 will be able to respond simply sending a message formatted with "GVserv2" as receiver, which has been registered on the proxy.
 +
The ''gateway/bridging agent'' stated before is an ''hybrid bordering agent'', capable of "speaking" 2 different languages (XML and ACL Fipa): each GV instance/route owns one of these, and its crossed through the messaging phase.  
  
You will receive an email containing attached a file with the request report. In case of error you will receive an email containing into the message body the available request services. You can control errors and exceptions from the log files present in the directory $GV_HOME/log.
+
Each messaging phase is meant to cross 2 bridging agents: in the case pictured above message will go from GVserv2 to one bridging agent (owned by the GVserv2 context), then to the Proxy Agent (which will "query" the receiver into its routing map). Proxy agent will "query" receiver name into its routing map and then reroutes message to the proper second bridging agent (owned by the GVserv1 context), down to the GVserv1.

Latest revision as of 13:42, 28 September 2012

GVJADE, a JADE integration in GreenVulcano

Introduction

This Java application provides a direct JADE platform integration, which allows GreenVulcano to transparently interact with an inner set of JADE agents, using a direct 1-1 message transposition (internal ACL message to external XML, and viceversa). The JADE technology could introduce a lighter and smarter way to interconnect between multiple legacy services and/or different GV instances.

Description

ATM, GVJADE allows to run different flow scenarios, involving internal (JADEd, using ACL messages) and external (GV's, using JMS queues) contexts. These scenarios are a direct proof of true bridging between a JADE platform and GV context:

Scenario 1 : Messaging communication started from an external service/application (simulation of an external request to the inner agent):

  • Through a simple JMS queue an external context may send an XML message, containing usual ACL message components such as: sender, receivers, action and content. (See section Example of messaging through JADE for a viable example)
  • A bridging agent will receive the message and re-routes it to the infiltrated agent in ACL format
  • Once the message is opened and used by the agent it prepares a proper response (following its internal logic) which will be sent back again to the bridging agent
  • Bridging agent translates (this time the way around) the message in the exit format (XML) to the exit queue
  • External context can now read response to its original message


Scenario 2 : Messaging communication started from inside the JADE platform agent (simulation of an inner update to deliver to the external context):

  • An internal business agent, with a system update ready to be posted to the external application, sends it to the bridging agent
  • The agent enroutes it to a proper queue, translated in XML code
  • External application, waiting for the update, finds and uses it, also preparing a proper response in XML and sending it to another queue
  • Bridging agent pops the message from the queue and sends it back to originating business agent, in ACL format


Scenario 3 : GV messaging service running on a ditributed GV cluster

  • With an XML registration message, a GV service can register through the proxy agent, which is meant to centralize communications
  • Once the service registration appliance is accepted, the GV "route" is stored and the service can be reached from others GV instances/services simply contacting the proxy agent


Usual default service actions are also available, such as: Start, Update configuration, Shutdown are triggerable from the GV console.

GVJADE service configuration

First, extract "GVJADEAdapter-Configuration.xml" file (provided into the package zip file) into the \GreenV\xmlconfig\ path. The XML file states JADE platform configuration as follows:

    <GCJADEAdapterConfiguration>

<Engine main="true" local-port="1500" gui="false" dump-options="true" no-display="true" platform-id="Main_GV_Container" nomtp="false"></Engine> <Agents> <Agent name="PingAgent" class="examples.PingAgent.PingAgent"/> </Agents>

    </GCJADEAdapterConfiguration>

Attributes optional to be changed are

  • "local-port", which needs to be different from any used by GV, since its a hosting port)
  • "gui", which allows to run other agents, such as Sniffer, useful to monitor communication between platforms and agents
  • "Agent name", in order to add any other eventual agent class

Other attributes are not to be edited.

To add GVJADE service to GV enumeration edit and add the following:

   <generic-initializer class="main.java.test.jmx.RegisterGVJADEAdapter" target="$Template:Jboss.server.name" type="initializer"/>                     

to \GreenV\xmlconfig\gv-jmx.xml file, under the "Initializers" tag.

Also add

   <mbean code="org.jboss.jms.server.destination.QueueService"
          name="jboss.messaging.destination:service=Queue,name=JADE_GV_Request_Queue"
          xmbean-dd="xmdesc/Queue-xmbean.xml">
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
      <attribute name="JNDIName">gvesb/jms/queue/JADE_GV_Request_Queue</attribute>
      <attribute name="RedeliveryDelay">60000</attribute>
      <attribute name="MaxDeliveryAttempts">100</attribute>
   </mbean>
   <mbean code="org.jboss.jms.server.destination.QueueService"
          name="jboss.messaging.destination:service=Queue,name=JADE_GV_Response_Queue"
          xmbean-dd="xmdesc/Queue-xmbean.xml">
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
      <attribute name="JNDIName">gvesb/jms/queue/JADE_GV_Response_Queue</attribute>
      <attribute name="RedeliveryDelay">60000</attribute>
      <attribute name="MaxDeliveryAttempts">100</attribute>
   </mbean>
   
   <mbean code="org.jboss.jms.server.destination.QueueService"
          name="jboss.messaging.destination:service=Queue,name=GV_JADE_Request_Queue"
          xmbean-dd="xmdesc/Queue-xmbean.xml">
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
      <attribute name="JNDIName">gvesb/jms/queue/GV_JADE_Request_Queue</attribute>
      <attribute name="RedeliveryDelay">60000</attribute>
      <attribute name="MaxDeliveryAttempts">100</attribute>
   </mbean>
   <mbean code="org.jboss.jms.server.destination.QueueService"
          name="jboss.messaging.destination:service=Queue,name=GV_JADE_Response_Queue"
          xmbean-dd="xmdesc/Queue-xmbean.xml">
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
      <attribute name="JNDIName">gvesb/jms/queue/GV_JADE_Response_Queue</attribute>
      <attribute name="RedeliveryDelay">60000</attribute>
      <attribute name="MaxDeliveryAttempts">100</attribute>
   </mbean>

in \GreenV\application\deploy\gvesb-mq-destinations-service.xml, under the "server" tag.


Examples of messaging through GVJADE

  • Applying scenario 1

Configure a process to send a JMS message to the "GV_JADE_Response_Queue" queue, serviced under GV, with the following XML code:

   <XMLMessage><sender>GVapp1</sender><receivers><receiver><name>PingAgent@Main_GV_Container</name></receiver></receivers><comm action="REQUEST"/><content>ping</content></XMLMessage>

This, as previously shown in case scenario 1, will trigger GVJADE processing the message to the inner JADE agent ("PingAgent"). The expected result to the REQUEST:"ping" message can be received through the "GV_JADE_Request_Queue" queue, which will be an INFORM:"pong" action.


  • Applying scenario 2

In order to trigger scenario 2 shown above a JADE platform must be run (via terminal console or IDE such as Eclipse). Through the platform run a simple agent with send/response capabilities (such as default DummyAgent). Prepare a message to send with:

- address to reach as the GVJADE address/agent (address is the platform one readable from the GVJADE output, while the agent name is the bridging one: "JadeToGvAgent")

- communicative act configured as REQUEST

- content edited a simple "ping" (a simple content to update the internal status to the outside world)

Then press to send the message.

An INFORM:"pong" message will be received from the original sender agent, reporting sort of a "course of action" to follow about the initial update.


  • Applying scenario 3

In order to gain accessibility to cluster based messaging between different GV instances a REGISTRATION kind of message needs to be sent to the ingoing queue from a certain GVserv1 service:

   <XMLMessage><sender><name>GVserv1</name></sender><receivers><receiver><name>ProxyAgent@Proxy_GV_Container</name></receiver></receivers><comm action="REQUEST"/><content>[REGISTRATION]</content>     
   </XMLMessage>

Once its registration process is done, GVserv1 will be reachable through the GV clustering. For instance, a GVserv2 (which has been previously been registered) can message GVserv1 by sending a simple XML message, formatted as before:

   <XMLMessage><sender><name>GVserv2</name></sender><receivers><receiver><name>GVserv1</name></receiver></receivers><comm action="REQUEST"/><content>Hi, im a service like you. Pleased to meet you. :-)</content>     
   </XMLMessage>

The Proxy agent will recognize the receiver name previously registered, and will be able to use it with the properly stored route (which is a simple pair : gateway/bridging agent + http GV machine address). Once received, GVserv1 will be able to respond simply sending a message formatted with "GVserv2" as receiver, which has been registered on the proxy. The gateway/bridging agent stated before is an hybrid bordering agent, capable of "speaking" 2 different languages (XML and ACL Fipa): each GV instance/route owns one of these, and its crossed through the messaging phase.

Each messaging phase is meant to cross 2 bridging agents: in the case pictured above message will go from GVserv2 to one bridging agent (owned by the GVserv2 context), then to the Proxy Agent (which will "query" the receiver into its routing map). Proxy agent will "query" receiver name into its routing map and then reroutes message to the proper second bridging agent (owned by the GVserv1 context), down to the GVserv1.