Skip to content

Commit

Permalink
JBPM-3814 BZ 1002724 Fixes that use SeamTransaction injection (cherry…
Browse files Browse the repository at this point in the history
… picked from commit ca439c9)
  • Loading branch information
Marco Rietveld committed Oct 4, 2013
1 parent 188f1d3 commit 8b7c800
Show file tree
Hide file tree
Showing 8 changed files with 665 additions and 292 deletions.

This file was deleted.

Expand Up @@ -24,19 +24,29 @@
import org.jbpm.services.task.commands.TaskCommand;
import org.jbpm.services.task.exception.PermissionDeniedException;
import org.kie.api.command.Command;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.Context;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.api.task.TaskService;
import org.kie.internal.runtime.manager.context.EmptyContext;
import org.kie.internal.runtime.manager.context.ProcessInstanceIdContext;
import org.kie.internal.task.api.InternalTaskService;
import org.kie.services.client.api.command.AcceptedCommands;
import org.kie.services.client.serialization.jaxb.JaxbSerializationProvider;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsRequest;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsResponse;
import org.kie.services.remote.cdi.ProcessRequestBean;
import org.kie.services.client.serialization.jaxb.impl.JaxbExceptionResponse;
import org.kie.services.remote.cdi.RuntimeManagerManager;
import org.kie.services.remote.exception.DomainNotFoundBadRequestException;
import org.kie.services.remote.exception.KieRemoteServicesInternalError;
import org.kie.services.remote.rest.RestProcessRequestBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class is the link between incoming request (whether via REST or JMS or .. whatever)
* and the bean that processes the requests, the {@link ProcessRequestBean}.
* and the bean that processes the requests, the {@link RestProcessRequestBean}.
* </p>
* Responses to requests are <b>not</b> placed on the reply-to queue, but on the answer queue.
* </p> Because there are multiple queues to which an instance of this class could listen to, the (JMS queue) configuration is
Expand All @@ -49,12 +59,15 @@ public class RequestMessageBean implements MessageListener {
@Resource(mappedName = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;

@Inject
private ProcessRequestBean processRequestBean;

private String RESPONSE_QUEUE_NAME = null;
private static String RESPONSE_QUEUE_NAME_PROPERTY = "kie.services.jms.queues.response";

@Inject
private RuntimeManagerManager runtimeMgrMgr;

@Inject
private TaskService taskService;

@PostConstruct
public void init() {
RESPONSE_QUEUE_NAME = System.getProperty(RESPONSE_QUEUE_NAME_PROPERTY, "queue/KIE.RESPONSE.ALL");
Expand All @@ -81,7 +94,7 @@ public void onMessage(Message message) {
// 2. process request
JaxbCommandsResponse jaxbResponse;
if (cmdsRequest != null) {
jaxbResponse = processJaxbCommandsRequest(cmdsRequest, processRequestBean);
jaxbResponse = processJaxbCommandsRequest(cmdsRequest);
} else {
// Failure reasons have been logged in deserializeRequest().
logger.error("Stopping processing of request message due to errors: see above.");
Expand Down Expand Up @@ -190,7 +203,7 @@ private Message serializeResponse(Session session, String msgId, int serializati
return byteMsg;
}

public JaxbCommandsResponse processJaxbCommandsRequest(JaxbCommandsRequest request, ProcessRequestBean requestBean) {
public JaxbCommandsResponse processJaxbCommandsRequest(JaxbCommandsRequest request) {
// If exceptions are happening here, then there is something REALLY wrong and they should be thrown.
JaxbCommandsResponse jaxbResponse = new JaxbCommandsResponse(request);
List<Command<?>> commands = request.getCommands();
Expand All @@ -207,9 +220,9 @@ public JaxbCommandsResponse processJaxbCommandsRequest(JaxbCommandsRequest reque

Object cmdResult = null;
if (cmd instanceof TaskCommand<?>) {
cmdResult = internalDoTaskOperation(requestBean, cmd, jaxbResponse, i);
cmdResult = internalDoTaskOperation(cmd, jaxbResponse, i);
} else {
cmdResult = internalDoKieSessionOperation(requestBean, cmd, request, jaxbResponse, i);
cmdResult = internalDoKieSessionOperation( cmd, request, jaxbResponse, i);
}
if (cmdResult != null) {
try {
Expand All @@ -232,10 +245,10 @@ public JaxbCommandsResponse processJaxbCommandsRequest(JaxbCommandsRequest reque
}

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Object internalDoTaskOperation(ProcessRequestBean requestBean, Command<?> cmd, JaxbCommandsResponse jaxbResponse, int i) {
public Object internalDoTaskOperation(Command<?> cmd, JaxbCommandsResponse jaxbResponse, int i) {
Object cmdResult;
try {
cmdResult = requestBean.doTaskOperation(cmd);
cmdResult = doTaskOperation(cmd);
} catch( UnauthorizedException ue ) {
Throwable cause = ue.getCause();
if( cause instanceof PermissionDeniedException ) {
Expand All @@ -250,15 +263,58 @@ public Object internalDoTaskOperation(ProcessRequestBean requestBean, Command<?>
}

@TransactionAttribute(TransactionAttributeType.NEVER)
public Object internalDoKieSessionOperation(ProcessRequestBean requestBean, Command<?> cmd, JaxbCommandsRequest request, JaxbCommandsResponse jaxbResponse, int i) {
public Object internalDoKieSessionOperation(Command<?> cmd, JaxbCommandsRequest request, JaxbCommandsResponse jaxbResponse, int i) {
Object cmdResult;
try {
cmdResult = requestBean.doKieSessionOperation(cmd, request.getDeploymentId(), request.getProcessInstanceId());
cmdResult = doKieSessionOperation(cmd, request.getDeploymentId(), request.getProcessInstanceId());
} catch( DomainNotFoundBadRequestException dnfbre ) {
logger.warn( dnfbre.getMessage() );
jaxbResponse.addException(dnfbre, i, cmd);
return null;
}
return cmdResult;
}

private Object doKieSessionOperation(Command<?> cmd, String deploymentId, Long processInstanceId) {
Object result = null;
try {
KieSession kieSession = getRuntimeEngine(deploymentId, processInstanceId).getKieSession();
result = kieSession.execute(cmd);
} catch( Exception e ) {
JaxbExceptionResponse exceptResp = new JaxbExceptionResponse(e, cmd);
logger.warn( "Unable to execute " + exceptResp.getCommandName() + " because of " + e.getClass().getSimpleName() + ": " + e.getMessage());
logger.trace("Stack trace: \n", e);
result = exceptResp;
}
return result;
}

private Object doTaskOperation(Command<?> cmd) {
Object result = null;
try {
result = ((InternalTaskService) taskService).execute(cmd);
} catch( PermissionDeniedException pde ) {
throw new UnauthorizedException(pde.getMessage(), pde);
} catch( Exception e ) {
JaxbExceptionResponse exceptResp = new JaxbExceptionResponse(e, cmd);
logger.warn( "Unable to execute " + exceptResp.getCommandName() + " because of " + e.getClass().getSimpleName() + ": " + e.getMessage());
logger.trace("Stack trace: \n", e);
result = exceptResp;
}
return result;
}

protected RuntimeEngine getRuntimeEngine(String domainName, Long processInstanceId) {
RuntimeManager runtimeManager = runtimeMgrMgr.getRuntimeManager(domainName);
Context<?> runtimeContext;
if (processInstanceId != null) {
runtimeContext = new ProcessInstanceIdContext(processInstanceId);
} else {
runtimeContext = EmptyContext.get();
}
if( runtimeManager == null ) {
throw new DomainNotFoundBadRequestException("No runtime manager could be found for domain '" + domainName + "'.");
}
return runtimeManager.getRuntimeEngine(runtimeContext);
}
}
Expand Up @@ -14,39 +14,124 @@
import javax.ws.rs.core.Variant;

import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotAcceptableException;
import org.jboss.resteasy.spi.NotFoundException;
import org.jbpm.services.task.commands.CompleteTaskCommand;
import org.jbpm.services.task.commands.ExitTaskCommand;
import org.jbpm.services.task.commands.FailTaskCommand;
import org.jbpm.services.task.commands.GetTaskCommand;
import org.jbpm.services.task.commands.SkipTaskCommand;
import org.jbpm.services.task.commands.TaskCommand;
import org.jbpm.services.task.impl.model.GroupImpl;
import org.jbpm.services.task.impl.model.TaskImpl;
import org.jbpm.services.task.impl.model.UserImpl;
import org.jbpm.services.task.query.TaskSummaryImpl;
import org.kie.api.command.Command;
import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.Status;
import org.kie.api.task.model.Task;
import org.kie.services.client.api.command.AcceptedCommands;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsRequest;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsResponse;
import org.kie.services.client.serialization.jaxb.impl.JaxbExceptionResponse;
import org.kie.services.remote.cdi.RuntimeManagerManager;
import org.kie.services.remote.exception.KieRemoteServicesInternalError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ResourceBase {

private static List<Variant> variants
private static final Logger logger = LoggerFactory.getLogger(ResourceBase.class);

// Seam-Transaction ----------------------------------------------------------------------------------------------------------

public static JaxbCommandsResponse restProcessJaxbCommandsRequest(JaxbCommandsRequest request, RestProcessRequestBean requestBean) {
// If exceptions are happening here, then there is something REALLY wrong and they should be thrown.
JaxbCommandsResponse jaxbResponse = new JaxbCommandsResponse(request);
List<Command<?>> commands = request.getCommands();

if (commands != null) {
int cmdListSize = commands.size();
for (int i = 0; i < cmdListSize; ++i) {
boolean restartTx = !( i == cmdListSize - 1 ); // restart tx for all cmds except the last one
Command<?> cmd = commands.get(i);
if (!AcceptedCommands.getSet().contains(cmd.getClass())) {
throw new NotAcceptableException("The execute REST operation does not accept " + cmd.getClass().getName() + " instances.");
}
logger.debug("Processing command " + cmd.getClass().getSimpleName());
Object cmdResult = null;
try {
if (cmd instanceof TaskCommand<?>) {
String errorMsg = "Unable to execute command " + cmd.getClass().getSimpleName();
TaskCommand<?> taskCmd = (TaskCommand<?>) cmd;
if( cmd instanceof CompleteTaskCommand
|| cmd instanceof ExitTaskCommand
|| cmd instanceof FailTaskCommand
|| cmd instanceof SkipTaskCommand ) {
cmdResult = requestBean.doTaskOperationOnDeployment(
taskCmd,
errorMsg,
request.getDeploymentId(),
restartTx); // restart commit
} else {
cmdResult = requestBean.doTaskOperation(taskCmd, errorMsg);
}
} else {
cmdResult = requestBean.doKieSessionOperation(
cmd,
request.getDeploymentId(),
request.getProcessInstanceId(),
"Unable to execute command " + cmd.getClass().getSimpleName(),
true, // commit
restartTx); // restart commit
}
} catch(Exception e) {
jaxbResponse.addException(e, i, cmd);
logger.warn("Unable to execute " + cmd.getClass().getSimpleName()
+ " because of " + e.getClass().getSimpleName() + ": " + e.getMessage());
logger.trace("Stack trace: \n", e);
}
if (cmdResult != null) {
try {
// addResult could possibly throw an exception, which is why it's here and not above
jaxbResponse.addResult(cmdResult, i, cmd);
} catch (Exception e) {
logger.error("Unable to add result from " + cmd.getClass().getSimpleName() + "/" + i + " because of "
+ e.getClass().getSimpleName(), e);
logger.trace("Stack trace: \n", e);
jaxbResponse.addException(e, i, cmd);
}
}
}
}

if (commands == null || commands.isEmpty()) {
logger.info("Commands request object with no commands sent!");
}

return jaxbResponse;
}

// JSON / JAXB ---------------------------------------------------------------------------------------------------------------

public static List<Variant> variants
= Variant.mediaTypes(MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE).build();

protected Variant getVariant(Request restRequest) {
protected static Variant getVariant(Request restRequest) {
return restRequest.selectVariant(variants);
}

protected Response createCorrectVariant(Object responseObj, Request restRequest) {
protected static Response createCorrectVariant(Object responseObj, Request restRequest) {
Variant v = getVariant(restRequest);
if( v != null ) {
return Response.ok(responseObj, v).build();
} else {
return Response.notAcceptable(variants).build();
}
}

protected static String checkThatOperationExists(String operation, String[] possibleOperations) {
for (String oper : possibleOperations) {
if (oper.equals(operation.trim().toLowerCase())) {
return oper;
}
}
throw new BadRequestException("Operation '" + operation + "' is not supported on tasks.");
}

// Request Params -------------------------------------------------------------------------------------------------------------

protected static Map<String, List<String>> getRequestParams(HttpServletRequest request) {
Map<String, List<String>> parameters = new HashMap<String, List<String>>();
Enumeration<String> names = request.getParameterNames();
Expand Down Expand Up @@ -231,6 +316,8 @@ protected static List<Status> convertStringListToStatusList( List<String> status
return statusList;
}

// Pagination ----------------------------------------------------------------------------------------------------------------

protected static int [] getPageNumAndPageSize(Map<String, List<String>> params) {
int [] pageInfo = new int[3];
Number page = getNumberParam("page", false, params, "query", false);
Expand Down

0 comments on commit 8b7c800

Please sign in to comment.