Safe X3 Java Bridge Server
The Safe X3 Java Bridge Server component has the same presence as a standard X3 engine: it listens to a port just as the deamon adxd does.
A client connecting to this port finds the same dialog as with the deamon adxd of a standard X3 engine. It can thus request the launch of a specific server.
When a client starts the Adonix server of the Java Bridge server, a context is created in the JVM instance. This session lasts until the connection interface is closed (explicit closing or client killed).
The Safe X3 Java Bridge Server is a multi-session process.
Concept
The Safe X3 Java Bridge Server is a scalable server that publishes technical features for the application servers of the Sage X3 software.
Delivered bundles
The Safe X3 Java Bridge Server is now developed in Java around an OSGi framework. Published features are implemented as OSGi bundles.
Bundle libraries
Apache libraries: these bundles are the OSGi identifications of the Apache libraries and multi-platform service wrapper tanuki.wrapper:
- com.sage.x3.bundle.lib.apache.axis2
- com.sage.x3.bundle.lib.apache.email
- com.sage.x3.bundle.lib.apache.httpcli
- com.sage.x3.bundle.lib.apache.xalan
- com.sage.x3.bundle.lib.apache.wrapper
Sage libraries: these bundles are the OSGi identifications of the Sage libraries, which are used as a basis to develop other Java components of Sage X3:
- com.sage.x3.bundle.shared.java
- com.sage.x3.bundle.shared.x3clients
The bundle below contains a set of technical and abstract classes, and interfaces used in all Sage X3 bundles:
- com.sage.x3.bundle.shared.bundles
Core bundles
com.sage.x3.bridge.bundle.main implements:
- The log services (IServiceConsole), trace services (IServiceTrace), configuration services (IServiceConfig), extension bundle management services (IServiceExtends) and resources services (IServiceResources)
- The http server
- The configuration visualization commands
com.sage.x3.bridge.bundle.broadcaster implements the message broadcasting service () used across bundles to share events.
com.sage.x3.bridge.bundle.qualifier implements the qualification commands and the script interpreter.
com.sage.x3.bridge.bundle.daemon implements:
- The deamon listening to the calls sent by the Adonix servers
- The object instance broker
- The interpreter of RPS calls sent by the Adonix servers
Functional bundles
com.sage.x3.bridge.bundle.httpclient publishes the implementation of generic http clients used to launch http queries aiming at calling the RESTful web services.
It depends on the com.sage.x3.bundle.lib.apache.httpclient bundle, which wraps the HttpComponents HttpClient v4 Apache library.
com.sage.x3.bridge.bundle.mailclient publishes the implementation of a generic mail sender.
It depends on the com.sage.x3.bundle.lib.apache.email bundle, which wraps the Commons email v1.1 Apache library.
com.sage.x3.bridge.bundle.soapclient publishes:
- A stub generator
- A Javadoc document generator
Component installation and configuration
For the installation and configuration of the Safe X3 Java Bridge Server component, the same procedure as for other components applies.
It is possible to verify whether the web interface provided by Jetty is available.
URL: http://serveur_bridge:httpport.
Available features
Principles
The Safe X3 Java Bridge Server handles object instances. It sends to the Adonix server either:
- Values of the native type:
JAVA
Byte
Short
Integer
BigDecimal
Date
String
String
Byte[ ]
4GL
Description
Shortint
Integer
Decimal
Date
Char
Clobfile
Blobfile
Booleans are not supported currently.
- References to object instances: X3 = 1, X3 = 2, X3 = 3, … , X3 = n.
Running HTTP requests
A 4GL processing can create an http client via a connection to a Java server.
Local Char KTARGETNEWHTTP (250)
KTARGETNEWHTTP = "com.sage.x3.runtime.bundle.httpclient.CServiceHttpClientImpl:newHttpClient"
Local Char WHTTPCLI (30)
WHTTPCLI = Funciu = KTARGETNEWHTTP Using [JAVSRV] With ( )
The resulting instance of CHttpClient can be called from various methods (see the X3HttpClient object in the javadoc of the software development kit).
Local Char WURL (250)
WURL = "http://www.webservicex.net/MortgageIndex.asmx?wsdl"
Local Char WHTTPREPLY (30)
WHTTPREPLY = Funciu = WHTTPCLI +":get" Using [JAVSRV] With ( WURL )
The resulting instance of CHttpRespons can be called from various methods.
Local Clbfile WWSDL (8)
WWSDL = FUNCIU = WHTTPREPLY +":getText" Using [JAVSRV] With ( )
SOAP web service calls
Generation of a stub for a business partner web service from their WSDL:
Local Char KTARGETGENST (30)
Local Char ASTUBID (30)
Local Char ATIMESTAMP (30)
KTARGETGENST = "com.sage.x3.runtime.bundle.webservices.CServiceStubsImpl:generate"
ASTUBID = "MortgageIndex"
ATIMESTAMP = "20091210093225"
Local Char WSTUBGENREP (30)
WSTUBGENREP = Funciu = KTARGETGENST Using [JAVSRV] With (ASTUBID,ATIMESTAMP,WWSDL )
Generation of the corresponding javadoc and publication of the html pages via Jetty:
Local Char KTARGETGENSD (30)
KTARGETGENSD = "com.sage.x3.runtime.bundle.webservices.CServiceStubsImpl:generateDoc"
Local Char WDOCGENREP (30)
WDOCGENREP = Funciu = KTARGETGENSD Using [JAVSRV] With (ASTUBID)
It is not necessary to restart for the stub classes to be taken into account.
There are two types of methods:
- Simple data
- Complex data
Instantiation of the stub:
Local Char WSTUBINST(250)
WSTUBINST = Funciu "com.sage.x3.runtime.bundle.deamon.CToolFactoryStubs:newStub" Using [JAVASRV]
With("PriceGetter","http://stubServer.com/PriceGetter")
The stub methods manipulating simple-type data can be called directly from the 4GL:
Local Char WBPC (30)
Local Char WITEM (30)
Local Integer
WQTY WBPC = "DIS001"
WITEM = "JL-KIT-PC-NGERE"
WQTY= 5
Local Decimal WPRICE
WPRICE = Funciu = WSTUBINST +":getPrice" Using [JAVASRV] With (WBPC,WITEM,WQTY)
Handling Beans
Local Char KTARGETNEWBEAN (250)
KTARGETNEWBEAN = "com.sage.x3.runtime.bundle.deamon.CToolFactoryBeans:newBean"
Local Char WFIELDSTOSET (250) # List of IDs for the properties of the bean to be valued
WFIELDSTOSET = "property1;property2;propertyZ"
WBEANINST = Funciu = KTARGETNEWBEAN Using [JAVASRV] With ("com.sage.mybean",WFIELDSTOSET, VARONE, VARTWO,...)
Local Char KTARGETWRITBEAN (250)
KTARGETWRITBEAN = "com.sage.x3.runtime.bundle.deamon.CToolFactoryBeans:writeBean" Local Char WFIELDSTOREAD(250) # List of IDs for the properties of the bean to be valued
WFIELDSTOREAD = "property1;property2;propertyZ"
WNBFIELDS = Funciu = KTARGETWRITBEAN Using [JAVASRV] With (WBEANINST, WFIELDSTOWRITE, VARONE, VARTWO,...)
Local Char KTARGETREADBEAN (250)
KTARGETREADBEAN = "com.sage.x3.runtime.bundle.deamon.CToolFactoryBeans:readBean" Local Char WFIELDSTOREAD(250) # List of IDs for the properties of the bean to be read
WFIELDSTOREAD = "property1;property2;propertyZ"
WNBFIELDS = Funciu = KTARGETREADBEAN Using [JAVASRV] With (WBEANINST, WFIELDSTOREAD, VARONE, VARTWO,...)
The GetMortgageIndexByWeek method for the MortgageIndexStub stub expects a MortgageIndexStub.GetMortgageIndexByWeek bean on input.
Instantiation of the stub:
Local Char WSTUB(250)
WSTUB = Funciu "com.sage.x3.runtime.bundle.deamon.CToolFactoryStubs:newStub"
Using [JAVASRV]
With("MortgageIndex","http://www.webservicex.net/MortgageIndex.asmx")
Creation of the setup bean:
Local Char WCLASSNAME(250)
WCLASSNAME = "net.stub.mortgageindex.MortgageIndexStub$GetMortgageIndexByWeek" Local Char WLISTFIELDS(250)
WLISTFIELDS="Day,Month,Year"
Local Char WBEANA(30)
WBEANA = Funciu = KTARGETNEWBEANUsing [JAVSRV] With (WCLASSNAME,WLISTFIELDS,9,9,1994)
Calling the GetMortgageIndexByWeek method:
WBEANB = Funciu = WSTUB +":GetMortgageIndexByWeek" Using [JAVSRV] With (WBEANA)
Creating and sending multi-part messages
Instantiation of the CMail object:
Local Char KTARGETNEWMAIL(250)
KTARGETNEWMAIL = "com.sage.x3.runtime.bundle.mail.CServiceMailImpl:newMail"
Local Char WMAIL (30)
WMAIL = Funciu = KTARGETNEWMAIL Using [JAVSRV] With ()
Methods required before sending the e-mail:
# Addition of the sender
Calliu = WMAIL+":setFrom" With "[email protected]", "Sage X3 Java Server" Using [JAVSRV]
# Addition of the recipients
Local Char
WTO(80)(1..10)
WTO(1)="[email protected]"
WTO(2)="[email protected]"
Calliu = WMAIL+":setTo" With (WTO) Using [JAVSRV]
# Addition of the subject
Calliu = WMAIL+":setSubject" With ("Email 'riche' de test") Using [JAVSRV]
Other features:
- Addition of resources by providing an URL
- Addition of binary resources as blobs
- Message body in rich text format
- Message body in raw text format
- Addition of attachments by providing an URL
- Addition of attachments via blobs
- Addition of a text attachment
The send() method:
Local Date WDATE
WDATE = Funciu = WMAIL +":send" Using [JAVSRV] With ()
Array[ ] results
The methods that do not return byte[] tables (4GL BLOB type) result in an error.
To perform this type of operation, it is necessary to use the tools provided by the CToolArrayReader class of the com.sage.x3.runtime.bundle.deamon plugin.
# Opening the Java channel
Opadxd "ecchambard-001:27160" With 7,nomap ,"FRA" ,adxusr ,password Using [JAVSRV]
# Instantiation of the stub
Local Char WSTUB(30)
WSTUB = Funciu = KTARGETNEWSTUB Using [JAVSRV] With ("FootballPoolWebService","http://euro2008.dataaccess.eu/footballpoolwebservice.wso" )
# Creating the bean parameter AllGoalKeepers
Local Char WCLASSNAME(250)
WCLASSNAME = "net.stub.footballpoolwebservice.FootballPoolWebServiceStub$AllGoalKeepers"
Local Char WLISTFIELDS(250)
WLISTFIELDS="SCountryName"
Local Char WBEANPARAM(30)
WBEANPARAM = Funciu = KTARGETNEWBEAN Using [JAVSRV] With (WCLASSNAME,WLISTFIELDS,"France")
# Calling the method AllGoalKeepers
Local Char WRESP(30)
WRESP = Funciu = WSTUB +":AllGoalKeepers" Using [JAVSRV] With (WBEANPARAM)
# Calling the method getAllGoalKeepersResult
Local Char WARRAY(30)
WARRAY = Funciu = WRESP +":getAllGoalKeepersResult" Using [JAVSRV] With ()
# Preparing the call of the getString method
Local Char REFREADER
Local Char GOALS (255)(100)
WREFREADER = Funciu = KTARGETARRAYREADER Using [JAVSRV] With (WARRAY,"getString","String")
# Recovering the table size
Local Integer WSIZE
WSIZE = Funciu = WREFREADER + ":size" Using [JAVSRV] With ()
# Browsing the table
Local Integer WIDX
For WIDX = 0 To WSIZE-1
# Recovering the array element no. WIDX using the getOneObject method
GOALS(WIDX) = Funciu = WREFREADER + ":getOneObject" Using [JAVSRV] With (WIDX)
Next WIDX
Broker management
The Adonix server is not aware of the object instances in the Safe X3 Java Bridge Server.
Releasing an instance:
Local Char KTARGETCLINST (250)
KTARGETCLINST = "com.sage.x3.runtime.bundle.deamon.broker.CBroker:clearInstance" Calliu = KTARGETCLINST With (WONEINST) Using [JAVSRV]
Releasing all instances in the session:
Local Char KTARGETCLEAR(250)
KTARGETCLEAR = "com.sage.x3.runtime.bundle.deamon.broker.CBroker:clear"
Calliu = KTARGETCLEAR With Using [JAVSRV]