当前位置: 首页 > 知识库问答 >
问题:

Camunda令牌在编程状态转换时不通过流移动

赵飞雨
2023-03-14

我基于最初的Camunda Twitter示例创建了一个工作流原型,并进行了以下几项修改。

当直接运行时,未经修改,进程令牌:

  1. 首先在查看推特用户任务时停止:

随后会引发以下异常,这似乎不会影响任何事情(或者会影响吗?):

现在,我对原始示例进行了以下修改:

a)引入了一个endpoint(/invoke),最初通过该endpoint调用进程:

@RequestMapping(value= "/invoke", method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE,consumes=MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public String tweetWritten( @RequestBody CreateTweet data) {
    Map<String, Object> context = new HashMap<>();
    context.put("content", data.content);
    context.put("email", data.email);
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("TwitterDemoProcessControlled",context);
    String processInstanceId = processInstance.getProcessInstanceId();
    logger.info("started instance: {}", processInstanceId);
    return processInstanceId;
}

b) 引入了另一个endpoint(/review),旨在以编程方式将流从查看推文的用户任务转换为:

    @RequestMapping(value= "/review", method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE,consumes=MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public String reviewTweet( @RequestBody ReviewTweet data) {

    boolean approved = data.approved;
    String comments = data.comments;

    Map<String, Object> context = new HashMap<>();
    context.put("approved", approved);
    context.put("comments", comments);

    logger.info("Application approved: {} with comments: {}", approved, comments);

    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().singleResult();
    String processInstanceId = processInstance.getId();
    logger.info("Instance from the query: {}", processInstanceId);


    runtimeService.createProcessInstanceModification(processInstanceId)
    .startAfterActivity("user_task_review_tweet")
    .setVariable("approved", approved)
    .setVariable("comments", comments)
    .execute();
    return processInstanceId;

}

当通过调用endpoint启动时:

    curl -X POST \
  http://localhost:8080/twitter-demo/invoke \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 95' \
  -H 'Content-Type: application/json' \
  -H 'Host: localhost:8080' \
  -H 'Postman-Token: 420dfc61-f7c8-4480-bd1b-d1b4ab90c4ac,6b18c053-b43d-4de3-9f88-61b70f5ad812' \
  -H 'User-Agent: PostmanRuntime/7.20.1' \
  -H 'cache-control: no-cache' \
  -d '{
    "email": "s.l@abc.com",
    "content": "This is the message to be twitted"
}'

Spring日志不再记录任何异常:

    2019-11-25 13:24:48.872  WARN 18188 --- [nio-8080-exec-4] o.glassfish.jersey.servlet.WebComponent  : A servlet request to the URI http://localhost:8080/api/admin/auth/user/default/login/cockpit contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.
2019-11-25 13:25:29.168  INFO 18188 --- [nio-8080-exec-1] o.c.b.s.b.e.t.ProcessFlowController      : started instance: f53c1e54-0fb0-11ea-b813-00155d0a5b14

驾驶舱显示的标记与上面原始示例中显示的类似:

然而,在调用endpoint后:

    curl -X POST \
  http://localhost:8080/twitter-demo/review \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 76' \
  -H 'Content-Type: application/json' \
  -H 'Host: localhost:8080' \
  -H 'Postman-Token: 74ed1585-6330-4506-ab7b-0c5b8727de90,fae2ee8d-1e23-4006-bbf5-ff80453d754f' \
  -H 'User-Agent: PostmanRuntime/7.20.1' \
  -H 'cache-control: no-cache' \
  -d '{
    "approved": false,
    "comments": "This does not deserve to be published"
}'

令牌符号计数仍保留在查看推文任务中:

尽管如此,根据Spring日志,该过程还是成功完成了:

    2019-11-25 13:24:48.872[0;39m [33m WARN[0;39m [35m18188[0;39m [2m---[0;39m [2m[nio-8080-exec-4][0;39m [36mo.glassfish.jersey.servlet.WebComponent [0;39m [2m:[0;39m A servlet request to the URI http://localhost:8080/api/admin/auth/user/default/login/cockpit contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.
[2m2019-11-25 13:25:29.168[0;39m [32m INFO[0;39m [35m18188[0;39m [2m---[0;39m [2m[nio-8080-exec-1][0;39m [36mo.c.b.s.b.e.t.ProcessFlowController     [0;39m [2m:[0;39m started instance: f53c1e54-0fb0-11ea-b813-00155d0a5b14
[2m2019-11-25 13:28:09.385[0;39m [32m INFO[0;39m [35m18188[0;39m [2m---[0;39m [2m[nio-8080-exec-6][0;39m [36mo.c.b.s.b.e.t.ProcessFlowController     [0;39m [2m:[0;39m Application approved: false with comments: This does not deserve to be published
[2m2019-11-25 13:28:09.387[0;39m [32m INFO[0;39m [35m18188[0;39m [2m---[0;39m [2m[nio-8080-exec-6][0;39m [36mo.c.b.s.b.e.t.ProcessFlowController     [0;39m [2m:[0;39m Instance from the query: f53c1e54-0fb0-11ea-b813-00155d0a5b14
Hi!

Unfortunately your tweet has been rejected.

Original content: This is the message to be twitted

Comment: This does not deserve to be published

Sorry, please try with better content the next time :-)

作为一个实验,如果我启动该过程的几个(2)实例:

审阅endpoint开始抛出以下异常:

org.camunda.bpm.engine.ProcessEngineException: Query return 2 results instead of max 1
at org.camunda.bpm.engine.impl.AbstractQuery.executeSingleResult(AbstractQuery.java:216) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.AbstractQuery.execute(AbstractQuery.java:170) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:28) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:107) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:46) ~[camunda-engine-spring-7.11.0.jar:7.11.0]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:44) ~[camunda-engine-spring-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:70) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.engine.impl.AbstractQuery.singleResult(AbstractQuery.java:133) ~[camunda-engine-7.11.0.jar:7.11.0]
at org.camunda.bpm.spring.boot.example.twitter.ProcessFlowController.reviewTweet(ProcessFlowController.java:61) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_231]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_231]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_231]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747) [tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.19.jar:9.0.19]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_231]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_231]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.19.jar:9.0.19]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_231]

然后,当两个进程中的一个通过任务列表应用程序转换到其末尾时,用户任务上的令牌计数从2减少到1,但不会像之前那样通过随后调用查看endpoint从1减少到0(如预期)。

我的问题是:

>

  • 为什么令牌在调用原始Camunda示例代码时消失,但即使在成功的流程完成后,当如上所述通过endpoint调用用户任务时,令牌在驾驶舱中仍然可见?通过代码转换用户状态不会影响驾驶舱视图和同步它们所需的一些额外代码操作吗?

    为什么我在原始代码中看到上述异常?它会影响任何事情吗?为什么当进程通过“/invoke”endpoint调用时没有抛出它?

    为了消除查询返回2个结果而不是最多1个异常,需要在endpoint后面的代码中更改什么?

  • 共有1个答案

    黄昊
    2023-03-14

    我可以试着回答(2):任务已经完成,过程正常完成。如果现在用任务列表重新加载浏览器窗口,它会再次尝试打开具有给定id的任务。。。但它已经不存在了,你以前完成过。因此,这不是流程流本身引发的异常,而是指示无效状态(尝试加载不存在的内容)。

    对于(1):您html" target="_blank">修改流程实例执行而不是使用taskService#completeTask API的方法非常不寻常。。。您不应该将该API用于常规流程执行,它用于迁移和管理/修复。我想你看到的是你有两个令牌。。。原始令牌仍在用户任务处等待,您额外创建的令牌在用户任务之后开始并完成了该过程,但由于仍有令牌在等待,因此实例仍处于活动状态。如果您使用修改API(您不应该这样做),则在创建修改时取消现有令牌。

    对于(3):假设我对(1)的猜测是正确的,那么情况就是这样:您没有取消原始令牌,因此通过使用修改API创建了第二个令牌,从而得到了“正确”的查询结果。

     类似资料:
    • 程序转移指令 1>无条件转移指令 (长转移) JMP 无条件转移指令 CALL 过程调用 RET/RETF过程返回. 2>条件转移指令 (短转移,-128到+127的距离内) ( 当且仅当(SF XOR OF)=1时,OP1循环控制指令(短转移) LOOP CX不为零时循环. LOOPE/LOOPZ CX不为零且标志Z=1时循环. LOOPNE/LOOPNZ CX不为零且标志Z=0时循环. JCX

    • 状态转换的一般含义是,相同情况的不同形式,并且根据含义,状态转换方法也是如此。当不同的输入值赋予相同的函数时,它用于捕获软件应用程序的行为。 我们都使用过自动取款机,当从中取款时,它会显示帐户详细信息。现在再次进行另一次交易,然后再次显示帐户详细信息,但第二次交易后显示的详细信息与第一次交易不同,但两个详细信息都使用ATM的相同功能显示。所以这里使用了相同的函数,但每次输出不同时,这称为状态转换。

    • 我有一些我无法控制的代码。此代码接受一个对象参数,并尝试将其转换为编译时已知的类型,如下所示: 在C#中是否可以设计一个自定义类(不是从KnownType派生的),该类可以作为参数传递给上述代码,并通过上述代码转换为,前提是可以使用其成员方法将自身转换为: 我曾尝试实现这样的自定义转换运算符: 但是它不起作用(它没有被使用)。假设转换运算符仅在编译时已知源类型、目标类型和转换运算符时才起作用,这是

    • Zuul路线 我能够从授权服务器获得访问令牌(无状态会话-没有JSESSIONID cookie) curl-d---请求后-u acme:acmesecret“http://localhost:8899/userauth/oauth/token?grant_type=password&username=<...>&password=<...>” [{“firstname”:“anil”.....

    • 问题内容: 我做了一个小实验:http : //codepen.io/hawkphil/pen/NqMomm?editors=101 这是我的状态流(单击按钮): 在每个状态变化,我在出了 但是,你可以在看线,奇怪的事情发生了。我从“后退”按钮获得的“思维”,它显示为先前的状态()。这是不对的,对吧?它应该显示为以前的状态,因为我必须通过单击按钮来 手动*状态。我还显示了(line )中的值,以防

    • 我需要支持Keytool的相同功能。exe通过使用KeyTool类编程将java密钥库转换为PFX文件。由于项目需求的限制,我无法从我的应用程序中使用命令提示符进程,因此通过编程,我也无法打开命令进程。 例如。 C:\keytool-importkeystore-srckeystore。k eystore-srcstoretype JKS-destkeystore-thekeystore。pfx-