public void executeRules(IlrRule[] rules){
IlrRuleset rulesetNew = new IlrRuleset();
IlrContext ctxt = new IlrContext(rulesetNew);
IlrTask task = ruleset.getTask("ExecFlow#exe");
IlrRuleTaskRunner runner = ctxt.getRuleTaskRunner(task);
runner.setActiveRules(rules);
int fired = 0;
runner.runInitialActions();
fired += runner.runBody();
runner.runFinalActions();
}
How we can create a dynamic ruleset from group of rules? this group is a dynamic.
I am using IBM ODM 8.0.1
Just be careful with dynamic selects. If you have a lot of rules, it can increase the execution time of the rule set significantly.
body = dynamicselect() {
return selectedFunction(context.getRuleset().allRules);
}
Is sufficient to custom the rules which you like to executed.
All Java implementation are disappeared, we used irl language, this is the solution :
We defined the scope and we select the rules dynamically
scope= {exe.R05,exe.R04,exe.R03}
body = dynamicselect() {
return selectedFunction(context.getRuleset().allRules);
}
Related
I have just started using durable functions and needs some advise for how to do fan out pattern correctly. I have a FTP server where from I read all the files. I want to start an Activity function for each file. As I understand it the orchestrator function will be called everytime an Activity function is being executed. I just want to read the files once. To avoid calling the code that read the files and starts the activity functions multiple times, what is the recommended approach? Is it having an activity function that that add's all the activity functions or is it using the IsReplaying property, or something different?
[FunctionName("OrchestrationMoveFilesToBlob")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
if (!context.IsReplaying)
{
// Do you call your database here and make a call to CallActivityAsync for each row?
}
// doing it here is properly very wrong as it will be called multiple times
var tasks = new Task<string>[7];
for (int i = 0; i < 7; i++)
{
tasks[i] = context.CallActivityAsync<string>("E2_CopyFileToBlob",""); }
await Task.WhenAll(tasks);
return outputs;
}
When looking into the sample in the link below this actually calls it directly in the orchestrator function? Is this not really bad? It continue adding same activities again and again .... ?
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-cloud-backup
Not sure I understand what you try to achieve but your code looks not bad so far. An orchestration is just called once (and maybe some times more for replay but this is not your problem here). From your orchestration you can call in a fan out all your activity functions (gathering a file from an ftp) each activity function one file. await Task.WhenAll(tasks) is your fan in. (you can use a List<Task> instead of the array and call .Add(task) on it if you want. In order to not edit your code I copied it here and added some comments and questions (feel free to edit here):
[FunctionName("OrchestrationMoveFilesToBlob")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
if (!context.IsReplaying)
{
// just needed for things that should not happen twice like logging....
}
// if your work isn't a fixed list just call an activity
// which replies with the list of work here (e.g. list of filenames)
var tasks = new Task<string>[7]; // can be a List<Task> too
for (int i = 0; i < 7; i++)
{
tasks[i] = context.CallActivityAsync<string>("E2_CopyFileToBlob","");
}
await Task.WhenAll(tasks);
return outputs; // currently an empty list. What do you want to give back?
}
Is it possible to generate different databases according to a specific parameter?
My final goal is john.domain.com => create john db, paul.domain.com => create paul db
How could I achieve this using EF6 code first, MVC5? Could model first do it?
Yes you can change the connection string at runtime, something like.
Need to add reference to System.Data.
public static class ConnectionStringExtension
{
public static void ChangeDatabaseTo(this DbContext db, string newDatabaseName)
{
var conStr = db.Database.Connection.ConnectionString;
var pattern = "Initial Catalog *= *([^;]*) *";
var newConStr = Regex.Replace(conStr, pattern, m =>
{
return m.Groups.Count == 2
? string.Format("Initial Catalog={0}", newDatabaseName)
: m.ToString();
});
db.Database.Connection.ConnectionString = newConStr;
}
}
Usage.
using (var db = new AppContext())
{
// Uses it just before any other execution.
db.ChangeDatabaseTo("MyNewDatabase");
}
I have a method to retrieve configuration details from a table MyConfiguration. The code currently being used is:
Query query;
QueryRun queryRun;
QueryBuildDataSource qbds;
MyConfiguration config;
int rowCount;
query = new Query();
qbds = query.addDataSource(tableNum(MyConfiguration));
queryRun = new QueryRun(query);
rowCount = SysQuery::countTotal(queryRun);
The table has 0 or 1 rows; there is an if statement of what process to use if there are configuration settings or to use the defaults.
Issue
Although there is a row in the table the query is intermittently returning 0 rows.
Update
Thanks to David's input I have simplified the code:
MyConfiguration config;
select firstOnly useSettings, firstField, secondField from config;
// This wasn't included in the original example, but demonstrates how it's used.
if(config){
// These variables are defined in classDeclaration
useCustom = config.useSettings;
first = config.firstField;
second = config.secondField;
}
else
{
// No custom configuration, use defaults.
useCustom = 0;
}
This code is in a method that is called when the primary method is called to find the configuration to be used.
When I run my test methods in the development environment all the tests pass (the configuration is being read for each test). However when the primary method is called from a button's click event the select isn't returning anything (I've checked this in the debugger). This causes the application to run using the defaults instead of the configured values. If I manually, in the debugger, move the execution past the if the second select also doesn't return any values.
Both the test and the form execute the method in the same way, but are getting different results from the select statement.
Your code looks right.
However the following may be easier to work with and debug
MyConfiguration config;
int rowCount;
;
select firstonly config;
if(config)
{
//Record exists
}
else
{
//Record does not exist
}
I am having a problem with transaction in Grails. I want to save a list of object to DB by a checking condition at each object. All these process I want to put to one transaction, it means if the k-th object does not satisfied the checking condition, all previous objects (from the first object to the (k-1)th one) will be rolled back from DB. Here is my example:
static transactional = true
public void saveManyPeople() {
// ...
List<People> peoples = new ArraysList();
for(i = 0, i < n, i++) {
People newPeople = createPeopleFromRawData(); // return a people object in memory
if(<checking-condition>) {
newPeople.save(flush : false)
} else {
throw new MyCustomizedException() // MyCustomizedException has extended from RuntimException
}
}
// ...
}
As you may see, I set transactional variable to true and I've tried to use flush : true and flush : false, but it didn't work as I want. I've read this article Rolling back a transaction in a Grails Service
And the author recommended that the service method should throw a RuntimeException then the process will be rollbacked. But if I want to throw another exception, so what I have to do?
Could you please give me some suggestions on this problem?
Thank you so much!
You can throw any exception that extends from RuntimeException to rollback the transaction. Or you can use Programmatic Transactions, using withTransation, to have more control over the transaction.
Could you verify that saveManyPeople() is within a Service and not a Controller?
The static transactional = true isn't respected in a Controller. I am suspecting that this is the issue.
If you need to have transactional support with the controller, you could always use DomainClass.withTransaction. Reference Documentation
Example:
Account.withTransaction { status ->
def source = Account.get(params.from)
def dest = Account.get(params.to)
def amount = params.amount.toInteger()
if(source.active) {
source.balance -= amount
if(dest.active) {
dest.amount += amount
}
else {
status.setRollbackOnly()
}
}
}
I am using asp.net mvc for an application. I've taken some guidance from Rob Conery's series on the MVC storefront. I am using a very similar data access pattern to the one that he used in the storefront.
However, I have added a small difference to the pattern. Each class I have created in my model has a property called IsNew. The intention on this is to allow me to specify whether I should be inserting or updating in the database.
Here's some code:
In my controller:
OrderService orderService = new OrderService();
Order dbOrder = orderService.GetOrder(ID);
if (ModelState.IsValid)
{
dbOrder.SomeField1 = "Whatever1";
dbOrder.SomeField2 = "Whatever2";
dbOrder.DateModified = DateTime.Now;
dbOrder.IsNew = false;
orderService.SaveOrder(dbOrder);
}
And then in the SQLOrderRepository:
public void SaveOrder(Order order)
{
ORDER dbOrder = new ORDER();
dbOrder.O_ID = order.ID;
dbOrder.O_SomeField1 = order.SomeField1;
dbOrder.O_SomeField2 = order.SomeField2;
dbOrder.O_DateCreated = order.DateCreated;
dbOrder.O_DateModified = order.DateModified;
if (order.IsNew)
db.ORDERs.InsertOnSubmit(dbOrder);
db.SubmitChanges();
}
If I change the controller code so that the dbOrder.IsNew = true; then the code works, and the values are inserted correctly.
However, if I set the dbOrder.IsNew = false; then nothing happens...there are no errors - it just doesn't update the order.
I am using DebuggerWriter here: http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11 to trace the SQL that is being generated, and as expected, when the IsNew value is true, the Insert SQL is generated and executed properly. However, when IsNew is set to false, there appears to be no SQL generated, so nothing is executed.
I've verified that the issue here (LINQ not updating on .SubmitChanges()) is not the problem.
Any help is appreciated.
In your SaveOrder method you are always creating a new ORDER object. You need to change this so that if order.IsNew is false, it retrieves the existing one from the DB and updates it instead.
public void SaveOrder(Order order)
{
ORDER dbOrder;
if (order.IsNew)
{
dbOrder = new ORDER();
dbOrder.O_ID = order.ID;
}
else
{
dbOrder = (from o in db.ORDERS where o.O_ID == order.ID select o).Single();
}
dbOrder.O_SomeField1 = order.SomeField1;
dbOrder.O_SomeField2 = order.SomeField2;
dbOrder.O_DateCreated = order.DateCreated;
dbOrder.O_DateModified = order.DateModified;
if (order.IsNew)
db.ORDERs.InsertOnSubmit(dbOrder);
db.SubmitChanges();
}
I think you have the problem that your entity is detached from your context.
You should try to attach your entity back to your context if you want to update. The downside of LINQtoSQL is that for the re-attachment you'll need the original state of the object when it was detached...
Another solution is to re-get your entity from the context and copy all the data from your entity in the parameter. This will do until you'll have more complex entities.
What tvanfosson said.
I would just like to add that I use logic where if Id equals default(0 or Empty if using guids), then I assume it is new. Otherwise if I have the id passed in, then I go get the existing object and update it.