Difference between revisions of "AMI Custom Java Plugins"

From 3forge Documentation
Jump to navigation Jump to search
Tag: visualeditor
Tag: visualeditor
Line 323: Line 323:
 
import java.util.List;
 
import java.util.List;
  
importcom.f1.ami.amicommon.AmiFactoryOption;
+
import com.f1.ami.amicommon.AmiFactoryOption;
importcom.f1.ami.center.triggers.AmiTrigger;
+
import com.f1.ami.center.triggers.AmiTrigger;
importcom.f1.ami.center.triggers.AmiTriggerFactory;
+
import com.f1.ami.center.triggers.AmiTriggerFactory;
importcom.f1.anvil.triggers.AnvilTriggerOrdersBySymSide;
+
import com.f1.anvil.triggers.AnvilTriggerOrdersBySymSide;
importcom.f1.container.ContainerTools;
+
import com.f1.container.ContainerTools;
importcom.f1.utils.PropertyController;
+
import com.f1.utils.PropertyController;
  
 
public class TestTriggerFactory implements AmiTriggerFactory {
 
public class TestTriggerFactory implements AmiTriggerFactory {
Line 551: Line 551:
  
 
CALL __RESET_TIMER_STATS("t1", true, false);
 
CALL __RESET_TIMER_STATS("t1", true, false);
 +
 +
= Custom Persistence Factory (AMI One, AMI Center) =
 +
 +
== Overview ==
 +
AMI's in-memory database is a comprehensive and realtime SQL storage engine that can be extended using Java Plugins.  The persistence plugin is a factory used to create table persister instances as defined in the imdb schema.
 +
 +
== Example ==
 +
Consider the Ami Script example:
 +
 +
CREATE TABLE mytable(col1 int) USE PersistEngine="'''MyPersister'''" PersistOptions="'''myoption=some_val'''"
 +
 +
The above sample command will cause AMI to:
 +
 +
# Create a table (named "mytable") with the specified columns (col1)
 +
# Look for a registered AmiTablePersisterFactory with the id "MyPersister".
 +
# Call newPersister()  on the factory, passing in a map of supplied options (''myoption=some_val'')
 +
# Call init(...) on the returned, newly generated persister.  
 +
 +
== Java interface (see javadoc for details)   ==
 +
com.f1.ami.center.table.persist.AmiTablePersisterFactory
 +
 +
== Property name ==
 +
ami.db.persister.plugins=''comma_delimited_list_of_fully_qualified_java_class_names''
 +
 +
== Example - Java Code ==
 +
<syntaxhighlight lang="java">
 +
package com.demo;
 +
 +
import java.util.Collection;
 +
import java.util.Collections;
 +
import java.util.Map;
 +
 +
import com.f1.ami.amicommon.AmiFactoryOption;
 +
import com.f1.container.ContainerTools;
 +
import com.f1.utils.PropertyController;
 +
 +
public class TestPersisterFactory implements AmiTablePersisterFactory {
 +
 +
        @Override
 +
        public void init(ContainerTools tools, PropertyController props) {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public AmiTablePersister newPersister(Map<String, Object> options) {
 +
                return new TestPersister();
 +
        }
 +
 +
        @Override
 +
        public String getPluginId() {
 +
                return "TESTPERSISTER";
 +
        }
 +
 +
        @Override
 +
        public Collection<AmiFactoryOption> getAllowedOptions() {
 +
                return Collections.EMPTY_LIST;
 +
        }
 +
 +
}
 +
 +
package com.demo;
 +
 +
import java.io.IOException;
 +
 +
import com.f1.ami.center.AmiSysCommandsUtils;
 +
import com.f1.ami.center.table.AmiImdbImpl;
 +
import com.f1.ami.center.table.AmiRowImpl;
 +
import com.f1.ami.center.table.AmiTable;
 +
import com.f1.utils.LH;
 +
 +
public class TestPersister implements AmiTablePersister {
 +
 +
        @Override
 +
        public void init(AmiTable sink) {
 +
                // TODOAuto-generated method stub      
 +
        }
 +
 +
        @Override
 +
        public void onRemoveRow(AmiRowImpl row) {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void onAddRow(AmiRowImpl r) {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void onRowUpdated(AmiRowImpl sink, long updatedColumns) {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void loadTableFromPersist() {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void saveTableToPersist() {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void clear() {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void flushChanges() {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void drop() {
 +
                // TODOAuto-generated method stub
 +
        }
 +
 +
        @Override
 +
        public void onTableRename(String oldName, String name) {
 +
                // TODOAuto-generated method stub
 +
        }
 +
}
 +
 +
 +
</syntaxhighlight>

Revision as of 23:29, 3 March 2021

Overview

AMI is an extendable platform such that java plugins can be integrated at various touch points throughout the product. There are various types of plugins, each for supporting a particular purpose. Regardless of type, there are certain guidelines to follow when embedding a plugin into AMI:

1. Write a Java class which implements the appropriate interface.

  • The various interfaces are discussed in the following sections.
  • Each plugin should have a universally unique ID, returned by getPluginId()
  • Many plugins operate as "factories" which create instances of class. For example, the Datasource Plugin creates Datasource Adapters on demand
  • The compiled class(es) must be added to the classpath. This is most easily done by bundling them into a jar and placing the jar in the lib directory. All jars in the lib directory are automatically added to the class path

2. Add the fully qualified Java class name to the appropriate property.

  • The name of the property coincides with the type of plugin
  • Defaults for a given plugin type are found in the config/defaults.properties file. You should override the property in the config/local.properties file).

In all cases, the plugins indirectly implement the AmiPlugin interface. Plugins are instantiated and initialized during startup, such that the failure of a plugin to startup will cause AMI to hard fail on startup. The exact reason for failure can be found in the log files.

Interfacing with Directory Naming Service (AMI One, Center)

Overview

In Enterprise environments, some services cannot be directly identified by a physical destination (ex: host name) and are instead logically identified. In this situation, the organization implements a directory naming service that can map, in realtime, the logical identifier to a physical destination. For AMI to access resources in this scenario, a plugin must be written that interfaces with the directory naming service. Then, when a resource is requested inside AMI, AMI will first ask the Plugin to "resolve" the logical name to a physical one, passing the resolved physical one to the underlying connectors. It's the plugin's responsibility to connect to the naming service and provide an answer in a timely fashion.

Using Multiple Resolvers

Note, that many resolvers can be supplied. The order in which they are defined in the property is the order in which they are visited. Once a resolver plugin says it "canResolve" the identifier, the remaining resolvers are not called.

Default case

If no resolvers plugins are provided, or none of the resolvers "canResolve(...)" a given identifier, then the identifier is considered a physical identifier and passed straight to the connector.

Java interface (see javadoc for details)

com.f1.ami.amicommon.AmiNamingServiceResolver

Property name

ami.naming.service.resolvers=comma_delimited_list_of_fully_qualified_java_class_names

Interfacing with Single Sign on and Entitlements (AMI One, Center, Web)

Overview

When a user attempts to access AMI, first it's necessary to validate the user should be granted access, through a valid user name and password. If the user should be granted, then certain attributes may need to be associated with the user that AMI can use to dictate fine-grained access.

There are two different entry points into AMI, each of which can have their own instance of an authentication adapter:

  • Frontend Web Interface - When accessing AMI through a browser, first the user must supply a user name and password via the html login page (see property name for front end web access)
  • Backend Command line interface - When accessing AMI's in-memory database using the command line interface, first the user must execute the login command, which in turn calls an instance of this plugin (see property name for backend command line access)

AMI Predefined Attributes

Attribute Description
ISADMIN If true, the user will be logged into the website with admin rights
ISDEV If true, the user will be logged into the website with developer rights
DEFAULT_LAYOUT If set, this will be the default layout loaded on login
LAYOUTS A comma delimited list of regular expressions for layouts that are available
amivar_some_varname A variable named user.some_varname of type string is added to the user's session. This has been deprecated, use amiscript.variable
amiscript.variable.some_varname A variable named varname of the supplied type is added to the user's session
AMIDB_PERMISSIONS A comma delimited combination of READ,WRITE,ALTER and EXECUTE which controls permissions for the user when logging in via jdbc or db command line

Java interface (see javadoc for details)

com.f1.ami.web.auth.AmiAuthenticator

Property name for front end web access

ami.auth.plugin.class=fully_qualified_class_name

Property name for backend command line access

ami.db.auth.plugin.class=fully_qualified_class_name

Example - Java Code

package com.demo;

import java.util.ArrayList;
import java.util.List;

importcom.f1.container.ContainerTools;
importcom.f1.utils.PropertyController;

public class TestAuthenticator implements AmiAuthenticator {

        @Override
        public void init(ContainerTools tools, PropertyController props) {
                // TODO Auto-generated method stub
        }

        @Override
        public AmiAuthResponse authenticate(String namespace, String location, String user, String password) {
                final List<AmiAuthAttribute> attributes = new ArrayList<AmiAuthAttribute>();
                attributes.add(new BasicAmiAttribute("ISDEV", "true"));
                attributes.add(new BasicAmiAttribute("ISADMIN", "true"));
                attributes.add(new BasicAmiAttribute("ami_layout_shared", "default_layout.ami"));
                return new BasicAmiAuthResponse(AmiAuthResponse.STATUS_OKAY, null, new BasicAmiAuthUser(user, "Jackie", "Davenson", "777-888-9999", "jDavenson@mail.com", "Tire Co.", attributes));
        }

        @Override
        public String getPluginId() {
                return "TestAuthenticator";
        }
}

Example - Configuration

ami.auth.plugin.class=com.demo.TestAuthenticatorPlugin

Connections to Custom External Datasources (AMI One, Center)

Overview

Connecting to external datasources or systems for accessing and uploading data is at the core of what AMI does. There are dozens of adapters out of the box for well known databases, file formats, etc. Large organizations that have custom databases/storage systems can access them in AMI by implementing a datasource plugin.

Each datasource can optionally support the following functionality:

  • Providing a list of available tables
  • Providing for a sample of data for a given table
  • Running a query (Downloading data into AMI)
  • Uploading data from AMI into the datasource

Java interface (see javadoc for details)  

com.f1.ami.amicommon.AmiDatasourcePlugin

com.f1.ami.amicommon.AmiDatasourceAdapter

Property name for front end web access

ami.datasource.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example Java Code

  1package com.demo;
  2
  3import java.util.HashMap;
  4import java.util.Map;
  5
  6importcom.f1.ami.amicommon.AmiDatasourceAdapter;
  7importcom.f1.ami.amicommon.AmiDatasourcePlugin;
  8importcom.f1.container.ContainerTools;
  9importcom.f1.utils.PropertyController;
 10
 11public class TestDatasourcePlugin implements AmiDatasourcePlugin {
 12       private static final Map<String, Object> OPERATORS_MAP = new HashMap<String, Object>();
 13       private static final Map<String, Object> WHERE_SYNTAX_MAP = new HashMap<String, Object>();
 14       private static final Map<String, Object> HELP_MAP = new HashMap<String, Object>();
 15       static {
 16               OPERATORS_MAP.put("eq", "=");
 17               OPERATORS_MAP.put("ne", "!=");
 18               OPERATORS_MAP.put("lt", "<");
 19               OPERATORS_MAP.put("gte", ">=");
 20               WHERE_SYNTAX_MAP.put("prefix", "((");
 21               WHERE_SYNTAX_MAP.put("suffix", "))");
 22               WHERE_SYNTAX_MAP.put("join", ") or (");
 23               WHERE_SYNTAX_MAP.put("true", "true");
 24       }
 25
 26       @Override
 27       public void init(ContainerTools tools, PropertyController props) {
 28       }
 29
 30       @Override
 31       public String getPluginId() {
 32               return "TestDatasource";
 33       }
 34
 35       @Override
 36       public String getDatasourceDescription() {
 37               return "Test";
 38       }
 39
 40       @Override
 41       public AmiDatasourceAdapter createDatasourceAdapter() {
 42               return new TestDatasourceAdapter();
 43       }
 44
 45       @Override
 46       public String getDatasourceIcon() {
 47               return "../../../../resources/test.PNG";
 48       }
 49
 50       @Override
 51       public String getDatasourceQuoteType() {
 52               return "\"";
 53       }
 54
 55       @Override
 56       public Map<String, Object> getDatasourceOperators() {
 57               return OPERATORS_MAP;
 58       }
 59
 60       @Override
 61       public Map<String, Object> getDatasourceWhereClauseSyntax() {
 62               return WHERE_SYNTAX_MAP;
 63       }
 64
 65       @Override
 66       public Map<String, Object> getDatasourceHelp() {
 67               return HELP_MAP;
 68       }
 69}
 70
 71package com.demo;
 72
 73import java.util.ArrayList;
 74import java.util.List;
 75
 76importcom.f1.ami.amicommon.AmiDatasourceAdapter;
 77importcom.f1.ami.amicommon.AmiDatasourceException;
 78import com.f1.ami.amicommon.AmiDatasourceTracker;
 79import com.f1.ami.amicommon.AmiServiceLocator;
 80import com.f1.ami.amicommon.msg.AmiCenterQuery;
 81import com.f1.ami.amicommon.msg.AmiCenterQueryResult;
 82import com.f1.ami.amicommon.msg.AmiCenterUpload;
 83import com.f1.ami.amicommon.msg.AmiDatasourceTable;
 84import com.f1.base.Columns;
 85import com.f1.base.Row;
 86importcom.f1.container.ContainerTools;
 87importcom.f1.utils.structs.table.BasicTable;
 88
 89public class TestDatasourceAdapter implements AmiDatasourceAdapter {
 90       private ContainerTools tools;
 91       private AmiServiceLocator serviceLocator;
 92
 93       @Override
 94       public void init(ContainerTools tools, AmiServiceLocator serviceLocator) throwsAmiDatasourceException {
 95               this.tools = tools;
 96               this.serviceLocator = serviceLocator;
 97       }
 98
 99       @Override
100       publicList<AmiDatasourceTable> getTables(AmiDatasourceTracker debugSink) throwsAmiDatasourceException {
101               List<AmiDatasourceTable> tables = newArrayList<AmiDatasourceTable>();
102               AmiDatasourceTable table = tools.nw(AmiDatasourceTable.class);
103               table.setCollectionName("master");
104               table.setName("accounts");
105               table.setCustomQuery("SELECT * FROM accounts WHERE ${WHERE}");
106               tables.add(table);
107               return tables;
108       }
109
110       @Override
111       publicList<AmiDatasourceTable> getPreviewData(List<AmiDatasourceTable> tables, int previewCount, AmiDatasourceTracker debugSink) throwsAmiDatasourceException {
112               for (int i = 0; i < tables.size(); i++) {
113                       AmiDatasourceTable table = tables.get(i);
114                       AmiCenterQuery q = tools.nw(AmiCenterQuery.class);
115                       q.setQuery(table.getCustomQuery());
116                       q.setLimit(previewCount);
117                       AmiCenterQueryResult rs = tools.nw(AmiCenterQueryResult.class);
118                       processQuery(q, rs, debugSink);
119                       List<Columns> results = rs.getTables();
120                       if (results.size() > 0)
121                               table.setPreviewData(results.get(i));
122               }
123               return tables;
124       }
125
126       @Override
127       public AmiServiceLocator getServiceLocator() {
128               return serviceLocator;
129       }
130
131       @Override
132       public void processQuery(AmiCenterQuery query, AmiCenterQueryResult resultSink, AmiDatasourceTracker debugSink) throws AmiDatasourceException {
133               String queryStatement = query.getQuery();
134               // Do something with query statement
135               List<Columns> result = newArrayList<Columns>();
136               BasicTable table = new BasicTable();
137               String id = "id";
138               String reputation = "reputation";
139               String isPaid = "isPaid";
140               table.addColumn(String.class, id);
141               table.addColumn(Integer.class, reputation);
142               bt.addColumn(Boolean.class, isPaid);
143               Row row = bt.newRow("superman123", 150, true);
144               bt.getRows().add(row);
145               Row row2 = bt.newRow("trucker66", 400, true);
146               bt.getRows().add(row2);
147               resultSink.setTables(result);
148       }
149
150       @Override
151       public boolean cancelQuery() {
152               return false;
153       }
154
155       @Override
156       public void processUpload(AmiCenterUpload upload, AmiCenterQueryResult resultsSink, AmiDatasourceTracker tracker) throwsAmiDatasourceException {
157               throw newAmiDatasourceException(AmiDatasourceException.UNSUPPORTED_OPERATION_ERROR, "Upload to datasource");
158       }
159}

Example - Configuration

ami.datasource.plugins=com.demo.TestDatasourcePlugin

Custom Triggers (AMI One, AMI Center)

Overview

AMI's in-memory database is a comprehensive and realtime SQL storage engine that can be extended using Java Plugins.  The trigger plugin is a factory used to create triggers as defined in the imdb schema.

Example

Consider the Ami Script example:                                                                                                                                      

CREATE TRIGGER mytrigger OFTYPE MyRiskCalc ON myTable USE myoption="some_value"

The above sample command will cause AMI to:

  1. Look for a registered AmiTriggerFactory with the id "MyRiskCalc".  
  2. Call newTrigger()  on the factory.
  3. Call startup(...) on the returned, newly generated trigger. Note that the startup will contain the necessary bindings:
    • Trigger name (ex: mytrigger)
    • Options (ex: myoption=some_value)
    • Target tables (ex: myTable)

Java interface (see javadoc for details)  

com.f1.ami.center.triggers.AmiTriggerFactory

Property name

ami.db.trigger.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example – Java Code  

 1package com.demo;
 2
 3import java.util.ArrayList;
 4import java.util.Collection;
 5import java.util.List;
 6
 7import com.f1.ami.amicommon.AmiFactoryOption;
 8import com.f1.ami.center.triggers.AmiTrigger;
 9import com.f1.ami.center.triggers.AmiTriggerFactory;
10import com.f1.anvil.triggers.AnvilTriggerOrdersBySymSide;
11import com.f1.container.ContainerTools;
12import com.f1.utils.PropertyController;
13
14public class TestTriggerFactory implements AmiTriggerFactory {
15        private List<AmiFactoryOption> options = new ArrayList<AmiFactoryOption>();
16
17        @Override
18        public Collection<AmiFactoryOption> getAllowedOptions() {
19                return options;
20        }
21
22        @Override
23        public void init(ContainerTools tools, PropertyController props) {
24        }
25
26        @Override
27        public String getPluginId() {
28                return "TESTTRIGGER";
29        }
30
31        @Override
32        public AmiTrigger newTrigger() {
33                return new TestTrigger();
34        }
35}
36
37package com.demo;
38
39importcom.f1.ami.center.table.AmiPreparedQuery;
40importcom.f1.ami.center.table.AmiPreparedQueryCompareClause;
41importcom.f1.ami.center.table.AmiPreparedRow;
42importcom.f1.ami.center.table.AmiRow;
43importcom.f1.ami.center.table.AmiTable;
44importcom.f1.ami.center.triggers.AmiAbstractTrigger;
45
46public class TestTrigger extends AmiAbstractTrigger {
47
48        @Override
49        public void onStartup() {
50                // TOD Auto-generated method stub
51        }
52
53        @Override
54        public void onInserted(AmiTable table, AmiRow row) {
55                // TODO Auto-generated method stub
56        }
57
58        @Override
59        public boolean onInserting(AmiTable table, AmiRow row) {
60                // TODO Auto-generated method stub
61                return super.onInserting(table, row);
62        }
63
64        @Override
65        public void onUpdated(AmiTable table, AmiRow row) {
66                // TODO Auto-generated method stub
67        }
68
69        @Override
70        public boolean onUpdating(AmiTable table, AmiRow row) {
71                // TODO Auto-generated method stub
72                return super.onUpdating(table, row);
73        }
74
75        @Override
76        public boolean onDeleting(AmiTable table, AmiRow row) {
77                // TODO Auto-generated method stub
78                return super.onDeleting(table, row);
79        }
80} 

Example - Configuration

ami.db.trigger.plugins=com.demo.TestTriggerFactory

Custom Stored Procedure (AMI One, AMI Center)

Overview

AMI's in-memory database is a comprehensive and realtime SQL storage engine that can be extended using Java Plugins.  The stored procedure plugin is a factory used to create stored procedures as defined in the imdb schema.

Example

Consider the Ami Script example:                                                                                                                                      

CREATE PROCEDURE myproc OFTYPE MyCustProc USE myoption="some_value"

The above sample command will cause AMI to:

  1. Look for a registered AmiStoredProcFactory with the id "MyCustProc".  
  2. Call newStoredProc()  on the factory.
  3. Call startup(...) on the returned, newly generated storedproc. Note that the startup will contain the necessary bindings:
    • Procedure name (ex: myproc)
    • Options (ex: myoption=some_value)
    • Target tables (ex: myTable)

Java interface (see javadoc for details)  

com.f1.ami.center.procs.AmiStoredProcFactory

Property name

ami.db.procedure.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example - Configuration

ami.db.procedure.plugins=com.demo.TestProcFactory

Custom Timer (AMI One, AMI Center)

Overview

AMI's in-memory database is a comprehensive and realtime SQL storage engine that can be extended using Java Plugins.  The timer plugin is a factory used to create timers as defined in the imdb schema.

Example

Consider the Ami Script example:

CREATE TIMER mytimer OFTYPE MyStartupTimer ON "0 0 0 0 MON-FRI UTC " USE myoption="some_value"

The above sample command will cause AMI to:

  1. Look for a registered AmiStoredProcFactory with the id "MyStartupTimer".  
  2. Call newTimer()  on the factory.  
  3. Call startup(...) on the returned, newly generated storedproc. Note that the startup will contain the necessary bindings:
    • Timer name (ex: mytimer)
    • Options (ex: myoption=some_value)
    • Schedule, Priority, etc.

Java interface (see javadoc for details)  

com.f1.ami.center.timers.AmiTimerFactory

Property name

ami.db.timer.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example - Java Code

 1package com.demo;
 2
 3import java.util.ArrayList;
 4import java.util.Collection;
 5import java.util.List;
 6
 7import com.f1.ami.amicommon.AmiFactoryOption;
 8import com.f1.container.ContainerTools;
 9import com.f1.utils.PropertyController;
10
11public class TestTimerFactory implements AmiTimerFactory {
12
13       private List<AmiFactoryOption> options = new ArrayList<AmiFactoryOption>();
14
15       public TestTimerFactory() {
16               // TODOAuto-generated method stub
17       }
18
19       @Override
20       public void init(ContainerTools tools, PropertyController props) {
21               // TODOAuto-generated method stub
22       }
23
24       @Override
25       public Collection<AmiFactoryOption> getAllowedOptions() {
26               return options;
27       }
28
29       @Override
30       public AmiTimer newTimer() {
31               return new TestTimer();
32       }
33
34       @Override
35       public String getPluginId() {
36               return "TESTTIMER";
37       }
38}
39
40package com.demo;
41
42import com.f1.ami.center.table.AmiImdb;
43
44public class TestTimer extends AmiAbstractTimer {
45
46       @Override
47       public void onTimer(long scheduledTime) {
48               // TODOAuto-generated method stub
49       }
50
51       @Override
52       public void onSchemaChanged(AmiImdb imdb) {
53               // TODOAuto-generated method stub
54       }
55
56       @Override
57       protected void onStartup() {
58               // TODOAuto-generated method stub
59       }
60}

Example - Configuration

ami.db.timer.plugins=com.demo.TestTimerFactory

================

TIMER PROCEDURES

================

__SCHEDULE_TIMER (TimerName String nonull, Delay long nonull)

runs a scheduled execution of timer with TimerName, Delay is in milliseconds from now

Example:

CALL __SCHEDULE_TIMER("t1",15000);

__SHOW_TIMER_ERROR (TimerName String nonull)

shows last error of timer with TimerName

Example:

CALL __SCHEDULE_TIMER_ERROR("t2");

__RESET_TIMER_STATS (TimerName String nonull,ExecutedStats boolean nonull, ErrorStats boolean nonull)

resets ExecutedCount and/or ErrorCount of timer with TimerName

Example:

CALL __RESET_TIMER_STATS("t1", true, false);

Custom Persistence Factory (AMI One, AMI Center)

Overview

AMI's in-memory database is a comprehensive and realtime SQL storage engine that can be extended using Java Plugins.  The persistence plugin is a factory used to create table persister instances as defined in the imdb schema.

Example

Consider the Ami Script example:

CREATE TABLE mytable(col1 int) USE PersistEngine="MyPersister" PersistOptions="myoption=some_val"

The above sample command will cause AMI to:

  1. Create a table (named "mytable") with the specified columns (col1)
  2. Look for a registered AmiTablePersisterFactory with the id "MyPersister".
  3. Call newPersister()  on the factory, passing in a map of supplied options (myoption=some_val)
  4. Call init(...) on the returned, newly generated persister.  

Java interface (see javadoc for details)  

com.f1.ami.center.table.persist.AmiTablePersisterFactory

Property name

ami.db.persister.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example - Java Code

package com.demo;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import com.f1.ami.amicommon.AmiFactoryOption;
import com.f1.container.ContainerTools;
import com.f1.utils.PropertyController;

public class TestPersisterFactory implements AmiTablePersisterFactory {

        @Override
        public void init(ContainerTools tools, PropertyController props) {
                // TODOAuto-generated method stub
        }

        @Override
        public AmiTablePersister newPersister(Map<String, Object> options) {
                return new TestPersister();
        }

        @Override
        public String getPluginId() {
                return "TESTPERSISTER";
        }

        @Override
        public Collection<AmiFactoryOption> getAllowedOptions() {
                return Collections.EMPTY_LIST;
        }

}

package com.demo;

import java.io.IOException;

import com.f1.ami.center.AmiSysCommandsUtils;
import com.f1.ami.center.table.AmiImdbImpl;
import com.f1.ami.center.table.AmiRowImpl;
import com.f1.ami.center.table.AmiTable;
import com.f1.utils.LH;

public class TestPersister implements AmiTablePersister {

        @Override
        public void init(AmiTable sink) {
                // TODOAuto-generated method stub      
        }

        @Override
        public void onRemoveRow(AmiRowImpl row) {
                // TODOAuto-generated method stub
        }

        @Override
        public void onAddRow(AmiRowImpl r) {
                // TODOAuto-generated method stub
        }

        @Override
        public void onRowUpdated(AmiRowImpl sink, long updatedColumns) {
                // TODOAuto-generated method stub
        }

        @Override
        public void loadTableFromPersist() {
                // TODOAuto-generated method stub
        }

        @Override
        public void saveTableToPersist() {
                // TODOAuto-generated method stub
        }

        @Override
        public void clear() {
                // TODOAuto-generated method stub
        }

        @Override
        public void flushChanges() {
                // TODOAuto-generated method stub
        }

        @Override
        public void drop() {
                // TODOAuto-generated method stub
        }

        @Override
        public void onTableRename(String oldName, String name) {
                // TODOAuto-generated method stub
        }
}