Data Adaptor Plugin overview

Data Adaptor Plugin overview

The Data Adaptor is an Engine Session plugin to the Web Determinations Interview Engine which allows the current Web Determinations session to use an arbitrary data source for loading and saving session data.

 

The Web Determinations server only loads one Data Adaptor plugin when a Web Determinations session is started. The Web Determinations server ships with a Data Adaptor plugin, called XDSDataAdaptor. By default this plugin is loaded unless another Data Adaptor plugin has been registered in the current Web Determinations session, in which case the new (custom) Data Adaptor plugin will be loaded.

The Data Adaptor is a plugin, therefore it follows plugin implementations and its benefits/restrictions.For more information about plugins, see Introduction to plugins. For more information about Interview Engine, see Understand the Interview Engine.

The XDS Data Adaptor loads and saves data with the .xds format. This is useful for testing purposes as a Web Determinations session can load data that was saved from, for example, a Debugger session, and likewise a Debugger session can load data from a Web Determinations session.

The examples are for Data Adaptor plugins based on Java programming, but the concepts apply to both Java and .NET.

For more information about implementing the Data Adaptor to common integration scenarios, please see Data Adaptor - common scenarios.

Go to:

Data Adaptor and the Web Determination architecture

Developing a Data Adaptor plugin for your specific project/datasource

General Data Adaptor functionality and design concepts

Miscellaneous notes

See also:

Introduction to plugins

Plugin loading, invocation and discovery

Plugins - general technical information

Create a plugin

Create a Data Adaptor

Data Adaptor - common scenarios

Data Adaptor - pseudo code

Data Adaptor - sample code (DerbyDataAdaptor)

Data Adaptor - sample code (Autosave with Derby)

Data Adaptor and the Web Determination architecture

This section details how the Data Adaptor fits into the Web Determinations architecture, and how to use it in the Web Determinations environment.

Go to:

How Web Determinations uses a Data Adaptor plugin by default

Data Adaptor plugin and other Web Determinations plugins

Error Handling

Data Adaptor Class Methods

How Web Determinations uses a Data Adaptor plugin by default

A Data Adaptor plugin is used whenever the user attempts to save or load Web Determinations session data. By default, the user saves/loads by clicking on the default 'Save/Load/Save As' buttons during a Web Determinations session.

When the user loads data using the default method, the following occurs:

  1. A list of available case ID's to load is displayed to the user.
  2. The user selects the caseID to load from a list.
  3. Web Determinations server retrieves the Data Adaptor registered to the current Web Determinations interview.
  4. Web Determinations Server calls the Data Adaptor load(), passing the caseID in together with the current Interview's rulebase.
  5. Data Adaptor load() returns an object that contains session data back to Web Determinations server.
  6. Web Determinations server starts a new session and loads the returned data into it.

 

When the user saves using the default method, the following occurs:

  1. The user clicks on either Save or Save As.
    1. If the user chooses to Save and there is no CaseID assigned to the current session, the user specifies the CaseID using the Save As screen. Otherwise the current session Case ID is used.
    2. If the user chooses to Save As, the user specifies the CaseID to use for the save in the Save As screen.
  2. Web Determinations server retrieves the Data Adaptor registered to the current Web Determinations interview.
  3. The CaseID from Step 1a/b is used by Web Determinations server to call the Data Adaptor save(). The Web Determinations server also passes in the Web Determinations interview session data.
  4. The Data Adaptor performs the save onto the datasource, and returns a Case ID.
  5. The Web Determinations server uses the Case ID returned and assigns it onto the current Web Determinations interview session.
Loading by URL

Web Determinations also allows a case to be loaded automatically via a URL template. Using the URL skips the step where the user has to choose which Case ID to load. Instead the user starts the Web Determinations interview with the data loaded already. This is useful for integrating Web Determinations  with other web applications.

http://<webdeterminations_webapp>/startsession/<rulebase>/<locale>/<goalID>?caseID=<caseID#>&user=guest 

 

Data Adaptor plugin and other Web Determinations plugins

Other ways in which the Data Adaptor is used in Web Determinations is through other Web Determinations plugins. These plugins can call the Data Adaptor's save and load methods, thus allowing loading data into the Web Determinations interview/saving data in the current Web Determinations interview to be controlled by plugins such as Event Handlers. Saving of session data can happen automatically without the user needing to explicitly issue a save command (which would be the most common case when Web Determinations is integrated within a web application/workflow).

Web Determinations plugins can access the Data Adaptor registered to the current Web Determinations session if the plugin has access to the SessionContext object or its member the InterviewSession object. The Web Determinations plugin can call the Data Adaptor load() via the InterviewSession object to retrieve InterviewUserData based on the provided caseID, or call the Data Adaptor save() to persist the current InterviewSession; for example:

 

Calling the Data Adaptor load

InterviewUserData InterviewUserData = sessionContext.getInterviewSession().getDataAdaptor().load(token, caseIDToLoad, sessionContext.getInterviewSession().getRulebase());


Calling the Data Adaptor save

interviewSession.getDataAdaptor().save(token, caseIDToSave, interviewSession);


Notes

Error handling

Data Adaptor plugins can handle errors that occur within it (for example, SQLExceptions), and then throw an exception for the calling method to handle (or in Java, an unchecked exception). 

When the Data Adaptor load method is called and an error occurs:

When the Data Adaptor save method is called:

Data Adaptor class methods

A Data Adaptor plugin implements the DataAdaptorPlugin interface. The DataAdaptorPlugin interface in turn extends the DataAdaptor interface and also the InterviewSessionPlugin interface.

The DataAdaptor interface requires the following when implemented:

 

Method Signature
Description
InterviewUserData load(SecurityToken token,
String caseID,
InterviewRulebase rulebase)
  • The SecurityToken can be used by the plugin developer for authorization.
  • The caseID is the ID used by the developer to retrieve the Web Determinations session data to load.
  • The InterviewRulebase allows the plugin developer to access the session's rulebase, and its
    contents; that is, entities, attributes, relationships, screens, flows, and so on.
  • an object of InterviewUserData is returned, which in turn is loaded by the calling process.
String save(SecurityToken token,
String caseID,
InterviewSession session)
  • The SecurityToken can be used by the plugin developer for authorization.
  • The caseID is used as the ID to save the Web Determinations Session data. This is optional if the dataAdaptor is generating it's own ID during the save.
  • The InterviewSession contains the Web Determinations session, which has the data to save and also data about the current session; for example, the rulebase being used.
  • The caseID used by the save() is returned.
boolean dataAdaptorProvidesCaseID
  • This is set by the plugin developer to true if the dataAdaptor will provide the caseID (usually for first-time save). When this is true, the Save As button is not displayed, therefore the user can only initiate Save action.
  • This is used for setups where the datasource of the Data Adaptor will generate the CaseID; for example, SQL insert into a table with autoincrement primary key.
  • For default setups where the Web Determinations server calls the Data Adaptor save() (and not another Web Determinations extension), the CaseID passed will be null/empty since the user was not able to provide the Case ID.
String[] listCases(SecurityToken token,
InterviewRulebase rulebase)
  • The SecurityToken can be used by the plugin developer for authorization.
  • The InterviewRulebase allows the plugin developer to access the session's rulebase, and its
    contents; that is, entities, attributes, relationships, screens, flows, and so on.
  • The String array returned is a list of Case ID's to display to the user as options of cases available to be loaded.

 

For requirements from the plugin interface, see Plugin loading, invocation and discovery See the sample code section for practical examples

Developing a Data Adaptor plugin for your specific project/datasource

This section explains the various approaches on designing and developing a Data Adaptor plugin for a specific project/rulebase/datasource.

Go to:

Factors to consider when designing a Data Adaptor plugin

About the data passed into the Data Adaptor methods

How to use the data passed into the Data Adaptor methods

How to build the InterviewUserData object in Data Adaptor load()

Factors to consider when designing a Data Adaptor plugin

When designing a Data Adaptor, the following factors needs to be analyzed

 

Essentially, the Data Adaptor needs to be able to:

 

The design of a Data Adaptor plugin varies because how it will map the datasource data to its equivalent Web Determinations session data depends on the datasource and rulebase setup/complexity. Also the maintainability aspect of the Data Adaptor is important - because for both rulebase and datasource change it is important to design the Data Adaptor to match the anticipated changes both will have in the future.

For example - the Data Adaptor might have to deal with a very complex rulebase and database system that is anticipated to change. It will probably be designed with an architecture, using other tools/libraries, etc to ensure that the it can meet various requirements such as authentication, datasource transaction, errors, as well as non-functional such as performance. On the other hand the rulebase and datasource might be small and simple in which case the Data Adaptor simply needs to be a small implementation, with a lot of hard coded data to access the datasource.

About the data passed into the Data Adaptor methods

It is important to understand the available data that is passed to the Data Adaptor load() and save().The input arguments objects that are of interest for both are the InterviewSession and InterviewRulebase objects. The SecurityToken and caseID are both sufficiently explained in the previous section Programming Constructs.

But first, it is important to understand the two main types of data that exists during Determination Engine runtime:

 

The following table shows the difference between the Model and Instance:

 

Rulebase Model data
Rulebase Instance data
the child (entity)
child1 (identifier value = Wayne)
the school (entity)
school2 (identifier value = Summer High)
the child's name (attribute)
Wayne
the child's school (relationship)
<child1 connects to school2>

 

The InterviewSession object contains many members, but with relation to the Data Adaptor it's useful members are:

How to use the data passed into the Data Adaptor methods

The Data Adaptor load() receives the InterviewRulebase, therefore it only has access to the rulebase model data.


The Data Adaptor save() receives the InterviewSession object, so it has access to both the rulebase model and instance data. Note that it does not receive the Web Determinations session user data in a InterviewUserData object - the return object of the Data Adaptor load().

public String save(SecurityToken token, String caseID,
                                             InterviewSession iSession)
{
    ...
    Session sessionDE = session.getRuleSession(); //note you need to get the Determination Engine session
    Rulebase rulebaseDE = sessionDE.getRulebase(); //this gets the Determination Engine rulebase
    ...

    for(Object entObj : rulebaseDE.getEntities())
    {
        //Get all instances of the current entity from the session and loop trhough it
        Entity currentEntity = (Entity)entObj;
        Collection<EntityInstance> currentEntityInstances = currentEntity.getEntityInstances(sessionDE);
        //note retrieval of instance using the Entity model object
        Iterator iterateCurrentEntityInstances = currentEntityInstances.iterator();
        while(iterateCurrentEntityInstances.hasNext())
        {
            EntityInstance currEntInstance = (EntityInstance)iterateCurrentEntityInstances.next();

            //Access attribute instance values of the current Entity Instance
            for(Object attrObj : currentEntity.getAttributes())
            {
                Attribute currAttr = (Attribute)attrObj;

                //Attributes in an entity instance is accessed through the Attribute object and passing the Entity
                //instance
                Object attributeValue = currAttr.getValue(currEntInstance); //note retrieval of instance using the
                             Attribute model object
            }
            //Get source or target instance for each relationship of the current Entity model by passing the
            //instance to the Relationship model data
            for(Object relObj : currentEntity.getRelationships())
            {
                Relationship currRel = (Relationship)relObj;
                     //note retrieval of relationship source/targets using the Relationship model object
                if(currRel.isSingleTarget) EntityInstance targetInstance = currRel.getTarget(currEntInstance);
                if(currRel.isSingleSource) EntityInstance sourceInstance = currRel.getSource(currEntInstance);
            }
        }
    }
    ...
}


How to build the InterviewUserData object in Data Adaptor load()

The InterviewUserData is much simpler than the InterviewSession or InterviewRulebase. The InterviewUserData has a List of Entities and Relationship instances.

General Data Adaptor functionality and design concepts

Authentication

A SecurityToken is provided to the save(), load(), and listCases() for the Data Adaptor to use if it needs to authenticate the user; for example, the Data Adaptor may need to use the token to authenticate and connect to the datasource as well.

It is optional to use the SecurityToken.

Identifying Entity instances from each other

There are a couple of uses for instance Identifiers in the Data Adaptor:

 

The instanceName of an Entity instance object (which is InterviewEntityInstance or EntityInstance) is it's unique identifier amongst all other Entity instances in aWeb Determinations session; for example, a School entity instance can have an instanceName of 's1'. Therefore no other instance, regardless of whether it is a School entity or not, may have an instanceName of 's1'. The instanceName can be anything from a simple number to composite text generated from attributes of the instance; for example, instanceName = firstName + lastName + dob.toString().

The instanceName of Entity instances loaded into the Web Determinations session is maintained - so any instanceNames from the Data Adaptor load() will still be intact for those same instances that are processed in Data Adaptor save()

For complicated setups, the Data Adaptor developer can implement their own method of ID'ing instances. The Data Adaptor can implement a complex/composite instanceName property generated from various data values of the instance or the Data Adaptor developer can create an Identifier object that can assist in ID management of instances.

Ways to make the Data Adaptor flexible to rulebase and datasource changes

Making the Data Adaptor flexible to rulebase and datasource changes varies wildly from each implementation, but there are approaches and tools that should work for most setups. One thing to note is that datasource, especially legacy database systems does no change often due to the number of other systems that depend on it. Rulebase changes can vary from project to project.

Using a tool that simplifies the Data Adaptor's data collection from the datasource will be useful for both managing datasource changes and also rulebase-datasource mapping; for example, Object-Relational Mapping for relational databases.

Ideally the Data Adaptor load and save can be driven via a rulebase-datasource mapping as opposed to hard coding rulebase and datasource mapping within the Data Adaptor logic. The mapping can be separate for Data Adaptor load and save.

Other Data Adaptor load() specific concepts

The following is a list of things to note when developing the Data Adaptor load():

Relationships

Entity Relationships is the more complex part of loading data into a Web Determinations session.

Other Data Adaptor save() specific concepts

The following is a list of handy notes for reference when developing the Data Adaptor save()

Miscellaneous Notes