You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

statemachine_config_parser_test.go 23 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package parser
  18. import (
  19. "github.com/seata/seata-go/pkg/saga/statemachine"
  20. "github.com/stretchr/testify/assert"
  21. "testing"
  22. )
  23. func TestStateMachineConfigParser_Parse(t *testing.T) {
  24. parser := NewStateMachineConfigParser()
  25. tests := []struct {
  26. name string
  27. configFilePath string
  28. expectedObject *statemachine.StateMachineObject
  29. }{
  30. {
  31. name: "JSON Simple 1",
  32. configFilePath: "../../../../../testdata/saga/statelang/simple_statelang_with_choice.json",
  33. expectedObject: GetStateMachineObject1("json"),
  34. },
  35. {
  36. name: "JSON Simple 2",
  37. configFilePath: "../../../../../testdata/saga/statelang/simple_statemachine.json",
  38. expectedObject: GetStateMachineObject2("json"),
  39. },
  40. {
  41. name: "JSON Simple 3",
  42. configFilePath: "../../../../../testdata/saga/statelang/state_machine_new_designer.json",
  43. expectedObject: GetStateMachineObject3("json"),
  44. },
  45. {
  46. name: "YAML Simple 1",
  47. configFilePath: "../../../../../testdata/saga/statelang/simple_statelang_with_choice.yaml",
  48. expectedObject: GetStateMachineObject1("yaml"),
  49. },
  50. {
  51. name: "YAML Simple 2",
  52. configFilePath: "../../../../../testdata/saga/statelang/simple_statemachine.yaml",
  53. expectedObject: GetStateMachineObject2("yaml"),
  54. },
  55. {
  56. name: "YAML Simple 3",
  57. configFilePath: "../../../../../testdata/saga/statelang/state_machine_new_designer.yaml",
  58. expectedObject: GetStateMachineObject3("yaml"),
  59. },
  60. }
  61. for _, tt := range tests {
  62. t.Run(tt.name, func(t *testing.T) {
  63. content, err := parser.ReadConfigFile(tt.configFilePath)
  64. if err != nil {
  65. t.Error("parse fail: " + err.Error())
  66. }
  67. object, err := parser.Parse(content)
  68. if err != nil {
  69. t.Error("parse fail: " + err.Error())
  70. }
  71. assert.Equal(t, tt.expectedObject, object)
  72. })
  73. }
  74. }
  75. func GetStateMachineObject1(format string) *statemachine.StateMachineObject {
  76. switch format {
  77. case "json":
  78. case "yaml":
  79. }
  80. return &statemachine.StateMachineObject{
  81. Name: "simpleChoiceTestStateMachine",
  82. Comment: "带条件分支的测试状态机定义",
  83. StartState: "FirstState",
  84. Version: "0.0.1",
  85. States: map[string]interface{}{
  86. "FirstState": map[string]interface{}{
  87. "Type": "ServiceTask",
  88. "ServiceName": "demoService",
  89. "ServiceMethod": "foo",
  90. "Next": "ChoiceState",
  91. },
  92. "ChoiceState": map[string]interface{}{
  93. "Type": "Choice",
  94. "Choices": []interface{}{
  95. map[string]interface{}{
  96. "Expression": "[a] == 1",
  97. "Next": "SecondState",
  98. },
  99. map[string]interface{}{
  100. "Expression": "[a] == 2",
  101. "Next": "ThirdState",
  102. },
  103. },
  104. "Default": "SecondState",
  105. },
  106. "SecondState": map[string]interface{}{
  107. "Type": "ServiceTask",
  108. "ServiceName": "demoService",
  109. "ServiceMethod": "bar",
  110. },
  111. "ThirdState": map[string]interface{}{
  112. "Type": "ServiceTask",
  113. "ServiceName": "demoService",
  114. "ServiceMethod": "foo",
  115. },
  116. },
  117. }
  118. }
  119. func GetStateMachineObject2(format string) *statemachine.StateMachineObject {
  120. var retryMap map[string]interface{}
  121. switch format {
  122. case "json":
  123. retryMap = map[string]interface{}{
  124. "Exceptions": []interface{}{
  125. "java.lang.Exception",
  126. },
  127. "IntervalSeconds": float64(2),
  128. "MaxAttempts": float64(3),
  129. "BackoffRate": 1.5,
  130. }
  131. case "yaml":
  132. retryMap = map[string]interface{}{
  133. "Exceptions": []interface{}{
  134. "java.lang.Exception",
  135. },
  136. "IntervalSeconds": 2,
  137. "MaxAttempts": 3,
  138. "BackoffRate": 1.5,
  139. }
  140. }
  141. return &statemachine.StateMachineObject{
  142. Name: "simpleTestStateMachine",
  143. Comment: "测试状态机定义",
  144. StartState: "FirstState",
  145. Version: "0.0.1",
  146. States: map[string]interface{}{
  147. "FirstState": map[string]interface{}{
  148. "Type": "ServiceTask",
  149. "ServiceName": "is.seata.saga.DemoService",
  150. "ServiceMethod": "foo",
  151. "IsPersist": false,
  152. "Next": "ScriptState",
  153. },
  154. "ScriptState": map[string]interface{}{
  155. "Type": "ScriptTask",
  156. "ScriptType": "groovy",
  157. "ScriptContent": "return 'hello ' + inputA",
  158. "Input": []interface{}{
  159. map[string]interface{}{
  160. "inputA": "$.data1",
  161. },
  162. },
  163. "Output": map[string]interface{}{
  164. "scriptStateResult": "$.#root",
  165. },
  166. "Next": "ChoiceState",
  167. },
  168. "ChoiceState": map[string]interface{}{
  169. "Type": "Choice",
  170. "Choices": []interface{}{
  171. map[string]interface{}{
  172. "Expression": "foo == 1",
  173. "Next": "FirstMatchState",
  174. },
  175. map[string]interface{}{
  176. "Expression": "foo == 2",
  177. "Next": "SecondMatchState",
  178. },
  179. },
  180. "Default": "FailState",
  181. },
  182. "FirstMatchState": map[string]interface{}{
  183. "Type": "ServiceTask",
  184. "ServiceName": "is.seata.saga.DemoService",
  185. "ServiceMethod": "bar",
  186. "CompensateState": "CompensateFirst",
  187. "Status": map[string]interface{}{
  188. "return.code == 'S'": "SU",
  189. "return.code == 'F'": "FA",
  190. "$exception{java.lang.Throwable}": "UN",
  191. },
  192. "Input": []interface{}{
  193. map[string]interface{}{
  194. "inputA1": "$.data1",
  195. "inputA2": map[string]interface{}{
  196. "a": "$.data2.a",
  197. },
  198. },
  199. map[string]interface{}{
  200. "inputB": "$.header",
  201. },
  202. },
  203. "Output": map[string]interface{}{
  204. "firstMatchStateResult": "$.#root",
  205. },
  206. "Retry": []interface{}{
  207. retryMap,
  208. },
  209. "Catch": []interface{}{
  210. map[string]interface{}{
  211. "Exceptions": []interface{}{
  212. "java.lang.Exception",
  213. },
  214. "Next": "CompensationTrigger",
  215. },
  216. },
  217. "Next": "SuccessState",
  218. },
  219. "CompensateFirst": map[string]interface{}{
  220. "Type": "ServiceTask",
  221. "ServiceName": "is.seata.saga.DemoService",
  222. "ServiceMethod": "compensateBar",
  223. "IsForCompensation": true,
  224. "IsForUpdate": true,
  225. "Input": []interface{}{
  226. map[string]interface{}{
  227. "input": "$.data",
  228. },
  229. },
  230. "Output": map[string]interface{}{
  231. "firstMatchStateResult": "$.#root",
  232. },
  233. "Status": map[string]interface{}{
  234. "return.code == 'S'": "SU",
  235. "return.code == 'F'": "FA",
  236. "$exception{java.lang.Throwable}": "UN",
  237. },
  238. },
  239. "CompensationTrigger": map[string]interface{}{
  240. "Type": "CompensationTrigger",
  241. "Next": "CompensateEndState",
  242. },
  243. "CompensateEndState": map[string]interface{}{
  244. "Type": "Fail",
  245. "ErrorCode": "StateCompensated",
  246. "Message": "State Compensated!",
  247. },
  248. "SecondMatchState": map[string]interface{}{
  249. "Type": "SubStateMachine",
  250. "StateMachineName": "simpleTestSubStateMachine",
  251. "Input": []interface{}{
  252. map[string]interface{}{
  253. "input": "$.data",
  254. },
  255. map[string]interface{}{
  256. "header": "$.header",
  257. },
  258. },
  259. "Output": map[string]interface{}{
  260. "firstMatchStateResult": "$.#root",
  261. },
  262. "Next": "SuccessState",
  263. },
  264. "FailState": map[string]interface{}{
  265. "Type": "Fail",
  266. "ErrorCode": "DefaultStateError",
  267. "Message": "No Matches!",
  268. },
  269. "SuccessState": map[string]interface{}{
  270. "Type": "Succeed",
  271. },
  272. },
  273. }
  274. }
  275. func GetStateMachineObject3(format string) *statemachine.StateMachineObject {
  276. var (
  277. boundsMap1 map[string]interface{}
  278. boundsMap2 map[string]interface{}
  279. boundsMap3 map[string]interface{}
  280. boundsMap4 map[string]interface{}
  281. boundsMap5 map[string]interface{}
  282. boundsMap6 map[string]interface{}
  283. boundsMap7 map[string]interface{}
  284. boundsMap8 map[string]interface{}
  285. boundsMap9 map[string]interface{}
  286. waypoints1 []interface{}
  287. waypoints2 []interface{}
  288. waypoints3 []interface{}
  289. waypoints4 []interface{}
  290. waypoints5 []interface{}
  291. waypoints6 []interface{}
  292. waypoints7 []interface{}
  293. )
  294. switch format {
  295. case "json":
  296. boundsMap1 = map[string]interface{}{
  297. "x": float64(300),
  298. "y": float64(178),
  299. "width": float64(100),
  300. "height": float64(80),
  301. }
  302. boundsMap2 = map[string]interface{}{
  303. "x": float64(455),
  304. "y": float64(193),
  305. "width": float64(50),
  306. "height": float64(50),
  307. }
  308. boundsMap3 = map[string]interface{}{
  309. "x": float64(300),
  310. "y": float64(310),
  311. "width": float64(100),
  312. "height": float64(80),
  313. }
  314. boundsMap4 = map[string]interface{}{
  315. "x": float64(550),
  316. "y": float64(178),
  317. "width": float64(100),
  318. "height": float64(80),
  319. }
  320. boundsMap5 = map[string]interface{}{
  321. "x": float64(550),
  322. "y": float64(310),
  323. "width": float64(100),
  324. "height": float64(80),
  325. }
  326. boundsMap6 = map[string]interface{}{
  327. "x": float64(632),
  328. "y": float64(372),
  329. "width": float64(36),
  330. "height": float64(36),
  331. }
  332. boundsMap7 = map[string]interface{}{
  333. "x": float64(722),
  334. "y": float64(200),
  335. "width": float64(36),
  336. "height": float64(36),
  337. }
  338. boundsMap8 = map[string]interface{}{
  339. "x": float64(722),
  340. "y": float64(372),
  341. "width": float64(36),
  342. "height": float64(36),
  343. }
  344. boundsMap9 = map[string]interface{}{
  345. "x": float64(812),
  346. "y": float64(372),
  347. "width": float64(36),
  348. "height": float64(36),
  349. }
  350. waypoints1 = []interface{}{
  351. map[string]interface{}{
  352. "original": map[string]interface{}{
  353. "x": float64(400),
  354. "y": float64(218),
  355. },
  356. "x": float64(400),
  357. "y": float64(218),
  358. },
  359. map[string]interface{}{"x": float64(435), "y": float64(218)},
  360. map[string]interface{}{
  361. "original": map[string]interface{}{
  362. "x": float64(455),
  363. "y": float64(218),
  364. },
  365. "x": float64(455),
  366. "y": float64(218),
  367. },
  368. }
  369. waypoints2 = []interface{}{
  370. map[string]interface{}{
  371. "original": map[string]interface{}{
  372. "x": float64(505),
  373. "y": float64(218),
  374. },
  375. "x": float64(505),
  376. "y": float64(218),
  377. },
  378. map[string]interface{}{"x": float64(530), "y": float64(218)},
  379. map[string]interface{}{
  380. "original": map[string]interface{}{
  381. "x": float64(550),
  382. "y": float64(218),
  383. },
  384. "x": float64(550),
  385. "y": float64(218),
  386. },
  387. }
  388. waypoints3 = []interface{}{
  389. map[string]interface{}{
  390. "original": map[string]interface{}{
  391. "x": float64(480),
  392. "y": float64(243),
  393. },
  394. "x": float64(480),
  395. "y": float64(243),
  396. },
  397. map[string]interface{}{"x": float64(600), "y": float64(290)},
  398. map[string]interface{}{
  399. "original": map[string]interface{}{
  400. "x": float64(600),
  401. "y": float64(310),
  402. },
  403. "x": float64(600),
  404. "y": float64(310),
  405. },
  406. }
  407. waypoints4 = []interface{}{
  408. map[string]interface{}{
  409. "original": map[string]interface{}{
  410. "x": float64(650),
  411. "y": float64(218),
  412. },
  413. "x": float64(650),
  414. "y": float64(218),
  415. },
  416. map[string]interface{}{"x": float64(702), "y": float64(218)},
  417. map[string]interface{}{
  418. "original": map[string]interface{}{
  419. "x": float64(722),
  420. "y": float64(218),
  421. },
  422. "x": float64(722),
  423. "y": float64(218),
  424. },
  425. }
  426. waypoints5 = []interface{}{
  427. map[string]interface{}{
  428. "original": map[string]interface{}{
  429. "x": float64(668),
  430. "y": float64(390),
  431. },
  432. "x": float64(668),
  433. "y": float64(390),
  434. },
  435. map[string]interface{}{"x": float64(702), "y": float64(390)},
  436. map[string]interface{}{
  437. "original": map[string]interface{}{
  438. "x": float64(722),
  439. "y": float64(390),
  440. },
  441. "x": float64(722),
  442. "y": float64(390),
  443. },
  444. }
  445. waypoints6 = []interface{}{
  446. map[string]interface{}{
  447. "original": map[string]interface{}{
  448. "x": float64(600),
  449. "y": float64(310),
  450. },
  451. "x": float64(600),
  452. "y": float64(310),
  453. },
  454. map[string]interface{}{"x": float64(740), "y": float64(256)},
  455. map[string]interface{}{
  456. "original": map[string]interface{}{
  457. "x": float64(740),
  458. "y": float64(236),
  459. },
  460. "x": float64(740),
  461. "y": float64(236),
  462. },
  463. }
  464. waypoints7 = []interface{}{
  465. map[string]interface{}{
  466. "original": map[string]interface{}{
  467. "x": float64(758),
  468. "y": float64(390),
  469. },
  470. "x": float64(758),
  471. "y": float64(390),
  472. },
  473. map[string]interface{}{"x": float64(792), "y": float64(390)},
  474. map[string]interface{}{
  475. "original": map[string]interface{}{
  476. "x": float64(812),
  477. "y": float64(390),
  478. },
  479. "x": float64(812),
  480. "y": float64(390),
  481. },
  482. }
  483. case "yaml":
  484. boundsMap1 = map[string]interface{}{
  485. "x": 300,
  486. "y": 178,
  487. "width": 100,
  488. "height": 80,
  489. }
  490. boundsMap2 = map[string]interface{}{
  491. "x": 455,
  492. "y": 193,
  493. "width": 50,
  494. "height": 50,
  495. }
  496. boundsMap3 = map[string]interface{}{
  497. "x": 300,
  498. "y": 310,
  499. "width": 100,
  500. "height": 80,
  501. }
  502. boundsMap4 = map[string]interface{}{
  503. "x": 550,
  504. "y": 178,
  505. "width": 100,
  506. "height": 80,
  507. }
  508. boundsMap5 = map[string]interface{}{
  509. "x": 550,
  510. "y": 310,
  511. "width": 100,
  512. "height": 80,
  513. }
  514. boundsMap6 = map[string]interface{}{
  515. "x": 632,
  516. "y": 372,
  517. "width": 36,
  518. "height": 36,
  519. }
  520. boundsMap7 = map[string]interface{}{
  521. "x": 722,
  522. "y": 200,
  523. "width": 36,
  524. "height": 36,
  525. }
  526. boundsMap8 = map[string]interface{}{
  527. "x": 722,
  528. "y": 372,
  529. "width": 36,
  530. "height": 36,
  531. }
  532. boundsMap9 = map[string]interface{}{
  533. "x": 812,
  534. "y": 372,
  535. "width": 36,
  536. "height": 36,
  537. }
  538. waypoints1 = []interface{}{
  539. map[string]interface{}{
  540. "original": map[string]interface{}{
  541. "x": 400,
  542. "y": 218,
  543. },
  544. "x": 400,
  545. "y": 218,
  546. },
  547. map[string]interface{}{"x": 435, "y": 218},
  548. map[string]interface{}{
  549. "original": map[string]interface{}{
  550. "x": 455,
  551. "y": 218,
  552. },
  553. "x": 455,
  554. "y": 218,
  555. },
  556. }
  557. waypoints2 = []interface{}{
  558. map[string]interface{}{
  559. "original": map[string]interface{}{
  560. "x": 505,
  561. "y": 218,
  562. },
  563. "x": 505,
  564. "y": 218,
  565. },
  566. map[string]interface{}{"x": 530, "y": 218},
  567. map[string]interface{}{
  568. "original": map[string]interface{}{
  569. "x": 550,
  570. "y": 218,
  571. },
  572. "x": 550,
  573. "y": 218,
  574. },
  575. }
  576. waypoints3 = []interface{}{
  577. map[string]interface{}{
  578. "original": map[string]interface{}{
  579. "x": 480,
  580. "y": 243,
  581. },
  582. "x": 480,
  583. "y": 243,
  584. },
  585. map[string]interface{}{"x": 600, "y": 290},
  586. map[string]interface{}{
  587. "original": map[string]interface{}{
  588. "x": 600,
  589. "y": 310,
  590. },
  591. "x": 600,
  592. "y": 310,
  593. },
  594. }
  595. waypoints4 = []interface{}{
  596. map[string]interface{}{
  597. "original": map[string]interface{}{
  598. "x": 650,
  599. "y": 218,
  600. },
  601. "x": 650,
  602. "y": 218,
  603. },
  604. map[string]interface{}{"x": 702, "y": 218},
  605. map[string]interface{}{
  606. "original": map[string]interface{}{
  607. "x": 722,
  608. "y": 218,
  609. },
  610. "x": 722,
  611. "y": 218,
  612. },
  613. }
  614. waypoints5 = []interface{}{
  615. map[string]interface{}{
  616. "original": map[string]interface{}{
  617. "x": 668,
  618. "y": 390,
  619. },
  620. "x": 668,
  621. "y": 390,
  622. },
  623. map[string]interface{}{"x": 702, "y": 390},
  624. map[string]interface{}{
  625. "original": map[string]interface{}{
  626. "x": 722,
  627. "y": 390,
  628. },
  629. "x": 722,
  630. "y": 390,
  631. },
  632. }
  633. waypoints6 = []interface{}{
  634. map[string]interface{}{
  635. "original": map[string]interface{}{
  636. "x": 600,
  637. "y": 310,
  638. },
  639. "x": 600,
  640. "y": 310,
  641. },
  642. map[string]interface{}{"x": 740, "y": 256},
  643. map[string]interface{}{
  644. "original": map[string]interface{}{
  645. "x": 740,
  646. "y": 236,
  647. },
  648. "x": 740,
  649. "y": 236,
  650. },
  651. }
  652. waypoints7 = []interface{}{
  653. map[string]interface{}{
  654. "original": map[string]interface{}{
  655. "x": 758,
  656. "y": 390,
  657. },
  658. "x": 758,
  659. "y": 390,
  660. },
  661. map[string]interface{}{"x": 792, "y": 390},
  662. map[string]interface{}{
  663. "original": map[string]interface{}{
  664. "x": 812,
  665. "y": 390,
  666. },
  667. "x": 812,
  668. "y": 390,
  669. },
  670. }
  671. }
  672. return &statemachine.StateMachineObject{
  673. Name: "StateMachineNewDesigner",
  674. Comment: "This state machine is modeled by designer tools.",
  675. Version: "0.0.1",
  676. StartState: "ServiceTask-a9h2o51",
  677. RecoverStrategy: "",
  678. Persist: false,
  679. RetryPersistModeUpdate: false,
  680. CompensatePersistModeUpdate: false,
  681. Type: "",
  682. States: map[string]interface{}{
  683. "ServiceTask-a9h2o51": map[string]interface{}{
  684. "style": map[string]interface{}{
  685. "bounds": boundsMap1,
  686. },
  687. "Name": "ServiceTask-a9h2o51",
  688. "IsForCompensation": false,
  689. "Input": []interface{}{map[string]interface{}{}},
  690. "Output": map[string]interface{}{},
  691. "Status": map[string]interface{}{},
  692. "Retry": []interface{}{},
  693. "ServiceName": "",
  694. "ServiceMethod": "",
  695. "Type": "ServiceTask",
  696. "Next": "Choice-4ajl8nt",
  697. "edge": map[string]interface{}{
  698. "Choice-4ajl8nt": map[string]interface{}{
  699. "style": map[string]interface{}{
  700. "waypoints": waypoints1,
  701. "source": "ServiceTask-a9h2o51",
  702. "target": "Choice-4ajl8nt",
  703. },
  704. "Type": "Transition",
  705. },
  706. },
  707. "CompensateState": "CompensateFirstState",
  708. },
  709. "Choice-4ajl8nt": map[string]interface{}{
  710. "style": map[string]interface{}{
  711. "bounds": boundsMap2,
  712. },
  713. "Name": "Choice-4ajl8nt",
  714. "Type": "Choice",
  715. "Choices": []interface{}{
  716. map[string]interface{}{
  717. "Expression": "",
  718. "Next": "SubStateMachine-cauj9uy",
  719. },
  720. map[string]interface{}{
  721. "Expression": "",
  722. "Next": "ServiceTask-vdij28l",
  723. },
  724. },
  725. "Default": "SubStateMachine-cauj9uy",
  726. "edge": map[string]interface{}{
  727. "SubStateMachine-cauj9uy": map[string]interface{}{
  728. "style": map[string]interface{}{
  729. "waypoints": waypoints2,
  730. "source": "Choice-4ajl8nt",
  731. "target": "SubStateMachine-cauj9uy",
  732. },
  733. "Type": "ChoiceEntry",
  734. },
  735. "ServiceTask-vdij28l": map[string]interface{}{
  736. "style": map[string]interface{}{
  737. "waypoints": waypoints3,
  738. "source": "Choice-4ajl8nt",
  739. "target": "ServiceTask-vdij28l",
  740. },
  741. "Type": "ChoiceEntry",
  742. },
  743. },
  744. },
  745. "CompensateFirstState": map[string]interface{}{
  746. "style": map[string]interface{}{
  747. "bounds": boundsMap3,
  748. },
  749. "Name": "CompensateFirstState",
  750. "IsForCompensation": true,
  751. "Input": []interface{}{map[string]interface{}{}},
  752. "Output": map[string]interface{}{},
  753. "Status": map[string]interface{}{},
  754. "Retry": []interface{}{},
  755. "ServiceName": "",
  756. "ServiceMethod": "",
  757. "Type": "ServiceTask",
  758. },
  759. "SubStateMachine-cauj9uy": map[string]interface{}{
  760. "style": map[string]interface{}{
  761. "bounds": boundsMap4,
  762. },
  763. "Name": "SubStateMachine-cauj9uy",
  764. "IsForCompensation": false,
  765. "Input": []interface{}{map[string]interface{}{}},
  766. "Output": map[string]interface{}{},
  767. "Status": map[string]interface{}{},
  768. "Retry": []interface{}{},
  769. "StateMachineName": "",
  770. "Type": "SubStateMachine",
  771. "Next": "Succeed-5x3z98u",
  772. "edge": map[string]interface{}{
  773. "Succeed-5x3z98u": map[string]interface{}{
  774. "style": map[string]interface{}{
  775. "waypoints": waypoints4,
  776. "source": "SubStateMachine-cauj9uy",
  777. "target": "Succeed-5x3z98u",
  778. },
  779. "Type": "Transition",
  780. },
  781. },
  782. },
  783. "ServiceTask-vdij28l": map[string]interface{}{
  784. "style": map[string]interface{}{
  785. "bounds": boundsMap5,
  786. },
  787. "Name": "ServiceTask-vdij28l",
  788. "IsForCompensation": false,
  789. "Input": []interface{}{map[string]interface{}{}},
  790. "Output": map[string]interface{}{},
  791. "Status": map[string]interface{}{},
  792. "Retry": []interface{}{},
  793. "ServiceName": "",
  794. "ServiceMethod": "",
  795. "Catch": []interface{}{
  796. map[string]interface{}{
  797. "Exceptions": []interface{}{},
  798. "Next": "CompensationTrigger-uldp2ou",
  799. },
  800. },
  801. "Type": "ServiceTask",
  802. "catch": map[string]interface{}{
  803. "style": map[string]interface{}{
  804. "bounds": boundsMap6,
  805. },
  806. "edge": map[string]interface{}{
  807. "CompensationTrigger-uldp2ou": map[string]interface{}{
  808. "style": map[string]interface{}{
  809. "waypoints": waypoints5,
  810. "source": "ServiceTask-vdij28l",
  811. "target": "CompensationTrigger-uldp2ou",
  812. },
  813. "Type": "ExceptionMatch",
  814. },
  815. },
  816. },
  817. "Next": "Succeed-5x3z98u",
  818. "edge": map[string]interface{}{
  819. "Succeed-5x3z98u": map[string]interface{}{
  820. "style": map[string]interface{}{
  821. "waypoints": waypoints6,
  822. "source": "ServiceTask-vdij28l",
  823. "target": "Succeed-5x3z98u",
  824. },
  825. "Type": "Transition",
  826. },
  827. },
  828. },
  829. "Succeed-5x3z98u": map[string]interface{}{
  830. "style": map[string]interface{}{
  831. "bounds": boundsMap7,
  832. },
  833. "Name": "Succeed-5x3z98u",
  834. "Type": "Succeed",
  835. },
  836. "CompensationTrigger-uldp2ou": map[string]interface{}{
  837. "style": map[string]interface{}{
  838. "bounds": boundsMap8,
  839. },
  840. "Name": "CompensationTrigger-uldp2ou",
  841. "Type": "CompensationTrigger",
  842. "Next": "Fail-9roxcv5",
  843. "edge": map[string]interface{}{
  844. "Fail-9roxcv5": map[string]interface{}{
  845. "style": map[string]interface{}{
  846. "waypoints": waypoints7,
  847. "source": "CompensationTrigger-uldp2ou",
  848. "target": "Fail-9roxcv5",
  849. },
  850. "Type": "Transition",
  851. },
  852. },
  853. },
  854. "Fail-9roxcv5": map[string]interface{}{
  855. "style": map[string]interface{}{
  856. "bounds": boundsMap9,
  857. },
  858. "Name": "Fail-9roxcv5",
  859. "ErrorCode": "",
  860. "Message": "",
  861. "Type": "Fail",
  862. },
  863. },
  864. }
  865. }