How to set custom property to business rules in (ILOG) IBM ODM - business-rules

I have a requirement to set a new property (example: unique ID) to each and every rule and access it from action part of the respective rules during the execution.
For example:
If
the age of person is more than 18
then
set the output to the ID of the rule.
(Here ID should come from the new property being added.)
I am using IBM ODM 8.5. Please suggest what are all the ways get unique ID from business rules?
In the B2X mapping of virtual method, I printed the rule.properties map using instance.getRule().properties. I was expecting custom properties and all other rule properties. However, the properties map only had a handful of following six:
key: ilog.rules.business_name value: test score
key: ilog.rules.package_name value: check score
key: requestorMail value:
key: status value: new
key: ilog.rules.package value: check_score
key: ilog.rules.group value: check_score.test_score

You can customize rule model with Model extension and add your custom property (YOUR_PROPERTY_NAME) to the rule artefact.
You can acces this by adding a virtual method (static method in the BOM! don't use a xom! simply add it with the BOM editor) verbalized YOUR_VERBALISATION.
In the method implementation (B2X), you can get the value with the instance.getRule().getPropertyValue("YOUR_PROPERTY_NAME"); (instance is a runtime variable containing the IlrRuleInstance of the current Rule)
In the action part use YOUR_VERBALISATION to call the method.

Another approach you could use is to create your set of variables (Variable Set). Within a Variable Set you define:
The name of the variable
The type of the variable
The verbalization for this variable
(Optional) The initial value for this variable
It's easy to create and it's accessible to any part of you Rule Application or Module.
Hope this helps.

Related

EdgeDB efficiently writing many to one functions using link

I am trying to make a one to many links where a user can put in multiple addresses after their name. For example the data can look like this:
name: "Robert Cane"
address:
location: 555 Fake Street
description: Primary address
is_residence: True
location: 123 Foobar Ave.
description: Mailing address
is_residence: False
There are two ways I can do this. Is it better to setup the database this way (similar to writing tables for SQL databases):
type Address {
required property location -> str;
description -> str;
is_residence ->bool;
}
type Person {
required property name -> str;
required multi link address -> Address{
constraint exclusive;
}
}
or this way using the properties inside the multi link (similar to a relationship inside a Graph database). Also note that this is a single, optional entry according to the docs:
type Address {
required property location -> str;
is_residence -> bool;
}
type Person {
required property name -> str;
required multi link address -> Address{
property description -> str;
constraint exclusive;
}
}
My question is are there best practices to do this? Is doing it one way more advantageous in query speed over the other?
Given that "address" is a one-to-many link there is no meaningful distinction between a property of the link and a property of the target object ("Address" in this case) because every target can only be linked at most once. In this situation using a link property is not necessary and not advisable because the same property on the "Address" is going to be easier to access, update, cast into JSON, etc.
Usually you want to use link properties with many-to-many links. In that case there is a significant distinction between the relationship described by the link and the object being linked. You can have multiple different links with different link property values linking to the same target object.
So if you wanted to re-use the same "Address" object for multiple people, then you'd want to put "description" into a link property (what's "home" for one Person is "grandma's house" for another). Incidentally, this scenario makes sense if you expect addresses to be shared and avoiding duplication is useful both for consistency of data and for performance.

apollo-server - Conditionally exclude fields from selection set

I have a situation where I would like to conditionally exclude a field from a query selection before I hit that query's resolver.
The use case being that my underlying API only exposes certain 'fields' based on the user's locale, and calls made to this API will throw errors if fields are requested that are not included of that locale.
I have tried an approach with directives,
type Person {
id: Int!
name: String!
medicare: String #locale(locales: ["AU"])
}
type query {
person(id: Int!): Person
}
And using the SchemaDirectiveVisitor.visitFieldDefinition, I override field.resolve for the medicare field to return null when the user locale doesn't match any of the locales defined on the directive.
However, when a client with a non "AU" locale executes the following
query {
person(id: 111) {
name
medicareNumber
}
}
}
the field resolver for medicare is never called and the query resolver makes a request to the underlying API, appending the fields in the selection set (including the invalid medicareNumber) as query parameters. The API call returns an error object at this point.
I believe this makes sense as it seems that the directive resolver is on the FieldDefinition and would only be called when the person resolver returns a valid result.
Is there a way to achieve this sort of functionality, with or without directives?
In general, I would caution against this kind of schema design. As a client, if I include a field in the selection set, I expect to see that field in the response -- removing the field from the selection set server-side goes against the spec and can cause unnecessary confusion (especially on a larger team or with a public API).
If you are examining the requested fields in order to determine the parameters to pass to your API call, then forcing a certain field to resolve to null won't do anything -- that field will still be included in the selection set. In fact, there's really no way to create a schema directive that will impact the selection set of a request.
The best approach here would be to 1) ensure any potentially-null fields are nullable in the schema and 2) explicitly filter the selection set wherever your selection-set-to-parameters logic is.
EDIT:
Schema directives won't show up as part of the schema object returned in the info, so they can't be used as flags. My suggestion would be to maintain a separate in-memory map. For example:
const fieldsByLocale = {
US: {
Person: ['name', 'medicareNumber'],
},
AU: {
Person: ['name'],
},
}
then you could just access the appropriate list to filter with fieldsByLocale[context.locale][info.returnType]. This filtering logic is specific to your data source (in this case, the external API), so this is a bit cleaner than "polluting" the schema with information that pertains to the storage layer. If the APIs change, or you switch to a different source for this information altogether (like a database), you can update the resolvers without touching your type definitions. In fact, this way, the filtering logic can easily live inside a domain/service layer instead of your resolvers.

GCP SPANNER: What options can be set on a column in table other than allow_commit_timestamp=true for timestamp datatype

I want to understand what properties can be set on a Column in Spanner table. I only see length, not null, allow_commit_timestamp=true (for timestamp).
Do we have any options like:
- Unique property - so that record insert gives an error if another record has the same value (not same as not null)
- Default value or bounded list - if not provided by application layer or for validation
- Comments: like a short description of that column and who created it
My impression is that all these are not available in SPANNER for a column and has to be handled in the business layer. Can someone confirm!
Unique Property: Cloud spanner does support unique indexes. We can create unique index on the column that we want to enforce uniqueness.
Default values: Cloud Spanner doesn't allow any default value to be specified regardless of type. This means the implicit default is Null, or Error, depending on whether to column was specified with NOT NULL.
Comments: This isn't supported currently.
CREATE UNIQUE INDEX table_name_index
ON table_name(column)

Configuring a picklist in CRM Online 2015

We currently have a CRM Dynamics 4.0 system and as part of our Account Entity we have a field new_accountstatus with the following set up:
Schema
Display Name: Account Status
Name: new_accountstatus
Requirement Level: No Constraint
Searchable: Yes
Description: "V1.0"
Type
Type: Picklist
Overdiew 2. Active 3. Suspended 4.De-Energise 5.Terminated 6.Inactive
Default Value: Unassigned Value
We are contemplating upgrading and moving to CRM Online 2015 and have created an online trial and as part of the initial configuration we are trying to set up account model and the picklist with similar values and layout.
On creating a new field in CRM 2015 online I can see that the Data Type fields have completely changed. And from the available list Option Set was seemed the most relevant for my needs.
Can anyone explain to me what the Field Type of Simple and Calculated is all about? Also if I try to enter the same values as was in our old system of between 1-6 I get the message:
"The option value you specified does not use this solution's option value prefix (10,000). You should enter a number between 100,000,000 and 100,009,999"
If I enter this as 10,000,001 will this then be read as 1 from the option set as would have been the case in dynamics 4.0 picklist?
The type you need for your picklist is Option Set.
From CRM 2011 you can choose between local and global (existing) Option Set. If your picklist is used only inside account entity you can create it as local, if it is used in more than one entity (or you plan in the future that this is a possibility) you can create it as global, in order to be reused.
The difference between Simple and Calculated is a feature introduced with CRM 2015, in your case you need Simple (Calculated is in case the value becomes from a calculation, more details here: http://blogs.technet.com/b/lystavlen/archive/2014/11/20/calculated-fields-new-in-crm-2015.aspx)
Regarding the value (1-6). CRM 2011 introduced the concept of Solutions and Publishers, each Publisher can have an Option Set prefix (10000 is the value for the Default Publisher) in order to differentiate Option Set coming from different solutions.
You can still override the prefix, so you can put the values 1-6 if you prefer, the use of the prefix is suggested but not mandatory. the value 100,000,001 is different from 1, so (considering backward compatibility with external system) you should put 1 as value.

Why does a Web Service DataMember's Specified Attribute need to be set for int and Data but not for String

I have created a web service via WCF. Then I exposed it as a web service to make it usable with a .NET 2.0 application. I created some DataContract with DataMember that could be used for by the exposed OperationContract.
I notice that when I try to create DataClass to be passed in the web service that each DataContract attribute now has a partner "Specified" attribute for each member.
For example:
[DataContract]
public class Sales
{
[DataMember]
public int InvoiceNo;
...
}
When I create an instance of Sales in the web service client. I get attribute named InvoiceNo and InvoiceNoSpecified.
Now here is my question, when the attribute is of type string, I do not need to set the corresponding "Specified" attribute to true, but when the attribute type is a int or DateTime, if I do not set the corresponding "Specified" attribute to true, the value becomes null in the web service host. Is there a way to avoid setting the Specified attribute? Cause I need to call the web service functions in a lot of places in my code. It would really be difficult to keep track of them all.
The default parameters for the DataMember attribute are:
bool EmitDefaultValue (default true)
bool IsRequired (default false)
If the property you are exposing is a non-nullable value type you should use:
[DataMember(IsRequired = true)]
public int InvoiceNo;
You could read the explanation here.
Quote from XmlSerializer:
If a schema includes an element that
is optional (minOccurs = '0'), or if
the schema includes a default value,
you have two options. One option is to
use
System.ComponentModel.DefaultValueAttribute
to specify the default value, as shown
in the following code. Another option
is to use a special pattern to create
a Boolean field recognized by the
XmlSerializer, and to apply the
XmlIgnoreAttribute to the field. The
pattern is created in the form of
propertyNameSpecified. For example, if
there is a field named "MyFirstName"
you would also create a field named
"MyFirstNameSpecified" that instructs
the XmlSerializer whether to generate
the XML element named "MyFirstName".
The only acceptable for me workaround I've come so far is to use XmlSerializer instead of DataContractSerializer by using XmlSerializerFormatAttribute.
Also you can use [DataMember(isRequired=True)]