Create new DateTime in Microsoft RulesEngine rule - json-rules-engine

I'm looking at the Microsoft RulesEngine. This appears to have what I'm looking for but I'm having difficulties getting some of my rules to execute. I have a need to dynamically set/check date times for the customer's rules. I can do this in code and pass it into the ruleset, but I want to eliminate the need to recompile my app to send input values should they decide to change their rules. Having everything in my json file is the optimal solution here. I can then modify the rules, resend a json and call it done.
Here's the scenario: If a person has a license and they are renewing between certain dates then they should get a specific cost. Yes, it's a bit contrived but it's what I need to meet the acceptance criteria. The following doesn't work. Any recommendations/pointers? Thank you in advance!
Here's the sample:
[
{
"WorkflowName": "WithinRenewalPeriod",
"GlobalParams": [
{
"Name": "Last_December",
"Expression": "new DateTime(DateTime.Now.Year - 1 , 12, 1)"
},
{
"Name": "Current_March",
"Expression": "new DateTime(DateTime.Now.Year, 3, 1)"
},
{
"Name": "Current_July",
"Expression": "new DateTime(DateTime.Now.Year, 7, 10)"
}
],
"Rules": [
{
"RuleName": "PriorLicense_Between_Dec1_Mar1",
"Enabled": true,
"ErrorType": 0,
"RuleExpressionType": 0,
"Expression": "person.HistoricalLicenseList.Count() > 0 AND (DateTime.Now >= Last_December AND DateTime.Now <= Current_March)",
"SuccessEvent": "1"
},
{
"RuleName": "HasPriorLicense_Between_Mar2_July10",
"Enabled": true,
"ErrorType": 0,
"RuleExpressionType": 0,
"Expression": "person.HistoricalLicenseList.Count() > 0 AND (DateTime.Now >= Current_March AND DateTime.Now <= Current_July)",
"SuccessEvent": "3000"
}
]
}
]

I figured it out. I was assuming that you would need to "new" the DateTime. This wasn't the case. I ended up removing the "new" keyword and was able to get the GlobalParams to work:
This is wrong:
This is the correct way to instantiate "new" DateTime in GlobalParams:
The end results generated as Inputs:

Related

data factory - check if result of pipeline task contains a specific string or value?

I have a web task in a pipeline.
The result of the api call can be one of 3:
An item exists in a database.
an item does not exist in a database.
the body sent to the call was invalid.
If the record exists, I want to take further action.
As the resulting JSON from the API call is entirely different when an entity exists vs does not exists, how can I check for if a specific value is returned, if there is a chance it wont be returned at all?
Below is the output from a successful call. I'd like to check for the "Tag" attribute, but also cover a case where this does not exist.
How is this done using a dynamic content expression, seeing as there is no exists function?
{
"Data": [
{
"Data": {
"RowNumber": 0,
"Tag": "GLT-GM-45",
"GMStatus": 0,
"CustomValues": [
{
"CSLabel": "Asset Status",
"CSType": 0,
"CSValue": "Assigned"
},
{
"CSLabel": "Usage Status",
"CSType": 0,
"CSValue": "Permanent"
}
],
"AttachmentsToAdd": [],
"AttachmentsToDelete": []
},
"Messages": [
{
"ResultCode": 0,
"Message": "Success",
"HttpStatusCode": 200,
"FieldName": "GLT-GM-45"
}
],
"HasError": false,
"HasHttpError": false,
"HasMessage": true,
"HasSuccessWithMoreDataRemaining": false
}
],
"Messages": [
{
"ResultCode": 0,
"Message": "Success.",
"HttpStatusCode": 200,
"FieldName": ""
}
],
"TotalRecordsLongCount": 1,
"HasSuccessWithMoreDataRemaining": false,
"HasError": false,
"HasMessage": true,
"HasHttpError": false,
"ADFWebActivityResponseHeaders": {
"Connection": "keep-alive",
"Pragma": "no-cache",
"WaspResult": "WaspResult",
"X-UA-Compatible": "IE=edge;IE=edge",
"Cache-Control": "no-store, no-cache",
"Date": "Tue, 02 Aug 2022 11:58:31 GMT",
"Server": "Microsoft-IIS/10.0;Microsoft-IIS/8.5",
"X-AspNet-Version": "4.0.30319",
"X-Powered-By": "ASP.NET;ASP.NET",
"Content-Length": "2364",
"Content-Type": "application/json",
"Expires": "-1"
},
"effectiveIntegrationRuntime": "AutoResolveIntegrationRuntime (North Europe)",
"executionDuration": 0,
"durationInQueue": {
"integrationRuntimeQueue": 1
},
"billingReference": {
"activityType": "ExternalActivity",
"billableDuration": [
{
"meterType": "AzureIR",
"duration": 0.016666666666666666,
"unit": "Hours"
}
]
}
}
Wouldn't you be able to use an IF Condition that uses a contains function? Obviously I do not have a way to recreate your output, but I did the following to simulate something.
Added an If Condition to a pipeline
Added dynamic content that uses a contains function. The first part was a string containing part of your output from above (copy/paste). The part behind the comma (i.e. the search string) being 'Tag'
Added False activity causing the component to fail
Added a True activity to set a variable to be equal to "Found"!.
The full If Condition:
#contains('{
"Data": [
{
"Data": {
"RowNumber": 0,
"Tag": "GLT-GM-45",
"GMStatus": 0
}
}', 'Tag')
Seeing the 'Tag' should be found in the string, it produces the result of setting the variable:
Changing the search word to NotATag which does not exist in the string produces this instead:
My guess would be that you can substitute the hard-coded string with something like the following:
#contains(activity('Web1').output, 'Tag')
Obviously, change 'Web1' to the name of your web component.
Might not be an ideal way but you can do something like below to check the existence of Tag attribute in output (the reason i am trying to check the string size is the pipeline exp expected the return type to be boolean, hence using condition to achieve it), you can map the other actions based on If activity status. If the property doesn't exist if condition fails with error.
Condition
Mapping

REST API design for specifying value options

Given a resource like:
GET: /api/examples/1
{
"id": 1,
"direction": "North"
}
Which also supports POST, PUT, how should the possible values for "direction" be specified?
Additionally, is there a solution which allows the consumer to know which values will be available if those values are contextual? e.g. if the example is made more complicated:
GET: /api/examples/
{[
{
"id": 1,
"startLocation": "Kentucky, USA",
"direction": "North"
}
{
"id": 2,
"startLocation": "North Pole",
"direction": "South"
}
}]
(with something vaguely like):
"options": [
{
"value": "North",
"validWhen": "startLocation !== `North Pole`"
},
{
"value": "East",
"validWhen": "true"
},
...
]
Is there a better solution than another resource linked from each example which returns the currently valid options? If not, how does the consumer know that changing "startLocation" changes the valid set of values for "direction"?
I think what you might be looking for is a JSON-Schema. This allows you to strictly describe what options are available in your JSON document, and you can link to the document using a describedBy link.
To expand on what #Justas said in his comment, if I understand your requirements correctly, your resource might look something like:
GET /examples/1
{
"startLocation": "Kentucky, USA",
...
"_links": {
"travel-north": "/some/url",
...
}
}

Validate referential integrity of object arrays with Joi

I'm trying to validate that the data I am returned it sensible. Validating data types is done. Now I want to validate that I've received all of the data needed to perform a task.
Here's a representative example:
{
"things": [
{
"id": "00fb60c7-520e-4228-96c7-13a1f7a82749",
"name": "Thing 1",
"url": "https://lolagons.com"
},
{
"id": "709b85a3-98be-4c02-85a5-e3f007ce4bbf",
"name": "Thing 2",
"url": "https://lolfacts.com"
}
],
"layouts": {
"sections": [
{
"id": "34f10988-bb3d-4c38-86ce-ed819cb6daee",
"name": "Section 1",
"content:" [
{
"type": 2,
"id": "00fb60c7-520e-4228-96c7-13a1f7a82749" //Ref to Thing 1
}
]
}
]
}
}
So every Section references 0+ Things, and I want to validate that every id value returned in the Content of Sections also exists as an id in Things.
The docs for Object.assert(..) implies that I need a concrete reference. Even if I do the validation within the Object.keys or Array.items, I can't resolve the reference at the other end.
Not that it matters, but my context is that I'm validating HTTP responses within IcedFrisby, a Frisby.js fork.
This wasn't really solveable in the way I asked (i.e. with Joi).
I solved this for my context by writing a plugin for icedfrisby (published on npm here) which uses jsonpath to fetch each id in Content and each id in Things. The plugin will then assert that all of the first set exist within the second.

magento 2 rest api product filters

I am working on magento 2 api. I need products based on below filters
store id
by product name search
shorting by name
category id
add limit
I have try with this api but no option available
index.php/rest/V1/categories/{id}/products
Please someone suggest how to archive this.
Thanks
You are looking for the (GET) API /rest/V1/products.
the store ID should be automatically detected by the store, because you can pass the store code in the URL before. If you have a store with code test, the API will start with GET /rest/test/V1/products/[...].
You can use the likecondition type. Ex.: products with "sample" in their name: ?searchCriteria[filter_groups][0][filters][0][field]=name
&searchCriteria[filter_groups][0][filters][0][value]=%sample%
&searchCriteria[filter_groups][0][filters][0][condition_type]=like
you are looking for the sortOrders. Ex.: searchCriteria[sortOrders][0][field]=name. You can even add the sort direction, for example DESC, with searchCriteria[sortOrders][0][direction]=DESC.
Use the category_id field and the eq condition type. Ex.: if you want products from category 10: searchCriteria[filter_groups][0][filters][0][field]=category_id&
searchCriteria[filter_groups][0][filters][0][value]=10&
searchCriteria[filter_groups][0][filters][0][condition_type]=eq
use searchCriteria[pageSize]. Ex.: 20 products starting from the 40th, equivalent in SQL to LIMIT 20 OFFSET 40: &searchCriteria[pageSize]=20&searchCriteria[currentPage]=3
Of course you can perform AND and OR operations with filters.
[
"filter_groups": [
{
"filters": [
{
"field": "type_id",
"value": "simple",
"condition_type": "eq"
}
]
},
{
"filters": [
{
"field": "category_id",
"value": "611",
"condition_type": "eq"
}
]
}
],
"page_size": 100,
"current_page": 1,
"sort_orders": [
{
"field": "name",
"direction": "ASC"
}
]
]

Does the OData protocol provide a way to transform an array of objects to an array of raw values?

Is there a way specify in an OData query that instead of certain name/value pairs being returned, a raw array should be returned instead? For example, if I have an OData query that results in the following:
{
"#odata.context": "http://blah.org/MyService/$metadata#People",
"value": [
{
"Name": "Joe Smith",
"Age": 55,
"Employers": [
{
"Name": "Acme",
"StartDate": "1/1/1990"
},
{
"Name": "Enron",
"StartDate": "1/1/1995"
},
{
"Name": "Amazon",
"StartDate": "1/1/1999"
}
]
},
{
"Name": "Jane Doe",
"Age": 30,
"Employers": [
{
"Name": "Joe's Crab Shack",
"StartDate": "1/1/2007"
},
{
"Name": "TGI Fridays",
"StartDate": "1/1/2010"
}
]
}
]
}
Is there anything I can add to the query to instead get back:
{
"#odata.context": "http://blah.org/MyService/$metadata#People",
"value": [
{
"Name": "Joe Smith",
"Age": 55,
"Employers": [
[ "Acme", "1/1/1990" ],
[ "Enron", "1/1/1995" ],
[ "Amazon", "1/1/1999" ]
]
},
{
"Name": "Jane Doe",
"Age": 30,
"Employers": [
[ "Joe's Crab Shack", "1/1/2007" ],
[ "TGI Fridays", "1/1/2010" ]
]
}
]
}
While I could obviously do the transformation client side, in my use case the field names are very large compared to the data, and I would rather not transmit all those names over the wire nor spend the CPU cycles on the client doing the transformation. Before I come up with my own custom parameters to indicate that the format should be as I desire, I wanted to check if there wasn't already a standardized way to do so.
OData provides several options to control the amount of data and metadata to be included in the response.
In OData v4, you can add odata.metadata=minimal to the Accept header parameters (check the documentation here). This is the default behaviour but even with this, it will still include the field names in the response and for a good reason.
I can see why you want to send only the values without the fields name but keep in mind that this will change the semantic meaning of the response structure. It will make it less intuitive to deal with as a json record on the client side.
So to answer your question, The answer is 'NO',
Other options to minimize the response size:
You can use the $value OData option to gets the raw value of a single property.
Check this example:
services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City/$value
You can also use the $select option to cherry pick only the fields you need by selecting a subset of properties to include in the response