Skip to content

Commit

Permalink
feature: Saga support auto configuration in the spring boot project (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
wangliang181230 committed Sep 30, 2021
1 parent 418ca45 commit b0dab9c
Show file tree
Hide file tree
Showing 13 changed files with 441 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import javax.script.ScriptEngineManager;

import io.seata.common.loader.EnhancedServiceLoader;
import io.seata.saga.engine.StateMachineConfig;
Expand Down Expand Up @@ -61,15 +62,15 @@
import io.seata.saga.proctrl.impl.ProcessControllerImpl;
import io.seata.saga.proctrl.process.impl.CustomizeBusinessProcessor;
import io.seata.saga.statelang.domain.DomainConstants;
import io.seata.saga.statelang.parser.utils.ResourceUtil;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 static io.seata.common.DefaultValues.DEFAULT_CLIENT_SAGA_COMPENSATE_PERSIST_MODE_UPDATE;
import static io.seata.common.DefaultValues.DEFAULT_CLIENT_SAGA_RETRY_PERSIST_MODE_UPDATE;
import static io.seata.common.DefaultValues.DEFAULT_SAGA_JSON_PARSER;
Expand Down Expand Up @@ -102,10 +103,11 @@ public class DefaultStateMachineConfig implements StateMachineConfig, Applicatio
private ProcessCtrlEventPublisher asyncProcessCtrlEventPublisher;
private ApplicationContext applicationContext;
private ThreadPoolExecutor threadPoolExecutor;
private boolean enableAsync;
private boolean enableAsync = false;
private ServiceInvokerManager serviceInvokerManager;

private Resource[] resources = new Resource[0];
private boolean autoRegisterResources = true;
private String[] resources = new String[]{"classpath*:seata/saga/statelang/**/*.json"};
private String charset = "UTF-8";
private String defaultTenantId = "000001";
private ScriptEngineManager scriptEngineManager;
Expand Down Expand Up @@ -149,15 +151,17 @@ protected void init() throws Exception {
stateMachineRepository.setStateLangStore(stateLangStore);
stateMachineRepository.setDefaultTenantId(defaultTenantId);
stateMachineRepository.setJsonParserName(sagaJsonParser);
if (resources != null) {
try {
stateMachineRepository.registryByResources(resources, defaultTenantId);
} catch (IOException e) {
LOGGER.error("Load State Language Resources failed.", e);
}
}
this.stateMachineRepository = stateMachineRepository;
}
//stateMachineRepository may be overridden, so move `stateMachineRepository.registryByResources()` here.
if (autoRegisterResources && ArrayUtils.isNotEmpty(resources)) {
try {
Resource[] resources = ResourceUtil.getResources(this.resources);
stateMachineRepository.registryByResources(resources, defaultTenantId);
} catch (IOException e) {
LOGGER.error("Load State Language Resources failed.", e);
}
}

if (stateLogRepository == null) {
StateLogRepositoryImpl stateLogRepositoryImpl = new StateLogRepositoryImpl();
Expand Down Expand Up @@ -427,7 +431,11 @@ public void setSyncProcessCtrlEventPublisher(ProcessCtrlEventPublisher syncProce
this.syncProcessCtrlEventPublisher = syncProcessCtrlEventPublisher;
}

public void setResources(Resource[] resources) {
public void setAutoRegisterResources(boolean autoRegisterResources) {
this.autoRegisterResources = autoRegisterResources;
}

public void setResources(String[] resources) {
this.resources = resources;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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.util.Optional;
import java.util.stream.Stream;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

/**
* State lang resource util.
*
* @author wang.liang
*/
public class ResourceUtil {

private static final ResourcePatternResolver RESOURCE_RESOLVER = new PathMatchingResourcePatternResolver();

public static Resource[] getResources(String location) {
try {
return RESOURCE_RESOLVER.getResources(location);
} catch (IOException e) {
return new Resource[0];
}
}

public static Resource[] getResources(String[] locationArr) {
return Stream
.of(Optional.ofNullable(locationArr).orElse(new String[0]))
.flatMap(location -> Stream.of(getResources(location)))
.toArray(i -> new Resource[i]);
}
}
Original file line number Diff line number Diff line change
@@ -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.parser.utils;

import org.junit.jupiter.api.Test;
import org.springframework.core.io.Resource;

import static org.assertj.core.api.Assertions.assertThat;

/**
* ResourceUtil tests
*
* @author wang.liang
*/
public class ResourceUtilTests {

@Test
public void getResources_test() {
Resource[] resources = ResourceUtil.getResources("classpath*:statelang/*.json");
assertThat(resources.length).isEqualTo(2);

Resource[] resources2 = ResourceUtil.getResources(new String[]{"classpath*:statelang/*.json"});
assertThat(resources2.length).isEqualTo(2);
}
}
2 changes: 1 addition & 1 deletion script/client/conf/file.conf
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ client {
tableMetaCheckerInterval = 60000
reportSuccessEnable = false
sagaBranchRegisterEnable = false
sagaJsonParser = jackson
sagaJsonParser = "fastjson"
sagaRetryPersistModeUpdate = false
sagaCompensatePersistModeUpdate = false
tccActionInterceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
Expand Down
16 changes: 15 additions & 1 deletion script/client/spring/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,18 @@ seata.registry.zk.password=
seata.registry.custom.name=

seata.tcc.fence.log-table-name=tcc_fence_log
seata.tcc.fence.clean-period=1h
seata.tcc.fence.clean-period=1h


seata.saga.enabled=false
seata.saga.state-machine.table-prefix=seata_
seata.saga.state-machine.enable-async=false
seata.saga.state-machine.async-thread-pool.core-pool-size=1
seata.saga.state-machine.async-thread-pool.max-pool-size=20
seata.saga.state-machine.async-thread-pool.keep-alive-time=60
seata.saga.state-machine.trans-operation-timeout=1800000
seata.saga.state-machine.service-invoke-timeout=300000
seata.saga.state-machine.auto-register-resources=true
seata.saga.state-machine.resources[0]=classpath*:seata/saga/statelang/**/*.json
seata.saga.state-machine.default-tenant-id=000001
seata.saga.state-machine.charset=UTF-8
18 changes: 17 additions & 1 deletion script/client/spring/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,20 @@ seata:
tcc:
fence:
log-table-name: tcc_fence_log
clean-period: 1h
clean-period: 1h
saga:
enabled: false
state-machine:
table-prefix: seata_
enable-async: false
async-thread-pool:
core-pool-size: 1
max-pool-size: 20
keep-alive-time: 60
trans-operation-timeout: 1800000
service-invoke-timeout: 300000
auto-register-resources: true
resources:
- classpath*:seata/saga/statelang/**/*.json
default-tenant-id: 000001
charset: UTF-8
1 change: 1 addition & 0 deletions script/config-center/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package io.seata.spring.boot.autoconfigure;

import io.seata.rm.tcc.config.TCCFenceConfig;
import io.seata.saga.engine.StateMachineConfig;
import io.seata.spring.boot.autoconfigure.properties.SagaAsyncThreadPoolProperties;
import io.seata.spring.boot.autoconfigure.properties.SeataProperties;
import io.seata.spring.boot.autoconfigure.properties.client.LoadBalanceProperties;
import io.seata.spring.boot.autoconfigure.properties.client.LockProperties;
Expand All @@ -35,10 +37,12 @@
import static io.seata.spring.boot.autoconfigure.StarterConstants.LOAD_BALANCE_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.LOCK_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.PROPERTY_BEAN_MAP;
import static io.seata.spring.boot.autoconfigure.StarterConstants.SAGA_ASYNC_THREAD_POOL_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.SAGA_STATE_MACHINE_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.SEATA_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.SERVICE_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.UNDO_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.TCC_FENCE_PREFIX;
import static io.seata.spring.boot.autoconfigure.StarterConstants.UNDO_PREFIX;

/**
* @author xingfudeshi@gmail.com
Expand All @@ -58,6 +62,8 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp
PROPERTY_BEAN_MAP.put(COMPRESS_PREFIX, UndoCompressProperties.class);
PROPERTY_BEAN_MAP.put(LOAD_BALANCE_PREFIX, LoadBalanceProperties.class);
PROPERTY_BEAN_MAP.put(TCC_FENCE_PREFIX, TCCFenceConfig.class);
PROPERTY_BEAN_MAP.put(SAGA_STATE_MACHINE_PREFIX, StateMachineConfig.class);
PROPERTY_BEAN_MAP.put(SAGA_ASYNC_THREAD_POOL_PREFIX, SagaAsyncThreadPoolProperties.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.spring.boot.autoconfigure.properties;

import io.seata.spring.boot.autoconfigure.StarterConstants;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* Saga state machine async thread pool properties.
*
* @author wang.liang
*/
@Component
@ConfigurationProperties(StarterConstants.SAGA_ASYNC_THREAD_POOL_PREFIX)
public class SagaAsyncThreadPoolProperties {

/**
* core pool size.
*/
private int corePoolSize = 1;

/**
* max pool size
*/
private int maxPoolSize = 20;

/**
* keep alive time
*/
private int keepAliveTime = 60;

public int getCorePoolSize() {
return corePoolSize;
}

public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}

public int getMaxPoolSize() {
return maxPoolSize;
}

public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}

public int getKeepAliveTime() {
return keepAliveTime;
}

public void setKeepAliveTime(int keepAliveTime) {
this.keepAliveTime = keepAliveTime;
}
}
Loading

0 comments on commit b0dab9c

Please sign in to comment.