Connector Development v5.2 References
Connector PlugIn API
From UNIFYBroker v5.2 onwards, the service provides a self-documenting REST endpoint for the web UI and other external actors to use. This API is extensibile and this article details process of implementing support for connector plugins. The following components are required for a standard connector plugin:
- Shared API Project
- Agent API Information
- Agent Extended Information
- Connector API Information
- Connector Extended Information
- API Project
- Agent Controller
- Connector Controller
- Web Project
- API Client
API Project Components
Agent and Connector Controllers
Controllers contain methods which are exposed via the API. Controllers must feature the following:
Implements PluggedAgentControllerBase<TInfo, TExtendedInfo> | Base controller class which contains standard agent controller functions. TInfo is AgentApiInformation<ExampleAgentExtendedInformation> and TExtendedInfo is IAgentExtendedInformation , both described below. |
Class has AgentPlugInVersionRouteAttribute set | Describes the route the controller and its methods should take on in the API. |
AgentPlugInVersionRouteAttribute argument agentFactoryName | Factory name for the agent. |
AgentPlugInVersionRouteAttribute argument agentPathElement | Name of the agent for use in the path. IE a value of 'Example' results in the path 'api/version/Agent/Example/AgentMethod' |
AgentPlugInVersionRouteAttribute argument version | Version of the API the controller is associated with. Should be in the format of 'x.x'. |
Factory name passed to base constructor | Factory name for the agent. |
Path element passed to base constructor | Name of the agent for use in the path. |
To XML function passed to base constructor | A function that accepts TExtended and converts this to XML. Should use the same factory class used elsewhere by the plugin. |
From XML function passed to base constructor | A function that accepts extended XML and converts it to TExtended . Should use the same factory class used elsewhere by the plugin. |
[AgentPlugInVersionedRoute(ExampleAgentAttributes.ADAgentName, "Example", "1.0")] public class ExampleAgentController : PluggedAgentControllerBase<ExampleAgentApiInformation, ExampleAgentExtendedInformation=""> { public ADAgentController(IAgentEngine agentEngine) : base(agentEngine, ADAgentAttributes.ADAgentName, ApiExtensions.ActiveDirectoryPathElement, ApiToXml, XmlToApi) { } private static XElement ApiToXml(ExampleAgentExtendedInformation apiInfo) { // Convert apiInfo -> internalInfo -> xml (using existing information factory) } private static ActiveDirectoryAgentExtendedInformation XmlToApi(XElement xml) { // Convert xml -> internalInfo (using existing information factory) -> apiInfo } }
Implements PluggedConnectorControllerBase<TInfo, TExtendedInfo> | Base controller class which contains standard connector controller functions. TInfo is ConnectorApiInformation<ExampleConnectorExtendedInformation> and TExtendedInfo is IConnectorExtendedInformation , both described below. |
Class has ConnectorPlugInVersionRouteAttribute set | Describes the route the controller and its methods should take on in the API. |
ConnectorPlugInVersionRouteAttribute argument connectorFactoryName | Factory name for the connector. |
ConnectorPlugInVersionRouteAttribute argument connectorPathElement | Name of the connector for use in the path. IE a value of 'Example' results in the path 'api/version/Connector/Example/ConnectorMethod' |
ConnectorPlugInVersionRouteAttribute argument version | Version of the API the controller is associated with. Should be in the format of 'x.x'. |
Factory name passed to base constructor | Factory name for the connector. |
Path element passed to base constructor | Name of the connector for use in the path. |
To XML function passed to base constructor | A function that accepts TExtended and converts this to XML. Should use the same factory class used elsewhere by the plugin. |
From XML function passed to base constructor | A function that accepts extended XML and converts it to TExtended . Should use the same factory class used elsewhere by the plugin. |
[ConnectorPlugInVersionedRoute(ExampleConnectorAttributes.ADConnectorName, "Example", "1.0")] public class ExampleConnectorController : PluggedConnectorControllerBase<ExampleConnectorApiInformation, ExampleConnectorExtendedInformation=""> { public ADConnectorController(IConnectorEngine connectorEngine) : base(connectorEngine, ADConnectorAttributes.ADConnectorName, ApiExtensions.ActiveDirectoryPathElement, ApiToXml, XmlToApi) { } private static XElement ApiToXml(ExampleConnectorExtendedInformation apiInfo) { // Convert apiInfo -> internalInfo -> xml (using existing information factory) } private static ActiveDirectoryConnectorExtendedInformation XmlToApi(XElement xml) { // Convert xml -> internalInfo (using existing information factory) -> apiInfo } }
Custom Controller Functions
If additional API methods are required on the plugin API controller they can be implemented by adding them to the API controllers with the appropriate attributes set.
Http method attribute | Attribute which dictates the HTTP method used. Options include HttpPostAttribute , HttpGetAttribute , HttpDeleteAttribute , HttpPutAttribute and HttpPatchAttribute . |
ActionNameAttribute | Give the API method a name different to the controller functions name. |
ApiMethodDescriptionAttribute | Sets a description for the method to be used in the APIs self-documentation. |
ApiMethodParamDescriptionAttribute | Sets a description for the specified method parameter to be used in the APIs self-documentation. Add this attribute once for each parameter. |
[HttpPost] [ActionName("FuctionName")] [ApiMethodDescription("A custom function which does something")] [ApiMethodParamDescription("argument1", "The first argument, part of the query string")] [ApiMethodParamDescription("argument2", "The second argument, the post body.")] public TReturn CustomFunction(string argument1, CustomDataObject argument2) { // Do something }
Controller Registration
To register a controller, use the appropriate method on the engine. This should be performed in the plugin factory CreateComponent method.
agentEngine.AddAgentController<ExampleAgentController, ExampleAgentApiInformation, ExampleAgentExtendedInformation>( VersionConstants.Version1_0, () => new ExampleAgentController(agentEngine)); // Other resources can be passed to the controller as needed.
connectorEngine.AddConnectorController<ExampleConnectorController, ExampleConnectorApiInformation, ExampleConnectorExtendedInformation>( VersionConstants.Version1_0, () => new ExampleConnectorController(connectorEngine)); // Other resources can be passed to the controller as needed.
Shared API Project Components
It is recommended to create a shared API project for the components described in the section as they are referenced by the API controllers and the client in the Web project.
Agent Extended Information and Connector Extended Information
These are the API information classes which contain properties specific to the agent/connector type it is implemented for. They should feature the following:
Implements IAgentExtendedInformation | Interface type for the extended information. |
AgentType property | Should be set to the same value as the agent factory name. |
DataContractAttribute and DataMemberAttribute | The class and properties (AgentType excluded) should have these attributes set. |
RequiredAttribute | Required properties should have this attribute set. |
ApiPropertyDescriptionAttribute | All properties (AgentType excluded) should have this attribute set with a description of the property. |
[DataContract] public class ExampleAgentExtendedInformation : IAgentExtendedInformation { public string Type => ExampleAgentAttributes.AgentFactoryName; // ie: Unify.Agent.Example [Required] [DataMember] [ApiPropertyDescription("The first value.")] public string Value1 { get; set; } [DataMember] [ApiPropertyDescription("The second value.")] public string Value2 { get; set; } }
Implements IConnectorExtendedInformation | Interface type for the extended information. |
ConnectorType property | Should be set to the same value as the connector factory name. |
DataContractAttribute and DataMemberAttribute | The class and properties (ConnectorType excluded) should have these attributes set. |
RequiredAttribute | Required properties should have this attribute set. |
ApiPropertyDescriptionAttribute | All properties (ConnectorType excluded) should have this attribute set with a description of the property. |
[DataContract] public class ExampleConnectorExtendedInformation : IConnectorExtendedInformation { public string Type => ExampleConnectorAttributes.ConnectorFactoryName; // ie: Unify.Connector.Example [Required] [DataMember] [ApiPropertyDescription("The first value.")] public string Value1 { get; set; } [DataMember] [ApiPropertyDescription("The second value.")] public string Value2 { get; set; } }
Agent API Information and Connector API Information
Information objects sent via the API cannot be generic types so these classes are needed to provide non-generic versions of ConnectorApiInformation<TExtended>
. Each connector and agent type should have a corresponding API information class created using that agent/connectors extended information type.
public class ExampleAgentApiInformation : AgentApiInformation<ExampleAgentExtendedInformation> { }
public class ExampleConnectorApiInformation : ConnectorApiInformation<ExampleConnectorExtendedInformation> { }
Web Project Components
API Client
To generate the Web API Client code (to allow communication from the user interface back to the service):
- install nSwagStudio
- Install or deploy new pluggable API
- Start Identity Broker
- Create a new Web API endpoint, with a white-list filter including only the new API
- Target nSwagStudio at the Identity Broker API endpoint
- Set the following options:
- Off: Generate exception classes (they're included in the the SDK Framework)
- Off: Generate DTO Types (these are the ApiInformation and ExtendedInformation classes from above)
Generate the client and make available to the user interface code
_SomethingClient = new SomethingClient {BaseUrl = ApiAddress};
Customer support service by UserEcho