how can i get the full user list of an actor in groovy script ?
Trying this in a email connector in the "to" field using Groovy I get the following error:
unable to resolve class com.bonitasoft.engine.api.ProcessAPI
on line:
import com.bonitasoft.engine.api.ProcessAPI;
My code *should* be what is posted above:
import org.bonitasoft.engine.bpm.actor.ActorCriterion;<br />
import org.bonitasoft.engine.bpm.actor.ActorMember;<br />
import org.bonitasoft.engine.identity.User;<br />
import org.bonitasoft.engine.identity.UserCriterion;<br />
import org.bonitasoft.engine.identity.UserSearchDescriptor;<br />
import org.bonitasoft.engine.search.SearchOptionsBuilder;<br />
import org.bonitasoft.engine.api.ProcessAPI;<br />
<br />
IdentityAPI identityAPI = apiAccessor.getIdentityAPI();<br />
ProcessAPI processAPI = apiAccessor.getProcessAPI();<br />
long actorId = processAPI.getActors(processDefinitionId, 0, 1, ActorCriterion.NAME_ASC).get(0).getId();<br />
List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);<br />
boolean hasMore = true;<br />
int pageSize = 2;<br />
int shift = 0;<br />
while (hasMore) { List<ActorMember> page = processAPI.getActorMembers(actorId, shift, pageSize);<br />
hasMore = actorMembers.addAll(page);<br />
shift += pageSize;<br />
}<br />
List<User> users = new ArrayList<User>();<br />
for (ActorMember actorMember : actorMembers) { long userId = actorMember.getUserId();<br />
long roleId = actorMember.getRoleId();<br />
long groupId = actorMember.getGroupId();<br />
if (userId > 0 && roleId < 0 && groupId < 0) { // user is directly associated to the actor: users.add(identityAPI.getUser(userId));<br />
} else if (userId < 0 && roleId > 0 && groupId < 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).done()).getResult());<br />
} else if (userId < 0 && roleId < 0 && groupId > 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.GROUP_ID, groupId).done()).getResult());<br />
} else if (userId < 0 && roleId > 0 && groupId > 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers( new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).filter(UserSearchDescriptor.GROUP_ID, groupId).done()) .getResult());<br />
} }<br />
return users;
I don't know much about groovy. I am guessing that the script is trying to return an arrayList called users when the "to" field is expecting string? The error in my studio execution engine is:
Feb 15, 2014 10:05:09 PM org.bonitasoft.engine.log.technical.TechnicalLoggerSLF4JImpl log
WARNING: Exception was:Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors
org.bonitasoft.engine.expression.exception.SInvalidExpressionException: Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors
at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.checkReturnType(ExpressionServiceImpl.java:157)
at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.evaluate(ExpressionServiceImpl.java:99)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionWithResolvedDependencies(ExpressionResolverServiceImpl.java:150)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionsFlatten(ExpressionResolverServiceImpl.java:109)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluate(ExpressionResolverServiceImpl.java:72)
at org.bonitasoft.engine.core.connector.impl.ConnectorServiceImpl.evaluateInputParameters(ConnectorServiceImpl.java:326)
at org.bonitasoft.engine.connector.ConnectorServiceDecorator.evaluateInputParameters(ConnectorServiceDecorator.java:105)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:183)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:147)
at org.bonitasoft.engine.transaction.JTATransactionServiceImpl.executeInTransaction(JTATransactionServiceImpl.java:207)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork.work(ExecuteConnectorWork.java:119)
at org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork.work(FailureHandlingBonitaWork.java:72)
at org.bonitasoft.engine.work.BonitaWork.run(BonitaWork.java:56)
at org.bonitasoft.engine.work.SequenceRunnableExecutor.innerRun(SequenceRunnableExecutor.java:45)
at org.bonitasoft.engine.work.BonitaRunnable.run(BonitaRunnable.java:35)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)Feb 15, 2014 10:05:09 PM org.bonitasoft.engine.log.technical.TechnicalLoggerSLF4JImpl log
WARNING: Error while executing connector with id 6
org.bonitasoft.engine.expression.exception.SInvalidExpressionException: Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors
at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.checkReturnType(ExpressionServiceImpl.java:157)
at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.evaluate(ExpressionServiceImpl.java:99)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionWithResolvedDependencies(ExpressionResolverServiceImpl.java:150)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionsFlatten(ExpressionResolverServiceImpl.java:109)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluate(ExpressionResolverServiceImpl.java:72)
at org.bonitasoft.engine.core.connector.impl.ConnectorServiceImpl.evaluateInputParameters(ConnectorServiceImpl.java:326)
at org.bonitasoft.engine.connector.ConnectorServiceDecorator.evaluateInputParameters(ConnectorServiceDecorator.java:105)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:183)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:147)
at org.bonitasoft.engine.transaction.JTATransactionServiceImpl.executeInTransaction(JTATransactionServiceImpl.java:207)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork.work(ExecuteConnectorWork.java:119)
at org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork.work(FailureHandlingBonitaWork.java:72)
at org.bonitasoft.engine.work.BonitaWork.run(BonitaWork.java:56)
at org.bonitasoft.engine.work.SequenceRunnableExecutor.innerRun(SequenceRunnableExecutor.java:45)
at org.bonitasoft.engine.work.BonitaRunnable.run(BonitaRunnable.java:35)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Below is a better, more complete, tested answer:
Hope this helps.
import org.bonitasoft.engine.bpm.actor.ActorCriterion;<br />
import org.bonitasoft.engine.bpm.actor.ActorMember;<br />
import org.bonitasoft.engine.identity.User;<br />
import org.bonitasoft.engine.identity.UserCriterion;<br />
import org.bonitasoft.engine.identity.UserSearchDescriptor;<br />
import org.bonitasoft.engine.search.SearchOptionsBuilder;<br />
import com.bonitasoft.engine.api.ProcessAPI; IdentityAPI identityAPI = apiAccessor.getIdentityAPI();<br />
ProcessAPI processAPI = apiAccessor.getProcessAPI();<br />
long actorId = processAPI.getActors(processDefinitionId, 0, 1, ActorCriterion.NAME_ASC).get(0).getId();<br />
List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);<br />
boolean hasMore = true;<br />
int pageSize = 2;<br />
int shift = 0;<br />
while (hasMore) {<br />
List<ActorMember> page = processAPI.getActorMembers(actorId, shift, pageSize);<br />
hasMore = actorMembers.addAll(page);<br />
shift += pageSize;<br />
}<br />
List<User> users = new ArrayList<User>();<br />
for (ActorMember actorMember : actorMembers) {<br />
long userId = actorMember.getUserId();<br />
long roleId = actorMember.getRoleId();<br />
long groupId = actorMember.getGroupId();<br />
if (userId > 0 && roleId < 0 && groupId < 0) {<br />
// user is directly associated to the actor:<br />
users.add(identityAPI.getUser(userId));<br />
} else if (userId < 0 && roleId > 0 && groupId < 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).done()).getResult());<br />
} else if (userId < 0 && roleId < 0 && groupId > 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.GROUP_ID, groupId).done()).getResult());<br />
} else if (userId < 0 && roleId > 0 && groupId > 0) {<br />
// should loop here...<br />
users.addAll(identityAPI.searchUsers(<br />
new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).filter(UserSearchDescriptor.GROUP_ID, groupId).done())<br />
.getResult());<br />
}<br />
}<br />
return users;
Hi,
Users can be mapped to an actor different ways:
- directly
- through a role that the user belongs to
- through a group that the user belongs to
- through a membership that the user belongs to (= group + role). For instance, let's say: will form part of an actor of a task all users that are testers in R&D depatement. That is, all users that have the role tester AND the group R&D
There is not one direct method for that, as it has not been identified as a need.
Your script would look like:
ProcessAPI processAPI = apiAccessor.getProcessAPI();<br />
long actorId = 1L;<br />
List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);<br />
boolean hasMore = true;<br />
int shift = 0;<br />
while (hasMore) {<br />
println("hasMore, continuing...")<br />
List<ActorMember> page = processAPI.getActorMembers(actorId, 0+shift, 100)<br />
hasMore = actorMembers.addAll();<br />
shift += 100;<br />
}<br />
List<User> users = new ArrayList<User>();<br />
for (ActorMember actorMember : actorMembers) {<br />
long userId = actorMember.getUserId();<br />
long roleId = actorMember.getRoleId();<br />
long groupId = actorMember.getGroupId();<br />
if (userId > 0L && roleId == 0L && groupId == 0L) {<br />
// user is directly associated to the actor:<br />
users.add(identityAPI.getUser(userId));<br />
} else if (userId == 0L && roleId > 0L && groupId == 0L) {<br />
// should loop here...<br />
users.addAll(identityAPI.getUsersInRole(roleId, 0, 100, UserCriterion.LAST_NAME_ASC));<br />
} else if (userId == 0L && roleId == 0L && groupId > 0L) {<br />
// should loop here...<br />
users.addAll(identityAPI.getUsersInGroup(groupId, 0, 100, UserCriterion.LAST_NAME_ASC));<br />
}<br />
}<br />
return users;
Comments
OOOps. Please see my "Answer" I just posted. I guess I should have posted it as a connent instead.