Go to primary content
Oracle® Retail POS Suite Implementation Guide, Volume 2 – Extension Solutions
Release 14.1
E54476-02
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

16 Extending Intra Store Data Distribution

This chapter describes how to extend the Intra Store Data Distribution.

Intra Store Data Distribution Extensibility

Extensibility is supported through the interface-based design and the use of the Spring Framework. From an extensibility stand point, an alternate implementation of any of the exposed interfaces could inherit from one of the out-of-the-box implementation classes and be injected into the system through Spring.

Additionally, the schema has been designed to enable the addition of datasets and dataset tables.

Adding New Table To Existing DataSet

Adding a new dataset table to the data model is as simple as adding a new row to the table CO_DT_ST_TB_IDDI and creating table script in CreateSchema.sql.

Adding More Tables To Existing DataSet Types

The following example walks through the process of adding more tables to the existing DataSet in IDDI.

  1. Insert the tables to be associated with the existing DataSet by adding records to CO_DT_ST_TB_IDDI using SQL.

    Run the following queries to insert the table association to DataSet.

    Example 16-1 Adding Table Association To Employee DataSet

    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (<<Employee DataSet ID>>, <<'Store ID'>>,<<'Table1'>>,<<'Table1.txt'>>,1 );
     
    TableName: CO_DT_ST_TB_IDDI 
     
    Column Description
    ID_DT_ST : DataSet ID
    ID_STR_RT: Store ID
    NM_TB    : Table Name
    NM_FL    : File Name of the Flat file to be generated
    AI_LD_SEQ: Table Order in which the data to be exported and imported 
     
    eg: Get the Employee DataSet ID from CO_DT_ST_IDDI table
     
    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (1,'04241','TABLE1','TABLE1.TXT',1 );
     
    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (1,'04241','TABLE2','TABLE2.TXT',2 );
    
  2. Add CREATE TABLE scripts in CreateSchema.sql.

    CREATE TABLE "offlinedb"."TABLE1"
        (   "COLUMN1” <<TYPE>> <<Constraint>>,
            "COLUMN2, <<TYPE>> <<Constraint>>)
    CREATE TABLE "offlinedb"."TABLE2"
        (   "COLUMN1” <<TYPE>> <<Constraint>>,
            "COLUMN2, <<TYPE>> <<Constraint>>)
    

Adding a Table to an Existing Data Set Using the Stores Build Scripts

Do the following to add a table using the build script:

  1. Open <source_directory>\modules\utility\build.xml.

  2. Find the target dataset's offline table list:

    ordered.<data set name>.tables
    
  3. Add the name of the SQL file that contains the create script.

    The create scripts are located at <source_directory>\modules\common\deploy\server\common\db\sql\Create.

Adding a New DataSet

Do the following to add new DataSet:

  1. Add DataSet information in CO_DT_ST_IDDI.

  2. Add DataSet tables to CO_DT_ST_TB_IDDI.

  3. Create <DataSetKey>Producer and <DataSetKey>Consumer classes extending from AbstractDataSetProducer and AbstractDataSetConsumer respectively.

  4. Define service_config_<<DataSetKey>> in ServiceContext.xml

  5. Define service_<<DataSetKey>>Producer with class=<DataSetKey>Producer and service_<<DataSetKey>>Consumer wit h class=<DataSetKey>Consumer in ServiceContext.xml

  6. Add to service_<<DataSetKey>>Producer and service_<<DataSetKey>>Consumer to service_DataSetService and service_ClientDataSetService respectively in ServiceContext.xml

  7. Add DataSet key to service_FrequentProducerJob/service_InfrequentProducerJob and service_FrequentConsumerJob/service_InfrequentConsumerJob in ServiceContext.xml

  8. Add create table scripts and insert script for newly added DataSet in CreateSchema.sql.

Adding a New DataSet Using the Stores Build Scripts

Do the following to add a new dataset using the build script:

  1. Open <source_directory>\modules\utility\build.xml .

  2. Find the section that defines the offline table lists (target assemble.iddi).

  3. Create the ordered list of tables, following the pattern established in the file. All create scripts are located at <source_directory>\modules\common\deploy\server\common\db\sql\Create.

  4. Add a call to concat.file for the new data set schema, following the other calls in the file:

            <antcall target="concat.file">
                <param name="target.file" value="${raw.sql.file}"/>  -- The path and name of the file being generated
                <param name="file.comment" value="-- Employee DataSet Tables"/> -- Comment added to the file ahead of the create SQL
                <param name="src.dir" value="${sql.src.dir}"/> -- Path to the create scripts listed in the "ordered.<data set name>.tables" list
                <param name="file.list" value="${ordered.employee.tables}"/> -- Variable holding the ordered list of create scripts
                <reference refid="comment.filter" torefid="filter"/>
            </antcall>
    

Configuring Schedule for DataSet Producer and Consumer

Any existing DataSet Producer and Consumer can be individually configured to run on scheduled basis.

Configure DataSet Producer

Do the following to configure DataSet Producer:

  1. Add JobDetailBean bean configuration service_<<DataSet>>ProducerJob.

        <bean id="service_<<DataSet>>ProducerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
            <property name="jobClass">
                <value>oracle.retail.stores.foundation.iddi.DataSetProducerJob</value>
            </property>
            <property name="jobDataAsMap">
                <map>
                    <entry key="producer" value-ref="service_DataSetService"/>
                    <entry key="dataSets">
                        <list>
                            <ref local="service_config_<<DataSetKey>>"/>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>
    

    Note:

    service_config_<<DataSetKey>> should have been configured with the DataSetKey

  2. Add CronTriggerBean bean configuration service_Trigger<<DataSet>>Producer

        <bean id="service_Trigger<<DataSet>>Producer" class = "org.springframework.scheduling.quartz.CronTriggerBean">
            <property name = "jobDetail">
                <ref local="service_<<DataSet>>ProducerJob"/>
            </property>
            <property name="cronExpression" value="0 0,15,30,45 0 * * ?"/>
        </bean>
    

    The above DataSet is configured to run once every 15 minutes.

    For more information about the Quartz scheduler, see the documentation at http://www.quartz-scheduler.org/documentation.

  3. Add service_Trigger<<DataSet>>Producer to the SchedulerFactoryBean bean configuration:

        <bean id="service_ProducerSchedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref local="service_TriggerFrequentProducer"/>
                    <ref local="service_TriggerInfrequentProducer"/>
                    <ref local="service_Trigger<<DataSet>>Producer"/>
                </list>
            </property>
        </bean>
    

Configure DataSet Consumer

Do the following to configure DataSet Consumer:

  1. Add JobDetailBean bean configuration service_<<DataSet>>ConsumerJob:

        <bean id="service_<<DataSet>>ConsumerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
            <property name="jobClass">
                <value>oracle.retail.stores.foundation.iddi.ClientDataSetController</value>
            </property>
            <property name="jobDataAsMap">
                <map>
                   <entry key="dataSets">
                        <list>
                            <ref local="service_config_<< DataSetKey>>"/>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>
    

    Note:

    service_config_<<DataSetKey>> should have been configured with the DataSetKey.

  2. Add CronTriggerBean bean configuration service_Trigger<<DataSet>>Consumer:

        <bean id="service_Trigger<<DataSet>>Consumer" class = "org.springframework.scheduling.quartz.CronTriggerBean">
            <property name = "jobDetail">
                <ref local="service_<<DataSet>>ConsumerJob"/>
            </property>
            <property name="cronExpression" value="0 0,15,30,45 0 * * ?"/>
        </bean>
    

    The DataSet is configured to run once every 15 minutes.

  3. Add service_Trigger<<DataSet>>Consumer to the SchedulerFactoryBean bean configuration:

        <bean id=" service_clientSchedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref local="service_TriggerFrequentConsumer"></ref>
                    <ref local="service_TriggerInfrequentConsumer"></ref>
                    <ref local="service_Trigger<<DataSet>>Consumer"/>
                </list>
            </property>
        </bean>
    

Adding New DataSet Type

The following example walks through the process of adding a new DataSet to the existing IDDI.

  • Insert the new DataSet information in into the databaset table CO_DT_ST_IDDI using SQL:

  • Insert the tables associated with the DataSet added to CO_DT_ST_TB_IDDI using SQL.

  1. Run the following queries to insert new DataSet information and table association to DataSet.

    Example 16-2 Adding New DataSet

    insert into CO_DT_ST_IDDI
    (ID_DT_ST, ID_STR_RT, NM_DT_ST)
    values
    (maxid+1,<<'StoreID'>> ,<<'DataSetName'>>);
     
    TableName: CO_DT_ST_IDDI 
     
    Column Description
    ID_DT_ST : DataSet ID
    ID_STR_RT: Store ID
    NM_DT_ST : DataSet Name
     
    eg:
    insert into CO_DT_ST_IDDI
    (ID_DT_ST, ID_STR_RT, NM_DT_ST)
    values
    (6,'04241','NEW');
    

    Example 16-3 Adding Table association to New DataSet

    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (<<New DataSet ID>>, <<'Store ID'>>,<<'Table1'>>,<<'Table1.txt'>>,1 );
     
    eg:
    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (6,'04241','TABLE1','TABLE1.TXT',1 );
     
    insert into CO_DT_ST_TB_IDDI
    (ID_DT_ST, ID_STR_RT, NM_TB, NM_FL,AI_LD_SEQ)
    values
    (6,'04241','TABLE2','TABLE2.TXT',2 );
    
  2. Create <DataSetKey>Producer and <DataSetKey>Consumer classes extending from AbstractDataSetProducer and AbstractDataSetConsumer respectively.

    Example 16-4 DataSetProducer Code

    package oracle.retail.stores.domain.iddi;
     
    import oracle.retail.stores.foundation.iddi.AbstractDataSetProducer;
    import oracle.retail.stores.foundation.iddi.DataSetMetaData;
    import oracle.retail.stores.foundation.iddi.TableQueryInfo;
    import oracle.retail.stores.foundation.iddi.ifc.DataSetMetaDataIfc;
     
    public class NewDataSetProducer extends AbstractDataSetProducer 
    {
     
            private final String[] TABLE_FIELDS={"*"};
            
    /**
            
             * NewDataSetProducer constructor
             */
     
            public NewDataSetProducer ()
            {
                    
            }
            /**
            * Get DataSetMetatIfc reference 
            * 
            */
            public DataSetMetaDataIfc getDataSetMetaData() 
            {
                    // Get the table names for the Key
                    return dataSetMetaData;
            }
            /**
            * Initialize the MetaData for the DataSetProducer 
            */
            public void initializeDataSet() 
            {
                    dataSetMetaData = new DataSetMetaData(dataSetKey);
            }
            /**
            * Create TableQueryInfo object with the column names to fetch 
            * @param TableName
            * @return TableQueryInfo Object
            */
            public TableQueryInfo getTableQueryInfo(String tableName) 
            {
                    TableQueryInfo tableQueryInfo = new TableQueryInfo(tableName);
                    tableQueryInfo.setTableFields(TABLE_FIELDS);
                    return tableQueryInfo;
            }
            /**
             * Finalize DataSet Method
             * 
             */
            public void finalizeDataSet()
            {
                    
            }
    }
    

    Example 16-5 DataSetConsumer Code

    package oracle.retail.stores.domain.iddi;
     
    import oracle.retail.stores.foundation.iddi.AbstractDataSetConsumer;
     
    //--------------------------------------------------------------------------
    /**
        The NewDataSetConsumer defines methods that the
        application calls to import Employee dataset files into
        offline database.
         @version $Revision: $
    **/
    //--------------------------------------------------------------------------
     
    public class NewDataSetConsumer extends AbstractDataSetConsumer
    {         /**  DataSet key name for currency dataset.
     
        */    private String dataSetKey = null;
     
        //  --------------------------------------------------------------------------    
        /**
            @return Returns the dataSetKey
        **/
        //--------------------------------------------------------------------------
     
        public String getDataSetKey()
        {
           
            return dataSetKey;            
        }   
     
        //  --------------------------------------------------------------------------
        /**
          @param dataSetKey The DataSetKey to set
        **/
        //--------------------------------------------------------------------------
     
        public void setDataSetKey(String dataSetKey)
        {               
     
            this.dataSetKey = dataSetKey;  
            
      }
    }
    
  3. Define service_config_<<DataSetKey>> in ServiceContext.xml:

        <bean id="service_config_<<datasetKey>> " class="java.lang.String">
            <constructor-arg type="java.lang.String" value="<<DataSetKey>>"/>
        </bean>eg:    <bean id="service_config_NEW_KEY" class="java.lang.String">
            <constructor-arg type="java.lang.String" value="NEW"/>
        </bean>
    
  4. Define service_<<DataSetKey>>Producer with class=<DataSetKey>Producer and service_<<DataSetKey>>Consumer with class=<DataSetKey>Consumer in ServiceContext.xml:

    <bean id="service_NewProducer" class="oracle.retail.stores.domain.iddi.NewDataSetProducer" lazy-init="true" singleton=”true”>
            <property name="dataSetKey" ref="service_config_NEW_KEY"/>
            <property name="dataExportFilePath" ref="service_config_DataExportFilePath"/>
            <property name="dataExportZipFilePath" ref="service_config_DataExportZipFilePath"/>
        </bean>
        <bean id="service_NewConsumer"
     class="oracle.retail.stores.domain.iddi.NewDataSetConsumer"
                 lazy-init="true"
                 singleton="true">
            <property name="dataSetKey" ref="service_config_NEW_KEY"/>
            <property name="dataImportFilePath" ref="service_config_DataImportFilePath"/>
        </bean>
    
  5. Add to service_<<DataSetKey>>Producer and service_<<DataSetKey>>Consumer to service_DataSetService and service_ClientDataSetService respectively in ServiceContext.xml

       <bean id="service_DataSetService" class="oracle.retail.stores.foundation.iddi.DataSetService" singleton="true">
            <property name="producers">
                <map>
                    <entry key-ref="service_config_EMP_KEY" value-ref="service_EmployeeProducer"/>
                    <entry key-ref="service_config_ITM_KEY" value-ref="service_ItemProducer"/>
                    <entry key-ref="service_config_PRC_KEY" value-ref="service_AdvancedPricingProducer"/>
                    <entry key-ref="service_config_TAX_KEY" value-ref="service_TaxProducer"/>
                    <entry key-ref="service_config_CUR_KEY" value-ref="service_CurrencyProducer"/>
                    <entry key-ref="service_config_NEW_KEY" value-ref="service_NewProducer"/>
                </map>
            </property>
        </bean>
        <bean id="service_ClientDataSetService"
         class="oracle.retail.stores.foundation.iddi.ClientDataSetService" singleton="true">
            <property name="consumers">
                <map>
                    <entry key-ref="service_config_EMP_KEY" value-ref="service_EmployeeConsumer"/>
                    <entry key-ref="service_config_CUR_KEY" value-ref="service_CurrencyConsumer"/>
                    <entry key-ref="service_config_TAX_KEY" value-ref="service_TaxConsumer"/>
                    <entry key-ref="service_config_ITM_KEY" value-ref="service_ItemConsumer"/>
                    <entry key-ref="service_config_PRC_KEY" value-ref="service_AdvancedPricingConsumer"/>
                    <entry key-ref="service_config_NEW_KEY" value-ref="service_NewConsumer"/>
                </map>
            </property>
            <property name="dataImportFilePath" ref="service_config_DataImportFilePath"/>
        </bean>
    
  6. Add DataSet key to service_FrequentProducerJob/service_InfrequentProducerJob and service_FrequentConsumerJob/service_InfrequentConsumerJob in ServiceContext.xml

        <bean id="service_FrequentProducerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
            <property name="jobClass">
                <value>oracle.retail.stores.foundation.iddi.DataSetProducerJob</value>
            </property>
            <property name="jobDataAsMap">
                <map>
                    <entry key="producer" value-ref="service_DataSetService"/>
                    <entry key="dataSets">
                        <list>
                            <ref local="service_config_EMP_KEY"/>
                            <ref local="service_config_PRC_KEY"/>
                            <ref local="service_config_TAX_KEY"/>
                            <ref local="service_config_NEW_KEY"/>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>
    
    <bean id="service_FrequentConsumerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
            <property name="jobClass">
                <value>oracle.retail.stores.foundation.iddi.ClientDataSetController</value>
            </property>
            <property name="jobDataAsMap">
                <map>
                   <entry key="dataSets">
                        <list>
                            <ref local="service_config_EMP_KEY"/>
                            <ref local="service_config_PRC_KEY"/>
                            <ref local="service_config_TAX_KEY"/>
                            <ref local="service_config_NEW_KEY"/>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>
    
  7. Add CREATE TABLE scripts and insert scripts to newly added DataSet in CreateSchema.sql.

    CREATE TABLE "offlinedb"."TABLE1"
        (   "COLUMN1” <<TYPE>> <<Constraint>>,
            "COLUMN2, <<TYPE>> <<Constraint>>)
    CREATE TABLE "offlinedb"."TABLE2"
        (   "COLUMN1” <<TYPE>> <<Constraint>>,
            "COLUMN2, <<TYPE>> <<Constraint>>)
    insert into CO_DT_ST_IDDI(ID_DT_ST, ID_STR_RT, NM_DT_ST) values(6,'04241','NEW');
    

Adding a New DataSet Type Using the Stores Build Scripts

Do the following to add a new dataset type using the build script:

  1. Open <source_directory>\modules\utility\build.xml .

  2. Find the section that defines the offline table lists (target assemble.iddi).

  3. Create the ordered list of tables, following the pattern established in the file. All create scripts are located at <source_directory>\modules\common\deploy\server\common\db\sql\Create.

  4. Add a call to concat.file for the new data set schema, following the other calls in the file:

            <antcall target="concat.file">
                <param name="target.file" value="${raw.sql.file}"/>  -- The path and name of the file being generated
                <param name="file.comment" value="-- Employee DataSet Tables"/> -- Comment added to the file ahead of the create SQL
                <param name="src.dir" value="${sql.src.dir}"/> -- Path to the create scripts listed in the "ordered.<data set name>.tables" list
                <param name="file.list" value="${ordered.employee.tables}"/> -- Variable holding the ordered list of create scripts
                <reference refid="comment.filter" torefid="filter"/>
            </antcall>
    

Changing Oracle Retail Point-of-Service Client Database Vendor

Currently the Oracle Retail Point-of-Service client uses Derby Database. However, the modifications to the code are minimal for replacing the Oracle Retail Point-of-Service client database from Derby to another database. Do the following to change the Oracle Retail Point-of-Service client database:

  1. Add Offline<<DBName>>Helper class which implements offlineDBHelperIfc.

  2. Change the installer to have new database driver jar file paths.

  3. Update the "<POOL name="jdbcpool class="DataConnectionPool" package="oracle.retail.stores.foundation.manager.data">" section of PosLFFDataTechnician.xml file with the driver, databaseUrl, userid, password.