Interfacing with Proxies
In most projects, data must be exchanged or synchronized between UBIK® and arbitrary third party systems in the customer's infrastructure, via so-called interfaces. Independent on the actual communication technology (e.g., REST/SOAP web service, or even file-based), which can differ depending on the external system, there are some, well, ubiquitous factors:
- There is a data contract that usually can be modeled in an object-oriented manner (data is structured in objects and properties).
- Data needs to be imported from a third party system, or exported to a third party system, or both.
- Data should only be exported if it was created or changed in UBIK®.
- Data should only be imported if it wasn't already imported and if there is no more recent change in UBIK® that needs to be exported.
Proxies can be used to deal with these factors. A proxy is a UBIK® object acting as a transmission layer between a content object ("Ubikle") and an external system. Primarily, proxies are data containers having knowledge about their last import and export date and time. The proxy technique allows a project engineer to configure a mapping between UBIK® objects and the entities of external systems. For example, if there are "pump" objects both in UBIK® as well as in the customer's ERP system, proxies can be configured to assign the UBIK® properties of a pump object to the equivalent properties from the ERP system. Further, one can configure whether to just receive data from the ERP system or to just send data to the ERP system, or both. For a fully functioning interface, the other required mechanisms are the communication to the third party system (e.g., calling a specific web service), and performing interface runs (i.e., checking for data to synchronize and doing so if necessary). Fortunately, there is an Interface Administration object in UBIK®, that can be used for configuring and triggering interface runs (resulting in an Interface Execution instance).
Proxies, as any other UBIK® object, require a MetaClass describing them. Since proxies have special features, they also have a special MetaClass, called a MetaProxy. A MetaProxy doesn't just have MetaProperties like a usual MetaClass, but it also has ProxyMetaProperties. These ProxyMetaProperties define interface properties with several interesting details:
- The external system's name of the property
- The Ubikle's (content object's) MetaProperty this ProxyMetaProperty corresponds to
- Whether to enable import for this property
- Whether to enable export for this property
- Whether the property is a primary key for the external system's entity
So, in order to configure proxies, one must start with defining a MetaProxy for the entity in question. Then, the MetaProxy can be added to the InterfaceAdministration object. The InterfaceExecution can be customized programmatically to use specific external data readers and writers capable of communicating with the external system, e.g., via web service call. The triggering of the interface using the InterfaceAdministration can be customized programmatically, too, for example when an object is saved.
The steps required for configuring proxies are:
- Make a list of the objects you want to synchronize with a third party system.
- For every entity, clarify:
- Do I want to update the third party system if it changes in UBIK? If so, then I want to configure the proxy for export.
- Do I want to update UBIK if the object changes in the third party system? If so, then I want to configure the proxy for import.
- Which properties do I want to synchronize? What is their name in UBIK, and what is their identifier in the external system?
- Which property of the object identifies it in the third party system? This is the "external primary key", and it can consist of multiple properties.
- For every type of entity, create a MetaProxy and link it to the MetaClass it is represented by in UBIK.
- Enter the external key for the MetaProxy, which identifies the type in the third party system (i.e., the name or ID of the type of entity in the external system, e.g., "Pump")
- Create MetaProxyProperties for every property to synchronize and relate them to the respective MetaProxy.
- Set the UBIK property name for the MetaProxyProperty.
- Set the external key of the property, i.e., the name or ID of the property in the external system, e.g., "Voltage".
- If the property identifies the object in the third party system, mark it as external primary key.
- If you want to update the external system when this property changes, set the Export property to true.
- If you want to update UBIK when this property changes in the external system, set the Import property to true.
- If the property represents a link to another UBIK object, set the reference target MetaProxy representing the UBIK MetaClass for the external system.
Implementing the synchronization workflow
- Clarify when UBIK objects should be synchronized to the external system or vice-versa.
- If you want to schedule interface runs regularly, you can use the UBIK® Enterprise service.
- If you want changes in UBIK® objects to trigger a synchronization run, you can customize the respective MetaClass programmatically to react to a change or being saved.
- If you're not using the Enterprise service, you can use the InterfaceAdministration MetaClass to trigger an execution.
- You can decide what mode should be executed when triggering the execution. There are the following important execution modes:
- Export: Write the values from the UBIK® object to the proxy instance
- Import: Write the values from the proxy instance to the UBIK® object
- ReadFromExternal: Write the values from the external system to the proxy instance
- WriteToExternal: Write the values from the proxy instance to the external system
Implementing the actual communication to the external system
The actual synchronization logic is defined in so-called interface executors (implementing the IInterfaceExecutor C# interface). For every execution mode, there is a method for getting the respective IInterfaceExecutor on the InterfaceAdministration MetaClass - you can customize them programmatically, so that they retrieve your implementation of the IInterfaceExecutor (C#) interface.
- For the import and export executors, there are standard implementations you don't have to provide.
- For writing to and reading from the external system, you must implement a custom way of communication.
Creating proxy instances for your Ubikles
For UBIK® content objects (Ubikles) to be synchronized, a proxy instance must be created and bound to it. Every proxy has a "Target" property linking to the bound Ubikle. There is a class ProxyManager providing methods for creating and registering new proxy instances. You can further customize a MetaClass so that a new proxy is created for every new instance automatically (using the ProxyManager), or you can create proxy instances manually or based on any custom logic. Further, proxy instances must also be created for objects received from the external system. You can customize the IInterfaceExecutor implementation for the execution mode "ReadFromExternal" to create proxies for new objects coming from the external system, for example.