I'm modeling a process at a given time and want to assign a User Task to the user who created the instance of the process.
What should I put in my User Task "Assignee" field?
Thank you in advance
We solve this by setting a "startedBy" process variable on process start. Then, just use the variable value in the Assignee field: ${startedBy}.
You will have to modify your process start to get the logged in user. This can either be done by passing the variable to the "startProcessByKey" ... method or implementing a Listener on the start event that tries to get the user from the current session.
end listener on the start event works fine:
<camunda:executionListener expression="${execution.setVariable('startedBy', authenticatedUserId)}" event="end" />
We can set the process initiator through IdentityService.
public void test(){
//start process
identityService.setAuthenticatedUserId(userId);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
//query
historyService.createHistoricProcessInstanceQuery().startedBy(userId).list()
}
Related
I am trying to use the Hangfire Filter and ILogger.BeginScope to log the correlation id. The requirement is that each job execution will have its own correlation id so that it's easier to group the logs of the same job execution together if something happens.
My approach is that in IServerFilter.OnPerforming method, I first create a GUID, then using below code to begin the scope
logger.BeginScope(new FormattedDictionary<string, object>
{
["CorrelationId"] = correlationId
})
The subsequent log statements in the method IServerFilter.OnPerforming will have correlation id attached. But unfortunately, during job execution, the log statement won't have the correlation id scope. The ILogger instance of the job class is resolved using constructor. And the ILogger instance of the method IServerFilter.OnPerforming is resolved using a IServiceProvider.GetRequiredService method
I am wondering why so? And how can we fix this issue? I am open to other approaches of implementing logging correlation id as long as it works.
Finally figured it out. The reason being that when the local IDisposable in IServerFilter.OnPerforming created by a local ILogger instance are out of scope, since nothing reference it again, after a while, GC will collect it and thus the locally created scope will be lost. The solution is simple, using AsyncLocal<ILogger> instance on the filter to hold a reference to the created scope and only dispose it after the job finishes
I have a requirement where I need to set assignee's to all the "user-tasks" in a process instance as soon as the instance is created, which is based on the candidate group set to the user-task.
i tries getting the user-tasks using this :
Collection<UserTask> userTasks = execution.getBpmnModelInstance().getModelElementsByType(UserTask.class);
which is correct in someway but i am not able to set the assignee's , Also, looks like this would apply to the process itself and not the process instance.
secondly , I tried getting it from the taskQuery which gives me only the next task and not all the user-tasks inside a process.
Please help !!
It does not work that way. A process flow can be simplified to "a token moves through the bpmn diagram" ... only the current position of the token is relevant. So naturally, the tasklist only gives you the current task. Not what could happen after ... which you cannot know, because if you had a gateway that continues differently based on the task outcome? So drop playing with the BPMN meta model. Focus on the runtime.
You have two choices to dynamically assign user tasks:
1.) in the modeler, instead of hard-assigning the task to "a-user", use an expression like ${taskAssignment.assignTask(task)} where "taskAssignment" is a bean that provides a String method that returns the user.
2.) add a taskListener on "create" to the task and set the assignee in the listener.
for option 2 you can use the camunda spring boot events (or the (outdated) camunda-bpm-reactor extension) to register one central component rather than adding a listener to every task.
I want to re-configure AR session after session has been running. I want to change Augmented Images database.
I don't seem to find a way to set the reset the session configuration.
getSessionConfiguration(Session session)
This function only seems to be called once at the beginning.
Is there a way to re-configure? Should I not be using the fragment?
I make changes to my config on the fly. You can accomplish this by extending ARFragment and having access to the config or simply be accessing the ARFragment from your xml within your activity. Here is an example.
arSceneView.session?.apply {
val changedConfig = config
changedConfig.planeFindingMode = Config.PlaneFindingMode.HORIZONTAL_AND_VERTICAL
configure(changedConfig)
}
That's it, just call configure(myNewConfig) and it will update it for you.
Of course in this example, I get the current config, modify it and put it back, but you could replace it if preferred.
I am very new to Activiti BPMN. I am creating a flow diagram in activiti. I m looking for how username (who has completed the task) can be pass into shell task arguments. so that I can fetch and save in db that user who has completed that task.
Any Help would be highly appreciated.
Thanks in advance...
Here's something I prepared for Java developers based on I think a blog post I saw
edit: https://community.alfresco.com/thread/224336-result-variable-in-javadelegate
RESULT VARIABLE
Option (1) – use expression language (EL) in the XML
<serviceTask id="serviceTask"
activiti:expression="#{myService.toUpperCase(myVar)}"
activiti:resultVariable="myVar" />
Java
public class MyService {
public String toUpperCase(String val) {
return val.toUpperCase();
}
}
The returned String is assigned to activiti:resultVariable
HACKING THE DATA MODEL DIRECTLY
Option (2) – use the execution environment
Java
public class MyService implements JavaDelegate {
public void execute(DelegateExecution execution) throws Exception {
String myVar = (String) execution.getVariable("myVar");
execution.setVariable("myVar", myVar.toUpperCase());
}
}
By contrast here we are being passed an ‘execution’, and we are pulling values out of it and twiddling them and putting them back.
This is somewhat analogous to a Servlet taking values we are passed in the HTMLRequest and then based on them doing different things in the response. (A stronger analogy would be a servlet Filter)
So in your particular instance (depnding on how you are invoking the shell script) using the Expression Language (EL) might be simplest and easiest.
Of course the value you want to pass has to be one that the process knows about (otherwise how can it pass a value it doesn't have a variable for?)
Hope that helps. :D
Usually in BPM engines you have a way to hook out listener to these kind of events. In Activiti if you are embedding it inside your service you can add an extra EventListener and then record the taskCompleted events which will contain the current logged in user.
https://www.activiti.org/userguide/#eventDispatcher
Hope this helps.
I have used activiti:taskListener from activiti app you need to configure below properties
1. I changed properties in task listener.
2. I used java script variable for holding task.assignee value.
Code Snip:-
I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}
I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.
Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.