02 - The connector project structure
Let's have a deeper look at how the autogenerated connector project is structured.
Folder structure
.
└─ connector-sample-rest/
├─ src/
│ ├─ main/
│ │ ├─ assembly/
│ │ │ └─ connector.xml
│ │ ├─ java/
│ │ │ └─ eu.inn.usal
│ │ │ ├─ SampleRestConnector
│ │ │ └─ ...
│ │ └─ resources/
│ │ └─ eu.inn.usal
│ │ └─ Messages.properties
│ └─ ...
└─ target
├─ connector-sample-rest-1.0-SNAPSHOT.jar
└─ ...
In the graph above we can see the following files:
- connector.xml, a file used by the maven-assembly-plugin to correctly generate the connector jar file
- SampleRestConnector, the entrypoint of our connector
- Messages.properties, the properties file that contains translations
- target, the folder where the built jar will be placed
Code structure
The SampleRestConnector class should look something like this:
package eu.inn.usal;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.framework.spi.Configuration;
import org.identityconnectors.framework.spi.Connector;
import org.identityconnectors.framework.spi.ConnectorClass;
@ConnectorClass(displayNameKey = "samplerest.connector.display", configurationClass = SampleRestConfiguration.class)
public class SampleRestConnector implements Connector {
private static final Log LOG = Log.getLog(SampleRestConnector.class);
private SampleRestConfiguration configuration;
private SampleRestConnection connection;
@Override
public Configuration getConfiguration() {
return configuration;
}
@Override
public void init(Configuration configuration) {
this.configuration = (SampleRestConfiguration)configuration;
this.connection = new SampleRestConnection(this.configuration);
}
@Override
public void dispose() {
configuration = null;
if (connection != null) {
connection.dispose();
connection = null;
}
}
}
All connectors implement the Connector but in this guide we will use the REST Connector Superclass which already implements
common connector functionalities for REST APIs.
Every connector needs also to have the @ConnectorClass annotation, that specifies the displayName of the connector and which
class represents its configuration, we will need to change our configuration later.
Connector Operations
Currently, our connector is not capable of doing anything, that is because we did not implement any operation yet.
Each connector will have it's set of supported operations, like Search, Create, Update and Delete, but the first operation we should implement in our connector is the Test operation.
Supported operations
You can find the list of operations a Connector can implement here: https://docs.evolveum.com/connectors/connid/1.x/connector-development-guide/#connector-operations
To implement any operation you have add a specific interface to your Connector class, like this:
@ConnectorClass(displayNameKey = "samplerest.connector.display", configurationClass = SampleRestConfiguration.class)
public class SampleRestConnector implements Connector, TestOp {
// skipping some lines...
@Override
public void test() {
LOG.ok("TODO: Add a proper test");
}
}
By implementing the TestOp interface and it's corresponding method test(), our connector can now test its configuration.
A better test
Right now this "TestOp" implementation is useless, we will later implement a proper test for our connector