Adding a service
In this task, you will replace the sample service and schema to align with the NYPD example. For the moment, the service returns some dummy data that you create to i2 Analyze. Later on, it will retrieve real data from the NYPD Complaint Dataset.
Remember to consult the troubleshooting guide if you come across any issues.
Create the NYPD schema
Now that you've deployed i2 Analyze and created a connector with a template schema, you can update that schema to represent the data in the NYPD example. To replace the template schema, you will need to:
Remove the
schema.xml
file from thesrc
directory of your connector project.Create a new directory named
schema
inside thesrc
directory.Copy
nypd-complaint-data-schema.xml
, the NYPD complaint schema that you created in Designing an i2 Analyze connector schema, to the newschema
directory.Alternatively, you can copy the sample NYPD complaint schema from this repository.
Import the NYPD schema into the connector project
You have removed the old schema and replaced it with a new one, so you need to update the references to it as well.
In
index.ts
, replace thisimport
statement:import { schema } from './schema';
with:
import { nypdcomplaintdataschema as schema } from './schema/nypd-complaint-data-schema';
In the same file, update
startConnector()
to use the new schema:startConnector({ schemas: { connector: schema }, hasPersistentResultIds: true, });
Update the service
Still in index.ts
, replace the basic service with the following NYPD getAll
service, which you'll develop further in the next steps.
addService(
{
id: 'getAll',
name: 'NYPD Connector: Get all',
description: 'A service that retrieves all data.',
},
({ result }) => {
// TODO: Implement the service
}
);
Reload the connector configuration in i2 Analyze
To make the new service available, you must reload the connector so that i2 Analyze picks up the configuration changes. Just like when you deployed the connector for the first time, you can use the Admin Console.
Open a web browser and navigate to
https://i2analyze.eia:9443/opal/admin#/connectors
.If you are prompted to log in, enter
Jenny
andJenny
as the username and password.Click the Reload gateway button.
Investigate in Analyst's Notebook
You can see the consequences of your changes when you try to use the connector from the Analyst's Notebook desktop client.
Open Analyst's Notebook and log in when prompted.
Click the External Searches button in the ribbon. Find the query named NYPD Connector: Get all.
Click Open to run the service.
Note: Although the service exists, running it returns no data because that part of the implementation is still to come.
Return some data
To make the service return some data, you must add entity and link records to its result, using the methods of the IResult
interface.
Create a file named result-building.ts
in the src
folder of your connector. You'll add result-building functions to this file as you progress through the walkthrough.
You can start with a function for creating links, which will require the following imports:
import { services, records, schema as apiSchema } from '@i2analyze/i2connect';
Next, create an object to represent a source reference that will be set on all entities and links returned by the connector. Source references are useful to users, as they provide provenance information about the data they see. For example:
const sourceReference = {
name: 'NYPD Complaint Dataset',
type: 'Open source data',
description:
'A dataset containing all valid felony, misdemeanor, and violation crimes reported to the New York City Police Department (NYPD)',
};
Add a function for creating links that wraps the addLink()
method on the service result and also sets the source reference, as follows:
export function addLink(
linkType: apiSchema.ILinkType,
id: string,
fromEnd: records.IResultLinkRecordEnd,
toEnd: records.IResultLinkRecordEnd,
result: services.IResult
): void {
const link = result.addLink(linkType, id, fromEnd, toEnd);
link.setSourceReference(sourceReference);
}
You can now update the service in index.ts
to create a Location and a Complaint entity using the schema entity types, as follows:
const { Complaint, Location } = schema.entityTypes;
const locationEntity = result.addEntity(Location, 'Location 1');
const complaintEntity = result.addEntity(Complaint, 'Complaint 1');
Then, create a link between the two entity records using the schema link types by importing the addLink()
from result-building
:
import { addLink } from './result-building';
And adding the following to the service itself:
const { Locatedat } = schema.linkTypes;
addLink(Locatedat, 'Link 1', complaintEntity, locationEntity, result);
The full NYPD Connector: Get all service should now look like this:
addService(
{
id: 'getAll',
name: 'NYPD Connector: Get all',
description: 'A service that retrieves all data.',
},
({ result }) => {
const { Complaint, Location } = schema.entityTypes;
const locationEntity = result.addEntity(Location, 'Location 1');
const complaintEntity = result.addEntity(Complaint, 'Complaint 1');
const { Locatedat } = schema.linkTypes;
addLink(Locatedat, 'Link 1', complaintEntity, locationEntity, result);
}
);
When the changes have been built, re-run the service from Analyst's Notebook, and you should see the data returned.
Note: When the server is running in developer mode, it picks up any changes you make to the data that the service returns automatically, as soon as you save changes to the source files. You just need to re-run the service, rather than having to reload the i2 Connect gateway.
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.