Skip to content

Bindaas Data Providers

Pradeeban Kathiravelu edited this page Aug 23, 2018 · 3 revisions

Overview

Bindaas Framework has a pluggable architecture that provides variety of interfaces for various classes of applications. Bindaas can be easily extended and customized by implementing these interfaces. The most critical of all is the Data Provider (DP) interface. Conceptually, DP is like JDBC specification, which provide standard set of interfaces to communicate with databases. It’s a contract between Bindaas Middleware and an underlying database technology that is responsible for handling query, submit and delete operations on data. The contract does not dictate how or where the data should be stored or manage. Hence, it is possible to build Data Providers that support relational or NoSQL database alike. Furthermore, it is possible to develop DP for specialized use-cases where data is managed in propriety systems or non-conventional sources such as web-services.

 

Data Provider Interface

public interface IProvider {
     public String getId();
     public int getVersion();
     public JsonObject  getDocumentation();
     public IQueryHandler getQueryHandler();
     public ISubmitHandler getSubmitHandler();
     public IDeleteHandler getDeleteHandler();
     public Profile validateAndInitializeProfile(Profile profile) throws ProviderException;
     public JsonObject getDataSourceSchema();
}

public String getId();

Returns a unique identifier identifying the data provider. The general practice is to return the class name of the IProvider implementation

 

public int getVersion();

Return an Integer representing version number of this provider. This method is marked for deprecation. The version number and the Id field together are used to lookup a given DP. However, as of now, the lookups are only performed using the Id field and version # is not really used. General practice is to return 1.

 

public JsonObject  getDocumentation();

Returns a JSON object describing meta-information about the provider.  It’s used by the AdminConsole GUI  to build DP specific layout.  More details in #TBD-DOCUMENTATION.

 

public IQueryHandler getQueryHandler();

Returns implementation of a IQueryHandler ; responsible for handling all HTTP GET(Query) requests.

public ISubmitHandler getSubmitHandler();

Returns implementation of ISubmitHandler ; responsible for handling HTTP POST request to upload data. The syntax and semantics of the data being uploaded depends on the DP. 

 

public IDeleteHandler getDeleteHandler();

Returns implementation of IDeleteHandler ; responsible for  handling HTTP DELETE request to delete data. The syntax and semantics of the data being uploaded depends on the DP.

 

public Profile validateAndInitializeProfile(Profile profile) throws ProviderException;

Validates and initializes configuration object in Profile, from the values specified by the query author at the time of creating a new data provider instance.

 

public JsonObject getDataSourceSchema();

Deprecated. Should be removed in later versions. An non-null JsonObject is expected.

 

IQueryHandler interface

public interface IQueryHandler {
    public QueryResult query(JsonObject dataSource , JsonObject outputFormatProps ,String queryToExecute , Map<String,String> runtimeParameters , RequestContext requestContext) throws   AbstractHttpCodeException;
    public QueryEndpoint validateAndInitializeQueryEndpoint(QueryEndpoint queryEndpoint) throws ProviderException;
    public JsonObject getOutputFormatSchema() ;
}
public QueryResult query(JsonObject dataSource , JsonObject outputFormatProps ,String queryToExecute , Map<String,String> runtimeParameters , RequestContext requestContext) throws   AbstractHttpCodeException;

The query method is invoked when Bindaas receives a HTTP GET request on a URL of the following form:

http(s)://<host>:<port>/services/<project>/<data-provider>/query/<query-api-name>

project and the data-provider names are used to lookup correct Data Provider. If the lookup is successful, getQueryHandler is invoked to obtain an instance of IQueryHandler(QH) to which the request is now delegated to. The query method is then invoked on the QH with following parameters:

1. JsonObject dataSource : Configuration object hosting values specified at the time of creating an instance of Data Provider.

2. JsonObject outputFormatProps : This object contains information about the format in which the results of query operation will be formatted. Must be a valid MIME type. Typical formats include JSON,XML,HTML, CSV.

3. String queryToExecute : This is a fully constructed query that will be executed on the underlying database. The syntax and semantics is determined by  DP. For example, in a SQL DP this could something like : 

SELECT PATIENT_ID FROM PATIENT_TABLE WHERE ID = ‘X’

 

4. Map<String,String> runtimeParamters : The parameters provided along with the HTTP GET request along with the URL. For example:

 http(s)://<host>:<port>/services/<project>/<data-provider>/query/<query-api-name>?param1=val1&param2=val2 

5. RequestContext  requestContext : Context object representing the state of the request. Contains information about the user who invoked this API.

 

The query method returns an instance of QueryResult which encapsulates the result of query execution. 

public QueryEndpoint validateAndInitializeQueryEndpoint(QueryEndpoint queryEndpoint) throws ProviderException;

Validate and initialize QueryEndpoint configuration specified by the query author at the time of creating it.

 

public JsonObject getOutputFormatSchema() ;

Deprecated. Implementers must return a non-null instance of JsonObject.

 

 

ISubmitHandler interface

public interface ISubmitHandler {
  
public QueryResult submit(JsonObject dataSource , JsonObject endpointProperties , InputStream is , RequestContext requestContext) throws AbstractHttpCodeException;


public QueryResult submit(JsonObject dataSource , JsonObject endpointProperties , String data , RequestContext requestContext) throws AbstractHttpCodeException;


public SubmitEndpoint validateAndInitializeSubmitEndpoint(SubmitEndpoint submitEndpoint) throws ProviderException;


public JsonObject getSubmitPropertiesSchema();


}
public QueryResult submit(JsonObject dataSource , JsonObject endpointProperties , InputStream is , RequestContext requestContext) throws AbstractHttpCodeException;


public QueryResult submit(JsonObject dataSource , JsonObject endpointProperties , String data , RequestContext requestContext) throws AbstractHttpCodeException;

The submit method is invoked when Bindaas receives a HTTP POST request on a URL of the following form:

http(s)://<host>:<port>/services/<project>/<data-provider>/submit/<submit-api-name>

``

Following parameters are provided to the submit method:

1. JsonObject dataSource : Configuration object hosting values specified at the time of creating an instance of Data Provider.

2. JsonObject endpointProperties : Configuration Properties assigned by the query author at the time of creating this endpoint. This object may contain any information relevant to the DP such as attributes describing what kind of file is being uploaded.

3. InputStream/String data : Data being uploaded

4. RequestContext  requestContext : Context object representing the state of the request. Contains information about the user who invoked this API.

It returns an instance of QueryResult which encapsulates the result of submit api execution. 

public SubmitEndpoint validateAndInitializeSubmitEndpoint(SubmitEndpoint submitEndpoint) throws ProviderException;

Validate and initialize SubmitEndpoint configuration specified by the query author at the time of creating it.

 

public JsonObject getSubmitPropertiesSchema();

Deprecated. Implementers must return a non-null instance of JsonObject.

 

IDeleteHandler interface

public interface IDeleteHandler {
public QueryResult delete(JsonObject dataSource , String deleteQueryToExecute , Map<String, String> runtimeParameters , RequestContext requestContext) throws AbstractHttpCodeException;
}
public QueryResult delete(JsonObject dataSource , String deleteQueryToExecute , Map<String, String> runtimeParameters , RequestContext requestContext) throws AbstractHttpCodeException;

The delete method is invoked when Bindaas receives a HTTP DELETE request on a URL of the following form:

http(s)://<host>:<port>/services/<project>/<data-provider>/delete/<delete-api-name>

``

Following parameters are provided to the delete method:

1. JsonObject dataSource : Configuration object hosting values specified at the time of creating an instance of Data Provider.

2. String deleteQueryToExecute : This is a fully constructed delete query that will be executed on the underlying database. The syntax and semantics is determined by  DP. For example, in a SQL DP this could something like : 

DELETE FROM PATIENT_TABLE WHERE ID = ‘X’

 

3. Map<String,String> runtimeParamters : The parameters provided along with the HTTP DELETE request along with the URL. For example:

 http(s)://<host>:<port>/services/<project>/<data-provider>/delete/<delete-api-name>?param1=val1&param2=val2 

4. RequestContext  requestContext : Context object representing the state of the request. Contains information about the user who invoked this API.

 It returns an instance of QueryResult which encapsulates the result of delete api execution. 

Profile

Profile is class declared in bindaas-core-api project, which forms runtime configuration for a Data Provider. Profile is an instance of Data Provider with certain set of configuration parameters and collection of  query,submit and delete endpoints. Each Profile has a unique name. Throughout this documentation the term data-provider is used to refer to this name.

 

public class Profile extends Entity{

    @Expose private JsonObject dataSource;

    @Expose private Map<String,QueryEndpoint> queryEndpoints;

    @Expose private Map<String,DeleteEndpoint> deleteEndpoints;

    @Expose private Map<String,SubmitEndpoint> submitEndpoints;

    @Expose private String providerId;

    @Expose private int providerVersion;
 
// other methods omitted for brevity

 

dataSource represents configuration required by the Data Provider to be provided at the time of creating a Profile(or instance of Data Provider). Implementations can choose what goes in there. Since a dataSource object is essentially a JsonObject it can easily be morphed into any data structure. For example, a typical SQL based Data Provider may require information such as : host, port, jdbc url,username,password,etc in order to connect to underlying database. A MongoDB provider, on the other hand would require information such as host,port,db and db-collection.

providerId/providerVersion indicates which Data Provider implementation should the control be delegated when any endpoint belonging to this Profile is invoked. It references IProvider.getId()/IProvider.getVersion() field to lookup Data Providers.

QueryResult

The QueryResult class encapsulates result of api(query,submit and delete) execution. 

public class QueryResult {
    private boolean isError;

    private String errorMessage;

    private String mimeType; 

    private InputStream data;

    private ResultSetIterator intermediateResult;

    private Callback callback;

    private Map<String,Object> responseHeaders;
 
// other methods omitted for brevity

 

The data field stores the result from query execution. The mimeType field indicates the MIME type of the HTTP response. Additional response headers can be set using responseHeaders field. 

The QueryResult object is handed out to Bindaas Middleware after the API execution completes. It invokes getData() method to retrieve the serialized data that is sent as the response to the RESTful request. This assumes that when getData() is invoked, the response is ready or staged. There are cases, however, where response must be directly streamed over HTTP bypassing Bindaas Middleware layer. This can be achieved by setting an instance of Callback in QueryResult. This callback method gets direct access to HttpServletResponse.getOutputStream(), which it may use to write directly to the network.

Clone this wiki locally