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_parser.go 8.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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/pkg/errors"
  20. "github.com/seata/seata-go/pkg/saga/statemachine/statelang"
  21. "strconv"
  22. "strings"
  23. "sync"
  24. )
  25. type StateMachineParser interface {
  26. GetType() string
  27. Parse(content string) (statelang.StateMachine, error)
  28. }
  29. type StateParser interface {
  30. StateType() string
  31. Parse(stateName string, stateMap map[string]interface{}) (statelang.State, error)
  32. }
  33. type BaseStateParser struct {
  34. }
  35. func NewBaseStateParser() *BaseStateParser {
  36. return &BaseStateParser{}
  37. }
  38. func (b BaseStateParser) ParseBaseAttributes(stateName string, state statelang.State, stateMap map[string]interface{}) error {
  39. state.SetName(stateName)
  40. comment, err := b.GetStringOrDefault(stateName, stateMap, "Comment", "")
  41. if err != nil {
  42. return err
  43. }
  44. state.SetComment(comment)
  45. next, err := b.GetStringOrDefault(stateName, stateMap, "Next", "")
  46. if err != nil {
  47. return err
  48. }
  49. state.SetNext(next)
  50. return nil
  51. }
  52. func (b BaseStateParser) GetString(stateName string, stateMap map[string]interface{}, key string) (string, error) {
  53. value := stateMap[key]
  54. if value == nil {
  55. var result string
  56. return result, errors.New("State [" + stateName + "] " + key + " not exist")
  57. }
  58. valueAsString, ok := value.(string)
  59. if !ok {
  60. var s string
  61. return s, errors.New("State [" + stateName + "] " + key + " illegal, required string")
  62. }
  63. return valueAsString, nil
  64. }
  65. func (b BaseStateParser) GetStringOrDefault(stateName string, stateMap map[string]interface{}, key string, defaultValue string) (string, error) {
  66. value := stateMap[key]
  67. if value == nil {
  68. return defaultValue, nil
  69. }
  70. valueAsString, ok := value.(string)
  71. if !ok {
  72. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required string")
  73. }
  74. return valueAsString, nil
  75. }
  76. func (b BaseStateParser) GetSlice(stateName string, stateMap map[string]interface{}, key string) ([]interface{}, error) {
  77. value := stateMap[key]
  78. if value == nil {
  79. var result []interface{}
  80. return result, errors.New("State [" + stateName + "] " + key + " not exist")
  81. }
  82. valueAsSlice, ok := value.([]interface{})
  83. if !ok {
  84. var slice []interface{}
  85. return slice, errors.New("State [" + stateName + "] " + key + " illegal, required []interface{}")
  86. }
  87. return valueAsSlice, nil
  88. }
  89. func (b BaseStateParser) GetSliceOrDefault(stateName string, stateMap map[string]interface{}, key string, defaultValue []interface{}) ([]interface{}, error) {
  90. value := stateMap[key]
  91. if value == nil {
  92. return defaultValue, nil
  93. }
  94. valueAsSlice, ok := value.([]interface{})
  95. if !ok {
  96. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required []interface{}")
  97. }
  98. return valueAsSlice, nil
  99. }
  100. func (b BaseStateParser) GetMapOrDefault(stateMap map[string]interface{}, key string, defaultValue map[string]interface{}) (map[string]interface{}, error) {
  101. value := stateMap[key]
  102. if value == nil {
  103. return defaultValue, nil
  104. }
  105. valueAsMap, ok := value.(map[string]interface{})
  106. if !ok {
  107. return defaultValue, nil
  108. }
  109. return valueAsMap, nil
  110. }
  111. func (b BaseStateParser) GetBool(stateName string, stateMap map[string]interface{}, key string) (bool, error) {
  112. value := stateMap[key]
  113. if value == nil {
  114. return false, errors.New("State [" + stateName + "] " + key + " not exist")
  115. }
  116. valueAsBool, ok := value.(bool)
  117. if !ok {
  118. return false, errors.New("State [" + stateName + "] " + key + " illegal, required bool")
  119. }
  120. return valueAsBool, nil
  121. }
  122. func (b BaseStateParser) GetBoolOrDefault(stateName string, stateMap map[string]interface{}, key string, defaultValue bool) (bool, error) {
  123. value := stateMap[key]
  124. if value == nil {
  125. return defaultValue, nil
  126. }
  127. valueAsBool, ok := value.(bool)
  128. if !ok {
  129. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required bool")
  130. }
  131. return valueAsBool, nil
  132. }
  133. func (b BaseStateParser) GetIntOrDefault(stateName string, stateMap map[string]interface{}, key string, defaultValue int) (int, error) {
  134. value := stateMap[key]
  135. if value == nil {
  136. return defaultValue, nil
  137. }
  138. // use float64 conversion when the configuration file is json, and use int conversion when the configuration file is yaml
  139. valueAsFloat64, okToFloat64 := value.(float64)
  140. valueAsInt, okToInt := value.(int)
  141. if !okToFloat64 && !okToInt {
  142. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required int")
  143. }
  144. if okToFloat64 {
  145. floatStr := strconv.FormatFloat(valueAsFloat64, 'f', -1, 64)
  146. if strings.Contains(floatStr, ".") {
  147. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required int")
  148. }
  149. return int(valueAsFloat64), nil
  150. }
  151. return valueAsInt, nil
  152. }
  153. func (b BaseStateParser) GetFloat64OrDefault(stateName string, stateMap map[string]interface{}, key string, defaultValue float64) (float64, error) {
  154. value := stateMap[key]
  155. if value == nil {
  156. return defaultValue, nil
  157. }
  158. // use float64 conversion when the configuration file is json, and use int conversion when the configuration file is yaml
  159. valueAsFloat64, okToFloat64 := value.(float64)
  160. valueAsInt, okToInt := value.(int)
  161. if !okToFloat64 && !okToInt {
  162. return defaultValue, errors.New("State [" + stateName + "] " + key + " illegal, required float64")
  163. }
  164. if okToFloat64 {
  165. return valueAsFloat64, nil
  166. }
  167. return float64(valueAsInt), nil
  168. }
  169. type StateParserFactory interface {
  170. RegistryStateParser(stateType string, stateParser StateParser)
  171. GetStateParser(stateType string) StateParser
  172. }
  173. type DefaultStateParserFactory struct {
  174. stateParserMap map[string]StateParser
  175. mutex sync.Mutex
  176. }
  177. func NewDefaultStateParserFactory() *DefaultStateParserFactory {
  178. var stateParserMap map[string]StateParser = make(map[string]StateParser)
  179. return &DefaultStateParserFactory{
  180. stateParserMap: stateParserMap,
  181. }
  182. }
  183. // InitDefaultStateParser init StateParser by default
  184. func (d *DefaultStateParserFactory) InitDefaultStateParser() {
  185. choiceStateParser := NewChoiceStateParser()
  186. serviceTaskStateParser := NewServiceTaskStateParser()
  187. subStateMachineParser := NewSubStateMachineParser()
  188. succeedEndStateParser := NewSucceedEndStateParser()
  189. compensationTriggerStateParser := NewCompensationTriggerStateParser()
  190. failEndStateParser := NewFailEndStateParser()
  191. scriptTaskStateParser := NewScriptTaskStateParser()
  192. d.RegistryStateParser(choiceStateParser.StateType(), choiceStateParser)
  193. d.RegistryStateParser(serviceTaskStateParser.StateType(), serviceTaskStateParser)
  194. d.RegistryStateParser(subStateMachineParser.StateType(), subStateMachineParser)
  195. d.RegistryStateParser(succeedEndStateParser.StateType(), succeedEndStateParser)
  196. d.RegistryStateParser(compensationTriggerStateParser.StateType(), compensationTriggerStateParser)
  197. d.RegistryStateParser(compensationTriggerStateParser.StateType(), compensationTriggerStateParser)
  198. d.RegistryStateParser(failEndStateParser.StateType(), failEndStateParser)
  199. d.RegistryStateParser(scriptTaskStateParser.StateType(), scriptTaskStateParser)
  200. }
  201. func (d *DefaultStateParserFactory) RegistryStateParser(stateType string, stateParser StateParser) {
  202. d.mutex.Lock()
  203. defer d.mutex.Unlock()
  204. d.stateParserMap[stateType] = stateParser
  205. }
  206. func (d *DefaultStateParserFactory) GetStateParser(stateType string) StateParser {
  207. return d.stateParserMap[stateType]
  208. }