This article contains the following sections:
- Sychronously calling the REST Service
- Asychronously calling the REST Service with JSON
- Asychronously calling the REST Service with XML
- Calling the SOAP EndPoint using a Service Reference
Synchronously calling the REST Service
The following example demonstrates calling the irServer - Rule Execution Service REST interface synchronously with the legacy WebRequest class.
// The name of the ruleApp in the Catalog
string ruleApp = "MortgageCalculator";
// The address of the Rule Execution Service
string ruleExecutionServiceURI = "http://localhost/InRuleRuleEngineService_v5.0.16/HttpService.svc";
// The name of the Entity
string entityName = "Mortgage";// The name of the RuleSet to execute, or use 'ApplyRules' if found to be null.
string ruleSetName = "PaymentSummaryRules";
// The entity state as a C# dynamic type
dynamic entityState = new
{
LoanInfo = new
{
Principal = 53000m, APR = 7.625f, TermInYears = 15
}
};
// We use Newtonsoft's Json.Net library to convert this dynamic C# object to a JSON string
string entityStateJsonInput = JsonConvert.SerializeObject(entityState);
// New create the full request, inserting the JSON string that represents EntityState.
dynamic requestData = new
{
RuleApp = new
{
RepositoryRuleAppRevisionSpec = new
{
RuleApplicationName = ruleApp
}
},
EntityName = entityName,
EntityState = entityStateJsonInput,
RuleSetName = ruleSetName
};
string requestDataString = JsonConvert.SerializeObject(requestData);
//If no ruleSetName exists, execute Auto rules, otherwise execute explicit rule.
string postUri;
if (string.IsNullOrEmpty(ruleSetName))
{ postUri = ruleExecutionServiceURI + "/ApplyRules"; }
else
{ postUri = ruleExecutionServiceURI + "/ExecuteRuleSet"; }
// Encode our string into an array of bytes, needed by WebRequest.
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(requestDataString);
// Create and prepare the request
WebRequest webRequest = WebRequest.Create(postUri);
// ApplyRules only works as a POST, not a GET
webRequest.Method = "POST";
// Our EntityState is encoded as an JSON document, not XML.
webRequest.ContentType = "application/json";
// WebRequest is old, and can't count by itself.
webRequest.ContentLength = bytes.Length;
string httpResponse;
// Create our requestStream by opening the request, make sure it gets disposed when done.
using (var requestStream = webRequest.GetRequestStream())
{
// send the data
requestStream.Write(bytes, 0, bytes.Length);
}
// In case it has not already been mentioned this is a rather primitive way of
// making an HTTP based request. We recommend you read the HttpClient based code samples
// elsewhere in this document, as that Asynchronous approach is a better way to go.
try
{
HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse;
using (var stream = response.GetResponseStream())
{
var reader = new StreamReader(stream, Encoding.UTF8);
httpResponse = reader.ReadToEnd();
}
}
catch (WebException ex)
{
using (var stream = ex.Response.GetResponseStream())
{
var reader = new StreamReader(stream, Encoding.UTF8);
httpResponse = reader.ReadToEnd();
throw new Exception(httpResponse, ex);
}
}
dynamic resultJson = JsonConvert.DeserializeObject<dynamic>(httpResponse);
string entityJsonString = resultJson.EntityState;
dynamic entityJson = JsonConvert.DeserializeObject<dynamic>(entityJsonString);
string paymentSummaryJsonString = JsonConvert.SerializeObject(entityJson.PaymentSummary);
Asynchronously calling the REST Service with JSON
The following example demonstrates calling the irServer - Rule Execution Service REST interface with a JSON based Entity State.
static void Main(string[] args)
{
// The name of the ruleApp in the Catalog
string ruleApp = "MortgageCalculator";
// The address of the Rule Execution Service
string ruleExecutionServiceURI = "http://localhost/InRuleRuleEngineService_v5.0.16/HttpService.svc";
// The name of the Entity
string entityName = "Mortgage";
// The name of the RuleSet to execute, or use 'ApplyRules' if found to be null.
string ruleSetName = "PaymentSummaryRules";
// The entity state as a C# dynamic type
dynamic entityState = new
{
LoanInfo = new
{
Principal = 53000m, APR = 7.625f, TermInYears = 15
}
};
// A console application's main() entry point cannot be declared as async, so here
// we are creating an Async task to execute the Async method, then we will wait on
// the result.
Task<string> httpTask = AsyncRestJsonCatalog(ruleExecutionServiceURI, ruleApp,
entityName, entityState, ruleSetName);
// Calling the Result property of a Task object will block this thread until
// the Task has had a chance to complete in it's worker thread.
string httpTaskResult = httpTask.Result;
// After this call you can inspect the raw result (as JSON) in resultJson, but note
// that the EntityState will be serialized Json and must be decoded.
dynamic resultJson = JsonConvert.DeserializeObject<dynamic>(httpTaskResult);
string entityJsonString = resultJson.EntityState;
// Decode the serialized entity Json into a dynamic entity.
dynamic entity = JsonConvert.DeserializeObject<dynamic>(entityJsonString);
}
private async static Task<string> AsyncRestJsonCatalog(string ruleExecutionServiceURI, string ruleApp,
string ruleApplicationEntityName, dynamic entityStateObjectInput, string ruleSetName)
{
// We use Newtonsoft's Json.Net library to convert this dynamic C# object to a JSON string
string entityStateJsonInput = JsonConvert.SerializeObject(entityStateObjectInput);
// New create the full request, inserting the JSON string that represents EntityState.
dynamic requestData = new
{
RuleApp = new
{
RepositoryRuleAppRevisionSpec = new
{
RuleApplicationName = ruleApp
}
},
EntityName = ruleApplicationEntityName,
EntityState = entityStateJsonInput,
RuleSetName = ruleSetName
};
string requestDataString = JsonConvert.SerializeObject(requestData);
//If no ruleSetName exists, execute Auto rules, otherwise execute explicit rule.
string postUri;
if (string.IsNullOrEmpty(ruleSetName))
{ postUri = ruleExecutionServiceURI + "/ApplyRules"; }
else
{ postUri = ruleExecutionServiceURI + "/ExecuteRuleSet"; }
// Our EntityState is encoded as JSON document, not XML.
string mediaType = "application/json";
// Async call to HttpClient with an HttpContent and wait for result.
HttpContent content = new StringContent(requestDataString, Encoding.UTF8, mediaType);
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(postUri, content);
// Async convert the HttpResponseMessage's content to a string.
string responsestring = await response.Content.ReadAsStringAsync();
// We're done, return result.
return responsestring;
}
Asynchronously calling the REST Service with XML
The following example demonstrates calling the irServer - Rule Execution Service REST interface with an XML based Entity State.
static void Main(string[] args)
{
// The name of the ruleApp in the Catalog
string ruleApp = "MortgageCalculator";
// The address of the Rule Execution Service
string ruleExecutionServiceURI = "http://localhost/InRuleRuleEngineService/HttpService.svc";
// The Entity Name:
string entityName = "Mortgage";
// The name of the RuleSet to execute, or use 'ApplyRules' if found to be null.
string ruleSetName = "PaymentSummaryRules";
// The Entity State as XML text.
string entityStateXMLInput = @"<?xml version='1.0' encoding='utf-8'?>
<Mortgage xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<LoanInfo>
<Principal>53000</Principal>
<APR>7.625</APR>
<TermInYears>15</TermInYears>
</LoanInfo>
<PaymentSummary/>
</Mortgage>";
// A console application's main() entry point cannot be declared as async, so here
// we are creating an Async task to execute the Async method, then we will wait on
// the result.
Task<string> httpTask = AsyncRestXmlCatalog(ruleExecutionServiceURI, ruleApp, entityName,
entityStateXMLInput, ruleSetName);
// Calling the Result property of a Task object will block this thread until
// the Task has had a chance to complete in it's worker thread.
string httpTaskResult = httpTask.Result;
Console.WriteLine(httpTaskResult);
// Now let's extract the <EntityState> element, which has been encoded.
// The Value property of the XElement will automatically decode the contents
// and expose it as a string, which lets us look at the inner XML document "EntityState".
// It's worth observing that while the input was encoded as UTF-8, this result is in
// UTF-16.
XDocument xmldoc = XDocument.Parse(httpTaskResult);
string xmlEntityStateOutput =
(from n in xmldoc.Descendants()
where n.Name.LocalName == "EntityState"
select n.Value).FirstOrDefault();
// Wonderful! Now lets take that concept further and extract just the
// <PaymentSummary> node from the document, which gives us our computed "answers".
XDocument xmlentitystatedoc = XDocument.Parse(xmlEntityStateOutput);
string paymentSummaryXml = (from n in xmlentitystatedoc.Descendants()
where n.Name.LocalName == "PaymentSummary"
select n.ToString()).FirstOrDefault();
}
private async static Task<string> AsyncRestXmlCatalog(string ruleExecutionServiceURI,
string ruleApp,
string entityName,
string entityStateXMLInput,
string ruleSetName)
{
// We must encode the Entity State XML into a valid XML string so that
// it can be wrapped with the outer XML request document.
string entityStateXMLEncoded = SecurityElement.Escape(entityStateXMLInput);
string rootNodeName;
if (string.IsNullOrEmpty(ruleSetName))
{ rootNodeName = "ApplyRulesRequest"; }
else
{ rootNodeName = "ExecuteRuleSetRequest"; }
// Now we generate the outer XML request document.
string requestXML = $@"<?xml version='1.0' encoding='utf-8'?>
<{rootNodeName} xmlns='http://www.inrule.com/XmlSchema/Schema'>
<RuleApp>
<RepositoryRuleAppRevisionSpec>
<RuleApplicationName>{ruleApp}</RuleApplicationName>
</RepositoryRuleAppRevisionSpec>
</RuleApp>
<EntityState>{entityStateXMLEncoded}</EntityState>
<EntityName>{entityName}</EntityName>
<RuleSetName>{ruleSetName}</RuleSetName>
</{rootNodeName}>";
//If no ruleSetName exists, execute Auto rules, otherwise execute explicit rule.
string postUri;
if (string.IsNullOrEmpty(ruleSetName))
{ postUri = ruleExecutionServiceURI + "/ApplyRules"; }
else
{ postUri = ruleExecutionServiceURI + "/ExecuteRuleSet"; }
// Our EntityState is encoded as an XML document, not JSON.
string mediaType = "application/xml";
// Async call to HttpClient with an HttpContent and wait for result.
HttpContent content = new StringContent(requestXML, Encoding.UTF8, mediaType);
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(postUri, content);
// Async convert the HttpResponseMessage's content to a string.
string responseXML = await response.Content.ReadAsStringAsync();
// We're done, return result.
return responseXML;
Calling the SOAP EndPoint using a Service Reference
Prerequisites | A valid Service Reference |
The following sample represents how to call irServer Rule Execution Service SOAP EndPoint using a service reference:
using (RuleEngineServiceClient proxy = new RuleEngineServiceClient())
{
try
{
// Get RuleApp as defined in the config (RepositoryRuleApp or FileSystemRuleApp)
RepositoryRuleApp rules = new RepositoryRuleApp();
rules.RepositoryServiceUri = "http://server/InRuleCatalogService/Service.svc";
RepositoryRuleAppRevisionSpec spec = new RepositoryRuleAppRevisionSpec();
spec.RuleApplicationName = "MortgageCalculator";
rules.RepositoryRuleAppRevisionSpec = spec;
rules.UserName = "Admin";
rules.Password = "password";
// Create new ApplyRulesRequest
ApplyRulesRequest request = new ApplyRulesRequest();
request.RuleApp = rules;
request.EntityName = "Mortgage";
request.RuleEngineServiceOutputTypes = new RuleEngineServiceOutputTypes();
request.RuleEngineServiceOutputTypes.ActiveNotifications = true;
request.RuleEngineServiceOutputTypes.ActiveValidations = true;
request.RuleEngineServiceOutputTypes.EntityState = true
// Load state XML
Console.WriteLine("- Loading XML state for 'Invoice'...");
request.EntityState =
"<Mortgage><LoanInfo><Principal>500000</Principal><APR>6.875</APR
< TermInYears > 30 </TermInYears ></LoanInfo ><PaymentSummary/ ></Mortgage > ";
Console.WriteLine("Input State:");
Console.WriteLine(request.EntityState);
Console.WriteLine("");
// Submit Request
Console.WriteLine("- Calling ApplyRules() from RuleEngineService...");
RuleEngineServiceResponse response = proxy.ExecuteRuleEngineRequest(request)
Console.WriteLine("Active Notifications:");
foreach (Notification notification in response.ActiveNotifications)
{
Console.WriteLine(notification.NotificationType + ": " + notification.Message);
}
Console.WriteLine("");
Console.WriteLine("Active Validations:");
foreach (Validation validation in response.ActiveValidations)
{
Console.WriteLine(validation.InvalidMessageText);
}
Console.WriteLine("");
Console.WriteLine("Output State:");
// Note: XML formatting not maintained in response
Console.WriteLine(response.EntityState);
Console.WriteLine("");
}
catch (Exception ex)
{
Console.WriteLine("Unknown exception occurred during RuleEngineService request: " +
ex.ToString());
}
}
Console.WriteLine("[END ServiceReferenceConsumer Sample]")
For more information, see the article: irServer - Rule Execution Service
Comments
0 comments
Please sign in to leave a comment.