Adding a service
In this task, you add a simple service with the minimum configuration required for your connector to be valid. For the moment, the service returns to i2 Analyze some dummy data that you create. Later on, it will retrieve real data from the NYPD Complaint Dataset.
Remember to consult the troubleshooting guide if you face any issues.
Prerequisites
Before starting, ensure that you have:
Define the SPI version
Before you define a service, you should determine the SPI version that you want to use. By default, the gateway assumes that your connector will use version 1.0 of the SPI. However, relying on the default setting causes the warning message that was highlighted in the previous topic.
To tell i2 Analyze which SPI version the connector wants to use, you must define it in the connector configuration returned by the config endpoint.
This means editing the config.json
file in the resources
directory.
To specify the SPI version, add the version
field to the top level of the configuration.
Since the walkthrough is based on version 1.2 of the SPI, your config.json
will look like this:
{
"defaultValues": {
"timeZoneId": "Europe/London",
"resultIdsPersistent": true
},
"version": "1.2"
}
Note: For more information about the SPI version, see SPI version negotiation.
Define the service
Now we can start to define the service.
Add a services array
At the top level of the configuration, add a services array:
{
...
"version": "1.2",
"services": []
}
Add a service
In the services array, define a service object. The mandatory fields to provide are the following.
Field | Description |
---|---|
id | The unique identifier of the service |
name | The name of the service |
To allow i2 Analyze to fetch data synchronously from the service, you should also specify the acquireUrl
.
Note: If you want the data fetched asynchronously, you must use the async
field instead.
For more information about the async
option, see Async Connector.
It is also common and recommended to add a description
field.
This appears to users in Analyst's Notebook, where it provides more information about what the service does.
You should have something like the following.
{
"defaultValues": {
"timeZoneId": "Europe/London",
"resultIdsPersistent": true
},
"version": "1.2",
"services": [
{
"id": "nypd-service",
"name": "NYPD Connector: Get all",
"description": "A service that retrieves all data.",
"acquireUrl": "/all"
}
]
}
After defining the service, you must restart your connector. Refer to the following language guides for the steps to take:
Update the i2 Connect gateway
In order for i2 Analyze to recognize these changes, you must reload the i2 Connect gateway.
Open a web browser and navigate to
<i2-Analyze-URL>/admin#/connectors
, where<i2-Analyze-URL>
is the URL used to access your i2 Analyze deployment. For example,http://localhost:9082/opaldaod/admin#/connectors
.Note: For more information about the Admin Console, refer to i2 Analyze Server Admin Console.
If you are prompted to log in, enter the credentials for your default user. If you added an example user, the username and the password will be
Jenny
.Click Reload gateway to enact your changes.
View the service in Analyst's Notebook
Now that you have defined a service, you can try to use it.
- Open Analyst's Notebook and log in to the i2 Analyze server. If you were already logged in, log out and then back in again.
- Open External Searches. The service you have defined should appear.
- Try to run it. Although the service is defined, since it has not yet been implemented, you should see a red banner appear with the message "The application failed to perform the search operation."
- To see the full error, look in the
i2_Analysis_Repository.log
found indeploy\wlp\usr\servers\opal-server\logs\opal-services
within thei2analyze
directory. You should see a 404 (Not Found) Error. This is because an endpoint for theacquireUrl
defined in theconfig.json
has not been implemented.
Implement the service
Now that i2 Analyze knows to expect the service, you had better create it.
Look at the SPI
The SPI you need to implement is documented here. Think about the relevant objects you will need to implement in order to build a service that returns a fixed set of entities and links that you will create.
Add an acquire endpoint
i2 Analyze knows the acquire URL for this service. Now you need to add an endpoint for it in the connector and return some data.
Note: For more information about the acquire endpoint, see Implementing acquire.
Java
Before adding the endpoint, we will start by adding a class that demonstrates a connector response. Create a new file named
ExternalConnectorDataService.java
at the same level asConnectorController.java
, and populate it with this code:package com.i2group.demo; import com.i2group.connector.spi.rest.transport.I2ConnectData; import com.i2group.connector.spi.rest.transport.I2ConnectEntityData; import com.i2group.connector.spi.rest.transport.I2ConnectLinkData; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class ExternalConnectorDataService { public I2ConnectData retrieveTestDataFromExternalSource() { final List<I2ConnectEntityData> entities = new ArrayList<>(); final List<I2ConnectLinkData> links = new ArrayList<>(); // TODO: Populate entity and link lists with some dummy data and see that it is returned to ANBP final I2ConnectData connectorResponse = new I2ConnectData(); connectorResponse.entities = entities; connectorResponse.links = links; return connectorResponse; } }
Note: This code uses the
I2ConnectData
,I2ConnectEntityData
, andI2ConnectLinkData
classes from the supplied Java implementation of the i2 Connect Gateway REST SPI.In the
ConnectorController
class, create an instance of theExternalConnectorDataService
class by replacing theConnectorController
no-args constructor with the following:private final ExternalConnectorDataService connectorDataService; public ConnectorController(ExternalConnectorDataService connectorDataService) { this.connectorDataService = connectorDataService; }
To add the endpoint, update the
ConnectorController
to include this method:@RequestMapping( method = RequestMethod.POST, value = "/all", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) public I2ConnectData testService() { return connectorDataService.retrieveTestDataFromExternalSource(); }
Python
Before adding the endpoint, we will start by adding a class that demonstrates a connector response. Create a new file named
service.py
at the same level ascontroller.py
, and populate it with this code:from spi.models.i2_connect_data import I2ConnectData def query_external_datasource(): """ Used to populate entity lists and link lists to return to ANBP. Returns: dict: A response with the entities and links. """ entities = [] links = [] # TODO: Populate entity and link lists with some dummy data and see that # it is returned to ANBP response = I2ConnectData( entities=entities, links=links ) return response.to_dict()
Note: This code uses the
I2ConnectData
class from the supplied Python implementation of the i2 Connect Gateway REST SPI.To add the endpoint, update
controller.py
to include this import and method:from helper.service import query_external_datasource @controller.route('/all', methods=['POST']) def all(): return query_external_datasource()
Test the service in Analyst's Notebook
Redeploy the connector. Depending on how you are running the connector, this may be done automatically for you when changes are made.
Re-run the service in Analyst's Notebook via the External Searches window.
You should no longer get a 404 error, but the search will return nothing.
Return some data
Java
In
ExternalConnectorDataService
, address theTODO
by adding some dummy data. Make sure to return entities and links.Test your changes in Analyst's Notebook in the same way.
If you don't see what you expect to, or you come across an error, investigate
i2_Analysis_Repository.log
in thedeploy\wlp\usr\servers\opal-server\logs\opal-services
directory.
Python
In
classes.py
, address theTODO
by adding some dummy data. Make sure to return entities and links. Ensure you are importing the classes intoservice.py
.Test your changes in Analyst's Notebook in the same way.
If you don't see what you expect to, or you come across an error, investigate
i2_Analysis_Repository.log
in thedeploy\wlp\usr\servers\opal-server\logs\opal-services
directory.
It is vital that you return property values in the expected format, which is defined by the logical type of each property. See the data model examples for examples of each supported logical type.
Querying data from an external source
Now that you have a basic connector with a working simple service, you can make it more useful by returning real data.