From 843d2a4b2fc19c381d4321438f4a1cf98bad7274 Mon Sep 17 00:00:00 2001 From: Xiangkun Yin <32592585+ptyin@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:38:09 +0800 Subject: [PATCH] optimize: add saga compatible subcomponent-level api (#6329) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 1 + .../seata/saga/engine/StateMachineConfig.java | 6 +- .../saga/engine/expression/Expression.java | 25 +++++ .../engine/expression/ExpressionFactory.java | 24 ++++ .../expression/ExpressionFactoryManager.java | 64 +++++++++++ .../impl/DefaultStateMachineConfig.java | 104 ++++++++++++++++-- .../impl/ProcessCtrlStateMachineEngine.java | 4 + .../saga/engine/repo/StateLogRepository.java | 71 ++++++++++++ .../engine/repo/StateMachineRepository.java | 25 +++++ 10 files changed, 311 insertions(+), 14 deletions(-) create mode 100644 compatible/src/main/java/io/seata/saga/engine/expression/Expression.java create mode 100644 compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactory.java create mode 100644 compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactoryManager.java create mode 100644 compatible/src/main/java/io/seata/saga/engine/repo/StateLogRepository.java create mode 100644 compatible/src/main/java/io/seata/saga/engine/repo/StateMachineRepository.java diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index ff55d2be6e4..2b586927185 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -81,6 +81,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6301](https://github.com/apache/incubator-seata/pull/6301)] upgrade console frontend dependencies and supported nodejs versions - [[#6301](https://github.com/apache/incubator-seata/pull/6312)] add saga related io.seata compatible api - [[#6313](https://github.com/apache/incubator-seata/pull/6313)] console display the version number +- [[#6329](https://github.com/apache/incubator-seata/pull/6312)] add saga subcomponent-level io.seata compatible api - [[#6254](https://github.com/apache/incubator-seata/pull/6254)] optimize Hessian Serialize ### security: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 40807862771..c9711e2f207 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -79,6 +79,7 @@ - [[#6301](https://github.com/apache/incubator-seata/pull/6301)] 升级console前端依赖及支持的nodejs版本 - [[#6301](https://github.com/apache/incubator-seata/pull/6312)] 添加saga相关的io.seata兼容性API - [[#6313](https://github.com/apache/incubator-seata/pull/6313)] console展示版本号 +- [[#6329](https://github.com/apache/incubator-seata/pull/6312)] 添加saga子组件的io.seata兼容性API - [[#6254](https://github.com/apache/incubator-seata/pull/6254)] 优化Hessian 序列化 diff --git a/compatible/src/main/java/io/seata/saga/engine/StateMachineConfig.java b/compatible/src/main/java/io/seata/saga/engine/StateMachineConfig.java index bf078722acc..60411b99c86 100644 --- a/compatible/src/main/java/io/seata/saga/engine/StateMachineConfig.java +++ b/compatible/src/main/java/io/seata/saga/engine/StateMachineConfig.java @@ -16,11 +16,11 @@ */ package io.seata.saga.engine; -import org.apache.seata.saga.engine.expression.ExpressionFactoryManager; +import io.seata.saga.engine.expression.ExpressionFactoryManager; +import io.seata.saga.engine.repo.StateLogRepository; +import io.seata.saga.engine.repo.StateMachineRepository; import org.apache.seata.saga.engine.expression.ExpressionResolver; import org.apache.seata.saga.engine.invoker.ServiceInvokerManager; -import org.apache.seata.saga.engine.repo.StateLogRepository; -import org.apache.seata.saga.engine.repo.StateMachineRepository; import org.apache.seata.saga.engine.sequence.SeqGenerator; import org.apache.seata.saga.engine.store.StateLangStore; import org.apache.seata.saga.engine.store.StateLogStore; diff --git a/compatible/src/main/java/io/seata/saga/engine/expression/Expression.java b/compatible/src/main/java/io/seata/saga/engine/expression/Expression.java new file mode 100644 index 00000000000..a2586ac73a8 --- /dev/null +++ b/compatible/src/main/java/io/seata/saga/engine/expression/Expression.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.engine.expression; + +/** + * Expression + * + */ +public interface Expression extends org.apache.seata.saga.engine.expression.Expression { + +} diff --git a/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactory.java b/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactory.java new file mode 100644 index 00000000000..56619c43c95 --- /dev/null +++ b/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactory.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.engine.expression; + +/** + * Expression Factory + * + */ +public interface ExpressionFactory extends org.apache.seata.saga.engine.expression.ExpressionFactory { +} diff --git a/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactoryManager.java b/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactoryManager.java new file mode 100644 index 00000000000..dc40a74ca19 --- /dev/null +++ b/compatible/src/main/java/io/seata/saga/engine/expression/ExpressionFactoryManager.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.engine.expression; + +import java.util.AbstractMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Expression factory manager + */ +public class ExpressionFactoryManager { + + private final org.apache.seata.saga.engine.expression.ExpressionFactoryManager actual; + + public static final String DEFAULT_EXPRESSION_TYPE = "Default"; + + private ExpressionFactoryManager(org.apache.seata.saga.engine.expression.ExpressionFactoryManager actual) { + this.actual = actual; + } + + public ExpressionFactoryManager() { + actual = new org.apache.seata.saga.engine.expression.ExpressionFactoryManager(); + } + + + public ExpressionFactory getExpressionFactory(String expressionType) { + org.apache.seata.saga.engine.expression.ExpressionFactory expressionFactory = actual.getExpressionFactory(expressionType); + return expressionFactory::createExpression; + } + + public void setExpressionFactoryMap(Map expressionFactoryMap) { + Map actualExpressionFactoryMap = expressionFactoryMap.entrySet().stream() + .map(e -> new AbstractMap.SimpleEntry(e.getKey(), e.getValue())) + .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); + actual.setExpressionFactoryMap(actualExpressionFactoryMap); + } + + public void putExpressionFactory(String type, ExpressionFactory factory) { + actual.putExpressionFactory(type, factory); + } + + public org.apache.seata.saga.engine.expression.ExpressionFactoryManager unwrap() { + return actual; + } + + public static ExpressionFactoryManager wrap(org.apache.seata.saga.engine.expression.ExpressionFactoryManager actual) { + return new ExpressionFactoryManager(actual); + } +} diff --git a/compatible/src/main/java/io/seata/saga/engine/impl/DefaultStateMachineConfig.java b/compatible/src/main/java/io/seata/saga/engine/impl/DefaultStateMachineConfig.java index 4f0866fdec1..1f7c0b86cbf 100644 --- a/compatible/src/main/java/io/seata/saga/engine/impl/DefaultStateMachineConfig.java +++ b/compatible/src/main/java/io/seata/saga/engine/impl/DefaultStateMachineConfig.java @@ -17,22 +17,31 @@ package io.seata.saga.engine.impl; import io.seata.saga.engine.StateMachineConfig; -import org.apache.seata.saga.engine.expression.ExpressionFactoryManager; +import io.seata.saga.engine.expression.ExpressionFactoryManager; +import io.seata.saga.engine.repo.StateLogRepository; +import io.seata.saga.engine.repo.StateMachineRepository; +import io.seata.saga.statelang.domain.StateInstance; +import io.seata.saga.statelang.domain.StateMachineInstance; +import io.seata.saga.statelang.domain.impl.StateInstanceImpl; +import io.seata.saga.statelang.domain.impl.StateMachineInstanceImpl; import org.apache.seata.saga.engine.expression.ExpressionResolver; import org.apache.seata.saga.engine.invoker.ServiceInvokerManager; -import org.apache.seata.saga.engine.repo.StateLogRepository; -import org.apache.seata.saga.engine.repo.StateMachineRepository; import org.apache.seata.saga.engine.sequence.SeqGenerator; import org.apache.seata.saga.engine.store.StateLangStore; import org.apache.seata.saga.engine.store.StateLogStore; import org.apache.seata.saga.engine.strategy.StatusDecisionStrategy; import org.apache.seata.saga.proctrl.eventing.impl.ProcessCtrlEventPublisher; +import org.apache.seata.saga.statelang.domain.StateMachine; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.core.io.Resource; import javax.script.ScriptEngineManager; +import java.io.IOException; +import java.util.List; import java.util.concurrent.ThreadPoolExecutor; +import java.util.stream.Collectors; /** * Default state machine configuration @@ -42,7 +51,15 @@ public class DefaultStateMachineConfig implements StateMachineConfig, Applicatio private final org.apache.seata.saga.engine.impl.DefaultStateMachineConfig actual; - public DefaultStateMachineConfig(org.apache.seata.saga.engine.impl.DefaultStateMachineConfig actual) { + private ExpressionFactoryManager expressionFactoryManager; + + private ExpressionResolver expressionResolver; + + public DefaultStateMachineConfig() { + this.actual = new org.apache.seata.saga.engine.impl.DefaultStateMachineConfig(); + } + + private DefaultStateMachineConfig(org.apache.seata.saga.engine.impl.DefaultStateMachineConfig actual) { this.actual = actual; } @@ -71,11 +88,15 @@ public void setStateLangStore(StateLangStore stateLangStore) { @Override public ExpressionFactoryManager getExpressionFactoryManager() { - return actual.getExpressionFactoryManager(); + if (expressionFactoryManager == null) { + expressionFactoryManager = ExpressionFactoryManager.wrap(actual.getExpressionFactoryManager()); + } + return expressionFactoryManager; } public void setExpressionFactoryManager(ExpressionFactoryManager expressionFactoryManager) { - actual.setExpressionFactoryManager(expressionFactoryManager); + this.expressionFactoryManager = expressionFactoryManager; + this.expressionResolver.setExpressionFactoryManager(expressionFactoryManager.unwrap()); } @Override @@ -98,7 +119,37 @@ public void setCharset(String charset) { @Override public StateMachineRepository getStateMachineRepository() { - return actual.getStateMachineRepository(); + org.apache.seata.saga.engine.repo.StateMachineRepository repository = actual.getStateMachineRepository(); + if (repository instanceof StateMachineRepository) { + return (StateMachineRepository) repository; + } + + return new StateMachineRepository() { + @Override + public StateMachine getStateMachineById(String stateMachineId) { + return repository.getStateMachineById(stateMachineId); + } + + @Override + public StateMachine getStateMachine(String stateMachineName, String tenantId) { + return repository.getStateMachine(stateMachineName, tenantId); + } + + @Override + public StateMachine getStateMachine(String stateMachineName, String tenantId, String version) { + return repository.getStateMachine(stateMachineName, tenantId, version); + } + + @Override + public StateMachine registryStateMachine(StateMachine stateMachine) { + return repository.registryStateMachine(stateMachine); + } + + @Override + public void registryByResources(Resource[] resources, String tenantId) throws IOException { + repository.registryByResources(resources, tenantId); + } + }; } public void setStateMachineRepository(StateMachineRepository stateMachineRepository) { @@ -168,10 +219,41 @@ public void setEnableAsync(boolean enableAsync) { @Override public StateLogRepository getStateLogRepository() { - return actual.getStateLogRepository(); - } - - public void setStateLogRepository(StateLogRepository stateLogRepository) { + org.apache.seata.saga.engine.repo.StateLogRepository repository = actual.getStateLogRepository(); + if (repository instanceof StateLogRepository) { + return (StateLogRepository) repository; + } + return new StateLogRepository() { + @Override + public StateMachineInstance getStateMachineInstance(String stateMachineInstanceId) { + return StateMachineInstanceImpl.wrap(repository.getStateMachineInstance(stateMachineInstanceId)); + } + + @Override + public StateMachineInstance getStateMachineInstanceByBusinessKey(String businessKey, String tenantId) { + return StateMachineInstanceImpl.wrap(repository.getStateMachineInstanceByBusinessKey(businessKey, tenantId)); + } + + @Override + public List queryStateMachineInstanceByParentId(String parentId) { + return repository.queryStateMachineInstanceByParentId(parentId).stream() + .map(StateMachineInstanceImpl::wrap).collect(Collectors.toList()); + } + + @Override + public StateInstance getStateInstance(String stateInstanceId, String machineInstId) { + return StateInstanceImpl.wrap(repository.getStateInstance(stateInstanceId, machineInstId)); + } + + @Override + public List queryStateInstanceListByMachineInstanceId(String stateMachineInstanceId) { + return repository.queryStateInstanceListByMachineInstanceId(stateMachineInstanceId).stream() + .map(StateInstanceImpl::wrap).collect(Collectors.toList()); + } + }; + } + + public void setStateLogRepository(org.apache.seata.saga.engine.repo.StateLogRepository stateLogRepository) { actual.setStateLogRepository(stateLogRepository); } diff --git a/compatible/src/main/java/io/seata/saga/engine/impl/ProcessCtrlStateMachineEngine.java b/compatible/src/main/java/io/seata/saga/engine/impl/ProcessCtrlStateMachineEngine.java index 9e169bef0f4..dfb47e981a0 100644 --- a/compatible/src/main/java/io/seata/saga/engine/impl/ProcessCtrlStateMachineEngine.java +++ b/compatible/src/main/java/io/seata/saga/engine/impl/ProcessCtrlStateMachineEngine.java @@ -132,6 +132,10 @@ public StateMachineConfig getStateMachineConfig() { actual.getStateMachineConfig()); } + public void setStateMachineConfig(StateMachineConfig stateMachineConfig) { + actual.setStateMachineConfig(((DefaultStateMachineConfig) stateMachineConfig).unwrap()); + } + @Override public StateMachineInstance reloadStateMachineInstance(String instId) { return StateMachineInstanceImpl.wrap(actual.reloadStateMachineInstance(instId)); diff --git a/compatible/src/main/java/io/seata/saga/engine/repo/StateLogRepository.java b/compatible/src/main/java/io/seata/saga/engine/repo/StateLogRepository.java new file mode 100644 index 00000000000..92e97a5af52 --- /dev/null +++ b/compatible/src/main/java/io/seata/saga/engine/repo/StateLogRepository.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.engine.repo; + +import io.seata.saga.statelang.domain.StateInstance; +import io.seata.saga.statelang.domain.StateMachineInstance; + +import java.util.List; + +/** + * State Log Repository + * + */ +public interface StateLogRepository { + + /** + * Get state machine instance + * + * @param stateMachineInstanceId the state machine instance id + * @return the state machine instance + */ + StateMachineInstance getStateMachineInstance(String stateMachineInstanceId); + + /** + * Get state machine instance by businessKey + * + * @param businessKey the business key + * @param tenantId the tenant id + * @return the state machine instance + */ + StateMachineInstance getStateMachineInstanceByBusinessKey(String businessKey, String tenantId); + + /** + * Query the list of state machine instances by parent id + * + * @param parentId the state parent id + * @return state machine instance list + */ + List queryStateMachineInstanceByParentId(String parentId); + + /** + * Get state instance + * + * @param stateInstanceId the state instance id + * @param machineInstId the state machine instance id + * @return the state instance + */ + StateInstance getStateInstance(String stateInstanceId, String machineInstId); + + /** + * Get a list of state instances by state machine instance id + * + * @param stateMachineInstanceId the state machine instance id + * @return the state machine instance list + */ + List queryStateInstanceListByMachineInstanceId(String stateMachineInstanceId); +} diff --git a/compatible/src/main/java/io/seata/saga/engine/repo/StateMachineRepository.java b/compatible/src/main/java/io/seata/saga/engine/repo/StateMachineRepository.java new file mode 100644 index 00000000000..f02515c0905 --- /dev/null +++ b/compatible/src/main/java/io/seata/saga/engine/repo/StateMachineRepository.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.engine.repo; + +/** + * StateMachineRepository + * + */ +public interface StateMachineRepository extends org.apache.seata.saga.engine.repo.StateMachineRepository { + +}