The MOMIS documentation * TOC

[Todo] Wrappers and Communication (CORBA,WS)

todo:doc:Alberto
MOMIS communication and Wrappers base package hierarchy.

The Wrapper classes

from the Momis faq file:
q. Wrapper: a bit of theory
a. Wrapper introduction
   - wrappers are designed to be as modular as possible,
     at least for the Java developers.
     Basically a wrapper is something that allows a (java) client
     to access to a source so a Wrapper can be described
     with a simple (Java) interface 
       it.unimo.dbgroup.momis.communication.Wrapper
     with the following methods:
       public String getDescription() throws WrapperException;
       public String getDescriptionXml() throws WrapperException;
       public String getSourceName() throws WrapperException;
       public String getType () throws WrapperException;
       public WrapperRS runQuery (String oql) throws WrapperException;
       public void close() throws WrapperException;
     most of them are intuitive, for more information look at the source
     code.
     The method runQuery makes exception since returns
     an object of type
       it.unimo.dbgroup.momis.communication.WrapperRS
     that is a Wrapper Result Set and defines the methods:
       void    close() throws WrapperException;
       long    getColumnByName(String column) throws WrapperException;
       long    getColumnCount() throws WrapperException;
       String  getColumnName(int column) throws WrapperException;
       char    getChar(int column) throws WrapperException;
       double  getDouble(int column) throws WrapperException;
       float   getFloat(int column) throws WrapperException;
       long    getLong(int column) throws WrapperException;
       String  getString(int column) throws WrapperException;
       String  getRSAsString() throws WrapperException ;
       boolean next() throws WrapperException;  
     Names are intuitive too.
     Here is implemented the concept of "cursor", so there are
     method to "close" the cursor, move to the "next" record
     or get the current record information  (getString, getFloat, etc.)
     or access to the record metadata information (getColumnByName,
     getColumnCount).
   Wrapper generalization
   - the interfaces Wrapper and WrapperRS are all we need to access
     a source INDEPENDENTLY from the type of source.
     The only thing the client need to know is:
     - the interfaces Wrapper and WrapperRS
     - the class that implements the wrapper
     - the parameters to let the wrapper working
     The idea is to make the Client as much INDEPENDENT 
     as possible from the used wrapper, so we tried to standardize
     also the way to pass specific parameters.
     This is through the interface
      it.unimo.dbgroup.momis.communication.WrapperCore
     that extends the interface Wrapper adding the methods
       public void   initialize(Map parameters) throws Exception;
       public String getParamersAsPropertiesTemplate();
     All wrappers implementing the WrapperCore interface have
     the same initialization interface!
     Parameters are passed through a java.util.Map object
     that must contain a set of couple (key, value) where the
     key is a String, the name of the parameter
     and value is the value of the parameter specific for the
     instance initialization.
     Every Wrapper implementation must be initialized passing
     a set of specific parameters.
     String parameters in a Map can be represented in the 
     "Properties" form. java.util.Properties is a core java tool class
     used to store/retrieve application configuration parameters.
     A couple (key, value) can be represented in a plain text file
     (or string) writing a couple per line
      key=value
     like the following example:
       #
       # Time out in seconds
       timeOutGracePeriod=28800
       timeOutCheckPeriod=3600
     lines starting with # are ignored. Are simply comments.
     See next section for more examples.
   Source specific wrappers
   - These are few examples of wrapper the Momis Client (such as
     SI-Designer) will instance to access data sources.
     - the Dummy wrapper:
       This is not a real wrapper.
       The only thing this wrapper can do is read a schema
       description from a given xml file and pass it to the client
       when the getDescriptionXml() is invoked. 
       The class to be instanced is
        it.unimo.dbgroup.momis.communication.core.dummy.WrapperDummyFromFile
       This wrapper requires the following parameter
        WrapperDummyFromFile.sourceDescriptionFileName=samples/file.xml
     - the Jdbc  wrapper:
       This is the wrapper for accessing JDBC data source.
       Opens a JDBC Connection using standard JDBC features.
       The wrapper simply translates requests from the Wrapper interface
       into JDBC throuth the open connection.
       The class to be instanced is
        it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore
       This wrapper requires the following parameter
        WrapperJdbcCore.DriverClassName=oracle.jdbc.driver.OracleDriver
        WrapperJdbcCore.Url=jdbc:oracle:thin:user/pwd@artemi...
        WrapperJdbcCore.User=user
        WrapperJdbcCore.Password=pwd
        WrapperJdbcCore.debug=true
     - the corba client wrapper
       This is the wrapper for accessing standard CORBA data source
       that implements the idl interface
        conf/declarationsIDL/CorbaWrapper.idl
       The CorbaWrapper.idl defines the same methods of the Java Wrapper 
       interface but is for the CORBA standard.
       Opens a CORBA connection with a remote CORBA server.
       The wrapper simply translates requests from the Wrapper interface
       into CORBA requests sent to the given CORBA server.
       The class to be instanced is
        it.unimo.dbgroup.momis.communication.client.corba.CorbaWrapperClient
       This wrapper requires the following parameter
        # Where runs the "orb-naming server"
        namingServerName=localhost
        # At which port responds the "orb-naming server"
        namingServerPort=1050
        # Name to use to register "this" corba wrapper
        wrapper_serverName=oracleSource
     - the Web Services client wrapper
       This is the wrapper for accessing standard WebServices data source
       that implements the wsdl interfaces:
        conf/declarationsWSDL/WSDLWrapper.wsdl
        conf/declarationsWSDL/WSDLWrapperRS.wsdl
       The WSDLWrapper.wsdl defines the same methods of the Java Wrapper
       interface while WSDLWrapperRS describes the 
       methods for the ResultSet object
       compliant with the WebService standard.
       Both such wsdl interfaces are "invisible" to the user.
       The wrapper simply translates requests from the Wrapper interface
       into WS requests sent to the given WS server.
       The class to be instanced is
        sam.wrapperClassName.5=it.unimo.dbgroup.momis.communication.client.wsdl.WSDLWrapperClient
       This wrapper requires the following parameter
        # endpoing of the wrapper web service to be connected
        endpointURL=localhost
   Communication wrappers
   - The idea is to implement servers that translates
     source data requests from a standard comunication protocol
     (such as CORBA, WebServices, or other)
     implementing such servers that translates the 
     communication protocol requests into
     the Wrapper interface requests.
     Now we can publish in a standard communication protocol
     any "Source specific wrappers" making any possible combination.
     examples
     - the corba server/client communication wrapper
       and the idl interface for external interfacement
       (client for input, server for output).
       The CORBA communications wrapper server
       defines CORBA object server that implements the idl interface
        declarationsIDL/CorbaWrapper.idl
       The server accepts requests through the CORBA protocol
       and translate them into Wrapper interface requests.
       To be as fexible possible also this server uses
       parameters,
       one of required parameters is the name of the 
       Source specific wrappers to use.
       Here are the required parameters
        # Where runs the "orb-naming server"
        namingServerName=localhost
        # At which port responds the "orb-naming server"
        namingServerPort=1050
        # Name to use to register "this" corba wrapper
        wrapper_serverName=oracleSource
        # These parameters are for Query pre-emption
        # a query object is killed after a time(out) of inactivity
        timeOutGracePeriod=28800
        timeOutCheckPeriod=3600
        # the Source specific wrappers to use
        wrapper_coreClass=it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore
       Usually in the configuration file there are the parameter
       for the "Source specific wrappers to use" initialization.
       In this case
        WrapperJdbcCore.DriverClassName=oracle.jdbc.driver.OracleDriver
        WrapperJdbcCore.Url=jdbc:oracle:thin:user/pwd@artemi...
        WrapperJdbcCore.User=user
        WrapperJdbcCore.Password=pwd
        WrapperJdbcCore.debug=true
     - the WebServices server/client communication wrapper
       and the WSDL interface for external interfacement
       (client for input, server for output)
       This is not implemented yet..
     NOTA
     - The communications wrapper server used with the
       corresponding communications wrapper client
       simply works as communication bridge between
       any Source specific wrappers and a remote client
       since "source" data are taken from the source specific
       core wrapper through the interface Wrapper used by the
       "communications wrapper server"
       and are provided to the client again 
       through the interface Wrapper
       by the communications wrapper client.
   See the question "Wrapper: An introduction for developers"
   for a few developer specific hints

q. Wrapper: An introduction for developers
a. Introduction
   - From the Java developement poin of view
     we can see a Wrapper as an object that implements the
       it.unimo.dbgroup.momis.communication.Wrapper
     interface.
     As first step You should read the well
     commented source code of such interface.
     Such interface is used by Client to access a data source.
     Actually real Wrappers must be initialized specifing parameters for
     accessing the data source (usually a username, password or host name).
     For this reason it exists the interface
       it.unimo.dbgroup.momis.communication.WrapperCore
     that inherits from the Wrapper interface
     and adds two method specific for wrapper initialization.
     Note that a Wrapper is really composed by two parts:
     the one supports the Wrapper interface and is the object
     representing the source.
     The second part implements the 
       it.unimo.dbgroup.momis.communication.WrapperRS
     (that means Wrapper Result Set)
     and is the code that manages the queries to the Source. 
   Capabilities
   - A wrapper is basically able to perform 2 tasks
     - 1. the source introspection.
       This describes the source "schema" in a MOMIS way, using
       both ODLi3 or an XML description.
       Nowaday (January 2003) the XML is better because is able
       to carry more information like the schema annotation
       or support attribute names with spaces or other strange
       characters. 
     - 2. the source quering (WrapperRs).
       The wrapper (by the interface WrapperRS) 
       enables a client to access data through a Result Set,
       that data resulting from a query are accessible
       as cursor on a table.
       Operation allowed are to get the numeber of
       selected columns, get value of a given column and move
       the cursor on the next row of the table.
   A few examples
   - at first look at some examples.
     To start look at the 
      it.unimo.dbgroup.momis.communication.core.dummy.WrapperDummyFromFile
     that is not a real wrapper,
     the only thing this wrapper can do is read a schema
     from a file and pass such description to the client.
     Next look at the 
      it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore_metaData
     where are solved both the source introspection
     and the source quering problems.
   - An exremely simple wrapper:
     here are describe the main wrapper code
     and code implemented to run queries
     - The WrapperDummyFromFile wrapper.
       This implements the interface WrapperCore.
       As you can see from the code most of method does nothin,
       returns null value or returns hard coded values 
       (e.g. the getSourceName() method ever returns "dummySource").
   - A real wrapper:
     here are describe the main wrapper code
     and code implemented to run queries
     - The WrapperJdbcCore wrapper.
       A WrapperJdbcCore simply opens a JDBC connection on the
       source and use such connection to get Schema Description
       or run queries (SQL) on the source.
       The connection is opened during the initialization()
       expecting the parameters
          WrapperJdbcCore.DriverClassName=oracle.jdbc.driver.OracleDriver
          WrapperJdbcCore.Url=jdbc:oracle:thin:user/passwd@artemide.ing....
          WrapperJdbcCore.User=user
          WrapperJdbcCore.Password=pwd
       - The source schema introspection:
         WrapperJdbcCore retrieves metadata from the JDBC connection
         create a new odli3.Schema object
         and fills it with odli3.Interfaces (the Tables) object.
         Every odli3.Interface object is then "filled" with
         odli3.SimpleAttribute object that are the fields of the
         corresponding table.
         Since for schema exists both the method to get the 
         xml and ODLi3 representation of the in memory odli3.Schema
         object,
         this is the recommended way to do get a source description.
         This allows the programmer to write a single code that
         loads well known data classes (the method getSchema())
         and the two methods getDescription and getDescriptionXML
         are really small (less than 20 lines).
     - The WrapperRSJdbcCore class.
       This implements the interface WrapperRS.
       The first thing to do is to see the source code.
       The constructor simply retrieve ask the connection to
       the jdbcWrapper, create a new Statement and
       runs the given query as SQL query on the JDBC source.
       The main source of informatio object of the WrapperRSJdbcCore
       is now the ResultSet resulting from the SQL query.
       Getting data is a trivial mapping of the WraperRS interface 
       methods to such resultset methods.
       For example, see the method
        public String getString(int column) throws WrapperException
       that simply calls the getString ResultSet method
        rv = _rs.getString(column);
Wrapper
Qualified Type Name it.unimo.dbgroup.momis.communication.Wrapper
Number of Fields: 0
Number of Methods: 6
Number of Lines: 65
* The interface for any MOMIS Wrapper.
A wrapper is the object that allows the access to a given data source.
methods:
WrapperRS
Qualified Type Name it.unimo.dbgroup.momis.communication.WrapperRS
Number of Fields: 0
Number of Methods: 15
Number of Lines: 138
* The interface for any MOMIS Wrapper Result sets.
When a wrapper query is run a new WrapperRS object is instantiated to manage the access to the returned data.
methods:
WrapperCore
Qualified Type Name it.unimo.dbgroup.momis.communication.WrapperCore
Number of Fields: 0
Number of Methods: 2
Number of Lines: 56
Interfaces: it.unimo.dbgroup.momis.communication.Wrapper
* The interface for any MOMIS Wrapper.

A wrapper is the object that allows the access to a given data source.
extension to the Wrapper medthods:

WrapperClient
Qualified Type Name it.unimo.dbgroup.momis.communication.client.WrapperClient
Number of Fields: 2
Number of Methods: 4
Number of Lines: 389
Superclass: java.lang.Object
* Generic command line wrapper client
This is a executable java class, must be run from comman line passing as parameter a properties file that describes which wrapper load (wrappers are ever loaded specifing the name of the class) and the specific parameters to allow such wrapper to connect to the data source.
   java WrapperClient configurationFileName.
 
a small test session
 o select * from turbine_permission
 getColumnCount
 getColumnName 1
 next
 getString 1
 getDouble 1
 getFloat 1
 getLong 1
 getBoolean 1
 getChar 1
 close
 
Once run the client this is a list of the command available to query the source
   - MOMIS Wrapper simple client -
  command allowed:
    \x (exit)     quit client
    \q (quit)     quit client
    \h (help)     this screen
    --------
    \t (type)     get the source type
    \do    get description ODLI3
    \dx    get description XML
    s oql   run a query (server side curor)
    x oql   run a query (xml output)
    o oql   open a WrapperRS on the query
  else the text is interpreted as oql query
  commands enabled on open ResultSets
   getColumnCount
   close
   next
   getColumnByName columnAsString
   getColumnName column
   getChar column
   getDouble column
   getFloat column
   getLong column
   getDate column
   getBoolean column
   getString column
 
WrapperJdbcCore
Qualified Type Name it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore
Number of Fields: 10
Number of Methods: 22
Number of Lines: 602
Interfaces: it.unimo.dbgroup.momis.communication.WrapperCore
Superclass: java.lang.Object
Subclasses: it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore_SQLServer
it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore_oracle
* Wrapper for accessing JDBC data sources.
WrapperJdbcCore_SQLServer
Qualified Type Name it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore_SQLServer
Number of Fields: 0
Number of Methods: 2
Number of Lines: 290
Superclass: it.unimo.dbgroup.momis.communication.core.jdbc.WrapperJdbcCore
* Wrapper Jdbc specific for Oracle.
Contains several filters on table name to remove system tables.

The wrapper communication layer classes

Wrappers "core" are designed to run locally, in the same virtual machine of the Momis application, this prevent to connect to remote sources not directy reachable from the Java VM.
This is the reason we developed a generic communication abstraction layer.
The communcation layer basically does 2 things: Running the server remotely and the client locally is it possible to remotely access any Wrapper data source through the chosen communication protocol.
from the Momis faq file:
- The wrappers

q. Running a wrapper directly from the command-line Client
a. There is a directory of examples in
    conf/samplesWrapperCore/
   For example:
   - to run a wrapper Dummy open and take a look to the file
      conf/samplesWrapperCore/samplesWrapperDummyFromFile/stato.conf
     and run the rapper inside the command line client:
      var/runWrapperClient.bat \
       conf/samplesWrapperCore/samplesWrapperDummyFromFile/stato.conf
     the only command allowed will be 
      \dx
   - to run a jdbc wrapper from the client open and take a look to the file
      conf/samplesWrapperCore/samplesWrapperJdbc/mySql.conf
     edit parameters such as
      driver to load
      uri where to connect
      username
      password
     according to the jdbc source you want connect to.
     Then run the rapper inside the command line client:
      var/runWrapperClient.bat \
       conf/samplesWrapperCore/samplesWrapperJdbc/mySql.conf
     This is an example useful to test JDBC wrapper connections
     or new wrapper implementation (if any).

q. Running a CORBA wrapper demon
a. Steps to run a Jdbc/CORBA wrapper
   - obtain the last sources from the CVS repository
   - compile everything
      ant init
   - run the orb
      var/startOrb.bat
   - crate a configuration file,
     for an oracle example see
       conf/samplesIdl/wrapperJdbcOracle.conf
     that is a well commented example.
          To use the oracle jdbc driver you need the jar file
     NOT distributed in the MOMIS CVS code.
     - To add a JDBC driver in MOMIS, simply copy the jar file
       in the directory
         the/Momis/Root/Dir/lib
       for example
        cp /somewhere/oracle_classes12.jar lib/
       and rebuild the .bat scripts using the command
        ant scripts
     - If you use a different DBMS please change the
        WrapperJdbcCore.DriverClassName
        WrapperJdbcCore.Url
        WrapperJdbcCore.User
        WrapperJdbcCore.Password
       parameters according to your needs.
   - run the CORBA demon that will run the wrapper type:
     use the command
      var/startWrapperCorba.bat conf/samplesIdl/wrapperJdbcOracle.conf
     that's all!
   - run a wrapper client.
     It is important to test the wrapper.
     We provide a comman line tool to do this for ANY wrapper.
     To work the WrapperClient needs a configuration file
     where are described which Wrapper load
     and the parameters for the wrapper itself.
     An example of configuration file for connecting to 
     the previous corba wrapper is (READ IT!)
      conf/wrapperJdbcOracle_client.conf
     To run the client type
      var/runWrapperClient.bat conf/samplesIdl/wrapperJdbcOracle_client.conf
     How use the WrapperClient:
     - type  \h to get a short help.
       For example use the command
        \dx
       to get the schema description in xml, or 
        select  something from someTable;
       to test the quering capabilities.
       For example, if the jdbc db contains the Ditta table, try
        select * from ditta
   End.

q. Running Configure and run a WEB SERVICE wrapper demon
a. To configure the environment
   - install an environment with a working tomcat
   - install a working axis package
   - copy the directory content
      $dmt/classes
     into the axis dir
      ....webapps/axis/WEB-INF/classes
   - configure the velocity macro enviroment in axis
     - copy the library
        velocity*.jar
       into
        ....webapps/axis/WEB-INF/lib
     - copy (or link) the directory
        $dmt/vmtemplates
       into the tomcat execution directory or tomcat,
       usually
        .../tomcat/bin
   - make sure the "connection" (e.g. jdbc drivers) are
     in the axis directory
      ....webapps/axis/WEB-INF/lib
   To start the service
    var/runAxisAdminClient.bat conf/samplesWsdl/dummy/wrapper.wsdd
   or
    var/runAxisAdminClient.bat \
      -lhttp://localhost/axis/services/dummyWrapper \
      conf/samplesWsdl/dummy/wrapper.wsdd
   to test the running service
    echo -e "\\dx\\n\\x" | var/runWrapperClient.bat \
      conf/samplesWsdl/dummy/wrapper_client.conf
   To stop the service
    var/runAxisAdminClient.bat conf/samplesWsdl/dummy/wrapper_undeploy.wsdd
    var/runAxisAdminClient.bat \
      -lhttp://localhost/axis/services \
      conf/samplesWsdl/dummy/wrapper_undeploy.wsdd
   Other examples:
   - WSDLWrapper test (see the faq "The Test web service"):
     - edit the deploy file
        conf/samplesWsdl/jdbc/wrapper.wsdd
       and the client configuration file
        conf/samplesWsdl/jdbc/wrapper
     - run axis and deply the service using (for localhost):
        var/runAxisAdminClient.bat conf/samplesWsdl/jdbc/wrapper.wsdd
     - test the client
        echo -e "\\dx\\n\\x" | var/runWrapperClient.bat \
         conf/samplesWsdl/jdbc/wrapper_client.conf
       or run the client
        var/runWrapperClient.bat conf/samplesWsdl/jdbc/wrapper_client.conf
       and type the following sequence
        o select * from turbine_permission
        getColumnCount
        getColumnName 1
        next
        getString 1
        getDouble 1
        getFloat 1
        getLong 1
        getBoolean 1
        getChar 1
        close
     - to undeploy the service
        var/runAxisAdminClient.bat conf/samplesWsdl/jdbc/wrapper_undeploy.wsdd
WSDLWrapper_impl
Qualified Type Name it.unimo.dbgroup.momis.communication.server.wsdl.WSDLWrapper_impl
Number of Fields: 4
Number of Methods: 7
Number of Lines: 222
Superclass: it.unimo.dbgroup.momis.wsdl.wrappers.WSDLWrapperSoapBindingImpl
* Implementation for the generic Momis Wrapper.
This is the class to deploy
Basically all code is generated by the Wsdl2java Axis tool
WSDLWrapperRS_impl
Qualified Type Name it.unimo.dbgroup.momis.communication.server.wsdl.WSDLWrapperRS_impl
Number of Fields: 1
Number of Methods: 15
Number of Lines: 289
Superclass: it.unimo.dbgroup.momis.wsdl.wrappers.WSDLWrapperRSSoapBindingImpl
* Implementation for the generic Momis Wrapper.
This is the class to deploy
Basically all code is generated by the Wsdl2java Axis tool
CorbaWrapper_impl
Qualified Type Name it.unimo.dbgroup.momis.communication.server.corba.CorbaWrapper_impl
Number of Fields: 9
Number of Methods: 13
Number of Lines: 455
Superclass: it.unimo.dbgroup.momis.idl.CorbaWrapper.CorbaWrapperPOA
* - Corba Interface
This class performs corba calls to the remote resultset object implementing the interface WrapperRS
In this way we hide the commonication layer and we work exactly as we use a local wrapper such as a core wrapper.
SERVER CORBA object for the MOMIS JDBC wrapper.
This object is ready to handle the timeout for other CORBA ojbects -
CorbaWrapperRS_impl
Qualified Type Name it.unimo.dbgroup.momis.communication.server.corba.CorbaWrapperRS_impl
Number of Fields: 7
Number of Methods: 23
Number of Lines: 516
Interfaces: it.unimo.dbgroup.momis.tools.TimeOutable
Superclass: it.unimo.dbgroup.momis.idl.CorbaWrapper.CorbaWrapperRSPOA
* This is the class for the MomisRecordset SERVANT objects.

Each instance of this class provides a way to handle the result of a query.

This object is managed in a TimeOutManager object because we want it'll expire after a time-out period.