chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
41
saga/seata-saga-statelang/pom.xml
Normal file
41
saga/seata-saga-statelang/pom.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-saga</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<name>seata-saga-statelang ${project.version}</name>
|
||||
<artifactId>seata-saga-statelang</artifactId>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Choice State, We can choose only one choice
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface ChoiceState extends State {
|
||||
|
||||
/**
|
||||
* get choices
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Choice> getChoices();
|
||||
|
||||
/**
|
||||
* default choice
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDefault();
|
||||
|
||||
/**
|
||||
* Choice
|
||||
*/
|
||||
static interface Choice {
|
||||
|
||||
String getExpression();
|
||||
|
||||
String getNext();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Compensate SubStateMachine State
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface CompensateSubStateMachineState extends ServiceTaskState {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Compensation trigger State
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface CompensationTriggerState extends State {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* State Language Domain Constants
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface DomainConstants {
|
||||
|
||||
//region State Types
|
||||
String STATE_TYPE_SERVICE_TASK = "ServiceTask";
|
||||
String STATE_TYPE_CHOICE = "Choice";
|
||||
String STATE_TYPE_FAIL = "Fail";
|
||||
String STATE_TYPE_SUCCEED = "Succeed";
|
||||
String STATE_TYPE_COMPENSATION_TRIGGER = "CompensationTrigger";
|
||||
String STATE_TYPE_SUB_STATE_MACHINE = "SubStateMachine";
|
||||
String STATE_TYPE_SUB_MACHINE_COMPENSATION = "CompensateSubMachine";
|
||||
String STATE_TYPE_SCRIPT_TASK = "ScriptTask";
|
||||
String STATE_TYPE_LOOP_START = "LoopStart";
|
||||
//endregion
|
||||
|
||||
String COMPENSATE_SUB_MACHINE_STATE_NAME_PREFIX = "_compensate_sub_machine_state_";
|
||||
|
||||
//region Service Types
|
||||
String SERVICE_TYPE_SPRING_BEAN = "SpringBean";
|
||||
//endregion
|
||||
|
||||
//region System Variables
|
||||
String VAR_NAME_STATEMACHINE_CONTEXT = "context";
|
||||
String VAR_NAME_INPUT_PARAMS = "inputParams";
|
||||
String VAR_NAME_OUTPUT_PARAMS = "outputParams";
|
||||
String VAR_NAME_CURRENT_EXCEPTION = "currentException";//exception of current state
|
||||
String VAR_NAME_BUSINESSKEY = "_business_key_";
|
||||
String VAR_NAME_SUB_MACHINE_PARENT_ID = "_sub_machine_parent_id_";
|
||||
String VAR_NAME_CURRENT_CHOICE = "_current_choice_";
|
||||
String VAR_NAME_STATEMACHINE_ERROR_CODE = "_statemachine_error_code_";
|
||||
String VAR_NAME_STATEMACHINE_ERROR_MSG = "_statemachine_error_message_";
|
||||
String VAR_NAME_CURRENT_EXCEPTION_ROUTE = "_current_exception_route_";
|
||||
String VAR_NAME_STATEMACHINE = "_current_statemachine_";
|
||||
String VAR_NAME_STATEMACHINE_INST = "_current_statemachine_instance_";
|
||||
String VAR_NAME_STATEMACHINE_ENGINE = "_current_statemachine_engine_";
|
||||
String VAR_NAME_STATE_INST = "_current_state_instance_";
|
||||
String VAR_NAME_STATEMACHINE_CONFIG = "_statemachine_config_";
|
||||
String VAR_NAME_FAIL_END_STATE_FLAG = "_fail_end_state_flag_";
|
||||
String VAR_NAME_CURRENT_COMPENSATION_HOLDER = "_current_compensation_holder_";
|
||||
String VAR_NAME_RETRIED_STATE_INST_ID = "_retried_state_instance_id";
|
||||
String VAR_NAME_OPERATION_NAME = "_operation_name_";
|
||||
String VAR_NAME_ASYNC_CALLBACK = "_async_callback_";
|
||||
String VAR_NAME_CURRENT_COMPEN_TRIGGER_STATE = "_is_compensating_";
|
||||
String VAR_NAME_IS_EXCEPTION_NOT_CATCH = "_is_exception_not_catch_";
|
||||
String VAR_NAME_PARENT_ID = "_parent_id_";
|
||||
String VAR_NAME_SUB_STATEMACHINE_EXEC_STATUE = "_sub_statemachine_execution_status_";
|
||||
String VAR_NAME_IS_FOR_SUB_STATMACHINE_FORWARD = "_is_for_sub_statemachine_forward_";
|
||||
String VAR_NAME_FIRST_COMPENSATION_STATE_STARTED = "_first_compensation_state_started";
|
||||
String VAR_NAME_GLOBAL_TX = "_global_transaction_";
|
||||
String VAR_NAME_IS_ASYNC_EXECUTION = "_is_async_execution_";
|
||||
String VAR_NAME_IS_LOOP_STATE = "_is_loop_state_";
|
||||
String VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER = "_current_loop_context_holder_";
|
||||
//endregion
|
||||
|
||||
// region of loop
|
||||
String LOOP_COUNTER = "loopCounter";
|
||||
String LOOP_SEMAPHORE = "loopSemaphore";
|
||||
String LOOP_RESULT = "loopResult";
|
||||
String NUMBER_OF_INSTANCES = "nrOfInstances";
|
||||
String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances";
|
||||
String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";
|
||||
// endregion
|
||||
|
||||
String OPERATION_NAME_START = "start";
|
||||
String OPERATION_NAME_FORWARD = "forward";
|
||||
String OPERATION_NAME_COMPENSATE = "compensate";
|
||||
|
||||
String SEQ_ENTITY_STATE_MACHINE = "STATE_MACHINE";
|
||||
String SEQ_ENTITY_STATE_MACHINE_INST = "STATE_MACHINE_INST";
|
||||
String SEQ_ENTITY_STATE_INST = "STATE_INST";
|
||||
|
||||
String EXPRESSION_TYPE_SEQUENCE = "Sequence";
|
||||
String EVALUATOR_TYPE_EXCEPTION = "Exception";
|
||||
|
||||
String SEPERATOR_PARENT_ID = ":";
|
||||
|
||||
String DEFAULT_JSON_PARSER = "fastjson";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* End State
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface EndState extends State {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Execution Status
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public enum ExecutionStatus {
|
||||
|
||||
/**
|
||||
* Running
|
||||
*/
|
||||
RU("Running"),
|
||||
|
||||
/**
|
||||
* Succeed
|
||||
*/
|
||||
SU("Succeed"),
|
||||
|
||||
/**
|
||||
* Failed
|
||||
*/
|
||||
FA("Failed"),
|
||||
|
||||
/**
|
||||
* Unknown
|
||||
*/
|
||||
UN("Unknown"),
|
||||
|
||||
/**
|
||||
* Skipped
|
||||
*/
|
||||
SK("Skipped");
|
||||
|
||||
private String statusString;
|
||||
|
||||
private ExecutionStatus(String statusString) {
|
||||
this.statusString = statusString;
|
||||
}
|
||||
|
||||
public String getStatusString() {
|
||||
return statusString;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Fail End State
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface FailEndState extends EndState {
|
||||
|
||||
/**
|
||||
* error code
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getErrorCode();
|
||||
|
||||
/**
|
||||
* error message
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getMessage();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Loop Starter
|
||||
*
|
||||
* @author anselleeyy
|
||||
*/
|
||||
public interface LoopStartState extends State {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* Recover Strategy
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public enum RecoverStrategy {
|
||||
|
||||
/**
|
||||
* Compensate
|
||||
*/
|
||||
Compensate,
|
||||
|
||||
/**
|
||||
* Forward
|
||||
*/
|
||||
Forward;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* ScriptTask State, execute scripts
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface ScriptTaskState extends TaskState {
|
||||
|
||||
/**
|
||||
* get ScriptType such as groovy
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getScriptType();
|
||||
|
||||
/**
|
||||
* get ScriptContent
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getScriptContent();
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ServiceTask State, be used to invoke a service
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface ServiceTaskState extends TaskState {
|
||||
|
||||
/**
|
||||
* Service type: such as SpringBean, SOFA RPC, default is StringBean
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceType();
|
||||
|
||||
/**
|
||||
* service name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceName();
|
||||
|
||||
/**
|
||||
* service method
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceMethod();
|
||||
|
||||
/**
|
||||
* service method
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<String> getParameterTypes();
|
||||
|
||||
/**
|
||||
* Is it necessary to persist the service execution log? default is true
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isPersist();
|
||||
|
||||
/**
|
||||
* Is update last retry execution log, default append new
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean isRetryPersistModeUpdate();
|
||||
|
||||
/**
|
||||
* Is update last compensate execution log, default append new
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean isCompensatePersistModeUpdate();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A State in StateMachine
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface State {
|
||||
|
||||
/**
|
||||
* name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* comment
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getComment();
|
||||
|
||||
/**
|
||||
* type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* next state name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getNext();
|
||||
|
||||
/**
|
||||
* extension properties
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> getExtensions();
|
||||
|
||||
/**
|
||||
* state machine instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
StateMachine getStateMachine();
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* State execution instance
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface StateInstance {
|
||||
|
||||
/**
|
||||
* id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* set id
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setId(String id);
|
||||
|
||||
/**
|
||||
* get Machine InstanceId
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getMachineInstanceId();
|
||||
|
||||
/**
|
||||
* set Machine InstanceId
|
||||
*
|
||||
* @param machineInstanceId
|
||||
*/
|
||||
void setMachineInstanceId(String machineInstanceId);
|
||||
|
||||
/**
|
||||
* get name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* set name
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* get type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* set type
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
void setType(String type);
|
||||
|
||||
/**
|
||||
* get service name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceName();
|
||||
|
||||
/**
|
||||
* set service name
|
||||
*
|
||||
* @param serviceName
|
||||
*/
|
||||
void setServiceName(String serviceName);
|
||||
|
||||
/**
|
||||
* get service method
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceMethod();
|
||||
|
||||
/**
|
||||
* set service method
|
||||
*
|
||||
* @param serviceMethod
|
||||
*/
|
||||
void setServiceMethod(String serviceMethod);
|
||||
|
||||
/**
|
||||
* get service type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getServiceType();
|
||||
|
||||
/**
|
||||
* get service type
|
||||
*
|
||||
* @param serviceType
|
||||
*/
|
||||
void setServiceType(String serviceType);
|
||||
|
||||
/**
|
||||
* get businessKey
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getBusinessKey();
|
||||
|
||||
/**
|
||||
* set business key
|
||||
*
|
||||
* @param businessKey
|
||||
*/
|
||||
void setBusinessKey(String businessKey);
|
||||
|
||||
/**
|
||||
* get start time
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Date getGmtStarted();
|
||||
|
||||
/**
|
||||
* set start time
|
||||
*
|
||||
* @param gmtStarted
|
||||
*/
|
||||
void setGmtStarted(Date gmtStarted);
|
||||
|
||||
/**
|
||||
* get update time
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Date getGmtUpdated();
|
||||
|
||||
/**
|
||||
* set update time
|
||||
*
|
||||
* @param gmtUpdated
|
||||
*/
|
||||
void setGmtUpdated(Date gmtUpdated);
|
||||
|
||||
/**
|
||||
* get end time
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Date getGmtEnd();
|
||||
|
||||
/**
|
||||
* set end time
|
||||
*
|
||||
* @param gmtEnd
|
||||
*/
|
||||
void setGmtEnd(Date gmtEnd);
|
||||
|
||||
/**
|
||||
* Is this state task will update data?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isForUpdate();
|
||||
|
||||
/**
|
||||
* setForUpdate
|
||||
*
|
||||
* @param forUpdate
|
||||
*/
|
||||
void setForUpdate(boolean forUpdate);
|
||||
|
||||
/**
|
||||
* get exception
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Exception getException();
|
||||
|
||||
/**
|
||||
* set exception
|
||||
*
|
||||
* @param exception
|
||||
*/
|
||||
void setException(Exception exception);
|
||||
|
||||
/**
|
||||
* get input params
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object getInputParams();
|
||||
|
||||
/**
|
||||
* set inout params
|
||||
*
|
||||
* @param inputParams
|
||||
*/
|
||||
void setInputParams(Object inputParams);
|
||||
|
||||
/**
|
||||
* get output params
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object getOutputParams();
|
||||
|
||||
/**
|
||||
* Sets set output params.
|
||||
*
|
||||
* @param outputParams the output params
|
||||
*/
|
||||
void setOutputParams(Object outputParams);
|
||||
|
||||
/**
|
||||
* Gets get status.
|
||||
*
|
||||
* @return the get status
|
||||
*/
|
||||
ExecutionStatus getStatus();
|
||||
|
||||
/**
|
||||
* Sets set status.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
void setStatus(ExecutionStatus status);
|
||||
|
||||
/**
|
||||
* Gets get state id compensated for.
|
||||
*
|
||||
* @return the get state id compensated for
|
||||
*/
|
||||
String getStateIdCompensatedFor();
|
||||
|
||||
/**
|
||||
* Sets set state id compensated for.
|
||||
*
|
||||
* @param stateIdCompensatedFor the state id compensated for
|
||||
*/
|
||||
void setStateIdCompensatedFor(String stateIdCompensatedFor);
|
||||
|
||||
/**
|
||||
* Gets get state id retried for.
|
||||
*
|
||||
* @return the get state id retried for
|
||||
*/
|
||||
String getStateIdRetriedFor();
|
||||
|
||||
/**
|
||||
* Sets set state id retried for.
|
||||
*
|
||||
* @param stateIdRetriedFor the state id retried for
|
||||
*/
|
||||
void setStateIdRetriedFor(String stateIdRetriedFor);
|
||||
|
||||
/**
|
||||
* Gets get compensation state.
|
||||
*
|
||||
* @return the get compensation state
|
||||
*/
|
||||
StateInstance getCompensationState();
|
||||
|
||||
/**
|
||||
* Sets set compensation state.
|
||||
*
|
||||
* @param compensationState the compensation state
|
||||
*/
|
||||
void setCompensationState(StateInstance compensationState);
|
||||
|
||||
/**
|
||||
* Gets get state machine instance.
|
||||
*
|
||||
* @return the get state machine instance
|
||||
*/
|
||||
StateMachineInstance getStateMachineInstance();
|
||||
|
||||
/**
|
||||
* Sets set state machine instance.
|
||||
*
|
||||
* @param stateMachineInstance the state machine instance
|
||||
*/
|
||||
void setStateMachineInstance(StateMachineInstance stateMachineInstance);
|
||||
|
||||
/**
|
||||
* Is ignore status boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean isIgnoreStatus();
|
||||
|
||||
/**
|
||||
* Sets set ignore status.
|
||||
*
|
||||
* @param ignoreStatus the ignore status
|
||||
*/
|
||||
void setIgnoreStatus(boolean ignoreStatus);
|
||||
|
||||
/**
|
||||
* Is for compensation boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean isForCompensation();
|
||||
|
||||
/**
|
||||
* Gets get serialized input params.
|
||||
*
|
||||
* @return the get serialized input params
|
||||
*/
|
||||
Object getSerializedInputParams();
|
||||
|
||||
/**
|
||||
* Sets set serialized input params.
|
||||
*
|
||||
* @param serializedInputParams the serialized input params
|
||||
*/
|
||||
void setSerializedInputParams(Object serializedInputParams);
|
||||
|
||||
/**
|
||||
* Gets get serialized output params.
|
||||
*
|
||||
* @return the get serialized output params
|
||||
*/
|
||||
Object getSerializedOutputParams();
|
||||
|
||||
/**
|
||||
* Sets set serialized output params.
|
||||
*
|
||||
* @param serializedOutputParams the serialized output params
|
||||
*/
|
||||
void setSerializedOutputParams(Object serializedOutputParams);
|
||||
|
||||
/**
|
||||
* Gets get serialized exception.
|
||||
*
|
||||
* @return the get serialized exception
|
||||
*/
|
||||
Object getSerializedException();
|
||||
|
||||
/**
|
||||
* Sets set serialized exception.
|
||||
*
|
||||
* @param serializedException the serialized exception
|
||||
*/
|
||||
void setSerializedException(Object serializedException);
|
||||
|
||||
/**
|
||||
* Gets get compensation status.
|
||||
*
|
||||
* @return the get compensation status
|
||||
*/
|
||||
ExecutionStatus getCompensationStatus();
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* StateMachine
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface StateMachine {
|
||||
|
||||
/**
|
||||
* name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* comment
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getComment();
|
||||
|
||||
/**
|
||||
* start state name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getStartState();
|
||||
|
||||
void setStartState(String startState);
|
||||
|
||||
/**
|
||||
* version
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* set version
|
||||
*
|
||||
* @param version
|
||||
*/
|
||||
void setVersion(String version);
|
||||
|
||||
/**
|
||||
* states
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String/** state machine name **/, State> getStates();
|
||||
|
||||
/**
|
||||
* get state
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
State getState(String name);
|
||||
|
||||
/**
|
||||
* get id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getId();
|
||||
|
||||
void setId(String id);
|
||||
|
||||
/**
|
||||
* get tenantId
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getTenantId();
|
||||
|
||||
/**
|
||||
* set tenantId
|
||||
*
|
||||
* @param tenantId
|
||||
*/
|
||||
void setTenantId(String tenantId);
|
||||
|
||||
/**
|
||||
* app name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAppName();
|
||||
|
||||
/**
|
||||
* type, there is only one type: SSL(SEATA state language)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* statue (Active|Inactive)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Status getStatus();
|
||||
|
||||
/**
|
||||
* recover strategy: prefer compensation or forward when error occurred
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
RecoverStrategy getRecoverStrategy();
|
||||
|
||||
/**
|
||||
* set RecoverStrategy
|
||||
*
|
||||
* @param recoverStrategy
|
||||
*/
|
||||
void setRecoverStrategy(RecoverStrategy recoverStrategy);
|
||||
|
||||
/**
|
||||
* Is it persist execution log to storage?, default true
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isPersist();
|
||||
|
||||
/**
|
||||
* Is update last retry execution log, default append new
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean isRetryPersistModeUpdate();
|
||||
|
||||
/**
|
||||
* Is update last compensate execution log, default append new
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean isCompensatePersistModeUpdate();
|
||||
|
||||
/**
|
||||
* State language text
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getContent();
|
||||
|
||||
void setContent(String content);
|
||||
|
||||
/**
|
||||
* get create time
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Date getGmtCreate();
|
||||
|
||||
/**
|
||||
* set create time
|
||||
*
|
||||
* @param date
|
||||
*/
|
||||
void setGmtCreate(Date date);
|
||||
|
||||
enum Status {
|
||||
/**
|
||||
* Active
|
||||
*/
|
||||
AC("Active"),
|
||||
/**
|
||||
* Inactive
|
||||
*/
|
||||
IN("Inactive");
|
||||
|
||||
private String statusString;
|
||||
|
||||
Status(String statusString) {
|
||||
this.statusString = statusString;
|
||||
}
|
||||
|
||||
public String getStatusString() {
|
||||
return statusString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* StateMachine execution instance
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface StateMachineInstance {
|
||||
|
||||
/**
|
||||
* Gets get id.
|
||||
*
|
||||
* @return the get id
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Sets set id.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
void setId(String id);
|
||||
|
||||
/**
|
||||
* Gets get machine id.
|
||||
*
|
||||
* @return the get machine id
|
||||
*/
|
||||
String getMachineId();
|
||||
|
||||
/**
|
||||
* Sets set machine id.
|
||||
*
|
||||
* @param machineId the machine id
|
||||
*/
|
||||
void setMachineId(String machineId);
|
||||
|
||||
/**
|
||||
* Gets get tenant id.
|
||||
*
|
||||
* @return the tenant id
|
||||
*/
|
||||
String getTenantId();
|
||||
|
||||
/**
|
||||
* Sets set tenant id.
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
void setTenantId(String tenantId);
|
||||
|
||||
/**
|
||||
* Gets get parent id.
|
||||
*
|
||||
* @return the get parent id
|
||||
*/
|
||||
String getParentId();
|
||||
|
||||
/**
|
||||
* Sets set parent id.
|
||||
*
|
||||
* @param parentId the parent id
|
||||
*/
|
||||
void setParentId(String parentId);
|
||||
|
||||
/**
|
||||
* Gets get gmt started.
|
||||
*
|
||||
* @return the get gmt started
|
||||
*/
|
||||
Date getGmtStarted();
|
||||
|
||||
/**
|
||||
* Sets set gmt started.
|
||||
*
|
||||
* @param gmtStarted the gmt started
|
||||
*/
|
||||
void setGmtStarted(Date gmtStarted);
|
||||
|
||||
/**
|
||||
* Gets get gmt end.
|
||||
*
|
||||
* @return the get gmt end
|
||||
*/
|
||||
Date getGmtEnd();
|
||||
|
||||
/**
|
||||
* Sets set gmt end.
|
||||
*
|
||||
* @param gmtEnd the gmt end
|
||||
*/
|
||||
void setGmtEnd(Date gmtEnd);
|
||||
|
||||
/**
|
||||
* Put state instance.
|
||||
*
|
||||
* @param stateId the state id
|
||||
* @param stateInstance the state instance
|
||||
*/
|
||||
void putStateInstance(String stateId, StateInstance stateInstance);
|
||||
|
||||
/**
|
||||
* Gets get status.
|
||||
*
|
||||
* @return the get status
|
||||
*/
|
||||
ExecutionStatus getStatus();
|
||||
|
||||
/**
|
||||
* Sets set status.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
void setStatus(ExecutionStatus status);
|
||||
|
||||
/**
|
||||
* Gets get compensation status.
|
||||
*
|
||||
* @return the get compensation status
|
||||
*/
|
||||
ExecutionStatus getCompensationStatus();
|
||||
|
||||
/**
|
||||
* Sets set compensation status.
|
||||
*
|
||||
* @param compensationStatus the compensation status
|
||||
*/
|
||||
void setCompensationStatus(ExecutionStatus compensationStatus);
|
||||
|
||||
/**
|
||||
* Is running boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean isRunning();
|
||||
|
||||
/**
|
||||
* Sets set running.
|
||||
*
|
||||
* @param running the running
|
||||
*/
|
||||
void setRunning(boolean running);
|
||||
|
||||
/**
|
||||
* Gets get gmt updated.
|
||||
*
|
||||
* @return the get gmt updated
|
||||
*/
|
||||
Date getGmtUpdated();
|
||||
|
||||
/**
|
||||
* Sets set gmt updated.
|
||||
*
|
||||
* @param gmtUpdated the gmt updated
|
||||
*/
|
||||
void setGmtUpdated(Date gmtUpdated);
|
||||
|
||||
/**
|
||||
* Gets get business key.
|
||||
*
|
||||
* @return the get business key
|
||||
*/
|
||||
String getBusinessKey();
|
||||
|
||||
/**
|
||||
* Sets set business key.
|
||||
*
|
||||
* @param businessKey the business key
|
||||
*/
|
||||
void setBusinessKey(String businessKey);
|
||||
|
||||
/**
|
||||
* Gets get exception.
|
||||
*
|
||||
* @return the get exception
|
||||
*/
|
||||
Exception getException();
|
||||
|
||||
/**
|
||||
* Sets set exception.
|
||||
*
|
||||
* @param exception the exception
|
||||
*/
|
||||
void setException(Exception exception);
|
||||
|
||||
/**
|
||||
* Gets get start params.
|
||||
*
|
||||
* @return the get start params
|
||||
*/
|
||||
Map<String, Object> getStartParams();
|
||||
|
||||
/**
|
||||
* Sets set start params.
|
||||
*
|
||||
* @param startParams the start params
|
||||
*/
|
||||
void setStartParams(Map<String, Object> startParams);
|
||||
|
||||
/**
|
||||
* Gets get end params.
|
||||
*
|
||||
* @return the get end params
|
||||
*/
|
||||
Map<String, Object> getEndParams();
|
||||
|
||||
/**
|
||||
* Sets set end params.
|
||||
*
|
||||
* @param endParams the end params
|
||||
*/
|
||||
void setEndParams(Map<String, Object> endParams);
|
||||
|
||||
/**
|
||||
* Gets get context.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> getContext();
|
||||
|
||||
/**
|
||||
* Sets set context.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void setContext(Map<String, Object> context);
|
||||
|
||||
/**
|
||||
* Gets get state machine.
|
||||
*
|
||||
* @return the get state machine
|
||||
*/
|
||||
StateMachine getStateMachine();
|
||||
|
||||
/**
|
||||
* Sets set state machine.
|
||||
*
|
||||
* @param stateMachine the state machine
|
||||
*/
|
||||
void setStateMachine(StateMachine stateMachine);
|
||||
|
||||
/**
|
||||
* Gets get state list.
|
||||
*
|
||||
* @return the get state list
|
||||
*/
|
||||
List<StateInstance> getStateList();
|
||||
|
||||
/**
|
||||
* Sets set state list.
|
||||
*
|
||||
* @param stateList the state list
|
||||
*/
|
||||
void setStateList(List<StateInstance> stateList);
|
||||
|
||||
/**
|
||||
* Gets get state map.
|
||||
*
|
||||
* @return the get state map
|
||||
*/
|
||||
Map<String, StateInstance> getStateMap();
|
||||
|
||||
/**
|
||||
* Sets set state map.
|
||||
*
|
||||
* @param stateMap the state map
|
||||
*/
|
||||
void setStateMap(Map<String, StateInstance> stateMap);
|
||||
|
||||
/**
|
||||
* Gets get serialized start params.
|
||||
*
|
||||
* @return the get serialized start params
|
||||
*/
|
||||
Object getSerializedStartParams();
|
||||
|
||||
/**
|
||||
* Sets set serialized start params.
|
||||
*
|
||||
* @param serializedStartParams the serialized start params
|
||||
*/
|
||||
void setSerializedStartParams(Object serializedStartParams);
|
||||
|
||||
/**
|
||||
* Gets get serialized end params.
|
||||
*
|
||||
* @return the get serialized end params
|
||||
*/
|
||||
Object getSerializedEndParams();
|
||||
|
||||
/**
|
||||
* Sets set serialized end params.
|
||||
*
|
||||
* @param serializedEndParams the serialized end params
|
||||
*/
|
||||
void setSerializedEndParams(Object serializedEndParams);
|
||||
|
||||
/**
|
||||
* Gets get serialized exception.
|
||||
*
|
||||
* @return the get serialized exception
|
||||
*/
|
||||
Object getSerializedException();
|
||||
|
||||
/**
|
||||
* Sets set serialized exception.
|
||||
*
|
||||
* @param serializedException the serialized exception
|
||||
*/
|
||||
void setSerializedException(Object serializedException);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* SubStateMachine
|
||||
*
|
||||
* @author lorne.cl
|
||||
* @see TaskState
|
||||
*/
|
||||
public interface SubStateMachine extends TaskState {
|
||||
|
||||
/**
|
||||
* state machine name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getStateMachineName();
|
||||
|
||||
/**
|
||||
* Get compensate state object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TaskState getCompensateStateObject();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
/**
|
||||
* SucceedEndState
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface SucceedEndState extends EndState {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A state used to execute a task
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface TaskState extends State {
|
||||
|
||||
/**
|
||||
* get compensate state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCompensateState();
|
||||
|
||||
/**
|
||||
* Is this state is used to compensate an other state, default false
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isForCompensation();
|
||||
|
||||
/**
|
||||
* Is this state will update data? default false
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isForUpdate();
|
||||
|
||||
/**
|
||||
* retry strategy
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Retry> getRetry();
|
||||
|
||||
/**
|
||||
* exception handling strategy
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ExceptionMatch> getCatches();
|
||||
|
||||
/**
|
||||
* Execution state determination rule
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> getStatus();
|
||||
|
||||
/**
|
||||
* loop strategy
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Loop getLoop();
|
||||
|
||||
/**
|
||||
* retry strategy
|
||||
*/
|
||||
interface Retry {
|
||||
|
||||
/**
|
||||
* exceptions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<String> getExceptions();
|
||||
|
||||
/**
|
||||
* exception classes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Class<? extends Exception>> getExceptionClasses();
|
||||
|
||||
/**
|
||||
* set exception classes
|
||||
* @param exceptionClasses
|
||||
*/
|
||||
void setExceptionClasses(List<Class<? extends Exception>> exceptionClasses);
|
||||
|
||||
/**
|
||||
* getIntervalSeconds
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double getIntervalSeconds();
|
||||
|
||||
/**
|
||||
* getMaxAttempts
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getMaxAttempts();
|
||||
|
||||
/**
|
||||
* get BackoffRate, default 1
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double getBackoffRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* exception match
|
||||
*/
|
||||
interface ExceptionMatch {
|
||||
|
||||
/**
|
||||
* exceptions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<String> getExceptions();
|
||||
|
||||
/**
|
||||
* exception classes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Class<? extends Exception>> getExceptionClasses();
|
||||
|
||||
/**
|
||||
* set exception classes
|
||||
* @param exceptionClasses
|
||||
*/
|
||||
void setExceptionClasses(List<Class<? extends Exception>> exceptionClasses);
|
||||
|
||||
/**
|
||||
* next state name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* status match
|
||||
*/
|
||||
interface StatusMatch {
|
||||
|
||||
/**
|
||||
* status
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ExecutionStatus getStatus();
|
||||
|
||||
/**
|
||||
* expression
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getExpression();
|
||||
|
||||
/**
|
||||
* expression type, default(SpringEL)|exception
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getExpressionType();
|
||||
}
|
||||
|
||||
/**
|
||||
* loop strategy
|
||||
*/
|
||||
interface Loop {
|
||||
|
||||
/**
|
||||
* parallel size, default 1
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getParallel();
|
||||
|
||||
/**
|
||||
* collection object name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollection();
|
||||
|
||||
/**
|
||||
* element variable name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getElementVariableName();
|
||||
|
||||
/**
|
||||
* element variable index name, default loopCounter
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getElementIndexName();
|
||||
|
||||
/**
|
||||
* completion condition, default nrOfInstances == nrOfCompletedInstances
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCompletionCondition();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.saga.statelang.domain.TaskState;
|
||||
|
||||
/**
|
||||
* The state of the execution task (abstract class), the specific task to be executed is determined by the subclass
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public abstract class AbstractTaskState extends BaseState implements TaskState {
|
||||
|
||||
private String compensateState;
|
||||
private boolean isForCompensation;
|
||||
private boolean isForUpdate;
|
||||
private List<Retry> retry;
|
||||
private List<ExceptionMatch> catches;
|
||||
private List<Object> input;
|
||||
private Map<String, Object> output;
|
||||
private Map<String, String> status;//Map<String/* expression */, String /* status */>
|
||||
private List<Object> inputExpressions;
|
||||
private Map<String, Object> outputExpressions;
|
||||
private boolean isPersist = true;
|
||||
private Boolean retryPersistModeUpdate;
|
||||
private Boolean compensatePersistModeUpdate;
|
||||
private Loop loop;
|
||||
|
||||
@Override
|
||||
public String getCompensateState() {
|
||||
return compensateState;
|
||||
}
|
||||
|
||||
public void setCompensateState(String compensateState) {
|
||||
this.compensateState = compensateState;
|
||||
|
||||
if (StringUtils.isNotBlank(this.compensateState)) {
|
||||
setForUpdate(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForCompensation() {
|
||||
return isForCompensation;
|
||||
}
|
||||
|
||||
public void setForCompensation(boolean isForCompensation) {
|
||||
this.isForCompensation = isForCompensation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForUpdate() {
|
||||
return this.isForUpdate;
|
||||
}
|
||||
|
||||
public void setForUpdate(boolean isForUpdate) {
|
||||
this.isForUpdate = isForUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Retry> getRetry() {
|
||||
return retry;
|
||||
}
|
||||
|
||||
public void setRetry(List<Retry> retry) {
|
||||
this.retry = retry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExceptionMatch> getCatches() {
|
||||
return catches;
|
||||
}
|
||||
|
||||
public void setCatches(List<ExceptionMatch> catches) {
|
||||
this.catches = catches;
|
||||
}
|
||||
|
||||
public List<Object> getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public void setInput(List<Object> input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public Map<String, Object> getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public void setOutput(Map<String, Object> output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public boolean isPersist() {
|
||||
return isPersist;
|
||||
}
|
||||
|
||||
public void setPersist(boolean persist) {
|
||||
isPersist = persist;
|
||||
}
|
||||
|
||||
public Boolean isRetryPersistModeUpdate() {
|
||||
return retryPersistModeUpdate;
|
||||
}
|
||||
|
||||
public void setRetryPersistModeUpdate(Boolean retryPersistModeUpdate) {
|
||||
this.retryPersistModeUpdate = retryPersistModeUpdate;
|
||||
}
|
||||
|
||||
public Boolean isCompensatePersistModeUpdate() {
|
||||
return compensatePersistModeUpdate;
|
||||
}
|
||||
|
||||
public void setCompensatePersistModeUpdate(Boolean compensatePersistModeUpdate) {
|
||||
this.compensatePersistModeUpdate = compensatePersistModeUpdate;
|
||||
}
|
||||
|
||||
public List<Object> getInputExpressions() {
|
||||
return inputExpressions;
|
||||
}
|
||||
|
||||
public void setInputExpressions(List<Object> inputExpressions) {
|
||||
this.inputExpressions = inputExpressions;
|
||||
}
|
||||
|
||||
public Map<String, Object> getOutputExpressions() {
|
||||
return outputExpressions;
|
||||
}
|
||||
|
||||
public void setOutputExpressions(Map<String, Object> outputExpressions) {
|
||||
this.outputExpressions = outputExpressions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Map<String, String> status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loop getLoop() {
|
||||
return loop;
|
||||
}
|
||||
|
||||
public void setLoop(Loop loop) {
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
public static class RetryImpl implements Retry {
|
||||
|
||||
private List<String> exceptions;
|
||||
private List<Class<? extends Exception>> exceptionClasses;
|
||||
private double intervalSeconds;
|
||||
private int maxAttempts;
|
||||
private double backoffRate;
|
||||
|
||||
@Override
|
||||
public List<String> getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
public void setExceptions(List<String> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends Exception>> getExceptionClasses() {
|
||||
return exceptionClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExceptionClasses(List<Class<? extends Exception>> exceptionClasses) {
|
||||
this.exceptionClasses = exceptionClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getIntervalSeconds() {
|
||||
return intervalSeconds;
|
||||
}
|
||||
|
||||
public void setIntervalSeconds(double intervalSeconds) {
|
||||
this.intervalSeconds = intervalSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxAttempts() {
|
||||
return maxAttempts;
|
||||
}
|
||||
|
||||
public void setMaxAttempts(int maxAttempts) {
|
||||
this.maxAttempts = maxAttempts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBackoffRate() {
|
||||
return backoffRate;
|
||||
}
|
||||
|
||||
public void setBackoffRate(double backoffRate) {
|
||||
this.backoffRate = backoffRate;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExceptionMatchImpl implements ExceptionMatch {
|
||||
|
||||
List<String> exceptions;
|
||||
List<Class<? extends Exception>> exceptionClasses;
|
||||
String next;
|
||||
|
||||
@Override
|
||||
public List<String> getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
public void setExceptions(List<String> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends Exception>> getExceptionClasses() {
|
||||
return exceptionClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExceptionClasses(List<Class<? extends Exception>> exceptionClasses) {
|
||||
this.exceptionClasses = exceptionClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(String next) {
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LoopImpl implements Loop {
|
||||
|
||||
private int parallel;
|
||||
private String collection;
|
||||
private String elementVariableName;
|
||||
private String elementIndexName;
|
||||
private String completionCondition;
|
||||
|
||||
@Override
|
||||
public int getParallel() {
|
||||
return parallel;
|
||||
}
|
||||
|
||||
public void setParallel(int parallel) {
|
||||
this.parallel = parallel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(String collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementVariableName() {
|
||||
return elementVariableName;
|
||||
}
|
||||
|
||||
public void setElementVariableName(String elementVariableName) {
|
||||
this.elementVariableName = elementVariableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementIndexName() {
|
||||
return elementIndexName;
|
||||
}
|
||||
|
||||
public void setElementIndexName(String elementIndexName) {
|
||||
this.elementIndexName = elementIndexName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompletionCondition() {
|
||||
return completionCondition;
|
||||
}
|
||||
|
||||
public void setCompletionCondition(String completionCondition) {
|
||||
this.completionCondition = completionCondition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.State;
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
|
||||
/**
|
||||
* BaseState
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public abstract class BaseState implements State {
|
||||
|
||||
private transient String name;
|
||||
private String type;
|
||||
private String comment;
|
||||
private String next;
|
||||
private Map<String, Object> extensions;
|
||||
private transient StateMachine stateMachine;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(String next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public void setExtensions(Map<String, Object> extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachine getStateMachine() {
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
public void setStateMachine(StateMachine stateMachine) {
|
||||
this.stateMachine = stateMachine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
protected void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.ChoiceState;
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
|
||||
/**
|
||||
* Single selection status
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ChoiceStateImpl extends BaseState implements ChoiceState {
|
||||
|
||||
private List<Choice> choices;
|
||||
private String defaultChoice;
|
||||
/**
|
||||
* key: Evaluator, value: Next
|
||||
**/
|
||||
private Map<Object, String> choiceEvaluators;
|
||||
|
||||
public ChoiceStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_CHOICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Choice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public void setChoices(List<Choice> choices) {
|
||||
this.choices = choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefault() {
|
||||
return defaultChoice;
|
||||
}
|
||||
|
||||
public void setDefaultChoice(String defaultChoice) {
|
||||
this.defaultChoice = defaultChoice;
|
||||
}
|
||||
|
||||
public Map<Object, String> getChoiceEvaluators() {
|
||||
return choiceEvaluators;
|
||||
}
|
||||
|
||||
public void setChoiceEvaluators(Map<Object, String> choiceEvaluators) {
|
||||
this.choiceEvaluators = choiceEvaluators;
|
||||
}
|
||||
|
||||
public static class ChoiceImpl implements ChoiceState.Choice {
|
||||
|
||||
private String expression;
|
||||
private String next;
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public void setExpression(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(String next) {
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.CompensateSubStateMachineState;
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
|
||||
/**
|
||||
* Used to compensate the state of the sub state machine, inherited from ServiceTaskState
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class CompensateSubStateMachineStateImpl extends ServiceTaskStateImpl implements CompensateSubStateMachineState {
|
||||
public CompensateSubStateMachineStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_SUB_MACHINE_COMPENSATION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.CompensationTriggerState;
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
|
||||
/**
|
||||
* Triggering the "compensation" process for the state machine
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class CompensationTriggerStateImpl extends BaseState implements CompensationTriggerState {
|
||||
|
||||
public CompensationTriggerStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_COMPENSATION_TRIGGER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.FailEndState;
|
||||
|
||||
/**
|
||||
* FailEndState
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class FailEndStateImpl extends BaseState implements FailEndState {
|
||||
|
||||
private String errorCode;
|
||||
private String message;
|
||||
|
||||
public FailEndStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_FAIL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(String errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.LoopStartState;
|
||||
|
||||
/**
|
||||
* Start the "loop" execution for the state with loop attribute
|
||||
*
|
||||
* @author anselleeyy
|
||||
*/
|
||||
public class LoopStartStateImpl extends BaseState implements LoopStartState {
|
||||
|
||||
public LoopStartStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_LOOP_START);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.ScriptTaskState;
|
||||
|
||||
/**
|
||||
* A state used to execute script such as groovy
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ScriptTaskStateImpl extends AbstractTaskState implements ScriptTaskState {
|
||||
|
||||
private static final String DEFAULT_SCRIPT_TYPE = "groovy";
|
||||
|
||||
private String scriptType = DEFAULT_SCRIPT_TYPE;
|
||||
|
||||
private String scriptContent;
|
||||
|
||||
public ScriptTaskStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_SCRIPT_TASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScriptType() {
|
||||
return this.scriptType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScriptContent() {
|
||||
return this.scriptContent;
|
||||
}
|
||||
|
||||
public void setScriptType(String scriptType) {
|
||||
this.scriptType = scriptType;
|
||||
}
|
||||
|
||||
public void setScriptContent(String scriptContent) {
|
||||
this.scriptContent = scriptContent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.ServiceTaskState;
|
||||
|
||||
/**
|
||||
* A state used to invoke a service
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ServiceTaskStateImpl extends AbstractTaskState implements ServiceTaskState {
|
||||
|
||||
private String serviceType;
|
||||
private String serviceName;
|
||||
private String serviceMethod;
|
||||
private List<String> parameterTypes;
|
||||
private Method method;
|
||||
private Map<Object, String> statusEvaluators;
|
||||
private boolean isAsync;
|
||||
|
||||
public ServiceTaskStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_SERVICE_TASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceType() {
|
||||
return serviceType;
|
||||
}
|
||||
|
||||
public void setServiceType(String serviceType) {
|
||||
this.serviceType = serviceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceMethod() {
|
||||
return serviceMethod;
|
||||
}
|
||||
|
||||
public void setServiceMethod(String serviceMethod) {
|
||||
this.serviceMethod = serviceMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public void setParameterTypes(List<String> parameterTypes) {
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Map<Object, String> getStatusEvaluators() {
|
||||
return statusEvaluators;
|
||||
}
|
||||
|
||||
public void setStatusEvaluators(Map<Object, String> statusEvaluators) {
|
||||
this.statusEvaluators = statusEvaluators;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return isAsync;
|
||||
}
|
||||
|
||||
public void setAsync(boolean async) {
|
||||
isAsync = async;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.saga.statelang.domain.ExecutionStatus;
|
||||
import io.seata.saga.statelang.domain.StateInstance;
|
||||
import io.seata.saga.statelang.domain.StateMachineInstance;
|
||||
|
||||
/**
|
||||
* state execution instance
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateInstanceImpl implements StateInstance {
|
||||
|
||||
private String id;
|
||||
private String machineInstanceId;
|
||||
private String name;
|
||||
private String type;
|
||||
private String serviceName;
|
||||
private String serviceMethod;
|
||||
private String serviceType;
|
||||
private String businessKey;
|
||||
private Date gmtStarted;
|
||||
private Date gmtUpdated;
|
||||
private Date gmtEnd;
|
||||
private boolean isForUpdate;
|
||||
private Exception exception;
|
||||
private Object serializedException;
|
||||
private Object inputParams;
|
||||
private Object serializedInputParams;
|
||||
private Object outputParams;
|
||||
private Object serializedOutputParams;
|
||||
private ExecutionStatus status;
|
||||
private String stateIdCompensatedFor;
|
||||
private String stateIdRetriedFor;
|
||||
private StateInstance compensationState;
|
||||
private StateMachineInstance stateMachineInstance;
|
||||
private boolean ignoreStatus;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMachineInstanceId() {
|
||||
return machineInstanceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMachineInstanceId(String machineInstanceId) {
|
||||
this.machineInstanceId = machineInstanceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceMethod() {
|
||||
return serviceMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceMethod(String serviceMethod) {
|
||||
this.serviceMethod = serviceMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceType() {
|
||||
return serviceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceType(String serviceType) {
|
||||
this.serviceType = serviceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBusinessKey() {
|
||||
return businessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBusinessKey(String businessKey) {
|
||||
this.businessKey = businessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtStarted() {
|
||||
return gmtStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtStarted(Date gmtStarted) {
|
||||
this.gmtStarted = gmtStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtUpdated() {
|
||||
return gmtUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtUpdated(Date gmtUpdated) {
|
||||
this.gmtUpdated = gmtUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtEnd() {
|
||||
return gmtEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtEnd(Date gmtEnd) {
|
||||
this.gmtEnd = gmtEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForUpdate() {
|
||||
return isForUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForUpdate(boolean forUpdate) {
|
||||
isForUpdate = forUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStateIdCompensatedFor() {
|
||||
return stateIdCompensatedFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateIdCompensatedFor(String stateIdCompensatedFor) {
|
||||
this.stateIdCompensatedFor = stateIdCompensatedFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStateIdRetriedFor() {
|
||||
return stateIdRetriedFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateIdRetriedFor(String stateIdRetriedFor) {
|
||||
this.stateIdRetriedFor = stateIdRetriedFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInputParams() {
|
||||
return inputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputParams(Object inputParams) {
|
||||
this.inputParams = inputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOutputParams() {
|
||||
return outputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOutputParams(Object outputParams) {
|
||||
this.outputParams = outputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(ExecutionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateInstance getCompensationState() {
|
||||
return compensationState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompensationState(StateInstance compensationState) {
|
||||
this.compensationState = compensationState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineInstance getStateMachineInstance() {
|
||||
return stateMachineInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateMachineInstance(StateMachineInstance stateMachineInstance) {
|
||||
this.stateMachineInstance = stateMachineInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIgnoreStatus() {
|
||||
return ignoreStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoreStatus(boolean ignoreStatus) {
|
||||
this.ignoreStatus = ignoreStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForCompensation() {
|
||||
return StringUtils.isNotBlank(this.stateIdCompensatedFor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedInputParams() {
|
||||
return serializedInputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedInputParams(Object serializedInputParams) {
|
||||
this.serializedInputParams = serializedInputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedOutputParams() {
|
||||
return serializedOutputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedOutputParams(Object serializedOutputParams) {
|
||||
this.serializedOutputParams = serializedOutputParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedException() {
|
||||
return serializedException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedException(Object serializedException) {
|
||||
this.serializedException = serializedException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionStatus getCompensationStatus() {
|
||||
if (this.compensationState != null) {
|
||||
return this.compensationState.getStatus();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.RecoverStrategy;
|
||||
import io.seata.saga.statelang.domain.State;
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
|
||||
/**
|
||||
* state machine
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateMachineImpl implements StateMachine {
|
||||
|
||||
private String id;
|
||||
private String tenantId;
|
||||
private String appName = "SEATA";
|
||||
private String name;
|
||||
private String comment;
|
||||
private String version;
|
||||
private String startState;
|
||||
private Status status = Status.AC;
|
||||
private RecoverStrategy recoverStrategy;
|
||||
private boolean isPersist = true;
|
||||
private Boolean retryPersistModeUpdate;
|
||||
private Boolean compensatePersistModeUpdate;
|
||||
private String type = "STATE_LANG";
|
||||
private transient String content;
|
||||
private Date gmtCreate;
|
||||
private Map<String, State> states = new LinkedHashMap<>();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStartState() {
|
||||
return startState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartState(String startState) {
|
||||
this.startState = startState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, State> getStates() {
|
||||
return states;
|
||||
}
|
||||
|
||||
public void setStates(Map<String, State> states) {
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState(String name) {
|
||||
return states.get(name);
|
||||
}
|
||||
|
||||
public void putState(String stateName, State state) {
|
||||
this.states.put(stateName, state);
|
||||
if (state instanceof BaseState) {
|
||||
((BaseState)state).setStateMachine(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecoverStrategy getRecoverStrategy() {
|
||||
return recoverStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecoverStrategy(RecoverStrategy recoverStrategy) {
|
||||
this.recoverStrategy = recoverStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersist() {
|
||||
return isPersist;
|
||||
}
|
||||
|
||||
public void setPersist(boolean persist) {
|
||||
isPersist = persist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isRetryPersistModeUpdate() {
|
||||
return retryPersistModeUpdate;
|
||||
}
|
||||
|
||||
public void setRetryPersistModeUpdate(Boolean retryPersistModeUpdate) {
|
||||
this.retryPersistModeUpdate = retryPersistModeUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isCompensatePersistModeUpdate() {
|
||||
return compensatePersistModeUpdate;
|
||||
}
|
||||
|
||||
public void setCompensatePersistModeUpdate(Boolean compensatePersistModeUpdate) {
|
||||
this.compensatePersistModeUpdate = compensatePersistModeUpdate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.seata.saga.statelang.domain.ExecutionStatus;
|
||||
import io.seata.saga.statelang.domain.StateInstance;
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
import io.seata.saga.statelang.domain.StateMachineInstance;
|
||||
|
||||
/**
|
||||
* state machine execution instance
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateMachineInstanceImpl implements StateMachineInstance {
|
||||
|
||||
private String id;
|
||||
private String machineId;
|
||||
private String tenantId;
|
||||
private String parentId;
|
||||
private Date gmtStarted;
|
||||
private String businessKey;
|
||||
private Map<String, Object> startParams = new HashMap<>();
|
||||
private Object serializedStartParams;
|
||||
private Date gmtEnd;
|
||||
private Exception exception;
|
||||
private Object serializedException;
|
||||
private Map<String, Object> endParams = new HashMap<>();
|
||||
private Object serializedEndParams;
|
||||
private ExecutionStatus status;
|
||||
private ExecutionStatus compensationStatus;
|
||||
private boolean isRunning;
|
||||
private Date gmtUpdated;
|
||||
private Map<String, Object> context;
|
||||
|
||||
private StateMachine stateMachine;
|
||||
private List<StateInstance> stateList = Collections.synchronizedList(new ArrayList<>());
|
||||
private Map<String, StateInstance> stateMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMachineId() {
|
||||
return machineId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMachineId(String machineId) {
|
||||
this.machineId = machineId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtStarted() {
|
||||
return gmtStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtStarted(Date gmtStarted) {
|
||||
this.gmtStarted = gmtStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtEnd() {
|
||||
return gmtEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtEnd(Date gmtEnd) {
|
||||
this.gmtEnd = gmtEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStateInstance(String stateId, StateInstance stateInstance) {
|
||||
stateInstance.setStateMachineInstance(this);
|
||||
stateMap.put(stateId, stateInstance);
|
||||
stateList.add(stateInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(ExecutionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionStatus getCompensationStatus() {
|
||||
return compensationStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompensationStatus(ExecutionStatus compensationStatus) {
|
||||
this.compensationStatus = compensationStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRunning(boolean running) {
|
||||
isRunning = running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtUpdated() {
|
||||
return gmtUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGmtUpdated(Date gmtUpdated) {
|
||||
this.gmtUpdated = gmtUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBusinessKey() {
|
||||
return businessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBusinessKey(String businessKey) {
|
||||
this.businessKey = businessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getStartParams() {
|
||||
return startParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartParams(Map<String, Object> startParams) {
|
||||
this.startParams = startParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getEndParams() {
|
||||
return endParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndParams(Map<String, Object> endParams) {
|
||||
this.endParams = endParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(Map<String, Object> context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachine getStateMachine() {
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateMachine(StateMachine stateMachine) {
|
||||
this.stateMachine = stateMachine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StateInstance> getStateList() {
|
||||
return stateList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateList(List<StateInstance> stateList) {
|
||||
this.stateList = stateList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, StateInstance> getStateMap() {
|
||||
return stateMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStateMap(Map<String, StateInstance> stateMap) {
|
||||
this.stateMap = stateMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedStartParams() {
|
||||
return serializedStartParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedStartParams(Object serializedStartParams) {
|
||||
this.serializedStartParams = serializedStartParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedEndParams() {
|
||||
return serializedEndParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedEndParams(Object serializedEndParams) {
|
||||
this.serializedEndParams = serializedEndParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSerializedException() {
|
||||
return serializedException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSerializedException(Object serializedException) {
|
||||
this.serializedException = serializedException;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.SubStateMachine;
|
||||
import io.seata.saga.statelang.domain.TaskState;
|
||||
|
||||
/**
|
||||
* sub state machine
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class SubStateMachineImpl extends ServiceTaskStateImpl implements SubStateMachine {
|
||||
|
||||
private String stateMachineName;
|
||||
|
||||
private TaskState compensateStateObject;
|
||||
|
||||
public SubStateMachineImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_SUB_STATE_MACHINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStateMachineName() {
|
||||
return stateMachineName;
|
||||
}
|
||||
|
||||
public void setStateMachineName(String stateMachineName) {
|
||||
this.stateMachineName = stateMachineName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskState getCompensateStateObject() {
|
||||
return compensateStateObject;
|
||||
}
|
||||
|
||||
public void setCompensateStateObject(TaskState compensateStateObject) {
|
||||
this.compensateStateObject = compensateStateObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.domain.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.SucceedEndState;
|
||||
|
||||
/**
|
||||
* SucceedEndState
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class SucceedEndStateImpl extends BaseState implements SucceedEndState {
|
||||
|
||||
public SucceedEndStateImpl() {
|
||||
setType(DomainConstants.STATE_TYPE_SUCCEED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
/**
|
||||
*
|
||||
* Json Parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface JsonParser {
|
||||
|
||||
/**
|
||||
* get Name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Object to Json string
|
||||
*
|
||||
* @param o
|
||||
* @param prettyPrint
|
||||
* @return
|
||||
*/
|
||||
String toJsonString(Object o, boolean prettyPrint);
|
||||
|
||||
/**
|
||||
* Object to Json string
|
||||
* @param o
|
||||
* @param ignoreAutoType
|
||||
* @param prettyPrint
|
||||
* @return
|
||||
*/
|
||||
String toJsonString(Object o, boolean ignoreAutoType, boolean prettyPrint);
|
||||
|
||||
/**
|
||||
* parse json string to Object
|
||||
*
|
||||
* @param json
|
||||
* @param type
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
<T> T parse(String json, Class<T> type, boolean ignoreAutoType);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* JsonParserFactory
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class JsonParserFactory {
|
||||
|
||||
private JsonParserFactory() {
|
||||
}
|
||||
|
||||
private static final ConcurrentMap<String, JsonParser> INSTANCES = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets JsonParser by name
|
||||
*
|
||||
* @param name parser name
|
||||
* @return the JsonParser
|
||||
*/
|
||||
public static JsonParser getJsonParser(String name) {
|
||||
return CollectionUtils.computeIfAbsent(INSTANCES, name,
|
||||
key -> EnhancedServiceLoader.load(JsonParser.class, name, Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
|
||||
/**
|
||||
* State machine parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface StateMachineParser {
|
||||
|
||||
/**
|
||||
* Parse an object (such as Json) into a State Machine model
|
||||
*
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
StateMachine parse(String json);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import io.seata.saga.statelang.parser.impl.StateMachineParserImpl;
|
||||
|
||||
/**
|
||||
* A simple factory of State machine language parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateMachineParserFactory {
|
||||
|
||||
public static StateMachineParser getStateMachineParser(String jsonParserName) {
|
||||
return new StateMachineParserImpl(jsonParserName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import io.seata.saga.statelang.domain.State;
|
||||
|
||||
/**
|
||||
* State Parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public interface StateParser<T extends State> {
|
||||
|
||||
/**
|
||||
* Parse an object (such as Json) into a State model
|
||||
*
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
T parse(Object node);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.parser.impl.ChoiceStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.CompensateSubStateMachineStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.CompensationTriggerStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.FailEndStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.ScriptTaskStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.ServiceTaskStateParser;
|
||||
import io.seata.saga.statelang.parser.impl.SubStateMachineParser;
|
||||
import io.seata.saga.statelang.parser.impl.SucceedEndStateParser;
|
||||
|
||||
/**
|
||||
* A simple factory of state parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateParserFactory {
|
||||
|
||||
protected static Map<String, StateParser> stateParserMap = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_SERVICE_TASK, new ServiceTaskStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_CHOICE, new ChoiceStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_COMPENSATION_TRIGGER, new CompensationTriggerStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_FAIL, new FailEndStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_SUCCEED, new SucceedEndStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_SUB_STATE_MACHINE, new SubStateMachineParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_SUB_MACHINE_COMPENSATION,
|
||||
new CompensateSubStateMachineStateParser());
|
||||
stateParserMap.put(DomainConstants.STATE_TYPE_SCRIPT_TASK, new ScriptTaskStateParser());
|
||||
}
|
||||
|
||||
public static StateParser getStateParser(String stateType) {
|
||||
return stateParserMap.get(stateType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.common.util.NumberUtils;
|
||||
import io.seata.saga.statelang.domain.TaskState.ExceptionMatch;
|
||||
import io.seata.saga.statelang.domain.TaskState.Loop;
|
||||
import io.seata.saga.statelang.domain.TaskState.Retry;
|
||||
import io.seata.saga.statelang.domain.impl.AbstractTaskState;
|
||||
import io.seata.saga.statelang.domain.impl.AbstractTaskState.ExceptionMatchImpl;
|
||||
import io.seata.saga.statelang.domain.impl.AbstractTaskState.LoopImpl;
|
||||
import io.seata.saga.statelang.domain.impl.AbstractTaskState.RetryImpl;
|
||||
|
||||
/**
|
||||
* AbstractTaskStateParser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public abstract class AbstractTaskStateParser extends BaseStatePaser {
|
||||
|
||||
protected void parseTaskAttributes(AbstractTaskState state, Object node) {
|
||||
|
||||
parseBaseAttributes(state, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>) node;
|
||||
|
||||
state.setCompensateState((String) nodeMap.get("CompensateState"));
|
||||
state.setForCompensation(Boolean.TRUE.equals(nodeMap.get("IsForCompensation")));
|
||||
state.setForUpdate(Boolean.TRUE.equals(nodeMap.get("IsForUpdate")));
|
||||
Object isPersist = nodeMap.get("IsPersist");
|
||||
if (Boolean.FALSE.equals(isPersist)) {
|
||||
state.setPersist(false);
|
||||
}
|
||||
|
||||
// customize if update origin or append new retryStateInstLog
|
||||
Object isRetryPersistModeUpdate = nodeMap.get("IsRetryPersistModeUpdate");
|
||||
if (isRetryPersistModeUpdate instanceof Boolean) {
|
||||
state.setRetryPersistModeUpdate(Boolean.TRUE.equals(isRetryPersistModeUpdate));
|
||||
}
|
||||
|
||||
// customize if update last or append new compensateStateInstLog
|
||||
Object isCompensatePersistModeUpdate = nodeMap.get("IsCompensatePersistModeUpdate");
|
||||
if (isCompensatePersistModeUpdate instanceof Boolean) {
|
||||
state.setCompensatePersistModeUpdate(Boolean.TRUE.equals(isCompensatePersistModeUpdate));
|
||||
}
|
||||
|
||||
List<Object> retryList = (List<Object>) nodeMap.get("Retry");
|
||||
if (retryList != null) {
|
||||
state.setRetry(parseRetry(retryList));
|
||||
}
|
||||
|
||||
List<Object> catchList = (List<Object>) nodeMap.get("Catch");
|
||||
if (catchList != null) {
|
||||
state.setCatches(parseCatch(catchList));
|
||||
}
|
||||
|
||||
List<Object> inputList = (List<Object>) nodeMap.get("Input");
|
||||
if (inputList != null) {
|
||||
state.setInput(inputList);
|
||||
}
|
||||
|
||||
Map<String, Object> outputMap = (Map<String, Object>) nodeMap.get("Output");
|
||||
if (outputMap != null) {
|
||||
state.setOutput(outputMap);
|
||||
}
|
||||
|
||||
Map<String/* expression */, String /* status */> statusMap = (Map<String, String>) nodeMap.get("Status");
|
||||
if (statusMap != null) {
|
||||
state.setStatus(statusMap);
|
||||
}
|
||||
|
||||
Object loopObj = nodeMap.get("Loop");
|
||||
if (loopObj != null) {
|
||||
state.setLoop(parseLoop(loopObj));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Retry> parseRetry(List<Object> retryList) {
|
||||
if (retryList != null) {
|
||||
List<Retry> retries = new ArrayList<>(retryList.size());
|
||||
for (Object retryObj : retryList) {
|
||||
Map<String, Object> retryMap = (Map<String, Object>) retryObj;
|
||||
RetryImpl retry = new RetryImpl();
|
||||
retry.setExceptions((List<String>) retryMap.get("Exceptions"));
|
||||
|
||||
Object intervalSeconds = retryMap.get("IntervalSeconds");
|
||||
if (intervalSeconds != null && intervalSeconds instanceof Number) {
|
||||
retry.setIntervalSeconds(((Number) intervalSeconds).doubleValue());
|
||||
}
|
||||
|
||||
retry.setMaxAttempts((Integer) retryMap.get("MaxAttempts"));
|
||||
|
||||
Object backoffRate = retryMap.get("BackoffRate");
|
||||
if (backoffRate != null && backoffRate instanceof Number) {
|
||||
retry.setBackoffRate(((Number) backoffRate).doubleValue());
|
||||
}
|
||||
|
||||
retries.add(retry);
|
||||
}
|
||||
return retries;
|
||||
}
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
protected List<ExceptionMatch> parseCatch(List<Object> catchList) {
|
||||
|
||||
List<ExceptionMatch> exceptionMatchList = new ArrayList<>(catchList.size());
|
||||
for (Object exceptionMatchObj : catchList) {
|
||||
Map<String, Object> exceptionMatchMap = (Map<String, Object>) exceptionMatchObj;
|
||||
ExceptionMatchImpl exceptionMatch = new ExceptionMatchImpl();
|
||||
exceptionMatch.setExceptions((List<String>) exceptionMatchMap.get("Exceptions"));
|
||||
exceptionMatch.setNext((String) exceptionMatchMap.get("Next"));
|
||||
|
||||
exceptionMatchList.add(exceptionMatch);
|
||||
}
|
||||
return exceptionMatchList;
|
||||
}
|
||||
|
||||
protected Loop parseLoop(Object loopObj) {
|
||||
Map<String, Object> loopMap = (Map<String, Object>)loopObj;
|
||||
LoopImpl loop = new LoopImpl();
|
||||
|
||||
Object parallel = loopMap.get("Parallel");
|
||||
loop.setParallel(NumberUtils.toInt(parallel.toString(), 1));
|
||||
|
||||
loop.setCollection((String)loopMap.get("Collection"));
|
||||
loop.setElementVariableName((String)loopMap.getOrDefault("ElementVariableName", "loopElement"));
|
||||
loop.setElementIndexName((String)loopMap.getOrDefault("ElementIndexName", "loopCounter"));
|
||||
loop.setCompletionCondition(
|
||||
(String)loopMap.getOrDefault("CompletionCondition", "[nrOfInstances] == [nrOfCompletedInstances]"));
|
||||
return loop;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.impl.BaseState;
|
||||
|
||||
/**
|
||||
* BaseStatePaser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public abstract class BaseStatePaser {
|
||||
|
||||
protected void parseBaseAttributes(BaseState state, Object node) {
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
state.setComment((String)nodeMap.get("Comment"));
|
||||
state.setNext((String)nodeMap.get("Next"));
|
||||
state.setExtensions((Map<String, Object>)nodeMap.get("Extensions"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.ChoiceState;
|
||||
import io.seata.saga.statelang.domain.ChoiceState.Choice;
|
||||
import io.seata.saga.statelang.domain.impl.ChoiceStateImpl;
|
||||
import io.seata.saga.statelang.domain.impl.ChoiceStateImpl.ChoiceImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
/**
|
||||
* Single item selection state parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ChoiceStateParser extends BaseStatePaser implements StateParser<ChoiceState> {
|
||||
|
||||
@Override
|
||||
public ChoiceState parse(Object node) {
|
||||
|
||||
ChoiceStateImpl choiceState = new ChoiceStateImpl();
|
||||
parseBaseAttributes(choiceState, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
List<Object> choiceObjList = (List<Object>)nodeMap.get("Choices");
|
||||
List<Choice> choiceStateList = new ArrayList<>(choiceObjList.size());
|
||||
for (Object choiceObj : choiceObjList) {
|
||||
|
||||
Map<String, Object> choiceObjMap = (Map<String, Object>)choiceObj;
|
||||
ChoiceImpl choice = new ChoiceImpl();
|
||||
choice.setExpression((String)choiceObjMap.get("Expression"));
|
||||
choice.setNext((String)choiceObjMap.get("Next"));
|
||||
|
||||
choiceStateList.add(choice);
|
||||
}
|
||||
choiceState.setChoices(choiceStateList);
|
||||
|
||||
choiceState.setDefaultChoice((String)nodeMap.get("Default"));
|
||||
|
||||
return choiceState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.ServiceTaskState;
|
||||
import io.seata.saga.statelang.domain.impl.CompensateSubStateMachineStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* CompensateSubStateMachineState Parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class CompensateSubStateMachineStateParser extends AbstractTaskStateParser
|
||||
implements StateParser<ServiceTaskState> {
|
||||
|
||||
@Override
|
||||
public ServiceTaskState parse(Object node) {
|
||||
|
||||
CompensateSubStateMachineStateImpl compensateSubStateMachineState = new CompensateSubStateMachineStateImpl();
|
||||
compensateSubStateMachineState.setForCompensation(true);
|
||||
if (node != null) {
|
||||
parseTaskAttributes(compensateSubStateMachineState, node);
|
||||
}
|
||||
if (StringUtils.isEmpty(compensateSubStateMachineState.getName())) {
|
||||
compensateSubStateMachineState.setName(
|
||||
DomainConstants.COMPENSATE_SUB_MACHINE_STATE_NAME_PREFIX + compensateSubStateMachineState.hashCode());
|
||||
}
|
||||
return compensateSubStateMachineState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.CompensationTriggerState;
|
||||
import io.seata.saga.statelang.domain.impl.CompensationTriggerStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
/**
|
||||
* 'trigger compensation process' state parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class CompensationTriggerStateParser extends BaseStatePaser implements StateParser<CompensationTriggerState> {
|
||||
|
||||
@Override
|
||||
public CompensationTriggerState parse(Object node) {
|
||||
|
||||
CompensationTriggerStateImpl compensationTriggerState = new CompensationTriggerStateImpl();
|
||||
parseBaseAttributes(compensationTriggerState, node);
|
||||
|
||||
return compensationTriggerState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.FailEndState;
|
||||
import io.seata.saga.statelang.domain.impl.FailEndStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
/**
|
||||
* Failed end state parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class FailEndStateParser extends BaseStatePaser implements StateParser<FailEndState> {
|
||||
|
||||
@Override
|
||||
public FailEndState parse(Object node) {
|
||||
|
||||
FailEndStateImpl failEndState = new FailEndStateImpl();
|
||||
parseBaseAttributes(failEndState, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
failEndState.setErrorCode((String)nodeMap.get("ErrorCode"));
|
||||
failEndState.setMessage((String)nodeMap.get("Message"));
|
||||
|
||||
return failEndState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.saga.statelang.parser.JsonParser;
|
||||
|
||||
/**
|
||||
* JsonParser implement by Fastjson
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
@LoadLevel(name = FastjsonParser.NAME)
|
||||
public class FastjsonParser implements JsonParser {
|
||||
|
||||
private static final SerializerFeature[] SERIALIZER_FEATURES = new SerializerFeature[] {
|
||||
SerializerFeature.DisableCircularReferenceDetect,
|
||||
SerializerFeature.WriteDateUseDateFormat,
|
||||
SerializerFeature.WriteClassName };
|
||||
|
||||
private static final SerializerFeature[] SERIALIZER_FEATURES_PRETTY = new SerializerFeature[] {
|
||||
SerializerFeature.DisableCircularReferenceDetect,
|
||||
SerializerFeature.WriteDateUseDateFormat,
|
||||
SerializerFeature.WriteClassName,
|
||||
SerializerFeature.PrettyFormat };
|
||||
|
||||
private static final SerializerFeature[] FEATURES_PRETTY = new SerializerFeature[] {
|
||||
SerializerFeature.DisableCircularReferenceDetect,
|
||||
SerializerFeature.WriteDateUseDateFormat,
|
||||
SerializerFeature.PrettyFormat };
|
||||
|
||||
public static final String NAME = "fastjson";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJsonString(Object o, boolean prettyPrint) {
|
||||
return toJsonString(o, false, prettyPrint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJsonString(Object o, boolean ignoreAutoType, boolean prettyPrint) {
|
||||
if (prettyPrint) {
|
||||
if (ignoreAutoType) {
|
||||
return JSON.toJSONString(o, FEATURES_PRETTY);
|
||||
}
|
||||
else {
|
||||
return JSON.toJSONString(o, SERIALIZER_FEATURES_PRETTY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ignoreAutoType) {
|
||||
return JSON.toJSONString(o);
|
||||
}
|
||||
else {
|
||||
return JSON.toJSONString(o, SERIALIZER_FEATURES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T parse(String json, Class<T> type, boolean ignoreAutoType) {
|
||||
if (ignoreAutoType) {
|
||||
return JSON.parseObject(json, type, Feature.IgnoreAutoType, Feature.OrderedField);
|
||||
}
|
||||
else {
|
||||
return JSON.parseObject(json, type, Feature.SupportAutoType, Feature.OrderedField);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.saga.statelang.parser.JsonParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JsonParser implement by Jackson
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
@LoadLevel(name = JacksonJsonParser.NAME)
|
||||
public class JacksonJsonParser implements JsonParser {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JacksonJsonParser.class);
|
||||
|
||||
private ObjectMapper objectMapperWithAutoType = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, "@type")
|
||||
.enable(MapperFeature.PROPAGATE_TRANSIENT_MARKER)
|
||||
.setSerializationInclusion(Include.NON_NULL);
|
||||
|
||||
private ObjectMapper objectMapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.disableDefaultTyping()
|
||||
.enable(MapperFeature.PROPAGATE_TRANSIENT_MARKER)
|
||||
.setSerializationInclusion(Include.NON_NULL);
|
||||
|
||||
public static final String NAME = "jackson";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJsonString(Object o, boolean prettyPrint) {
|
||||
return toJsonString(o, false, prettyPrint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJsonString(Object o, boolean ignoreAutoType, boolean prettyPrint) {
|
||||
try {
|
||||
if (o instanceof List && ((List) o).isEmpty()) {
|
||||
return "[]";
|
||||
}
|
||||
if (prettyPrint) {
|
||||
if (ignoreAutoType) {
|
||||
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(o);
|
||||
}
|
||||
else {
|
||||
return objectMapperWithAutoType.writerWithDefaultPrettyPrinter().writeValueAsString(o);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if (ignoreAutoType) {
|
||||
return objectMapper.writeValueAsString(o);
|
||||
}
|
||||
else {
|
||||
return objectMapperWithAutoType.writeValueAsString(o);
|
||||
}
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Parse object to json error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T parse(String json, Class<T> type, boolean ignoreAutoType) {
|
||||
try {
|
||||
if (json != null && "[]".equals(json)) {
|
||||
return (T) (new ArrayList(0));
|
||||
}
|
||||
if (ignoreAutoType) {
|
||||
return objectMapper.readValue(json, type);
|
||||
}
|
||||
else {
|
||||
return objectMapperWithAutoType.readValue(json, type);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Parse json to object error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.saga.statelang.domain.ScriptTaskState;
|
||||
import io.seata.saga.statelang.domain.impl.ScriptTaskStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ScriptTaskState parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ScriptTaskStateParser extends AbstractTaskStateParser implements StateParser<ScriptTaskState> {
|
||||
|
||||
@Override
|
||||
public ScriptTaskState parse(Object node) {
|
||||
|
||||
ScriptTaskStateImpl scriptTaskState = new ScriptTaskStateImpl();
|
||||
|
||||
parseTaskAttributes(scriptTaskState, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
String scriptType = (String) nodeMap.get("ScriptType");
|
||||
if (StringUtils.isNotBlank(scriptType)) {
|
||||
scriptTaskState.setScriptType(scriptType);
|
||||
}
|
||||
scriptTaskState.setScriptContent((String)nodeMap.get("ScriptContent"));
|
||||
|
||||
scriptTaskState.setForCompensation(false);
|
||||
scriptTaskState.setForUpdate(false);
|
||||
scriptTaskState.setPersist(false);
|
||||
|
||||
return scriptTaskState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.ServiceTaskState;
|
||||
import io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
/**
|
||||
* ServcieTaskTask parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class ServiceTaskStateParser extends AbstractTaskStateParser implements StateParser<ServiceTaskState> {
|
||||
|
||||
@Override
|
||||
public ServiceTaskState parse(Object node) {
|
||||
|
||||
ServiceTaskStateImpl serviceTaskState = new ServiceTaskStateImpl();
|
||||
|
||||
parseTaskAttributes(serviceTaskState, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
serviceTaskState.setServiceName((String)nodeMap.get("ServiceName"));
|
||||
serviceTaskState.setServiceMethod((String)nodeMap.get("ServiceMethod"));
|
||||
serviceTaskState.setServiceType((String)nodeMap.get("ServiceType"));
|
||||
serviceTaskState.setParameterTypes((List<String>)nodeMap.get("ParameterTypes"));
|
||||
Object isAsync = nodeMap.get("IsAsync");
|
||||
if (Boolean.TRUE.equals(isAsync)) {
|
||||
serviceTaskState.setAsync(true);
|
||||
}
|
||||
|
||||
return serviceTaskState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.Map;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.saga.statelang.domain.DomainConstants;
|
||||
import io.seata.saga.statelang.domain.RecoverStrategy;
|
||||
import io.seata.saga.statelang.domain.State;
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
import io.seata.saga.statelang.domain.impl.AbstractTaskState;
|
||||
import io.seata.saga.statelang.domain.impl.BaseState;
|
||||
import io.seata.saga.statelang.domain.impl.StateMachineImpl;
|
||||
import io.seata.saga.statelang.parser.JsonParser;
|
||||
import io.seata.saga.statelang.parser.JsonParserFactory;
|
||||
import io.seata.saga.statelang.parser.StateMachineParser;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
import io.seata.saga.statelang.parser.StateParserFactory;
|
||||
import io.seata.saga.statelang.parser.utils.DesignerJsonTransformer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* State machine language parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateMachineParserImpl implements StateMachineParser {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(StateMachineParserImpl.class);
|
||||
|
||||
private String jsonParserName = DomainConstants.DEFAULT_JSON_PARSER;
|
||||
|
||||
public StateMachineParserImpl(String jsonParserName) {
|
||||
if (StringUtils.isNotBlank(jsonParserName)) {
|
||||
this.jsonParserName = jsonParserName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachine parse(String json) {
|
||||
|
||||
JsonParser jsonParser = JsonParserFactory.getJsonParser(jsonParserName);
|
||||
if (jsonParser == null) {
|
||||
throw new RuntimeException("Cannot find JsonParer by name: " + jsonParserName);
|
||||
}
|
||||
Map<String, Object> node = jsonParser.parse(json, Map.class, true);
|
||||
if (DesignerJsonTransformer.isDesignerJson(node)) {
|
||||
node = DesignerJsonTransformer.toStandardJson(node);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("===== Transformed standard state language:\n{}", jsonParser.toJsonString(node, true));
|
||||
}
|
||||
}
|
||||
|
||||
StateMachineImpl stateMachine = new StateMachineImpl();
|
||||
stateMachine.setName((String) node.get("Name"));
|
||||
stateMachine.setComment((String) node.get("Comment"));
|
||||
stateMachine.setVersion((String) node.get("Version"));
|
||||
stateMachine.setStartState((String) node.get("StartState"));
|
||||
String recoverStrategy = (String) node.get("RecoverStrategy");
|
||||
if (StringUtils.isNotBlank(recoverStrategy)) {
|
||||
stateMachine.setRecoverStrategy(RecoverStrategy.valueOf(recoverStrategy));
|
||||
}
|
||||
Object isPersist = node.get("IsPersist");
|
||||
if (Boolean.FALSE.equals(isPersist)) {
|
||||
stateMachine.setPersist(false);
|
||||
}
|
||||
|
||||
// customize if update origin or append new retryStateInstLog
|
||||
Object isRetryPersistModeUpdate = node.get("IsRetryPersistModeUpdate");
|
||||
if (isRetryPersistModeUpdate instanceof Boolean) {
|
||||
stateMachine.setRetryPersistModeUpdate(Boolean.TRUE.equals(isRetryPersistModeUpdate));
|
||||
}
|
||||
|
||||
// customize if update last or append new compensateStateInstLog
|
||||
Object isCompensatePersistModeUpdate = node.get("IsCompensatePersistModeUpdate");
|
||||
if (isCompensatePersistModeUpdate instanceof Boolean) {
|
||||
stateMachine.setCompensatePersistModeUpdate(Boolean.TRUE.equals(isCompensatePersistModeUpdate));
|
||||
}
|
||||
|
||||
Map<String, Object> statesNode = (Map<String, Object>) node.get("States");
|
||||
statesNode.forEach((stateName, value) -> {
|
||||
Map<String, Object> stateNode = (Map<String, Object>) value;
|
||||
String stateType = (String) stateNode.get("Type");
|
||||
StateParser<?> stateParser = StateParserFactory.getStateParser(stateType);
|
||||
if (stateParser == null) {
|
||||
throw new IllegalArgumentException("State Type [" + stateType + "] is not support");
|
||||
}
|
||||
State state = stateParser.parse(stateNode);
|
||||
if (state instanceof BaseState) {
|
||||
((BaseState) state).setName(stateName);
|
||||
}
|
||||
|
||||
if (stateMachine.getState(stateName) != null) {
|
||||
throw new IllegalArgumentException("State[name:" + stateName + "] is already exists");
|
||||
}
|
||||
stateMachine.putState(stateName, state);
|
||||
});
|
||||
|
||||
Map<String, State> stateMap = stateMachine.getStates();
|
||||
for (State state : stateMap.values()) {
|
||||
if (state instanceof AbstractTaskState) {
|
||||
AbstractTaskState taskState = (AbstractTaskState) state;
|
||||
if (StringUtils.isNotBlank(taskState.getCompensateState())) {
|
||||
taskState.setForUpdate(true);
|
||||
|
||||
State compState = stateMap.get(taskState.getCompensateState());
|
||||
if (compState instanceof AbstractTaskState) {
|
||||
((AbstractTaskState) compState).setForCompensation(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
public String getJsonParserName() {
|
||||
return jsonParserName;
|
||||
}
|
||||
|
||||
public void setJsonParserName(String jsonParserName) {
|
||||
this.jsonParserName = jsonParserName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.ServiceTaskState;
|
||||
import io.seata.saga.statelang.domain.SubStateMachine;
|
||||
import io.seata.saga.statelang.domain.impl.SubStateMachineImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* SubStateMachineParser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class SubStateMachineParser extends AbstractTaskStateParser implements StateParser<SubStateMachine> {
|
||||
|
||||
@Override
|
||||
public SubStateMachine parse(Object node) {
|
||||
|
||||
SubStateMachineImpl subStateMachine = new SubStateMachineImpl();
|
||||
|
||||
parseTaskAttributes(subStateMachine, node);
|
||||
|
||||
Map<String, Object> nodeMap = (Map<String, Object>)node;
|
||||
subStateMachine.setStateMachineName((String)nodeMap.get("StateMachineName"));
|
||||
|
||||
if (StringUtils.isEmpty(subStateMachine.getCompensateState())) {
|
||||
//build default SubStateMachine compensate state
|
||||
CompensateSubStateMachineStateParser compensateSubStateMachineStateParser
|
||||
= new CompensateSubStateMachineStateParser();
|
||||
ServiceTaskState subStateMachineCompenState = compensateSubStateMachineStateParser.parse(null);
|
||||
subStateMachine.setCompensateStateObject(subStateMachineCompenState);
|
||||
subStateMachine.setCompensateState(subStateMachineCompenState.getName());
|
||||
}
|
||||
|
||||
return subStateMachine;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.impl;
|
||||
|
||||
import io.seata.saga.statelang.domain.SucceedEndState;
|
||||
import io.seata.saga.statelang.domain.impl.SucceedEndStateImpl;
|
||||
import io.seata.saga.statelang.parser.StateParser;
|
||||
|
||||
/**
|
||||
* Succeed end state parser
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class SucceedEndStateParser extends BaseStatePaser implements StateParser<SucceedEndState> {
|
||||
|
||||
@Override
|
||||
public SucceedEndState parse(Object node) {
|
||||
|
||||
SucceedEndStateImpl succeedEndState = new SucceedEndStateImpl();
|
||||
parseBaseAttributes(succeedEndState, node);
|
||||
|
||||
return succeedEndState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.utils;
|
||||
|
||||
import io.seata.common.exception.FrameworkErrorCode;
|
||||
import io.seata.common.exception.FrameworkException;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.saga.statelang.domain.ExecutionStatus;
|
||||
import io.seata.saga.statelang.domain.StateInstance;
|
||||
import io.seata.saga.statelang.domain.StateMachineInstance;
|
||||
import io.seata.saga.statelang.parser.JsonParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Transform designer json to standard Saga State language json
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class DesignerJsonTransformer {
|
||||
|
||||
public static Map<String, Object> toStandardJson(Map<String, Object> designerJsonObject) {
|
||||
|
||||
if (!isDesignerJson(designerJsonObject)) {
|
||||
return designerJsonObject;
|
||||
}
|
||||
Map<String, Object> machineJsonObject = new LinkedHashMap<>();
|
||||
|
||||
List<Object> nodes = (List) designerJsonObject.get("nodes");
|
||||
if (CollectionUtils.isNotEmpty(nodes)) {
|
||||
Map<String, Object> nodeMap = new LinkedHashMap<>(nodes.size());
|
||||
|
||||
for (Object node : nodes) {
|
||||
Map<String, Object> nodeObj = (Map<String, Object>) node;
|
||||
|
||||
transformNode(machineJsonObject, nodeMap, nodeObj);
|
||||
}
|
||||
|
||||
List<Object> edges = (List) designerJsonObject.get("edges");
|
||||
if (CollectionUtils.isNotEmpty(edges)) {
|
||||
for (Object edge : edges) {
|
||||
Map<String, Object> edgeObj = (Map<String, Object>) edge;
|
||||
transformEdge(machineJsonObject, nodes, nodeMap, edgeObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return machineJsonObject;
|
||||
}
|
||||
|
||||
private static void transformNode(Map<String, Object> machineJsonObject, Map<String, Object> nodeMap, Map<String, Object> nodeObj) {
|
||||
nodeMap.put((String) nodeObj.get("id"), nodeObj);
|
||||
|
||||
String type = (String) nodeObj.get("stateType");
|
||||
Map<String, Object> propsObj = (Map<String, Object>) nodeObj.get("stateProps");
|
||||
if ("Start".equals(type)) {
|
||||
if (propsObj != null && propsObj.containsKey("StateMachine")) {
|
||||
machineJsonObject.putAll((Map<String, Object>) propsObj.get("StateMachine"));
|
||||
}
|
||||
} else if (!"Catch".equals(type)) {
|
||||
Map<String, Object> states = (Map<String, Object>) CollectionUtils.computeIfAbsent(machineJsonObject, "States",
|
||||
key -> new LinkedHashMap<>());
|
||||
|
||||
Map<String, Object> stateJsonObject = new LinkedHashMap<>();
|
||||
String stateId = (String) nodeObj.get("stateId");
|
||||
if (states.containsKey(stateId)) {
|
||||
throw new RuntimeException(
|
||||
"Transform designer json to standard json failed, stateId[" + stateId + "] already exists, pls rename it.");
|
||||
}
|
||||
|
||||
String comment = (String) nodeObj.get("label");
|
||||
if (StringUtils.hasLength(comment)) {
|
||||
stateJsonObject.put("Comment", comment);
|
||||
}
|
||||
if (propsObj != null) {
|
||||
stateJsonObject.putAll(propsObj);
|
||||
}
|
||||
|
||||
states.put(stateId, stateJsonObject);
|
||||
|
||||
String stateType = (String) nodeObj.get("stateType");
|
||||
if ("Compensation".equals(stateType)) {
|
||||
stateJsonObject.put("Type", "ServiceTask");
|
||||
} else {
|
||||
stateJsonObject.put("Type", stateType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void transformEdge(Map<String, Object> machineJsonObject, List<Object> nodes, Map<String, Object> nodeMap, Map<String, Object> edgeObj) {
|
||||
String sourceId = (String) edgeObj.get("source");
|
||||
String targetId = (String) edgeObj.get("target");
|
||||
if (StringUtils.hasLength(sourceId)) {
|
||||
Map<String, Object> sourceNode = (Map<String, Object>) nodeMap.get(sourceId);
|
||||
Map<String, Object> targetNode = (Map<String, Object>) nodeMap.get(targetId);
|
||||
|
||||
if (sourceNode != null) {
|
||||
Map<String, Object> states = (Map<String, Object>) machineJsonObject.get("States");
|
||||
Map<String, Object> sourceState = (Map<String, Object>) states.get((String) sourceNode.get("stateId"));
|
||||
String targetStateId = (String) targetNode.get("stateId");
|
||||
|
||||
String sourceType = (String) sourceNode.get("stateType");
|
||||
if ("Start".equals(sourceType)) {
|
||||
machineJsonObject.put("StartState", targetStateId);
|
||||
//Make sure 'StartState' is before 'States'
|
||||
machineJsonObject.put("States", machineJsonObject.remove("States"));
|
||||
} else if ("ServiceTask".equals(sourceType)) {
|
||||
if (targetNode != null && "Compensation".equals(targetNode.get("stateType"))) {
|
||||
sourceState.put("CompensateState", targetStateId);
|
||||
} else {
|
||||
sourceState.put("Next", targetStateId);
|
||||
}
|
||||
} else if ("Catch".equals(sourceType)) {
|
||||
Map<String, Object> catchAttachedNode = getCatchAttachedNode(sourceNode, nodes);
|
||||
if (catchAttachedNode == null) {
|
||||
throw new RuntimeException("'Catch' node[" + sourceNode.get("id") + "] is not attached on a 'ServiceTask' or 'ScriptTask'");
|
||||
}
|
||||
Map<String, Object> catchAttachedState = (Map<String, Object>) states.get(catchAttachedNode.get("stateId"));
|
||||
List<Object> catches = (List<Object>) CollectionUtils.computeIfAbsent(catchAttachedState, "Catch",
|
||||
key -> new ArrayList<>());
|
||||
|
||||
Map<String, Object> edgeProps = (Map<String, Object>) edgeObj.get("stateProps");
|
||||
if (edgeProps != null) {
|
||||
Map<String, Object> catchObj = new LinkedHashMap<>();
|
||||
catchObj.put("Exceptions", edgeProps.get("Exceptions"));
|
||||
catchObj.put("Next", targetStateId);
|
||||
catches.add(catchObj);
|
||||
}
|
||||
} else if ("Choice".equals(sourceType)) {
|
||||
List<Object> choices = (List<Object>) CollectionUtils.computeIfAbsent(sourceState, "Choices",
|
||||
key -> new ArrayList<>());
|
||||
|
||||
Map<String, Object> edgeProps = (Map<String, Object>) edgeObj.get("stateProps");
|
||||
if (edgeProps != null) {
|
||||
if (Boolean.TRUE.equals(edgeProps.get("Default"))) {
|
||||
sourceState.put("Default", targetStateId);
|
||||
} else {
|
||||
Map<String, Object> choiceObj = new LinkedHashMap<>();
|
||||
choiceObj.put("Expression", edgeProps.get("Expression"));
|
||||
choiceObj.put("Next", targetStateId);
|
||||
choices.add(choiceObj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sourceState.put("Next", targetStateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDesignerJson(Map<String, Object> jsonObject) {
|
||||
return jsonObject != null && jsonObject.containsKey("nodes") && jsonObject.containsKey("edges");
|
||||
}
|
||||
|
||||
private static Map<String, Object> getCatchAttachedNode(Map<String, Object> catchNode, List<Object> nodes) {
|
||||
Number catchNodeX = (Number) catchNode.get("x");
|
||||
Number catchNodeY = (Number) catchNode.get("y");
|
||||
String catchSize = (String) catchNode.get("size");
|
||||
String[] catchSizes = catchSize.split("\\*");
|
||||
int catchWidth = Integer.parseInt(catchSizes[0]);
|
||||
int catchHeight = Integer.parseInt(catchSizes[1]);
|
||||
|
||||
for (Object node : nodes) {
|
||||
Map<String, Object> nodeObj = (Map<String, Object>) node;
|
||||
if (catchNode != nodeObj &&
|
||||
("ServiceTask".equals(nodeObj.get("stateType"))
|
||||
|| "ScriptTask".equals(nodeObj.get("stateType")))) {
|
||||
|
||||
Number nodeX = (Number) nodeObj.get("x");
|
||||
Number nodeY = (Number) nodeObj.get("y");
|
||||
|
||||
String nodeSize = (String) nodeObj.get("size");
|
||||
String[] nodeSizes = nodeSize.split("\\*");
|
||||
int nodeWidth = Integer.parseInt(nodeSizes[0]);
|
||||
int nodeHeight = Integer.parseInt(nodeSizes[1]);
|
||||
|
||||
if (isBordersCoincided(catchNodeX, nodeX, catchWidth, nodeWidth)
|
||||
&& isBordersCoincided(catchNodeY, nodeY, catchHeight, nodeHeight)) {
|
||||
|
||||
return nodeObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isBordersCoincided(Number xyA, Number xyB, Number lengthA, Number lengthB) {
|
||||
double centerPointLength = xyA.doubleValue() > xyB.doubleValue() ? xyA.doubleValue() - xyB.doubleValue() : xyB.doubleValue() - xyA.doubleValue();
|
||||
return ((lengthA.doubleValue() + lengthB.doubleValue()) / 2) > centerPointLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tracing graph json
|
||||
* @param stateMachineInstance
|
||||
* @return
|
||||
*/
|
||||
public static String generateTracingGraphJson(StateMachineInstance stateMachineInstance, JsonParser jsonParser) {
|
||||
|
||||
if (stateMachineInstance == null) {
|
||||
throw new FrameworkException("StateMachineInstance is not exits",
|
||||
FrameworkErrorCode.StateMachineInstanceNotExists);
|
||||
}
|
||||
String stateMachineJson = stateMachineInstance.getStateMachine().getContent();
|
||||
if (StringUtils.isEmpty(stateMachineJson)) {
|
||||
throw new FrameworkException("Cannot get StateMachine Json",
|
||||
FrameworkErrorCode.ObjectNotExists);
|
||||
}
|
||||
|
||||
Map<String, Object> stateMachineJsonObj = jsonParser.parse(stateMachineJson, Map.class, true);
|
||||
if (!DesignerJsonTransformer.isDesignerJson(stateMachineJsonObj)) {
|
||||
throw new FrameworkException("StateMachine Json is not generated by Designer",
|
||||
FrameworkErrorCode.InvalidConfiguration);
|
||||
}
|
||||
Map<String, List<StateInstance>> stateInstanceMapGroupByName = new HashMap<>(stateMachineInstance.getStateMap().size());
|
||||
for (StateInstance stateInstance : stateMachineInstance.getStateMap().values()) {
|
||||
CollectionUtils.computeIfAbsent(stateInstanceMapGroupByName, stateInstance.getName(), key -> new ArrayList<>())
|
||||
.add(stateInstance);
|
||||
}
|
||||
List<Object> nodesArray = (List<Object>) stateMachineJsonObj.get("nodes");
|
||||
for (Object nodeObj : nodesArray) {
|
||||
Map<String, Object> node = (Map<String, Object>) nodeObj;
|
||||
String stateId = (String) node.get("stateId");
|
||||
String stateType = (String) node.get("stateType");
|
||||
if ("ServiceTask".equals(stateType)
|
||||
|| "SubStateMachine".equals(stateType)
|
||||
|| "Compensation".equals(stateType)) {
|
||||
node.remove("color");
|
||||
}
|
||||
List<StateInstance> stateInstanceList = stateInstanceMapGroupByName.get(stateId);
|
||||
if (CollectionUtils.isNotEmpty(stateInstanceList)) {
|
||||
StateInstance stateInstance = null;
|
||||
if (stateInstanceList.size() == 1) {
|
||||
stateInstance = stateInstanceList.get(0);
|
||||
} else {
|
||||
//find out latest stateInstance
|
||||
for (StateInstance stateInst : stateInstanceList) {
|
||||
|
||||
if (stateInstance == null
|
||||
|| stateInst.getGmtStarted().after(stateInstance.getGmtStarted())) {
|
||||
stateInstance = stateInst;
|
||||
}
|
||||
}
|
||||
}
|
||||
node.put("stateInstanceId", stateInstance.getId());
|
||||
node.put("stateInstanceStatus", stateInstance.getStatus());
|
||||
if (ExecutionStatus.SU.equals(stateInstance.getStatus())) {
|
||||
node.put("color", "green");
|
||||
Map<String, Object> style = new LinkedHashMap<>();
|
||||
style.put("fill", "#00D73E");
|
||||
style.put("lineWidth", 2);
|
||||
node.put("style", style);
|
||||
} else {
|
||||
node.put("color", "red");
|
||||
Map<String, Object> style = new LinkedHashMap<>();
|
||||
style.put("fill", "#FF7777");
|
||||
style.put("lineWidth", 2);
|
||||
node.put("style", style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stateMachineJsonObj != null) {
|
||||
return jsonParser.toJsonString(stateMachineJsonObj, true);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* IOUtils
|
||||
* copy from commons-io
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class IOUtils {
|
||||
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
||||
|
||||
public static String toString(InputStream input, String encoding) throws IOException {
|
||||
StringWriter sw = new StringWriter();
|
||||
copy(input, sw, encoding);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static void copy(InputStream input, Writer output, String encoding) throws IOException {
|
||||
if (encoding == null) {
|
||||
copy(input, output);
|
||||
} else {
|
||||
InputStreamReader in = new InputStreamReader(input, encoding);
|
||||
copy(in, output);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copy(InputStream input, Writer output) throws IOException {
|
||||
InputStreamReader in = new InputStreamReader(input);
|
||||
copy(in, output);
|
||||
}
|
||||
|
||||
public static int copy(Reader input, Writer output) throws IOException {
|
||||
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
|
||||
int count = 0;
|
||||
int n = 0;
|
||||
while (-1 != (n = input.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
io.seata.saga.statelang.parser.impl.FastjsonParser
|
||||
io.seata.saga.statelang.parser.impl.JacksonJsonParser
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.saga.statelang.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import io.seata.saga.statelang.domain.StateMachine;
|
||||
import io.seata.saga.statelang.parser.utils.DesignerJsonTransformer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* StateParser tests
|
||||
*
|
||||
* @author lorne.cl
|
||||
*/
|
||||
public class StateParserTests {
|
||||
|
||||
@Test
|
||||
public void testParser() throws IOException {
|
||||
|
||||
ClassPathResource resource = new ClassPathResource("statelang/simple_statemachine.json");
|
||||
String json = io.seata.saga.statelang.parser.utils.IOUtils.toString(resource.getInputStream(), "UTF-8");
|
||||
StateMachine stateMachine = StateMachineParserFactory.getStateMachineParser(null).parse(json);
|
||||
stateMachine.setGmtCreate(new Date());
|
||||
Assertions.assertNotNull(stateMachine);
|
||||
|
||||
JsonParser jsonParser = JsonParserFactory.getJsonParser("jackson");
|
||||
String outputJson = jsonParser.toJsonString(stateMachine, true);
|
||||
System.out.println(outputJson);
|
||||
|
||||
|
||||
JsonParser fastjsonParser = JsonParserFactory.getJsonParser("fastjson");
|
||||
String fastjsonOutputJson = fastjsonParser.toJsonString(stateMachine, true);
|
||||
System.out.println(fastjsonOutputJson);
|
||||
|
||||
Assertions.assertEquals(stateMachine.getName(), "simpleTestStateMachine");
|
||||
Assertions.assertTrue(stateMachine.getStates().size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDesignerJsonTransformer() throws IOException {
|
||||
|
||||
ClassPathResource resource = new ClassPathResource("statelang/simple_statemachine_with_layout.json");
|
||||
String json = io.seata.saga.statelang.parser.utils.IOUtils.toString(resource.getInputStream(), "UTF-8");
|
||||
JsonParser jsonParser = JsonParserFactory.getJsonParser("jackson");
|
||||
Map<String, Object> parsedObj = DesignerJsonTransformer.toStandardJson(jsonParser.parse(json, Map.class, true));
|
||||
Assertions.assertNotNull(parsedObj);
|
||||
|
||||
String outputJson = jsonParser.toJsonString(parsedObj, true);
|
||||
System.out.println(outputJson);
|
||||
|
||||
|
||||
JsonParser fastjsonParser = JsonParserFactory.getJsonParser("fastjson");
|
||||
Map<String, Object> fastjsonParsedObj = DesignerJsonTransformer.toStandardJson(fastjsonParser.parse(json, Map.class, true));
|
||||
Assertions.assertNotNull(fastjsonParsedObj);
|
||||
|
||||
String fastjsonOutputJson = fastjsonParser.toJsonString(fastjsonParsedObj, true);
|
||||
System.out.println(fastjsonOutputJson);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>%d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n</Pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"Name": "simpleTestStateMachine",
|
||||
"Comment": "测试状态机定义",
|
||||
"StartState": "FirstState",
|
||||
"Version": "0.0.1",
|
||||
"States": {
|
||||
"FirstState": {
|
||||
"Type": "ServiceTask",
|
||||
"ServiceName": "is.seata.saga.DemoService",
|
||||
"ServiceMethod": "foo",
|
||||
"IsPersist": false,
|
||||
"Next": "ScriptState"
|
||||
},
|
||||
"ScriptState": {
|
||||
"Type": "ScriptTask",
|
||||
"ScriptType": "groovy",
|
||||
"ScriptContent": "return 'hello ' + inputA",
|
||||
"Input": [
|
||||
{
|
||||
"inputA": "$.data1"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"scriptStateResult": "$.#root"
|
||||
},
|
||||
"Next": "ChoiceState"
|
||||
},
|
||||
"ChoiceState": {
|
||||
"Type": "Choice",
|
||||
"Choices": [
|
||||
{
|
||||
"Expression": "foo == 1",
|
||||
"Next": "FirstMatchState"
|
||||
},
|
||||
{
|
||||
"Expression": "foo == 2",
|
||||
"Next": "SecondMatchState"
|
||||
}
|
||||
],
|
||||
"Default": "FailState"
|
||||
},
|
||||
"FirstMatchState": {
|
||||
"Type": "ServiceTask",
|
||||
"ServiceName": "is.seata.saga.DemoService",
|
||||
"ServiceMethod": "bar",
|
||||
"CompensateState": "CompensateFirst",
|
||||
"Status": {
|
||||
"return.code == 'S'": "SU",
|
||||
"return.code == 'F'": "FA",
|
||||
"$exception{java.lang.Throwable}": "UN"
|
||||
},
|
||||
"Input": [
|
||||
{
|
||||
"inputA1": "$.data1",
|
||||
"inputA2": {
|
||||
"a": "$.data2.a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"inputB": "$.header"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"firstMatchStateResult": "$.#root"
|
||||
},
|
||||
"Retry": [
|
||||
{
|
||||
"Exceptions": ["java.lang.Exception"],
|
||||
"IntervalSeconds": 2,
|
||||
"MaxAttempts": 3,
|
||||
"BackoffRate": 1.5
|
||||
}
|
||||
],
|
||||
"Catch": [
|
||||
{
|
||||
"Exceptions": [
|
||||
"java.lang.Exception"
|
||||
],
|
||||
"Next": "CompensationTrigger"
|
||||
}
|
||||
],
|
||||
"Next": "SuccessState"
|
||||
},
|
||||
"CompensateFirst": {
|
||||
"Type": "ServiceTask",
|
||||
"ServiceName": "is.seata.saga.DemoService",
|
||||
"ServiceMethod": "compensateBar",
|
||||
"IsForCompensation": true,
|
||||
"IsForUpdate": true,
|
||||
"Input": [
|
||||
{
|
||||
"input": "$.data"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"firstMatchStateResult": "$.#root"
|
||||
},
|
||||
"Status": {
|
||||
"return.code == 'S'": "SU",
|
||||
"return.code == 'F'": "FA",
|
||||
"$exception{java.lang.Throwable}": "UN"
|
||||
}
|
||||
},
|
||||
"CompensationTrigger": {
|
||||
"Type": "CompensationTrigger",
|
||||
"Next": "CompensateEndState"
|
||||
},
|
||||
"CompensateEndState": {
|
||||
"Type": "Fail",
|
||||
"ErrorCode": "StateCompensated",
|
||||
"Message": "State Compensated!"
|
||||
},
|
||||
"SecondMatchState": {
|
||||
"Type": "SubStateMachine",
|
||||
"StateMachineName": "simpleTestStateMachine",
|
||||
"Input": [
|
||||
{
|
||||
"input": "$.data"
|
||||
},
|
||||
{
|
||||
"header": "$.header"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"firstMatchStateResult": "$.#root"
|
||||
},
|
||||
"Next": "SuccessState"
|
||||
},
|
||||
"FailState": {
|
||||
"Type": "Fail",
|
||||
"ErrorCode": "DefaultStateError",
|
||||
"Message": "No Matches!"
|
||||
},
|
||||
"SuccessState": {
|
||||
"Type": "Succeed"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"type": "node",
|
||||
"size": "72*72",
|
||||
"shape": "flow-circle",
|
||||
"color": "#FA8C16",
|
||||
"label": "Start",
|
||||
"stateId": "Start",
|
||||
"stateType": "Start",
|
||||
"stateProps": {
|
||||
"StateMachine": {
|
||||
"Name": "simpleStateMachineWithCompensationAndSubMachine_layout",
|
||||
"Comment": "带补偿定义和调用子状态机",
|
||||
"Version": "0.0.1"
|
||||
}
|
||||
},
|
||||
"x": 199.875,
|
||||
"y": 95,
|
||||
"id": "e2d86441"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "110*48",
|
||||
"shape": "flow-rect",
|
||||
"color": "#1890FF",
|
||||
"label": "FirstState",
|
||||
"stateId": "FirstState",
|
||||
"stateType": "ServiceTask",
|
||||
"stateProps": {
|
||||
"ServiceName": "demoService",
|
||||
"ServiceMethod": "foo",
|
||||
"Input": [
|
||||
{
|
||||
"fooInput": "$.[a]"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"fooResult": "$.#root"
|
||||
}
|
||||
},
|
||||
"x": 199.875,
|
||||
"y": 213,
|
||||
"id": "6111bf54"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "80*72",
|
||||
"shape": "flow-rhombus",
|
||||
"color": "#13C2C2",
|
||||
"label": "ChoiceState",
|
||||
"stateId": "ChoiceState",
|
||||
"stateType": "Choice",
|
||||
"x": 199.875,
|
||||
"y": 341.5,
|
||||
"id": "5610fa37"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "110*48",
|
||||
"shape": "flow-rect",
|
||||
"color": "#1890FF",
|
||||
"label": "SecondState",
|
||||
"stateId": "SecondState",
|
||||
"stateType": "ServiceTask",
|
||||
"stateProps": {
|
||||
"ServiceName": "demoService",
|
||||
"ServiceMethod": "bar",
|
||||
"Input": [
|
||||
{
|
||||
"barInput": "$.[fooResult]",
|
||||
"throwException": "$.[barThrowException]"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"barResult": "$.#root"
|
||||
},
|
||||
"Status": {
|
||||
"#root != null": "SU",
|
||||
"#root == null": "FA",
|
||||
"$Exception{io.seata.saga.engine.exception.EngineExecutionException}": "UN"
|
||||
}
|
||||
},
|
||||
"x": 199.375,
|
||||
"y": 468,
|
||||
"id": "af5591f9"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "72*72",
|
||||
"shape": "flow-circle",
|
||||
"color": "#05A465",
|
||||
"label": "Succeed",
|
||||
"stateId": "Succeed",
|
||||
"stateType": "Succeed",
|
||||
"x": 199.375,
|
||||
"y": 609,
|
||||
"id": "2fd4c8de"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "110*48",
|
||||
"shape": "flow-rect",
|
||||
"color": "#FA8C16",
|
||||
"label": "SubStateMachine",
|
||||
"stateId": "CallSubStateMachine",
|
||||
"stateType": "SubStateMachine",
|
||||
"stateProps": {
|
||||
"StateMachineName": "simpleCompensationStateMachine",
|
||||
"Input": [
|
||||
{
|
||||
"a": "$.1",
|
||||
"barThrowException": "$.[barThrowException]",
|
||||
"fooThrowException": "$.[fooThrowException]",
|
||||
"compensateFooThrowException": "$.[compensateFooThrowException]"
|
||||
}
|
||||
],
|
||||
"Output": {
|
||||
"fooResult": "$.#root"
|
||||
}
|
||||
},
|
||||
"x": 55.875,
|
||||
"y": 467,
|
||||
"id": "04ea55a5"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "110*48",
|
||||
"shape": "flow-capsule",
|
||||
"color": "#722ED1",
|
||||
"label": "CompenFirstState",
|
||||
"stateId": "CompensateFirstState",
|
||||
"stateType": "Compensation",
|
||||
"stateProps": {
|
||||
"ServiceName": "demoService",
|
||||
"ServiceMethod": "compensateFoo",
|
||||
"Input": [
|
||||
{
|
||||
"compensateFooInput": "$.[fooResult]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"x": 68.875,
|
||||
"y": 126,
|
||||
"id": "6a09a5c2"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "39*39",
|
||||
"shape": "flow-circle",
|
||||
"color": "red",
|
||||
"label": "Catch",
|
||||
"stateId": "Catch",
|
||||
"stateType": "Catch",
|
||||
"x": 257.875,
|
||||
"y": 492,
|
||||
"id": "e28af1c2"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "110*48",
|
||||
"shape": "flow-capsule",
|
||||
"color": "red",
|
||||
"label": "Compensation\nTrigger",
|
||||
"stateId": "CompensationTrigger",
|
||||
"stateType": "CompensationTrigger",
|
||||
"x": 366.875,
|
||||
"y": 491.5,
|
||||
"id": "e32417a0"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"size": "72*72",
|
||||
"shape": "flow-circle",
|
||||
"color": "red",
|
||||
"label": "Fail",
|
||||
"stateId": "Fail",
|
||||
"stateType": "Fail",
|
||||
"stateProps": {
|
||||
"ErrorCode": "NOT_FOUND",
|
||||
"Message": "not found"
|
||||
},
|
||||
"x": 513.375,
|
||||
"y": 491.5,
|
||||
"id": "d21d24c9"
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "e2d86441",
|
||||
"sourceAnchor": 2,
|
||||
"target": "6111bf54",
|
||||
"targetAnchor": 0,
|
||||
"id": "51f30b96"
|
||||
},
|
||||
{
|
||||
"source": "6111bf54",
|
||||
"sourceAnchor": 2,
|
||||
"target": "5610fa37",
|
||||
"targetAnchor": 0,
|
||||
"id": "8c3029b1"
|
||||
},
|
||||
{
|
||||
"source": "5610fa37",
|
||||
"sourceAnchor": 2,
|
||||
"target": "af5591f9",
|
||||
"targetAnchor": 0,
|
||||
"id": "a9e7d5b4",
|
||||
"stateProps": {
|
||||
"Expression": "[a] == 1",
|
||||
"Default": false
|
||||
},
|
||||
"label": "",
|
||||
"shape": "flow-smooth"
|
||||
},
|
||||
{
|
||||
"source": "af5591f9",
|
||||
"sourceAnchor": 2,
|
||||
"target": "2fd4c8de",
|
||||
"targetAnchor": 0,
|
||||
"id": "61f34a49"
|
||||
},
|
||||
{
|
||||
"source": "6111bf54",
|
||||
"sourceAnchor": 3,
|
||||
"target": "6a09a5c2",
|
||||
"targetAnchor": 2,
|
||||
"id": "553384ab",
|
||||
"style": {
|
||||
"lineDash": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "5610fa37",
|
||||
"sourceAnchor": 3,
|
||||
"target": "04ea55a5",
|
||||
"targetAnchor": 0,
|
||||
"id": "2ee91c33",
|
||||
"stateProps": {
|
||||
"Expression": "[a] == 2",
|
||||
"Default": false
|
||||
},
|
||||
"label": "",
|
||||
"shape": "flow-smooth"
|
||||
},
|
||||
{
|
||||
"source": "e28af1c2",
|
||||
"sourceAnchor": 1,
|
||||
"target": "e32417a0",
|
||||
"targetAnchor": 3,
|
||||
"id": "d854a4d0",
|
||||
"stateProps": {
|
||||
"Exceptions": [
|
||||
"io.seata.common.exception.FrameworkException"
|
||||
]
|
||||
},
|
||||
"label": "",
|
||||
"shape": "flow-smooth"
|
||||
},
|
||||
{
|
||||
"source": "04ea55a5",
|
||||
"sourceAnchor": 2,
|
||||
"target": "2fd4c8de",
|
||||
"targetAnchor": 3,
|
||||
"id": "28734ad2"
|
||||
},
|
||||
{
|
||||
"source": "5610fa37",
|
||||
"sourceAnchor": 1,
|
||||
"target": "d21d24c9",
|
||||
"targetAnchor": 0,
|
||||
"id": "7c7595c0",
|
||||
"stateProps": {
|
||||
"Expression": "",
|
||||
"Default": true
|
||||
},
|
||||
"label": "",
|
||||
"shape": "flow-smooth"
|
||||
},
|
||||
{
|
||||
"source": "e32417a0",
|
||||
"sourceAnchor": 1,
|
||||
"target": "d21d24c9",
|
||||
"targetAnchor": 3,
|
||||
"id": "16d809ce"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user