Business Rules
NOTE: Gateways must have a local data source defined to invoke remote business rules.
There are two ways business rules can be used with the Smart Integration Connector Gateway:
-
OneStream BRAPIs interact with a specific local gateway and run on OneStream application servers.
-
Business rules that reference DLLs that are only accessible by the Local Gateway Server. These BRs are compiled and executed on the local gateway (Remote Business Rules when creating them in the Windows Desktop Client).
In these scenarios, the local gateway must have the allowRemoteCodeExec setting configured to True to enable remote execution.
The BR APIs are outlined below:
ExecRemoteGatewayRequest
Initiates a request to a local gateway as specified in the remote request object. This request is dispatched to the Smart Integration Connector local gateway connection data source with the specified command remote invoked.
NOTE: This method is used for request and response type interactions to a remote endpoint that runs for three or less minutes. The default execution timeout is 90 seconds and can be overridden by setting the CommandTimeout property on the RemoteRequestDTO instance provided.
Parameter details:
-
RemoteRequestDTO: Remote request object populated with the remote command and endpoint
-
Returns: RemoteRequestResultDto - Result of execution including the status and any exceptions which may have occurred on the remote endpoint
Following is an example connector business rule that would run on the OneStream application server sending a remote request and block of code to a Local Gateway Connection:
// ExecRemoteGatewayRequest for arbitrary code execution returning a DataTable
string GatewayName = "";
RemoteRequestResultDto objxfRemoteRequestResultDto;
RemoteCodeRequestDto objxfRemoteRequest = new RemoteCodeRequestDto();
// Indication the desire is to run a remote block of code
objxfRemoteRequest.ConnectionType = RemoteCommandType.RemoteCodeExec;
// Name of the remote host to pass to
objxfRemoteRequest.GatewayHostForRequest = GatewayName;
var strCode = "using System;...."; // Valid block of C# or VB.NET code
objxfRemoteRequest.LanguageType = RemoteCodeLanguageType.CSHARP;
objxfRemoteRequest.RemoteCodeBlock = strCode;
objxfRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayRequest(objxfRemoteRequest);
var xfDT = new XFDataTable(si, objxfRemoteRequestResultDto.ResultSet, null, 1000);
Here is the example in VB:
' ExecRemoteGatewayRequest for arbitrary code execution returning a DataTable
Dim GatewayName As String = ""
Dim objxfRemoteRequestResultDto As RemoteRequestResultDto
Dim objxfRemoteRequest As New RemoteCodeRequestDto
' Indication the desire is to run a remote block of code
objxfRemoteRequest.connectionType = RemoteCommandType.RemoteCodeExec
' Name of the remote host to pass to
objxfRemoteRequest.gatewayHostforRequest = GatewayName
Dim strCode As String = "using System;...." ' Valid block of C# or VB.NET code
objxfRemoteRequest.LanguageType = RemoteCodeLanguageType.CSHARP
objxfRemoteRequest.remoteCodeBlock = strCode
objxfRemoteRequestResultDto=BRApi.Utilities.ExecRemoteGatewayRequest(objxfRemoteRequest)
Dim xfDT = New XFDataTable(si, objxfRemoteRequestResultDto.ResultSet, Nothing, 1000)
This BR API can also be used to invoke arbitrary SQL commands against a Smart Integration Connector local gateway connection data source at your site:
/ ExecRemoteGatewayRequest for arbitrary SQL returning a DataTable
string SQL = ""; // SQL SELECT statement goes here
RemoteRequestResultDto objxfRemoteRequestResultDto;
RemoteRequestDto objxfRemoteRequest = new RemoteRequestDto();
// Indicate this is a remote SQL command request
objxfRemoteRequest.ConnectionType = RemoteCommandType.SQLCommand;
objxfRemoteRequest.RelayRemoteDBConnection = ""; // Name of the connection defined in the remote endpoint
objxfRemoteRequest.GatewayHostForRequest = ""; // Name of the remote host to pass to
objxfRemoteRequest.RemoteCommand = SQL;
objxfRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayRequest(objxfRemoteRequest);
// Evaulate the results to determine if it was successful
if (objxfRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Success)
{
// Logic to use results in `objxfRemoteRequestResultDto.ResultSet`
}
else
{
// Query failed. Add additional logic here to handle this case.
}
Here is the example in VB:
' ExecRemoteGatewayRequest for arbitrary SQL returning a DataTable
Dim SQL As String = "" ' SQL SELECT statement goes here
Dim objxfRemoteRequestResultDto As RemoteRequestResultDto
Dim objxfRemoteRequest As New RemoteRequestDto
' Indicate this is a remote SQL command request
objxfRemoteRequest.connectionType = RemoteCommandType.SQLCommand
objxfRemoteRequest.RelayRemoteDBConnection = "" ' Name of the connection defined in the remote endpoint
objxfRemoteRequest.GatewayHostforRequest = "" ' Name of the remote host to pass to
objxfRemoteRequest.RemoteCommand = SQL
objxfRemoteRequestResultDto=BRApi.Utilities.ExecRemoteGatewayRequest(objxfRemoteRequest)
' Evaulate the results to determine if it was successful
If (objxfRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Success) Then
' Logic to use results in `objxfRemoteRequestResultDto.ResultSet`
Else
' Query failed. Add additional logic here to handle this case.
End If
Remote function returning a datatable (C#) without parameters:
// ExecRemoteGatewayBusinessRule
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
var RemoteMethodName = ""; // Name of the method inside the SIC Function that will be called
var objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, GatewayName, null, SICFunctionName, RemoteMethodName);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Success && !(objRemoteRequestResultDto.ResultSet is null))
{
if (objRemoteRequestResultDto.ResultType == RemoteResultType.DataTable)
{
BRApi.ErrorLog.LogMessage(si, "Data Returned: " + objRemoteRequestResultDto.ResultSet.Rows.Count);
}
}
else
{
if (!(objRemoteRequestResultDto.RemoteException is null))
{
throw ErrorHandler.LogWrite(si, new XFException(si, objRemoteRequestResultDto.RemoteException));
}
}
Here is the example in VB:
' ExecRemoteGatewayBusinessRule
' Call a remote Smart Integration Function
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
Dim RemoteMethodName As String = "" ' Name of the method inside the SIC Function that will be called
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, GatewayName, Nothing, SICFunctionName, RemoteMethodName)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Success AndAlso objRemoteRequestResultDto.ResultSet IsNot Nothing) Then
If (objRemoteRequestResultDto.ResultType = RemoteResultType.DataTable) Then
BRApi.ErrorLog.LogMessage(si, "Data Returned: " & objRemoteRequestResultDto.ResultSet.Rows.Count)
End If
Else
If (Not (objRemoteRequestResultDto.RemoteException Is Nothing)) Then
Throw ErrorHandler.LogWrite(si, New XFException(si, objRemoteRequestResultDto.RemoteException))
End If
End If
ExecRemoteGatewayCachedBusinessRule
When a cache flag and key is provided to the ExecRemoteGatewayBusinessRule BR API, this method is used to invoke a previously cached method. This is intended to be used for high-frequency remote business rules to avoid the performance impact of recompiling a remote method on each invocation.
NOTE: Requires allowRemoteCodeExec = True on Smart Integration Connector local gateway. If the previously cached method is not invoked after 60 minutes, the remote cached method is purged.
Parameter details:
-
si: SessionInfo object used to create connection objects
-
cachedFunctionKey: Key of previously cached remote function to invoke
-
functionArguments: Array of objects aligning to function / method parameters. Null / Nothing if there are none required
-
remoteHost: Name of remote host to invoke operation. (Smart Integration Connector Local Gateway Name)
-
executionTimeOut: Timeout (in seconds) on the remote job
-
Returns: RemoteRequestResultDto - Result of execution including the status and any exceptions which may have occurred on the remote endpoint
Here is the rule in C#:
// ExecRemoteGatewayCachedBusinessRule
// Execute and cache a remote SIC Function for later use
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
var RemoteMethodName = ""; // Name of the method inside the SIC Function that will be called
var SICCachedFunctionName = ""; // Name of the cache key for this SIC Function, which can be called on subsequent requests
RemoteRequestResultDto objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, null, GatewayName, RemoteMethodName, SICCachedFunctionName, false, 90);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Success
&& !(objRemoteRequestResultDto.ResultSet is null)
&& objRemoteRequestResultDto.ResultType == RemoteResultType.DataTable)
{
BRApi.ErrorLog.LogMessage(si, "Data Returned - Rows:" + objRemoteRequestResultDto.ResultSet.Rows.Count);
}
else
{
if (objRemoteRequestResultDto.RemoteException != null)
{
throw ErrorHandler.LogWrite(si, new XFException(si, objRemoteRequestResultDto.RemoteException));
}
else
{
BRApi.ErrorLog.LogMessage(si, "Remote Smart Integration Function Succeeded - no data/datatable returned");
}
}
// Subsequent invocations of the remote BR can be run by specifying the endpoint and the cached key name
RemoteRequestResultDto objRemoteRequestResultDtoCached = BRApi.Utilities.ExecRemoteGatewayCachedBusinessRule(si, SICCachedFunctionName , null, GatewayName, 90);
Here is the rule in VB.NET:
' ExecRemoteGatewayCachedBusinessRule
' Execute and cache a remote SIC Function for later use
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
Dim RemoteMethodName As String = "" ' Name of the method inside the SIC Function that will be called
Dim SICCachedFunctionName As String = "" ' Name of the cache key for this SIC Function, which can be called on subsequent requests
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, Nothing, GatewayName, RemoteMethodName, SICCachedFunctionName, False, 90)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Success AndAlso objRemoteRequestResultDto.ResultSet IsNot Nothing AndAlso objRemoteRequestResultDto.ResultType = RemoteResultType.DataTable) Then
BRApi.ErrorLog.LogMessage(si, "Data Returned - Rows:" + objRemoteRequestResultDto.ResultSet.Rows.Count)
Else
If (objRemoteRequestResultDto.RemoteException IsNot Nothing) Then
Throw ErrorHandler.LogWrite(si, New XFException(si, objRemoteRequestResultDto.RemoteException))
Else
BRApi.ErrorLog.LogMessage(si, "Remote Smart Integration Function Succeeded - no data/datatable returned")
End If
End If
' Subsequent invocations of the remote BR can be run by specifying the endpoint and the cached key name
Dim objRemoteRequestResultDtoCached As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayCachedBusinessRule(si, SICCachedFunctionName, Nothing, GatewayName, 90)
ExecRemoteGatewayJob
There may be instances where a remote operation on the Smart Integration Connector Local Gateway host would need to process and assemble data that may take several minutes to run. In this situation, you could use this BR API to queue and run a remote business rule in an asynchronous manner where the remote Smart Integration Connector Local Gateway host returns a Job ID (GUID) that can later be used to obtain the job’s status or the results if the job is complete. When invoking this method, if the RemoteMessageResultStatus is returned as JobRunning (as shown in the example below), the RequestJobID is populated with the ID of the queued job that can later be used to obtain status.
NOTE: Requires allowRemoteCodeExec = True on Smart Integration Connector Local Gateway. There is a defined default limit of 30 minutes for remote jobs to execute before the job is cancelled, and an overloaded version of ExecremoteGatewayJob exists allowing the timeout to be provided, but can never exceed 4 hours. This is not configurable and if this timeout is reached, the status returned shows the timeout. If the result is not obtained within five minutes after the job completes (using the GetRemoteGatewayJobStatus BR API), the remote results are purged to ensure that result objects reclaim server memory on the Smart Integration Service host.
NOTE: This is required to call back into GetRemoteJobStatus with the returned ID to obtain the result:
Here is a basic overview of invoking a remote job and displaying the returned remote Job ID in C#.
// ExecRemoteGatewayJob basic example
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
var argTest = new object[2];
argTest[0] = 100; // Example first argument to SIC Function
argTest[1] = "test"; // Example second argument to SIC Function
// Invoking a OneStream SIC Function Business Rule as a remote job
var objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, SICFunctionName, argTest, GatewayName, String.Empty);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.JobRunning)
{
// Logic to wait for job to complete
}
Here is the basic example in VB:
' ExecRemoteGatewayJob basic example
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
Dim argTest(1) As Object
argTest(0) = 100 ' Example first argument to SIC Function
argTest(1) = "test" ' Example second argument to SIC Function
' Invoking a OneStream SIC Function Business Rule as a remote job
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, SICFunctionName, argTest, GatewayName, String.Empty)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.JobRunning) Then
' Logic to wait for job to complete
End If
Here is the rule in C# to invoke a job, obtain the job ID, and 'poll' until completion:
// ExecRemoteGatewayJob with polling
var jobID = new Guid();
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
// Invoke a long-running Job with a Smart Integration Function
var objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, GatewayName, null, SICFunctionName, String.Empty);
// If Successful, the status is retuned indicating the job is running with the job ID. Use this ID to interrogate if the job is compleed.
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.JobRunning)
{
jobID = objRemoteRequestResultDto.RequestJobID;
BRApi.ErrorLog.LogMessage(si, "Remote Job Queued and Running - JobID: " + jobID.ToString());
// Example waiting 20 seconds for job to complete
for (var loopControl = 0; loopControl < 10; loopControl++)
{
System.Threading.Thread.Sleep(2000);
var objJobStatus = BRApi.Utilities.GetRemoteGatewayJobStatus(si, jobID, GatewayName);
if (objJobStatus.RemoteJobState == RemoteJobState.Running)
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Still running - JobID: " + jobID.ToString());
}
else if (objJobStatus.RemoteJobState == RemoteJobState.Completed)
{
// Checking the return type from the remote job
if (!(objJobStatus.RemoteJobResult.ResultSet is null))
{
var xfDT = new XFDataTable(si, objJobStatus.RemoteJobResult.ResultSet, null, 1000);
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Datatable Returned - JobID: " + jobID.ToString());
return null;
}
else if (!(objJobStatus.RemoteJobResult.ResultDataSet is null))
{
var xfDT = new XFDataTable(si, objJobStatus.RemoteJobResult.ResultDataSet.Tables[0], null, 1000);
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Dataset Returned - JobID: " + jobID.ToString());
return null;
}
else if (!(objJobStatus.RemoteJobResult.ResultDataCompressed is null))
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Object Returned - JobID: " + jobID.ToString());
var value = CompressionHelper.InflateJsonObject<String>(si, objJobStatus.RemoteJobResult.ResultDataCompressed);
BRApi.ErrorLog.LogMessage(si, value);
return null;
}
}
else if (objJobStatus.RemoteJobState == RemoteJobState.JobNotFound)
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Not Found - JobID: " + jobID.ToString());
return null;
}
else if (objJobStatus.RemoteJobState == RemoteJobState.RequestTimeOut)
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Timed Out - JobID: " + jobID.ToString());
return null;
}
else if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Exception)
{
BRApi.ErrorLog.LogMessage(si, "Exception During Execution of Job: " + objRemoteRequestResultDto.RemoteException.ToString());
}
}
}
else
{
// Exception occurred immediately during compile/initial run
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Exception)
{
BRApi.ErrorLog.LogMessage(si, "Exception Executing Job: " + objRemoteRequestResultDto.RemoteException.ToString());
}
else
{
BRApi.ErrorLog.LogMessage(si, "General Job Execution Error - State: " + objRemoteRequestResultDto.RemoteResultStatus.ToString());
}
}
return null;
Here is the rule in VB.NET to invoke a job, obtain the job ID, and 'poll' until completion:
' ExecRemoteGatewayJob with polling
Dim jobID As Guid
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
' Invoke a long-running Job with a Smart Integration Function
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, GatewayName, Nothing, SICFunctionName, String.Empty)
' If Successful, the status is retuned indicating the job is running with the job ID. Use this ID to interrogate if the job is compleed.
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.JobRunning) Then
jobID = objRemoteRequestResultDto.RequestJobID
BRApi.ErrorLog.LogMessage(si, "Remote Job Queued and Running - JobID: " & jobID.ToString())
' Example waiting 20 seconds for job to complete
For loopControl = 0 To 10
System.Threading.Thread.Sleep(2000)
Dim objJobStatus As RemoteJobStatusResultDto = BRApi.Utilities.GetRemoteGatewayJobStatus(si, JobID, GatewayName)
If (objJobStatus.RemoteJobState = RemoteJobState.Running) Then
BRApi.ErrorLog.LogMessage(si, "Remote Job Still running - JobID: " & jobID.ToString())
Else If (objJobStatus.RemoteJobState = RemoteJobState.Completed)
' Checking the return type from the remote job
If (objJobStatus.RemoteJobResult.ResultSet IsNot Nothing) Then
Dim xfDT As XFDataTable = New XFDataTable(si, objJobStatus.RemoteJobResult.ResultSet, Nothing, 1000)
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Datatable Returned - JobID: " & jobID.ToString())
Return Nothing
Else If (Not objJobStatus.RemoteJobResult.ResultDataSet Is Nothing) Then
Dim xfDT As XFDataTable = New XFDataTable(si,objJobStatus.RemoteJobResult.ResultDataSet.Tables(0), Nothing, 1000)
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Dataset Returned - JobID: " & jobID.ToString())
Return Nothing
Else If objJobStatus.RemoteJobResult.ResultDataCompressed IsNot Nothing Then
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Object Returned - JobID: " & jobID.ToString())
Dim value As String = CompressionHelper.InflateJsonObject(Of String)(si, objJobStatus.RemoteJobResult.ResultDataCompressed)
Brapi.ErrorLog.LogMessage(si, value)
Return Nothing
End If
Else If (objJobStatus.RemoteJobState = RemoteJobState.JobNotFound) Then
BRApi.ErrorLog.LogMessage(si, "Remote Job Not Found - JobID: " & jobID.ToString())
Return Nothing
Else If (objJobStatus.RemoteJobState = RemoteJobState.RequestTimeOut) Then
BRApi.ErrorLog.LogMessage(si, "Remote Job Timed Out - JobID: " & jobID.ToString())
Return Nothing
Else If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Exception) Then
BRApi.ErrorLog.LogMessage(si, "Exception During Exeuction of Job: " & objRemoteRequestResultDto.RemoteException.ToString())
End If
Next
Else
' Exception occurred immediately during compile/initial run
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Exception) Then
BRApi.ErrorLog.LogMessage(si, "Exception Executing Job: " & objRemoteRequestResultDto.RemoteException.ToString())
Else
BRApi.ErrorLog.LogMessage(si, "General Job Execution Error - State: " & objRemoteRequestResultDto.RemoteResultStatus.ToString())
End If
End If
Return Nothing
ExecRemoteGatewayBusinessRule
This is a core BR API that can be used to remotely invoke Smart Integration functions on a specified remote Smart Integration Connector Local Gateway host. The Smart Integration Connector Local Gateway must have allowRemoteCodeExec set to True for this BR API to invoke an operation successfully, otherwise the Smart Integration Connector Local Gateway host returns a result indicating that remote code execution is disabled.
This method takes a previously authored Smart Integration function, written in VB.NET or C#, in the OneStream application and passes it to the remote host for execution. With this BR API, it is expected that remote calls should take no more than 2-3 minutes to return a result to the caller as this BR API will block until a result is returned. If longer running or sync operations are needed, consider using the execRemoteGatewayJob BR API.
NOTE: Requires allowRemoteCodeExec = True on Smart Integration Service
Parameter details:
-
si: SessionInfo object used to create connection objects
-
brName: Name of the locally defined (within the OneStream Application scope) Smart Integration function
-
functionArguments: Array of objects aligning to function / method parameters. Null / Nothing if there are none required.
-
remoteHost: Name of remote host to invoke operation. (Smart Integration Connector name)
-
functionName: Name of the function in the Smart Integration function to invoke. If null or empty, a function/method with the name RunOperation is expected to exist within the authored code.
-
(Optional) cachedFunctionKey: Name used to cache the remote function to avoid recompiling the function on a subsequent call. This is optional and if missing or null the function will not be cached.
-
(Optional) forceCacheUpdate: Option indicating if a previously cached function should be replaced with this version. When true, and an existing function is found with a name specified in the cachedFunctionKey parameter, the BR is recompiled and recached. This is useful for situations where a remote function is cached and a change was made.
-
executionTimeOut: Timeout (in seconds) on the remote job (In 7.4, this is now an optional parameter and defaults to 90 seconds if the parameter is missing.)
Here is a C# drill-back example:
// ExecRemoteGatewayBusinessRule displaying results in drillback
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
DrillBackResultInfo drillBackInfo = new DrillBackResultInfo();
DataTable dtf = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, null, GatewayName, string.Empty).ResultSet;
var xfDT = new XFDataTable(si, dtf, null, 1000);
drillBackInfo.DataTable = xfDT;
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.DataGrid;
return drillBackInfo;
Here is a VB example:
' ExecRemoteGatewayBusinessRule displaying results in drillback
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
Dim drillBackInfo As DrillBackResultInfo = new DrillBackResultInfo()
Dim dtf As DataTable = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, Nothing, GatewayName, String.Empty).ResultSet
Dim xfDT As XFDataTable = new XFDataTable(si, dtf, Nothing, 1000)
drillBackInfo.DataTable = xfDT
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.DataGrid
Return drillBackInfo
Here is a C# drill-back example that invokes a remote business rule accepting 2 parameters:
// ExecRemoteGatewayBusinessRule Drillback example
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = ""; // Name of the SIC Function to run
var RemoteMethodName = ""; // Name of the method inside the SIC Function that will be called.
var drillBackInfo = new DrillBackResultInfo();
object[] argTest = new object[2]; // Creating an object array to package the method parameters
argTest[0] = 12; // First parameter is an integer
argTest[1] = "test"; // Second parameter is a string
// Remote Smart Integration Function Signature: ' Public Shared Function RunOperation2(testval As Integer, teststr As String) As ArrayList
// Invoking method RunOperation2 on endpoint testConnection passing in user defined parameters as an array
var objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, argTest, GatewayName, RemoteMethodName);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.RunOperationReturnObject)
{
var returnVal = objRemoteRequestResultDto.ObjectResultValue as ArrayList;
// Simple demonstration without error checking to look at the first element of the arraylist
drillBackInfo.TextMessage = "Completed! " + returnVal[0].ToString();
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.TextMessage;
return drillBackInfo;
}
else if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Success)
{
// Demonstrating a 'pattern' whereby the caller can verify what the type is that's returned and handle properly.
var xfDT = new XFDataTable(si, objRemoteRequestResultDto.ResultSet, null, 1000);
drillBackInfo.DataTable = xfDT;
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.DataGrid;
return drillBackInfo;
}
else if (!(objRemoteRequestResultDto.RemoteException is null))
{
throw ErrorHandler.LogWrite(si, new XFException(si, objRemoteRequestResultDto.RemoteException));
}
Here is a VB.NET drill-back example that invokes a remote business rule accepting 2 parameters:
' ExecRemoteGatewayBusinessRule Drillback example
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "" ' Name of the SIC Function to run
Dim RemoteMethodName As String = "" ' Name of the method inside the SIC Function that will be called.
Dim drillBackInfo As New DrillBackResultInfo
Dim argTest(1) As Object ' Creating an object array to package the method parameters
argTest(0) = 12 ' First parameter is an integer
argTest(1) = "test" ' Second parameter is a string
' Remote Smart Integration Function Signature: ' Public Shared Function RunOperation2(testval As Integer, teststr As String) As ArrayList
' Invoking method RunOperation2 on endpoint testConnection passing in user defined parameters as an array
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, argTest, GatewayName, RemoteMethodName)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.RunOperationReturnObject) Then
Dim returnVal As ArrayList = objRemoteRequestResultDto.ObjectResultValue
'Simple demonstration without error checking to look at the first element of the arraylist
drillBackInfo.TextMessage = "Completed! " & returnVal(0).ToString()
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.TextMessage
Return drillBackInfo
Else If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Success)
' Demonstrating a 'pattern' whereby the caller can verify what the type is that's returned and handle properly.
Dim xfDT = New XFDataTable(si, objRemoteRequestResultDto.ResultSet, Nothing, 1000)
drillBackInfo.DataTable = xfDT
drillBackInfo.DisplayType = ConnectorDrillBackDisplayTypes.DataGrid
Return drillBackInfo
Else If (Not (objRemoteRequestResultDto.remoteException Is Nothing))
Throw ErrorHandler.LogWrite(si, New XFException(si, objRemoteRequestResultDto.RemoteException))
End If
Below is a TestFileRead Remote Business Rule function in C# Referenced by Examples Below.
Here it is in C#:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.IO;
using System.Linq;
namespace OneStream.BusinessRule.SmartIntegrationFunction.TestFileRead
{
public class MainClass
{
public byte[] RunOperation(string year)
{
string fname = @"c:\temp\hw_" + year + ".csv";
byte[] buffer = System.IO.File.ReadAllBytes(fname);
return buffer;
}
public byte[] GetOtherFileData(string year)
{
string fname = @"c:\temp\zw_" + year + ".csv";
byte[] buffer = System.IO.File.ReadAllBytes(fname);
return buffer;
}
public bool DeleteOldFileData(string year)
{
string fname = @"c:\temp\zw_" + year + ".csv";
try
{
System.IO.File.Delete(fname);
return true;
}
catch (IOException ex)
{
return false;
}
}
}
}
Here it is in VB:
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Globalization
Imports System.IO
Imports System.Linq
Namespace OneStream.BusinessRule.SmartIntegrationFunction.TestFileRead
Public Class MainClass
Public Function RunOperation(ByVal year As String) As Byte()
Dim fname As String = "c:\temp\hw_" & year & ".csv"
Dim buffer As Byte() = System.IO.File.ReadAllBytes(fname)
Return buffer
End Function
Public Function GetOtherFileData(ByVal year As String) As Byte()
Dim fname As String = "c:\temp\zw_" & year & ".csv"
Dim buffer As Byte() = System.IO.File.ReadAllBytes(fname)
Return buffer
End Function
Public Function DeleteOldFileData(ByVal year As String) As Boolean
Dim fname As String = "c:\temp\zw_" & year & ".csv"
Try
System.IO.File.Delete(fname)
Return True
Catch ex As IOException
Return False
End Try
End Function
End Class
End Namespace
Below is a remote business rule that queries a database and returns a datatable.
Here is the rule in C#:
// SIC Function referenced by other examples here
namespace OneStream.BusinessRule.SmartIntegrationFunction.GetDataFromDB
{
public class MainClass
{
private const string DataSourceName = "";
public DataTable RunOperation()
{
DataTable dataTableResults = new DataTable();
string connectionString, sql;
connectionString = OneStreamGatewayService.APILibrary.GetRemoteDataSourceConnection(DataSourceName);
SqlConnection conn;
conn = new SqlConnection(connectionStringconn.Open());
sql = ""; // Enter SQL Query here
SqlCommand cmd = new SqlCommand(sql, conn);
var dbreader = cmd.ExecuteReader();
dataTableResults.Load(dbreader);
return dataTableResults;
}
}
}
Here is the rule in VB:
' SIC Function referenced by other examples here
Namespace OneStream.BusinessRule.SmartIntegrationFunction.GetDataFromDB
Public Class MainClass
Private Const DataSourceName As String = ""
Public Function RunOperation() As DataTable
Dim dataTableResults As DataTable = New DataTable()
Dim connectionString, sql As String
connectionString = APILibrary.GetRemoteDataSourceConnection(DataSourceName)
Dim conn As SqlConnection
conn = New SqlConnection(connectionStringconn.Open())
sql = "" ' Enter SQL Query here
Dim cmd As SqlCommand = New SqlCommand(sql, conn)
Dim dbreader = cmd.ExecuteReader()
dataTableResults.Load(dbreader)
Return dataTableResults
End Function
End Class
End Namespace
Here is an example of calling a TestFileRead remote business rule in C#.
// Here we are telling it to specifically call a remote Smart Integration Function called TestFileRead at SIC Gateway
// called TestConnection with a method called DeleteOldFileData
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = "TestFileRead"; // Name of the SIC Function from above example
var RemoteMethodName = "DeleteOldFileData"; // Name of the method inside the SIC Function that will be called.
RemoteRequestResultDto objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, new object[] {"2024"}, GatewayName, RemoteMethodName);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.RunOperationReturnObject && !(objRemoteRequestResultDto.ObjectResultValue is null))
{
bool result;
if (bool.TryParse(objRemoteRequestResultDto.ObjectResultValue.ToString(), out result))
{
BRApi.ErrorLog.LogMessage(si, "File Deleted: " + result.ToString());
}
else
{
BRApi.ErrorLog.LogMessage(si, "Returned a non-boolean value");
}
}
else
{
if (objRemoteRequestResultDto.RemoteException != null)
{
throw ErrorHandler.LogWrite(si, new XFException(si, objRemoteRequestResultDto.RemoteException));
}
}
return null;
Here is an example of calling a TestFileRead remote business rule in VB.NET.
'Here we are telling it to specifically call a remote Smart Integration Function called TestFileRead at SIC Gateway
'called TestConnection with a method called DeleteOldFileData
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "TestFileRead" ' Name of the SIC Function from above example
Dim RemoteMethodName As String = "DeleteOldFileData" ' Name of the method inside the SIC Function that will be called.
Dim argTest(0) As Object ' Creating an object array to package the method parameters
argTest(0) = "2024" ' First parameter is an integer
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, argTest, GatewayName, RemoteMethodName)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.RunOperationReturnObject) Then
'The delete method returns a true/false return type
Dim result As Boolean
'ObjectResultValue introduced in v7.4 to simplify obtaining the return
'value from a method that doesn't return a Dataset/Datatable
result = objRemoteRequestResultDto.ObjectResultValue
BRApi.ErrorLog.LogMessage(si, "File Deleted: " & result)
Else
If (Not (objRemoteRequestResultDto.remoteException Is Nothing)) Then
Throw ErrorHandler.LogWrite(si, New XFException(si, objRemoteRequestResultDto.remoteException))
End If
End if
Here's an example to call the remote BR called "GetDataFromDB" (C#):
// Here we are telling it to specifically call a remote Smart Integration Function called GetDataFromDB at SIC Gateway called TestConnection with a method called RunOperation
var GatewayName = ""; // Name of the Gateway
var SICFunctionName = "GetDataFromDB"; // Name of the SIC Function from above example
var RemoteMethodName = "RunOperation"; // Name of the method inside the SIC Function that will be called.
var objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, null, GatewayName, RemoteMethodName);
if (objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Success
&& objRemoteRequestResultDto.ResultSet != null
&& objRemoteRequestResultDto.ResultType == RemoteResultType.DataTable)
{
BRApi.ErrorLog.LogMessage(si, "Data Returned - Rows:" + objRemoteRequestResultDto.ResultSet.Rows.Count);
}
else
{
if (objRemoteRequestResultDto.RemoteException != null)
{
throw ErrorHandler.LogWrite(si, new XFException(si, objRemoteRequestResultDto.RemoteException));
}
else
{
BRApi.ErrorLog.LogMessage(si, "Remote Smart Integration Function Succeeded - no data/datatable returned");
}
}
Here's an example to call the remote BR called "GetDataFromDB" (VB):
' Here we are telling it to specifically call a remote Smart Integration Function called GetDataFromDB at SIC Gateway called TestConnection with a method called RunOperation
Dim GatewayName As String = "" ' Name of the Gateway
Dim SICFunctionName As String = "GetDataFromDB" ' Name of the SIC Function from above example
Dim RemoteMethodName As String = "RunOperation" ' Name of the method inside the SIC Function that will be called.
Dim objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayBusinessRule(si, SICFunctionName, Nothing, GatewayName, RemoteMethodName)
If objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Success AndAlso objRemoteRequestResultDto.ResultSet IsNot Nothing AndAlso objRemoteRequestResultDto.ResultType = RemoteResultType.DataTable Then
BRApi.ErrorLog.LogMessage(si, "Data Returned - Rows:" & objRemoteRequestResultDto.ResultSet.Rows.Count)
Else
If objRemoteRequestResultDto.RemoteException IsNot Nothing Then
Throw ErrorHandler.LogWrite(si, New XFException(si, objRemoteRequestResultDto.RemoteException))
Else
BRApi.ErrorLog.LogMessage(si, "Remote Smart Integration Function Succeeded - no data/datatable returned")
End If
End If
GetRemoteDataSourceConnection
This remote business rule will return the connection string associated with a Local Gateway Configuration Data Source.
NOTE: Requires allowRemoteCodeExec = True on Smart Integration Local Gateway.
Parameter details:
-
Data Source: The name of the Local Gateway Configuration Data Source.
Here is the rule in C#:
// SIC Function to get configured connection string from SIC Gateway
namespace OneStream.BusinessRule.SmartIntegrationFunction.GetRemoteDataSourceSample
{
public class MainClass
{
public DataTable RunOperation()
{
DataTable dataTableResults = new DataTable();
// Get the remotely defined connection string
string connectionString = OneStreamGatewayService.APILibrary.GetRemoteDataSourceConnection(""); // enter name of DB Connection
SqlConnection conn = new SqlConnection(connectionString);
// Insert custom code
return dataTableResults;
}
}
}
Here is the rule in VB.NET :
' SIC Function to get configured connection string from SIC Gateway
Namespace OneStream.BusinessRule.SmartIntegrationFunction.GetRemoteDataSource_VB
Public Class MainClass
Public Shared Function RunOperation() As DataTable
Dim dataTableResults As New DataTable
' Get the remotely defined connection String
Dim connectionString As String = OneStreamGatewayService.APILibrary.GetRemoteDataSourceConnection("") ' enter name of DB Connection
Dim conn As SqlConnection = New SqlConnection(connectionString)
' Insert custom code
Return dataTableResults
End Function
End Class
End Namespace
GetRemoteGatewayJobStatus
This BR API returns the status or the results of a previously remotely queued job invoked against a specified Smart Integration Connector Local Gateway host.
NOTE: Requires allowRemoteCodeExec = true on Smart Integration Service.
Parameter details:
-
si: SessionInfo object used to create connection objects
-
JobID: GUID of remote job ID returned upon successful call to ExecRemoteGatewayJob
-
remoteHost: Name of remote host to invoke operation (Smart Integration Connector Name)
The sample below invokes a job as part of a data management job inside a OneStream extender rule. The example demonstrates a simple Smart Integration Function that sleeps 2 seconds 1000 times in a loop simulating a long running task. The corresponding extender rule illustrates how this long running function can be invoked as a job, returning a job ID and subsequently polled until it's completed.
It would be typical to invoke long running jobs as part of a Data management/Extender Rule and the code below is an example on how this could be accomplished in C#:
[6:53 PM] Connor Shields
// Invoke long running job as part of a Data management/Extender rule
public object Main(SessionInfo si, BRGlobals globals, object api, ExtenderArgs args)
{
Guid jobID;
RemoteRequestResultDto objRemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, "LongRunningTest", null/* TODO Change to default(_) if this is not a reference type */, "testConnection", string.Empty);
if ((objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.JobRunning))
{
jobID = objRemoteRequestResultDto.RequestJobID;
BRApi.ErrorLog.LogMessage(si, "Remote Job Queued and Running - JobID: " + jobID.ToString());
for (var loopControl = 0; loopControl <= 10; loopControl++)
{
System.Threading.Thread.Sleep(2000);
RemoteJobStatusResultDto objJobStatus = BRApi.Utilities.GetRemoteGatewayJobStatus(si, jobID, "testconnection2");
if ((objJobStatus.RemoteJobState == RemoteJobState.Running))
BRApi.ErrorLog.LogMessage(si, "Remote Job Still running - JobID: " + jobID.ToString());
else if ((objJobStatus.RemoteJobState == RemoteJobState.Completed)
)
{
// Checking the return type from the remote job
if (!(objJobStatus.RemoteJobResult.ResultSet == null))
{
var xfDT = new XFDataTable(si, objJobStatus.RemoteJobResult.ResultSet, null, 1000);
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Datatable Returned - JobID: " + jobID.ToString());
return null;
}
else if (!(objJobStatus.RemoteJobResult.ResultDataSet == null))
{
var xfDT = new XFDataTable(si, objJobStatus.RemoteJobResult.ResultDataSet.Tables[0], null, 1000);
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Dataset Returned - JobID: " + jobID.ToString());
}
else if (!(objJobStatus.RemoteJobResult.ObjectResultValue == null))
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Object Returned - JobID: " + jobID.ToString());
return null;
}
}
else if ((objJobStatus.RemoteJobState == RemoteJobState.JobNotFound))
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Not Found - JobID: " + jobID.ToString());
return null;
}
else if ((objJobStatus.RemoteJobState == RemoteJobState.RequestTimeOut))
{
BRApi.ErrorLog.LogMessage(si, "Remote Job Timed Out - JobID: " + jobID.ToString());
return null;
}
else if ((objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Exception))
BRApi.ErrorLog.LogMessage(si, "Exception During Exeuction of Job: " + objRemoteRequestResultDto.RemoteException.ToString());
}
}
else if ((objRemoteRequestResultDto.RemoteResultStatus == RemoteMessageResultType.Exception))
BRApi.ErrorLog.LogMessage(si, "Exception Executing Job: " + objRemoteRequestResultDto.RemoteException.ToString());
else
BRApi.ErrorLog.LogMessage(si, "General Job Execution Error - State: " + objRemoteRequestResultDto.RemoteResultStatus.ToString());
return null;
}
Here is the example in VB:
' Invoke long running job as part of a Data management/Extender rule
Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object
Dim jobID As Guid
Dim objRemoteRequestResultDto As RemoteRequestResultDto = BRApi.Utilities.ExecRemoteGatewayJob(si, "LongRunningTest", Nothing, "testConnection",String.Empty)
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.JobRunning) Then
jobID = objRemoteRequestResultDto.RequestJobID
BRApi.ErrorLog.LogMessage(si, "Remote Job Queued and Running - JobID: " & jobID.ToString())
'Example waiting 20 seconds for job to complete
For loopControl = 0 To 10
System.Threading.Thread.Sleep(2000)
Dim objJobStatus As RemoteJobStatusResultDto = BRApi.Utilities.GetRemoteGatewayJobStatus(si, JobID, "testconnection2")
If (objJobStatus.RemoteJobState = RemoteJobState.Running)
BRApi.ErrorLog.LogMessage(si, "Remote Job Still running - JobID: " & jobID.ToString())
Else If (objJobStatus.RemoteJobState = RemoteJobState.Completed)
' Checking the return type from the remote job
If (Not objJobStatus.RemoteJobResult.ResultSet Is Nothing) Then
Dim xfDT = New XFDataTable(si,objJobStatus.RemoteJobResult.ResultSet,Nothing,1000)
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Datatable Returned - JobID: " & jobID.ToString())
Return Nothing
Else If (Not objJobStatus.RemoteJobResult.ResultDataSet Is Nothing) Then
Dim xfDT = New XFDataTable(si,objJobStatus.RemoteJobResult.ResultDataSet.Tables(0),Nothing,1000)
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Dataset Returned - JobID: " & jobID.ToString())
Return Nothing
Else If (Not objJobStatus.RemoteJobResult.ObjectResultValue Is Nothing) Then
BRApi.ErrorLog.LogMessage(si, "Remote Job Completed - Object Returned - JobID: " & jobID.ToString())
Return Nothing
End If
Else If (objJobStatus.RemoteJobState = RemoteJobState.JobNotFound)
BRApi.ErrorLog.LogMessage(si, "Remote Job Not Found - JobID: " & jobID.ToString())
Return Nothing
Else If (objJobStatus.RemoteJobState = RemoteJobState.RequestTimeOut)
BRApi.ErrorLog.LogMessage(si, "Remote Job Timed Out - JobID: " & jobID.ToString())
Return Nothing
Else If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Exception)
BRApi.ErrorLog.LogMessage(si, "Exception During Exeuction of Job: " & objRemoteRequestResultDto.RemoteException.ToString())
End If
Next
Else ' Exception occuring immediately during compile/initial run
If (objRemoteRequestResultDto.RemoteResultStatus = RemoteMessageResultType.Exception)
BRApi.ErrorLog.LogMessage(si, "Exception Executing Job: " & objRemoteRequestResultDto.RemoteException.ToString())
Else
BRApi.ErrorLog.LogMessage(si, "General Job Execution Error - State: " & objRemoteRequestResultDto.RemoteResultStatus.ToString())
End If
End If
Return Nothing
End Function
GetSmartIntegrationConfigValue
This BR API allows access to the Local Gateway Local Application Data Settings. Accessing the remotely stored secret or customer-defined configuration values is done using a new "Remote" equivalent of the BR API namespace. This feature can be used to:
-
Reference configuration parameters in a remote business rule running on a Smart Integration Connector Local Gateway Server
-
Store credentials to network resources allowing the developer of remote business rules to reference values stored in the configuration file instead of having them hard-coded and viewable by anyone with permission to edit a business rule.
These configuration values are defined and edited using the Smart Integration Connector Local Gateway Configuration Utility. The API used to obtain these values is demonstrated in the full business rule example below:
NOTE: Requires allowRemoteCodeExec = True on Smart Integration Local Gateway.
Here is the rule in C#:
// SIC Function demonstrating GetSmartIntegrationConfigValue
namespace TestProject.OneStream.BusinessRule.SmartIntegrationFunction.SecretTester
{
public class MainClass
{
public static @bool RunOperation()
{
string result;
// APILibrary is the class containing new remote BRAPI methods
// GetSmartIntegrationConfigValue returns the string value of a found configuration
// element -- returns empty string if the specified key is not found
result = APILibrary.GetSmartIntegrationConfigValue(""); //Enter config value name
return true;
}
}
}
Here is another example in VB.NET:
' SIC Function demonstrating GetSmartIntegrationConfigValue
Namespace OneStream.BusinessRule.SmartIntegrationFunction.SecretTester
Public Class MainClass
Public Shared Function RunOperation() as bool
Dim result As String
' APILibrary is the class containing new remote BRAPI methods
' GetSmartIntegrationConfigValue returns the string value of a found configuration
' element -- returns empty string if the specified key is not found
result = APILibrary.GetSmartIntegrationConfigValue("") ' Enter config value name
Return True
End Function
End Class
End NameSpace
GetGatewayConnectionInfo
From a OneStream business rule, you can invoke this API to obtain gateway details such as:
-
GatewayName: Name of the remote gateway
-
GatewayVersion: Version of the Smart Integration Connector Gateway Service running on the remote host
-
RemoteGatewayPortNumber: Bound Port at Gateway, the port of the remote service this direct connection is associated with.
-
RemoteGatewayHost: Name of the remote host associated with the direct connection.
-
OneStreamPortNumber: Bound Port in OneStream, the port number defined within OneStream that refers/maps to the specified direct connection.
-
SmartIntegrationGatewayType: Type of the Smart Integration Connection (0=Database Connection, 1=Direct Connection)
This API is useful for direct connections where the port number is required before connecting to remote services such as sFTP or remote Web APIs because each endpoint defined in OneStream to Smart Integration Connector Local Gateways has a different port number and would need to be known by the business rule developer at design time. This API makes it easy to look up the remote port by knowing the name of the direct connection defined in OneStream. It returns other useful information outlined below:
Here is the rule in C#:
// GetGatewayConnectionInfo
var GatewayName = "" //Name of the Gateway
GatewayDetails gatewayDetailInformation = BRApi.Utilities.GetGatewayConnectionInfo(si, GatewayName);
int oneStreamPortNumber = gatewayDetailInformation.OneStreamPortNumber;
Here is the rule in VB:
' GetGatewayConnectionInfo
Dim GatewayName As String = "" ' Name of the Gateway
Dim objGatewayDetails As GatewayDetails = BRApi.Utilities.GetGatewayConnectionInfo(si, GatewayName)
Dim oneStreamPortNumber As Integer = objGatewayDetails.OneStreamPortNumber
Check OneStream Version
Remote business rules have the ability to provide logic based on the OneStream Version.
Here is the example rule in C#:
namespace OneStream.BusinessRule.SmartIntegrationFunction.version_test_csharp
{
public class MainClass
{
public string RunOperation()
{
#if ONESTREAM8_4_0_OR_GREATER
// Code if true
#else
// Code if false
#endif
}
}
}
Here is the example rule in VB:
Namespace OneStream.BusinessRule.SmartIntegrationFunction.version_test_vb
Public Class MainClass
Public Shared Function RunOperation() As String
#If ONESTREAM8_4_0_OR_GREATER
' Code if true
#Else
' Code if false
#End If
End Function
End Class
End Namespace
BRApi.Utilities.IsGatewayOnline
The following business rule can check the status of Smart Integration Connector. You will need to replace "gateway-name" with the name of the gateway to be tested.
Here is the rule in C#:
// IsGatewayOnline
namespace OneStream.BusinessRule.Extender.TestHealthCheck
{
public class MainClass
{
public const string GatewayName = "";
public object Main(SessionInfo si, BRGlobals globals, object api, ExtenderArgs args)
{
try
{
TestGatewayConnection(si, GatewayName);
return null;
}
catch (Exception ex)
{
throw ErrorHandler.LogWrite(si, new XFException(si, ex));
}
}
public void TestGatewayConnection(SessionInfo si, string gwName)
{
bool response = BRApi.Utilities.IsGatewayOnline(gwName);
if (response)
{
BRApi.ErrorLog.LogMessage(si, $"Health Check Successful for {gwName}");
}
else
{
BRApi.ErrorLog.LogMessage(si, $"Health Check Failed for {gwName}");
}
}
}
}
Here is the rule in VB:
Namespace OneStream.BusinessRule.Extender.TestHealthCheck
Public Class MainClass
Public Const GatewayName As String = ""
Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object
Try
TestGatewayConnection(si, GatewayName)
Return Nothing
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Function
Public Sub TestGatewayConnection(ByVal si As SessionInfo, ByVal gwName As String)
Dim response As Boolean = BRApi.Utilities.IsGatewayOnline(gwName)
If response Then
BRApi.ErrorLog.LogMessage(si, $"Health Check Successful for {gwName}")
Else
BRApi.ErrorLog.LogMessage(si, $"Health Check Failed for {gwName}")
End If
End Sub
End Class
End Namespace
Business Rules Compatibility
There are some business rules that are not compatible with Smart Integration Connector. If you attempt certain rules, you will run into the following error: This BR API is not compatible with Smart Integration Connector. Refer to Smart Integration Connector Remote BRs.
The following business rules are not compatible with Smart Integration Connector:
BRApi.Database.SaveCustomDataTable
Although, this business rule is not supported, the functionality can be achieved through a remote business rule. You can call this business rule using BRApi.Utilities.ExecRemoteGatewayBusinessRule.
Here is the rule in C#:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
using System.IO;
using System.Linq;
namespace OneStream.BusinessRule.SmartIntegrationFunction.SaveCustomDataTable
{
public class MainClass
{
public void RunOperation()
{
var tableName = ""; // Enter the name of the table to update
var connectionName = ""; // Enter the name of the configured database connection
var connString = OneStreamGatewayService.APILibrary.GetRemoteDataSourceConnection(connectionName);
var dataTable = new DataTable();
using (var connection = new SqlConnection(connString))
{
connection.Open();
var sql = $"SELECT * FROM {tableName}";
var cmd = new SqlCommand(sql, connection);
var adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
var commandBuilder = new SqlCommandBuilder(adapter);
adapter.Fill(dataTable);
// Add logic here to update values in DataTable
// Update database with changes to the DataTable
adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
adapter.Update(dataTable);
}
}
}
}
Here is the same rule VB:
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Globalization
Imports System.IO
Imports System.Linq
Namespace OneStream.BusinessRule.SmartIntegrationFunction.SaveCustomDataTableVB
Public Class MainClass
Public Sub RunOperation()
Dim tableName = "" ' Enter the name of the table to update
Dim connectionName = "" ' Enter the name of the configured database connection
Dim connString = OneStreamGatewayService.APILibrary.GetRemoteDataSourceConnection(connectionName)
Dim dataTable = New DataTable()
Using connection = New SqlConnection(connString)
connection.Open()
Dim sql = $"SELECT * FROM {tableName}"
Dim cmd = New SqlCommand(sql, connection)
Dim adapter = New SqlDataAdapter()
adapter.SelectCommand = cmd
Dim commandBuilder = New SqlCommandBuilder(adapter)
adapter.Fill(dataTable)
' Add logic here to update values in DataTable
' Update database with changes to the DataTable
adapter.UpdateCommand = commandBuilder.GetUpdateCommand()
adapter.Update(dataTable)
End Using
End Sub
End Class
End Namespace
BRApi.Database.InsertOrUpdateRow
BRApi.Database.DeleteRows
Although, these business rules are not supported, inserting, deleting and updating rows can be accomplished through the same remote business rule referenced above. You can call this business rule using BRApi.Utilities.ExecRemoteGatewayBusinessRule. You will insert your logic at the specific comment in the remote business rule.
SQL Bulk Copy
Use of the SQL Bulk Copy class is not supported to copy to and from databases accessed over Smart Integration Connector. Currently, there is not a workaround available.
SQL Transactions
Use of the SqlTransaction class is currently only supported in Smart Integration Connector Functions / remote business rules.