UBIK Enterprise Service
The UBIK® Enterprise Service is a Windows service that is meant to automate UBIK® interface components or interface workflows.
Contents
Concept
The UBIK® EnterpriseService typically runs on a server and watches an arbitrary amount of folders in the file system for changes, like new or modified files. Once such a change occurs, it parses the file and checks if its extension matches the signature of a UBIK® command file. If true, it will be processed.
Command file
A command file for the UBIK® EnterpriseService is a plain text file and has the extension .command or ".json.command". When the EnterpriseService starts processing such a file, it will be parsed as an XML or JSON document. In the case of an XML document every non-XML information in the file will be ignored.
XML Command
A sample command file for starting an interface component looks like this:
<Commands>
<Interface FullName="UBIK.TEST, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" File="F:\Test\UBIK.TEST.dll" Class="UBIK.TestInterface" Direction="E">
<Parameter Key="Server" Value="AUGLNZ0SQL" />
<Parameter Key="InitialCatalog" Value="UBIK.Sandbox.Dev.V2" />
<Parameter Key="UserID" Value="sa" />
<Parameter Key="Password" Value="secretpassword123" />
<Parameter Key="RecordLifeTime" Value="-1" />
<Parameter Key="MyIFNeedsThis" Value="TestValue" />
</Interface>
</Commands>
</InterfaceManager>
This command file would attempt to instantiate the class UBIK.TestInterface from the assembly F:\Test\UBIK.TEST.dll. If connection succeeds, it will then invoke the the methods of the export interface, because of the setting Direction="E".
A sample command file for starting a workflow looks slightly different:
<Commands>
<Workflow Name="WF_XML_TEST" UID="5fdccb8c-85db-4dfc-861a-57be38267bfb" Async="False">
<Parameter Key="Server" Value="AUGLNZ0SQL" />
<Parameter Key="InitialCatalog" Value="UBIK.Sandbox.Dev.V2" />
<Parameter Key="UserID" Value="sa" />
<Parameter Key="Password" Value="secretpassword123" />
<Parameter Key="RecordLifeTime" Value="-1" />
<Parameter Key="MyWorkflowNeedsThis" Value="TestValue" />
</Workflow>
</Commands>
</InterfaceManager>
This command file would attempt to load the workflow object with the Guid 5fdccb8c-85db-4dfc-861a-57be38267bfb and invoke it synchronously, because of the setting Async="False".
Keep UserID and Password empty, if you want the system to connect to the SQL Server using the Windows Authentication (https://msdn.microsoft.com/en-us/library/dd787978.aspx). |
If the database server is on the same machine (localhost) then write Value="." for the server parameter. |
Workflow Arguments
Every workflow started by the Enterprise Service needs an argument UBIKObject of data type UBIK.Kernel.BaseClass. The Enterprise Service initiates this default argument with the workflow object itself.
Any additional parameter, which is passed from the command file to the workflow, has to have an equivalent workflow argument as well. |
Configuration files can of course be created and edited manually, but they can be more comfortably created using the Interface Manager |
JSON Command
Using this command file type UBIK® EnterpriseService will start a UBIK.Console and pass the scripts defined in the command file as parameter. The CommandFileAction is the same parameter as in the configuration of the UBIK® EnterpriseService. The EnterpriseService will evaluate this setting before the setting in the config fle. If it is not set (either -1 or null) the value from the config file will be used. This way it is possible to execute different actions for each command file.
"PathToUbikConsole": "...\\UBIK.Studio\\UBIK.Console.exe",
"InitStatement": "...\\UBIK.Studio\\Scripts\\init.cs",
"PathToScriptFile": "...\\UBIK.Studio\\Scripts\\script.cs",
"ConfigFilePath": "...\\UBIK.Studio\\Scripts\\config.cs",
"CommandFileAction": 2
}
Web Interface
Since version 3.5.0 UBIK.EnterpriseService supports a new web interface. Since the EnterpriseService already provides a file based interface which can be used to execute code or workflows we added an interface that is backward compatible so that not only tasks but also workflows and code (Note: The code must derive from UBIK.Interface.UBIKInterfaceBase and implement IUBIKImport and/or IUBIKExport) can be enqueued via this interface.
How to consume the web interface
First of all the address of the webinterface to a certain action follows a specific pattern: "api/{controller}/{action}". For example, that means if you want to call the GetUpTimeInfo() method to see wether the WebInterface is online or not you will have to do a GET request to http://localhost:9000/api/basicenterpriseservice/getuptimeinfo.
By default the WebInterface allows you to enqueue tasks in the same way the command file based interface does described in here: UBIK_Enterprise_Service#XML_Command. Additionally it implements a new feature, namely the possibility to enqueue a task. A task is an abstract concept and describes something that needs to be done by UBIK. A task must have an entry point which must be a .Net implementation of a method. There are two ways for UBIK to identify a task to executed: Either you provide the full class name (Namespacename.Classname) and the methodname or you provide the full class name make the class implement the UBIK.ServiceTask.TaskExecution.ITask interface. You can also provide parameters to your task. These parameters must be a json serialized string. It is then the responsibility of the implementation of the task itself to deserialize the json string to an object. Finally you will need to tell the EnterpriseService on which database/UBIK project you want it to execute the task on. Overall the parameters to enqueue a task by the WebInterface must be as follows:
string SQLUser
string SQLPassword
string SQLServer
string SQLInitialCatalog
// Full path ({Methodname}) to the method (task) to be executed.
string MethodName
// Full path ({Namespacename}.{Classname}) to the method to be executed.
string ClassFullname
// As an example of how to write a method parameter as a json string:
// string methodParametersAsJson = @"{
// ""ParamA"": ""ValueA"",
// ""ParamB"": ""ValueB""
// }";
string MethodParametersAsJson
UBIK.EnterpriseService.WebInterface.Client
In order to consume this new interface you can use the UBIK.EnterpriseService.WebInterface.Client which is a .Net client library that you can include in your project. It is also included in the standard UBIK installation and can be used from within UBIK.Studio.
UBIK.EnterpriseService.BasicClient.App
Another possibility is to use UBIK.EnterpriseService.BasicClient.App which is a stand-alone application that uses the aforementioned library internally. This application can be used in the Windows Task Scheduler to schedule executions. In order to use this application you will need to configure it in its accompanying UBIK.EnterpriseService.BasicClient.App.exe.config file. This xml file has an “appSettings” section with three entries:
- BaseAddress: This is the base address on which the EnterpriseService hosts its WebInterface. You can find it in the appsettings section (WebInterfacePort & WebInterfaceHost) in the UBIK.EnterpriseService.exe.config file of your EnterpriseService installation path. The default value is http://localhost:9000
- PathToBasicEnterpriseServiceRequestJsonFile: This is a file path to a json file that contains all parameters needed to execute one or more tasks. As an example:
"Tasks": [
{
"ClassFullname": "namespace1.class1",
"MethodName": "method1",
"MethodParameterPathFullName": "pathToFileContainingAnyJson1"
//No parameters required if method is like below:
//public void Run(IExecutionRequest executionRequest, UBIKEnvironment ubikEnvironment) { ... }
},
{
"ClassFullname": "namespace2.class2",
"MethodName": "method2",
"MethodParameterPathFullName": "pathToFileContainingAnyJson2"
}
],
"RepeateEveryMinutes": 0,
"SqlConnectionDefinition": {
"SSPI": false,
"SQLUser": "user",
"SQLPassword": "pw",
"SQLServer": "server",
"SQLInitialCatalog": "db"
},
"ClassFullname": null,
"MethodName": null,
"MethodParameterPathFullName": null
}
- PathToBasicEnterpriseServiceRequestJsonFileList: Path to a file containing paths (separated by line breaks). The paths should lead to files as described above, in the order they should be processed.
Own Implementation
Of course you can also write or use any other implementation or client technology to call the WebInterface. I suggest to learn from the UBIK.EnterpriseService.WebInterfaceClient on how to use the API.
How to extend the web interface
The EnterpriseService not only hosts a WebInterface it allows you to extend it by adding your own controllers. For this you have to do two steps:
- Create your own controller that derives from System.Web.Http.ApiController (Nuget Microsoft.AspNet.WebApi.Core)
- Place the assembly to the EnterpriseService Injection directory
As an example a controller can be implemented like this:
namespace PluginLibrary
{
public class MyExtentionController : ApiController
{
[HttpPost]
public void DoThingsWithObject(string param)
{
// Do things here
}
}
}
Configuring UBIK® EnterpriseService
Since version 2.6.3 UBIK.EnterpriseService it is now possible to mark a command file as processed, delete a command file or do nothing once a command file is processed. This behaviour needs to be configured in the UBIK.EnterpriseService.exe.config configuration file. The following values are valid: Do Nothing = 0, Mark as processed with ".processed" = 1 and Delete = 2. The setting-key "ConsoleRunMode" defines whether UBIK.EnterpriseService will start the UBIK.Console either Normal = 0, Hidden = 1, Minimized = 2 or Maximized = 3.
Since Version 3.5.0 UBIK.EnterpriseService is now able to host a WebInterface. In order to have the WebInterface up and running you will need to start the UBIK.EnterpriseService and by default it will host the WebInterface at http://localhost:9000/. We added three new parameter settings in UBIK.EnterpriseService.exe.config to configure the WebInterface:
- ExecuteWebInterface: The default is “1” and indicates that the WebInterface is turned on. Any other value or empty will prevent the EnterpriseService to host the WebInterface.
- WebInterfacePort: The default is “8000”.
- WebInterfaceHost: The default is http://localhost.
<appSettings>
<add key="ConsoleRunMode" value="1" />
<add key="CommandFileAction" value="0" />
<add key="ClearWatchFolders" value="0" />
<add key="ExecuteWebInterface" value="1" />
<add key="WebInterfacePort" value="1" />
<add key="WebInterfaceHost" value="1" />
</appSettings>
</configuration>k
Command File Action
It is possible to configure what should happen with the config file once it was processed.
Value | Action | Description |
---|---|---|
0 | No Action | The Command File stays in the folder and does not get renamed. |
1 | Mark | The Command File stays in the folder but gets renamed (.processed) |
2 | Delete | The Command File gets deleted after it was processed. |
If "Mark" or "Delete" is configured UBIK Enterprise Server will queue unprocessed files during the startup of the service and will process them one by one. If you want to avoid this you need to clear the watch folders before (e.g. by setting ClearWatchFolders to 1).
Enterprise Service Task Execution Mode
For special cases the UBIK® EnterpriseService can be executed as a simple task. The reason to run it as a task can be for troubleshooting or for the case some referenced components cannot be run in service mode (e.g. Microsoft Office etc.). To be executed as a Task, the Enterprise Service .exe-File has to be started with the command line option "-tray". There will be a tray icon shown in the Windows Tray. Right-Clicking the tray icon opens the menu, where the user can start, stop, pause, or continue the enterprise service. Please note that starting the enterprise service as a task requires an active user session in order to be executed.
Logging
Especially for complex interfacing tasks, good logging is paramount.
The Logging Configuration can be used to specify the target folder, log level, etc.
Log entries are really your best way to find out what happens during the execution of an Enterprise Service task. They are also much more versatile than any UI we could provide. So even though it looks cumbersome, logs can help you a lot after you get used to them!
Our best practice recommendation is:
- In the custom code executed by the Enterprise Service, do very detailed logging in critical places (e.g., conditional actions depending on runtime input), especially for exceptional cases (missing or unexpected parameters).
- This detailed logging can be done with log level "Verbose". This way, you can switch it on and off on demand, for debugging - without filling the hard disk with irrelevant logs in production.
- For every log entry, create a randomly generated large number for finding the correct place in the code later. The random number helps you avoiding to maintain an incremental log ID list.