Service Broker Best Practices and Considerations
The following are some best practices and considerations when creating custom Service Brokers
- When creating a Service Broker that should target different instances of the same technology, use the Dynamic (Discovered) Broker approach.
- The Service Broker .dll files must be copied to each physical server in your K2 environment
- When registering instances of the same service on different environments (e.g. a DevHR instance in your development K2 environment that points to the Developer HR database and a ProdHR instance in your production K2 environment that points to your production HR database) ensure that the Service Instance GUID is the same for both instances.
- Service Objects are only described when a Service Instance is registered or refreshed . If the underlying system changes (for example a new column was added to a table), you need to refresh the service instance to "discover" the new property. Any SmartObjects that use this service will need to be refreshed or edited to add this new property.
Before you implement custom Service Brokers
Before you start to build a custom Service Broker, consider the following:
Does an existing generic broker meet your needs?
Determine of one of the generic/endpoint service types can meet your needs. Often you can connect to a provider using one of these generic Service Types, but sometimes requirements such as authentication or conversion of data types (such as non-primitive or complex data) is not possible using one of the generic service types.
The provider’s API(s) and API security
The provider should expose some API that can be consumed by .NET code. It doesn’t matter what technology the APIs use: as long as you can call the APIs with .NET code (or through some intermediary) you can create a Service Broker for the provider. You should also be familiar with the underlying system’s API, and understand the security requirements for the API so that you if and how to handle the various Authentication Modes available for Service Instances. Other questions you should ask are: can the underlying system use Active Directory security principals, or does it have its own security mechanism? Does the underlying system implement its own authorization mechanism to secure data and operations?
Other security considerations
Consider any other security requirements for the Provider, such as encryption of data that is passed over the network, security keys that may need to be passed to the API, whether user credentials need to be persisted when K2 connects to the provider and so on. When using Static credentials, consider whether you want to encrypt the username/password for a service instance. K2 doesn’t automatically encrypt these settings, so you will need to implement your own encryption/decryption mechanism.
Configuration settings for the provider and service instance
What configuration settings are required to set up a Service Instance so that it can connect to the Provider? Examples of such configuration settings include web service URLs, database names, connection strings and machine names. This is especially important for Dynamic Brokers since these brokers are typically used to connect to multiple instances of a specific provider, and you need some way to configure each instance to point to a particular location/serv/URL.
Communications path
You should understand the communication path between the K2 server and the provider so that you can troubleshoot any issues that may occur at runtime or instance registration-time. This includes researching impact of network security, ports, firewalls, timeouts and other network communication that could impact the behavior of your custom service broker.
Authentication and authorization in the provider
Understand how the provider handles authentication and authorization, even if only on a high level. This will help you troubleshoot issues when no data is being returned at runtime, or if the service instance discovery fails to describe the Schema of the Provider correctly.
Is the provider’s schema discoverable (dynamic) or described (static)?
Determine whether the provider's schema is described or discovered. (If the providers schema changes often or you are creating a re-usable broker for a certain technology, the schema should be discoverable.) Determine how you will query the provider to describe the schema. For a provider like SQL you may need to execute Data Definition Scripts to discover the entities in the database, but for a web service, you may need to execute a Service Discovery statement to discover the entities in the service.
Once you know whether the provider's schema is Discoverable or Described, decide on the appropriate type of Service Broker (Dynamic or Static)
Configuration settings for the broker
Determine if any additional configuration settings are required by the Service Broker. This could include settings that are used by the Broker internally (for example, which character to use when replacing special characters, or perhaps a logging target file that the custom Broker will output custom logging messages to).
Considerations while implementing custom Service Brokers
Support for special values
Determine if you want to add support for special values in your service broker. This might include your own reserved values which are interpreted by your code in a specific way, or supporting values like the common SCNULL input value, which is used to pass a NULL value to the underlying provider. If you want to add support for SCNULL, you should add code to your service type that checks if the input value for a property/parameter was SCNULL, and then convert the value into an equivalent NULL data type/value that the underlying provider will understand.
Returning the schema XML in the DescribeSchema method
The SmartObject framework does not need the SmartObject service brokers to return the schema XML in the DescribeSchema method. When overriding the DescribeSchema method, you can return null instead of base.DescribeSchema() or ToXml(). Returning null improves performance. Returning null or string.Empty, the SmartObject framework will use the populated service (ServiceInstance) property.
For backwards compatibility, the base.DescribeSchema() method still returns the XML.