Skip to content
Data > Datasource Adapters

Custom Datasource Adapter

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

com.f1.ami.amicommon.AmiDatasourcePlugin
com.f1.ami.amicommon.AmiDatasourceAdapter

Properties

ami.datasource.plugins=comma_delimited_list_of_fully_qualified_java_class_names

Example

Java Code:

package com.demo;

import java.util.HashMap;
import java.util.Map;

import com.f1.ami.amicommon.AmiDatasourceAdapter;
import com.f1.ami.amicommon.AmiDatasourcePlugin;
import com.f1.container.ContainerTools;
import com.f1.utils.PropertyController;

public class TestDatasourcePlugin implements AmiDatasourcePlugin {
       private static final Map<String, Object> OPERATORS_MAP = new HashMap<String, Object>();
       private static final Map<String, Object> WHERE_SYNTAX_MAP = new HashMap<String, Object>();
       private static final Map<String, Object> HELP_MAP = new HashMap<String, Object>();
       static {
               OPERATORS_MAP.put("eq", "=");
               OPERATORS_MAP.put("ne", "!=");
               OPERATORS_MAP.put("lt", "<");
               OPERATORS_MAP.put("gte", ">=");
               WHERE_SYNTAX_MAP.put("prefix", "((");
               WHERE_SYNTAX_MAP.put("suffix", "))");
               WHERE_SYNTAX_MAP.put("join", ") or (");
               WHERE_SYNTAX_MAP.put("true", "true");
       }

       @Override
       public void init(ContainerTools tools, PropertyController props) {
       }

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

       @Override
       public String getDatasourceDescription() {
               return "Test";
       }

       @Override
       public AmiDatasourceAdapter createDatasourceAdapter() {
               return new TestDatasourceAdapter();
       }

       @Override
       public String getDatasourceIcon() {
               return "../../../../resources/test.PNG";
       }

       @Override
       public String getDatasourceQuoteType() {
               return "\"";
       }

       @Override
       public Map<String, Object> getDatasourceOperators() {
               return OPERATORS_MAP;
       }

       @Override
       public Map<String, Object> getDatasourceWhereClauseSyntax() {
               return WHERE_SYNTAX_MAP;
       }

       @Override
       public Map<String, Object> getDatasourceHelp() {
               return HELP_MAP;
       }
}

package com.demo;

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

import com.f1.ami.amicommon.AmiDatasourceAdapter;
import com.f1.ami.amicommon.AmiDatasourceException;
import com.f1.ami.amicommon.AmiDatasourceTracker;
import com.f1.ami.amicommon.AmiServiceLocator;
import com.f1.ami.amicommon.msg.AmiCenterQuery;
import com.f1.ami.amicommon.msg.AmiCenterQueryResult;
import com.f1.ami.amicommon.msg.AmiCenterUpload;
import com.f1.ami.amicommon.msg.AmiDatasourceTable;
import com.f1.base.Columns;
import com.f1.base.Row;
import com.f1.container.ContainerTools;
import com.f1.utils.structs.table.BasicTable;

public class TestDatasourceAdapter implements AmiDatasourceAdapter {
       private ContainerTools tools;
       private AmiServiceLocator serviceLocator;

       @Override
       public void init(ContainerTools tools, AmiServiceLocator serviceLocator) throwsAmiDatasourceException {
               this.tools = tools;
               this.serviceLocator = serviceLocator;
       }

       @Override
       publicList<AmiDatasourceTable> getTables(AmiDatasourceTracker debugSink) throwsAmiDatasourceException {
               List<AmiDatasourceTable> tables = newArrayList<AmiDatasourceTable>();
               AmiDatasourceTable table = tools.nw(AmiDatasourceTable.class);
               table.setCollectionName("master");
               table.setName("accounts");
               table.setCustomQuery("SELECT * FROM accounts WHERE ${WHERE}");
               tables.add(table);
               return tables;
       }

       @Override
       publicList<AmiDatasourceTable> getPreviewData(List<AmiDatasourceTable> tables, int previewCount, AmiDatasourceTracker debugSink) throwsAmiDatasourceException {
               for (int i = 0; i < tables.size(); i++) {
                       AmiDatasourceTable table = tables.get(i);
                       AmiCenterQuery q = tools.nw(AmiCenterQuery.class);
                       q.setQuery(table.getCustomQuery());
                       q.setLimit(previewCount);
                       AmiCenterQueryResult rs = tools.nw(AmiCenterQueryResult.class);
                       processQuery(q, rs, debugSink);
                       List<Columns> results = rs.getTables();
                       if (results.size() > 0)
                               table.setPreviewData(results.get(i));
               }
               return tables;
       }

       @Override
       public AmiServiceLocator getServiceLocator() {
               return serviceLocator;
       }

       @Override
       public void processQuery(AmiCenterQuery query, AmiCenterQueryResult resultSink, AmiDatasourceTracker debugSink) throws AmiDatasourceException {
               String queryStatement = query.getQuery();
               // Do something with query statement
               List<Columns> result = newArrayList<Columns>();
               BasicTable table = new BasicTable();
               String id = "id";
               String reputation = "reputation";
               String isPaid = "isPaid";
               table.addColumn(String.class, id);
               table.addColumn(Integer.class, reputation);
               bt.addColumn(Boolean.class, isPaid);
               Row row = bt.newRow("superman123", 150, true);
               bt.getRows().add(row);
               Row row2 = bt.newRow("trucker66", 400, true);
               bt.getRows().add(row2);
               resultSink.setTables(result);
       }

       @Override
       public boolean cancelQuery() {
               return false;
       }

       @Override
       public void processUpload(AmiCenterUpload upload, AmiCenterQueryResult resultsSink, AmiDatasourceTracker tracker) throwsAmiDatasourceException {
               throw newAmiDatasourceException(AmiDatasourceException.UNSUPPORTED_OPERATION_ERROR, "Upload to datasource");
       }
}

Configuration:

ami.datasource.plugins=com.demo.TestDatasourcePlugin