Asynchron programatically access

  • 15 February 2007
  • 7 replies
  • 1 view

Badge +2
Hi

I have some people from K2 here with me, and have asked the same question to them.
They suggest to solve the problem by messagequeue. Where my system process add a message to the queue when the event occurs, and the K2 workflow waits and listenes to the queue.

I will now try this and report back how this works.

Arne

7 replies

Badge +2
I'm new to the K2.Net, but I have created a few sucessfull processes.

Now I need to make a process that is started programatically, and all steps are solved programatically by updating a status field in the process.

I'm using K2ROM to access the process, but I have a concern. Since I'm only using programaticaly access I do not have any destination rule, I'm also unsure of witch event to use. (I have selected the Defaul Client )

so my pseudocode solution is:

//start the workflow
Connection conn = new Connection();
conn.Open("nokrs01app10");
ProcessInstance proc = conn.CreateProcessInstance("PorteringDanmark");
proc.DataFields["msisdn"].Value = message.Msisdn;
proc.DataFields["newmsisdn"].Value = message.NewMsisdn;
conn.StartProcessInstance(proc);
peristentstore = proc.ID;


Here I will store the pro
after some processing i want my application to do the following

Connection conn = new Connection();
conn.Open("nokrs01app10");
ProcessInstance proc = conn.OpenProcessInstance(persistenstore);
//something like this
proc.Datafields["Status"] = "Created"
proc.update() //process should move to next step.


Any ideas on how to solve this?

Arne
Badge +9
Below is an excerpt from a document (with code sample) I wrote describing how to do essentially the same thing but betwen Activities (as opposed to from the Start Process) within an ASP.NET page. I think you should be able to easily leverage this in your situation where you are using the StartProcessInstance() method...

Please pay special attention to the discussion of the boolean Sync parameter of the StartProcessInstance() and Finish() methods.

Generally what needs to occur is that when the first worklist item is programmatically finished, it must be finished with the Synchronous flag set to true ( WorklistItem.Finish(true); ); This will instruct K2ROM to block the return of execution focus back to the calling code until the K2 process has hit a stop point (such as a new client event or the end of the process). Please note, in order for this technique to work successfully, the true flag MUST be set within the Finish(), otherwise K2 will execute asynchronously and return execution almost immediately to the calling application. Otherwise there is no way to guarantee that the new WorklistItem will exist within K2 by the time the calling application looks for it.

Please keep in mind that even though execution will be returned when the next client event is reached, the application code will still only have a handle to the previous, finished WorklistItem object; NOT the new task. As such, the new WorklistItem must be retrieved. To do this, the Process Instance ID (the unique identifier for this specific process instance within the K2 system) is retrieve from the existing WorklistItem object and used as the basis of a filtered Worklist search (via the WorklistCritera object and OpenWorklist() method). This will return all the WorklistItems for the connected user for this specific process instance. The returned Worklist collection can than be interrogated to find the appropriate WorklistItem object.

Once the new WorklistItem object is located it can be used to either repopulate portions of the current ASP.NET page (as is done in this example), or can be used to redirect to a different page (via the WorklistItem.Data property)

One additional note, as done in this specific example, when the same page is being used to handle multiple WorklistItems the developer can not always rely on the Serial Number within the page s query string, as that will always contain the original WorklistItem s serial number. As such, this example caches the Serial Number within a hidden field on the page. On the initial page load the Serial Number is recovered from the hidden field and stored within the hidden field. When the new WorklistItem is located after the synchronous call, the new Serial Number is cached back to this hidden field. Whenever a Serial Number is needed in the code, it is retrieved from this hidden field, not from the query string.






.Value = TextBox1.Text;

// finish this task
oWli.Finish();

// disable the button for this example
this.btnFinish.Enabled = false;
}

// close the k2rom connection
oConn.Close();
}

Badge +13
I do not believe you can continue/pick up where you left off after CreateProcessInstance and have NOT used StartProcessInstance.
Badge +2
BOB:

Thanks for the example, but this still leaves the question about user credentials, I use a system process, so then I need to have a system user with my AD and give it create permissions? Or is there another way?


Peter: I do not understand what you mean. I use the Start method. Should I have used it another way? Please submit a code sample, so I can understand what you mean.

Regards

Arne
Badge +9
Arne,

I'm not exactly sure by what you mean by a "system process". Do you mean that you want to start the process instance via a utility that is running under the K2 service account? If so, then yes, that AD service account must be granted start permissions on the process just like any other user. The K2 service account has no special ability to start processes.

I think a code sample that characterizes what Peter is referring too is below. Take note that once you call CreateProcessInstance (which only returns an object... it does not yet existin within K2), you must eventually call StartProcessInstance() in order for K2 to begin processing the instance.

.Value = "some value here";
conn.StartProcessInstance(proc, true);
conn.Close();


Badge +13
I think arnejohe wants to do this:

SourceCode.K2ROM.Connection conn = new SourceCode.K2ROM.Connection();
conn.Open("nokrs01app10");
SourceCode.K2ROM.ProcessInstance proc = conn.CreateProcessInstance("PorteringDanmark");

Application exits.... wait for 3 days.... then somehow reconnect to the old object to call StartProcessInstance to actually starts the process. I don't think that's possible?

proc.DataFields["msisdn"].Value = "some value here";
conn.StartProcessInstance(proc, true);
conn.Close();
Badge +2
The pseudocode for the solution

In the asynchronus waitingstate, add an server event.
Set synchronus = false;
add K2.serialnumber to a datafield value

On the external server, keep the process id when you start the process.
Use the process id to locate the active process.
Retrive the serialnumber from the datafield
Open item with serialnumber
Finish item.

This gives a problem if the process is split into two parallell runs, where both has a asynchron access, but can be solved with seperate serialnumber datafields.

Reply