Source:
public Object doPost(ExecutionRequest xreq) { OperationResource op = (OperationResource) getTarget(); String opId = op.getId(); try { AutomationServer srv = Framework.getService(AutomationServer.class); if (!srv.accept(opId, op.isChain(), request)) { return ResponseHelper.notFound(); } final String executionId = UUID.randomUUID().toString(); OperationContext opCtx = xreq.createContext(request, response, null); opCtx.setCallback(new OperationCallback() { @Override public void onChainEnter(OperationType chain) { } @Override public void onChainExit() { setCompleted(executionId); } @Override public void onOperationEnter(OperationContext context, OperationType type, InvokableMethod method, Map<String, Object> params) { enterMethod(executionId, method); } @Override public void onOperationExit(Object output) { setOutput(executionId, (Serializable) output); } @Override public OperationException onError(OperationException error) { setError(executionId, error.getMessage()); return error; } }); String repoName = session.getRepositoryName(); NuxeoPrincipal principal = session.getPrincipal(); new Thread(() -> { TransactionHelper.runInTransaction(() -> { try (CloseableCoreSession session = CoreInstance.openCoreSession(repoName, principal)){ opCtx.setCoreSession(session); service.run(opCtx, opId, xreq.getParams()); } catch (OperationException e) { setError(executionId, e.getMessage()); } }); }).start(); String statusURL = String.format("%s/%s/status", ctx.getURL(), executionId); return Response.status(HttpServletResponse.SC_ACCEPTED).location(new URI(statusURL)).build(); } catch (URISyntaxException cause) { String exceptionMessage = "Failed to invoke operation: " + op.getId(); Throwable unWrapException = ExceptionHelper.unwrapException(cause); if (unWrapException instanceof RestOperationException) { int customHttpStatus = ((RestOperationException) unWrapException).getStatus(); throw new NuxeoException(exceptionMessage, cause, customHttpStatus); } throw new NuxeoException(exceptionMessage, cause); } }

Target:
public Object doPost(ExecutionRequest xreq) { OperationResource op = (OperationResource) getTarget(); String opId = op.getId(); if (!srv.accept(opId, op.isChain(), request)) { return ResponseHelper.notFound(); } String executionId = UUID.randomUUID().toString(); OperationContext opCtx = xreq.createContext(request, response, null); opCtx.setCallback(new OperationCallback() { @Override public void onChainEnter(OperationType chain) { } @Override public void onChainExit() { setCompleted(executionId); } @Override public void onOperationEnter(OperationContext context, OperationType type, InvokableMethod method, Map<String, Object> params) { enterMethod(executionId, method); } @Override public void onOperationExit(Object output) { setOutput(executionId, (Serializable) output); } @Override public OperationException onError(OperationException error) { setError(executionId, error.getMessage()); return error; } }); String repoName = session.getRepositoryName(); NuxeoPrincipal principal = session.getPrincipal(); new Thread(() -> { TransactionHelper.runInTransaction(() -> { try (CloseableCoreSession session = CoreInstance.openCoreSession(repoName, principal)){ opCtx.setCoreSession(session); service.run(opCtx, opId, xreq.getParams()); } catch (OperationException e) { setError(executionId, e.getMessage()); } }); }, String.format("Nuxeo-AsyncOperation-%s", executionId)).start(); try { String statusURL = String.format("%s/%s/%s", ctx.getURL(), executionId, STATUS_PATH); return Response.status(HttpServletResponse.SC_ACCEPTED).location(new URI(statusURL)).build(); } catch (URISyntaxException e) { throw new NuxeoException(e); } }