diff --git a/integration/solon-plugin/pom.xml b/integration/solon-plugin/pom.xml
new file mode 100644
index 00000000000..e00118d8bb8
--- /dev/null
+++ b/integration/solon-plugin/pom.xml
@@ -0,0 +1,129 @@
+
+
+
+
+ org.apache.seata
+ seata-parent
+ 2.2.0
+
+
+ 4.0.0
+ seata-solon-plugin
+ jar
+ seata-solon-plugin ${project.version}
+ solon-plugin for Seata built with Maven
+
+
+ 3.0.3
+ 2.18.1
+
+
+
+
+
+ ${project.groupId}
+ seata-tm
+ ${project.version}
+
+
+
+ ${project.groupId}
+ seata-integration-tx-api
+ ${project.version}
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
+
+
+ org.noear
+ solon-data
+ ${solon.version}
+
+
+
+ org.noear
+ solon-net-httputils
+ ${solon.version}
+ true
+
+
+
+ org.noear
+ nami
+ ${solon.version}
+ true
+
+
+
+ org.noear
+ solon-boot-jdkhttp
+ ${solon.version}
+ test
+
+
+
+ org.noear
+ solon-test
+ ${solon.version}
+ test
+
+
+
+
+
+ sonatype-nexus-snapshots
+ Sonatype Nexus Snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+
+ false
+
+
+
+
+
+ sonatype-nexus-snapshots
+ Sonatype Nexus Snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+
+ false
+
+
+
+
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionLifecycle.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionLifecycle.java
new file mode 100644
index 00000000000..4c1bfe22162
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionLifecycle.java
@@ -0,0 +1,201 @@
+/*
+ * 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 org.apache.seata.solon.annotation;
+
+import org.apache.seata.common.util.StringUtils;
+import org.apache.seata.config.CachedConfigurationChangeListener;
+import org.apache.seata.config.ConfigurationChangeEvent;
+import org.apache.seata.config.ConfigurationFactory;
+import org.apache.seata.core.constants.ConfigurationKeys;
+import org.apache.seata.core.rpc.ShutdownHook;
+import org.apache.seata.core.rpc.netty.RmNettyRemotingClient;
+import org.apache.seata.core.rpc.netty.TmNettyRemotingClient;
+import org.apache.seata.rm.RMClient;
+import org.apache.seata.tm.TMClient;
+import org.apache.seata.tm.api.FailureHandler;
+import org.apache.seata.tm.api.FailureHandlerHolder;
+import org.noear.solon.core.bean.LifecycleBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.seata.common.DefaultValues.*;
+
+/**
+ * The type Global transaction lifecycle (old: The type Global transaction scanner.)
+ *
+ */
+public class GlobalTransactionLifecycle implements CachedConfigurationChangeListener, LifecycleBean {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GlobalTransactionLifecycle.class);
+
+ private static final int AT_MODE = 1;
+ private static final int MT_MODE = 2;
+
+ private static final int ORDER_NUM = 1024;
+ private static final int DEFAULT_MODE = AT_MODE + MT_MODE;
+
+ private final String applicationId;
+ private final String txServiceGroup;
+ private static String accessKey;
+ private static String secretKey;
+ private volatile boolean disableGlobalTransaction = ConfigurationFactory.getInstance().getBoolean(
+ ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, DEFAULT_DISABLE_GLOBAL_TRANSACTION);
+ private final AtomicBoolean initialized = new AtomicBoolean(false);
+
+ private final FailureHandler failureHandlerHook;
+
+
+ /**
+ * Instantiates a new Global transaction scanner.
+ *
+ * @param applicationId the application id
+ * @param txServiceGroup the tx service group
+ * @param exposeProxy the exposeProxy
+ * @param failureHandlerHook the failure handler hook
+ */
+ public GlobalTransactionLifecycle(String applicationId, String txServiceGroup, boolean exposeProxy,
+ FailureHandler failureHandlerHook) {
+ this(applicationId, txServiceGroup, DEFAULT_MODE, exposeProxy, failureHandlerHook);
+ }
+
+ /**
+ * Instantiates a new Global transaction scanner.
+ *
+ * @param applicationId the application id
+ * @param txServiceGroup the tx service group
+ * @param mode the mode
+ * @param exposeProxy the exposeProxy
+ * @param failureHandlerHook the failure handler hook
+ */
+ public GlobalTransactionLifecycle(String applicationId, String txServiceGroup, int mode, boolean exposeProxy,
+ FailureHandler failureHandlerHook) {
+ this.applicationId = applicationId;
+ this.txServiceGroup = txServiceGroup;
+ this.failureHandlerHook = failureHandlerHook;
+ FailureHandlerHolder.setFailureHandler(this.failureHandlerHook);
+ }
+
+ /**
+ * Sets access key.
+ *
+ * @param accessKey the access key
+ */
+ public static void setAccessKey(String accessKey) {
+ GlobalTransactionLifecycle.accessKey = accessKey;
+ }
+
+ /**
+ * Sets secret key.
+ *
+ * @param secretKey the secret key
+ */
+ public static void setSecretKey(String secretKey) {
+ GlobalTransactionLifecycle.secretKey = secretKey;
+ }
+
+
+ protected void initClient() {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Initializing Global Transaction Clients ... ");
+ }
+ if (DEFAULT_TX_GROUP_OLD.equals(txServiceGroup)) {
+ LOGGER.warn("the default value of seata.tx-service-group: {} has already changed to {} since Seata 1.5, " +
+ "please change your default configuration as soon as possible " +
+ "and we don't recommend you to use default tx-service-group's value provided by seata",
+ DEFAULT_TX_GROUP_OLD, DEFAULT_TX_GROUP);
+ }
+ if (StringUtils.isNullOrEmpty(applicationId) || StringUtils.isNullOrEmpty(txServiceGroup)) {
+ throw new IllegalArgumentException(String.format("applicationId: %s, txServiceGroup: %s", applicationId, txServiceGroup));
+ }
+ //init TM
+ TMClient.init(applicationId, txServiceGroup, accessKey, secretKey);
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Transaction Manager Client is initialized. applicationId[{}] txServiceGroup[{}]", applicationId, txServiceGroup);
+ }
+ //init RM
+ RMClient.init(applicationId, txServiceGroup);
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Resource Manager is initialized. applicationId[{}] txServiceGroup[{}]", applicationId, txServiceGroup);
+ }
+
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Global Transaction Clients are initialized. ");
+ }
+ registerSpringShutdownHook();
+
+ }
+
+ protected void registerSpringShutdownHook() {
+ ShutdownHook.getInstance().addDisposable(TmNettyRemotingClient.getInstance(applicationId, txServiceGroup, accessKey, secretKey));
+ ShutdownHook.getInstance().addDisposable(RmNettyRemotingClient.getInstance(applicationId, txServiceGroup));
+ }
+
+
+ @Override
+ public void start() {
+ if (disableGlobalTransaction) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Global transaction is disabled.");
+ }
+ ConfigurationFactory.getInstance().addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, (CachedConfigurationChangeListener) this);
+ return;
+ }
+
+ if (initialized.compareAndSet(false, true)) {
+ initClient();
+ }
+ }
+
+ @Override
+ public void stop() {
+ ShutdownHook.getInstance().destroyAll();
+ }
+
+
+ @Override
+ public void onChangeEvent(ConfigurationChangeEvent event) {
+ if (ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION.equals(event.getDataId())) {
+ disableGlobalTransaction = Boolean.parseBoolean(event.getNewValue().trim());
+ if (!disableGlobalTransaction && initialized.compareAndSet(false, true)) {
+ LOGGER.info("{} config changed, old value:true, new value:{}", ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
+ event.getNewValue());
+ initClient();
+ ConfigurationFactory.getInstance().removeConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, this);
+ }
+ }
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public String getTxServiceGroup() {
+ return txServiceGroup;
+ }
+
+ public static String getAccessKey() {
+ return accessKey;
+ }
+
+ public static String getSecretKey() {
+ return secretKey;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionalInterceptor.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionalInterceptor.java
new file mode 100644
index 00000000000..ff9be132dd1
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/GlobalTransactionalInterceptor.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.seata.solon.annotation;
+
+import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
+import org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
+import org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+import org.apache.seata.tm.api.FailureHandlerHolder;
+import org.noear.solon.core.aspect.Invocation;
+import org.noear.solon.core.aspect.MethodInterceptor;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * GlobalTransactional annotation interceptor
+ *
+ * @author noear 2024/10/25 created
+ */
+public class GlobalTransactionalInterceptor implements MethodInterceptor {
+ private final Set methodsToProxy = new HashSet<>();
+ @Override
+ public Object doIntercept(Invocation inv) throws Throwable {
+ InvocationWrapper invocationWrapper = new SolonInvocationWrapper(inv);
+
+ return this.createProxyInvocationHandler().invoke(invocationWrapper);
+ }
+
+ protected ProxyInvocationHandler createProxyInvocationHandler() {
+ return new GlobalTransactionalInterceptorHandler(FailureHandlerHolder.getFailureHandler(), methodsToProxy);
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/SolonInvocationWrapper.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/SolonInvocationWrapper.java
new file mode 100644
index 00000000000..fce845deed9
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/SolonInvocationWrapper.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.seata.solon.annotation;
+
+import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
+import org.noear.solon.core.aspect.Invocation;
+
+import java.lang.reflect.Method;
+
+/**
+ * Solon invocation wrapper
+ *
+ * @author noear 2024/10/25 created
+ */
+public class SolonInvocationWrapper implements InvocationWrapper {
+ private final Invocation inv;
+
+ public SolonInvocationWrapper(Invocation inv) {
+ this.inv = inv;
+ }
+
+ @Override
+ public Method getMethod() {
+ return inv.method().getMethod();
+ }
+
+ @Override
+ public Object getProxy() {
+ return inv.target();
+ }
+
+ @Override
+ public Object getTarget() {
+ return inv.getTargetClz();
+ }
+
+ @Override
+ public Object[] getArguments() {
+ return inv.args();
+ }
+
+ @Override
+ public Object proceed() throws Throwable {
+ return inv.invoke();
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/DataSourceProxyHolder.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/DataSourceProxyHolder.java
new file mode 100644
index 00000000000..b59403232eb
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/DataSourceProxyHolder.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.seata.solon.annotation.datasource;
+
+import org.apache.seata.rm.datasource.SeataDataSourceProxy;
+
+import javax.sql.DataSource;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+/**
+ * the type data source proxy holder
+ *
+ */
+public class DataSourceProxyHolder {
+
+ private static final Map PROXY_MAP = new ConcurrentHashMap<>(4);
+
+ static SeataDataSourceProxy put(DataSource origin, SeataDataSourceProxy proxy) {
+ return PROXY_MAP.put(origin, proxy);
+ }
+
+ static SeataDataSourceProxy computeIfAbsent(DataSource origin, Function mappingFunction) {
+ return PROXY_MAP.computeIfAbsent(origin, mappingFunction);
+ }
+
+ static SeataDataSourceProxy get(DataSource origin) {
+ return PROXY_MAP.get(origin);
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyAT.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyAT.java
new file mode 100644
index 00000000000..72937b6dc53
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyAT.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.seata.solon.annotation.datasource;
+
+import org.apache.seata.rm.datasource.DataSourceProxy;
+import org.apache.seata.rm.datasource.SeataDataSourceProxy;
+import org.noear.solon.data.datasource.RoutingDataSource;
+
+import javax.sql.DataSource;
+
+/**
+ * @author noear 2024/10/26 created
+ */
+public class RoutingDataSourceProxyAT extends DataSourceProxy implements RoutingDataSource {
+ public RoutingDataSourceProxyAT(DataSource targetDataSource) {
+ super(targetDataSource);
+ }
+
+ public RoutingDataSourceProxyAT(DataSource targetDataSource, String resourceGroupId) {
+ super(targetDataSource, resourceGroupId);
+ }
+
+ @Override
+ public DataSource determineCurrentTarget() {
+ DataSource dataSource = ((RoutingDataSource) getTargetDataSource()).determineCurrentTarget();
+
+ if (dataSource instanceof SeataDataSourceProxy == false) {
+ dataSource = DataSourceProxyHolder.computeIfAbsent(dataSource, DataSourceProxy::new);
+ }
+
+ return dataSource;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyXA.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyXA.java
new file mode 100644
index 00000000000..c0f29b737a9
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/RoutingDataSourceProxyXA.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.seata.solon.annotation.datasource;
+
+import org.apache.seata.rm.datasource.SeataDataSourceProxy;
+import org.apache.seata.rm.datasource.xa.DataSourceProxyXA;
+import org.noear.solon.data.datasource.RoutingDataSource;
+
+import javax.sql.DataSource;
+
+/**
+ * @author noear 2024/10/26 created
+ */
+public class RoutingDataSourceProxyXA extends DataSourceProxyXA implements RoutingDataSource {
+ public RoutingDataSourceProxyXA(DataSource dataSource) {
+ super(dataSource);
+ }
+
+ public RoutingDataSourceProxyXA(DataSource dataSource, String resourceGroupId) {
+ super(dataSource, resourceGroupId);
+ }
+
+ @Override
+ public DataSource determineCurrentTarget() {
+ DataSource dataSource = ((RoutingDataSource) getTargetDataSource()).determineCurrentTarget();
+
+ if (dataSource instanceof SeataDataSourceProxy == false) {
+ dataSource = DataSourceProxyHolder.computeIfAbsent(dataSource, DataSourceProxyXA::new);
+ }
+
+ return dataSource;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/SeataAutoDataSourceProxyCreator.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/SeataAutoDataSourceProxyCreator.java
new file mode 100644
index 00000000000..e98a6d86e04
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/annotation/datasource/SeataAutoDataSourceProxyCreator.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.seata.solon.annotation.datasource;
+
+import org.apache.seata.core.model.BranchType;
+import org.apache.seata.rm.datasource.SeataDataSourceProxy;
+import org.apache.seata.rm.datasource.xa.DataSourceProxyXA;
+import org.noear.solon.core.BeanWrap;
+import org.noear.solon.data.datasource.RoutingDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+
+/**
+ * @author noear 2024/10/25 created
+ */
+public class SeataAutoDataSourceProxyCreator implements BeanWrap.Proxy {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SeataAutoDataSourceProxyCreator.class);
+
+ private final String dataSourceProxyMode;
+
+ public SeataAutoDataSourceProxyCreator(String dataSourceProxyMode) {
+ this.dataSourceProxyMode = dataSourceProxyMode;
+ }
+
+ @Override
+ public Object getProxy(BeanWrap bw, Object bean) {
+ // we only care DataSource bean
+ if (!(bean instanceof DataSource)) {
+ return bean;
+ }
+
+ // when this bean is just a simple DataSource, not SeataDataSourceProxy
+ if (!(bean instanceof SeataDataSourceProxy)) {
+ // else, build proxy, put to holder and return enhancer
+ DataSource origin = (DataSource) bean;
+ SeataDataSourceProxy proxy = buildProxy(origin, dataSourceProxyMode);
+ DataSourceProxyHolder.put(origin, proxy);
+ LOGGER.info("Auto proxy data source '{}' by '{}' mode.", bw.name(), dataSourceProxyMode);
+ return proxy;
+ }
+
+ return bean;
+ }
+
+ protected SeataDataSourceProxy buildProxy(DataSource origin, String proxyMode) {
+ if (BranchType.AT.name().equalsIgnoreCase(proxyMode)) {
+ if (origin instanceof RoutingDataSource) {
+ return new RoutingDataSourceProxyAT(origin);
+ } else {
+ return new org.apache.seata.rm.datasource.DataSourceProxy(origin);
+ }
+ }
+
+ if (BranchType.XA.name().equalsIgnoreCase(proxyMode)) {
+ if (origin instanceof RoutingDataSource) {
+ return new RoutingDataSourceProxyXA(origin);
+ } else {
+ return new DataSourceProxyXA(origin);
+ }
+ }
+
+ throw new IllegalArgumentException("Unknown dataSourceProxyMode: " + proxyMode);
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/SeataAutoConfiguration.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/SeataAutoConfiguration.java
new file mode 100644
index 00000000000..906c8985658
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/SeataAutoConfiguration.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure;
+
+import org.apache.seata.solon.annotation.GlobalTransactionLifecycle;
+import org.apache.seata.solon.autoconfigure.properties.SeataProperties;
+import org.apache.seata.tm.api.DefaultFailureHandlerImpl;
+import org.apache.seata.tm.api.FailureHandler;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Condition;
+import org.noear.solon.annotation.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.seata.common.ConfigurationKeys.SEATA_PREFIX;
+import static org.apache.seata.common.Constants.BEAN_NAME_FAILURE_HANDLER;
+
+@Configuration
+@Condition(onProperty = "${"+SEATA_PREFIX+".enabled:true} = true")
+public class SeataAutoConfiguration {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SeataAutoConfiguration.class);
+
+ @Bean(value = BEAN_NAME_FAILURE_HANDLER, typed = true)
+ @Condition(onMissingBean = FailureHandler.class)
+ public FailureHandler failureHandler() {
+ return new DefaultFailureHandlerImpl();
+ }
+
+ //old: globalTransactionScanner
+ @Bean
+ @Condition(onMissingBean = GlobalTransactionLifecycle.class)
+ public GlobalTransactionLifecycle globalTransactionLifecycle(SeataProperties seataProperties,
+ FailureHandler failureHandler) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Automatically configure Seata");
+ }
+
+ //set accessKey and secretKey
+ GlobalTransactionLifecycle.setAccessKey(seataProperties.getAccessKey());
+ GlobalTransactionLifecycle.setSecretKey(seataProperties.getSecretKey());
+
+ // create global transaction scanner
+ return new GlobalTransactionLifecycle(seataProperties.getApplicationId(), seataProperties.getTxServiceGroup(),
+ seataProperties.isExposeProxy(), failureHandler);
+ }
+}
\ No newline at end of file
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/StarterConstants.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/StarterConstants.java
new file mode 100644
index 00000000000..639427048cb
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/StarterConstants.java
@@ -0,0 +1,101 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure;
+
+import org.apache.seata.config.ConfigurationKeys;
+
+import java.util.HashMap;
+
+/**
+ * @author noear 2024/10/25 created
+ */
+public interface StarterConstants {
+ String SEATA_PREFIX = "seata";
+ String TRANSPORT_PREFIX = SEATA_PREFIX + ".transport";
+ String THREAD_FACTORY_PREFIX_KEBAB_STYLE = TRANSPORT_PREFIX + ".thread-factory";
+ String THREAD_FACTORY_PREFIX = TRANSPORT_PREFIX + ".threadFactory";
+ String SHUTDOWN_PREFIX = TRANSPORT_PREFIX + ".shutdown";
+ String SERVICE_PREFIX = SEATA_PREFIX + ".service";
+ String CLIENT_PREFIX = SEATA_PREFIX + ".client";
+ String SAGA_PREFIX = SEATA_PREFIX + ".saga";
+ String CLIENT_RM_PREFIX = CLIENT_PREFIX + ".rm";
+ String CLIENT_TM_PREFIX = CLIENT_PREFIX + ".tm";
+ String LOCK_PREFIX = CLIENT_RM_PREFIX + ".lock";
+ String UNDO_PREFIX = CLIENT_PREFIX + ".undo";
+ String LOAD_BALANCE_PREFIX_KEBAB_STYLE = CLIENT_PREFIX + ".load-balance";
+ String LOAD_BALANCE_PREFIX = CLIENT_PREFIX + ".loadBalance";
+ String HTTP_PREFIX = CLIENT_PREFIX + ".http";
+ String LOG_PREFIX = SEATA_PREFIX + ".log";
+ String COMPRESS_PREFIX = UNDO_PREFIX + ".compress";
+ String TCC_PREFIX = SEATA_PREFIX + ".tcc";
+ String TCC_FENCE_PREFIX = TCC_PREFIX + ".fence";
+ String SAGA_STATE_MACHINE_PREFIX = SAGA_PREFIX + ".state-machine";
+ String SAGA_ASYNC_THREAD_POOL_PREFIX = SAGA_STATE_MACHINE_PREFIX + ".async-thread-pool";
+
+ String REGISTRY_PREFIX = SEATA_PREFIX + ".registry";
+ String REGISTRY_PREFERED_NETWORKS = ConfigurationKeys.FILE_ROOT_REGISTRY + ".preferredNetworks";
+ String REGISTRY_NACOS_PREFIX = REGISTRY_PREFIX + ".nacos";
+ String REGISTRY_RAFT_PREFIX = REGISTRY_PREFIX + ".raft";
+ String REGISTRY_EUREKA_PREFIX = REGISTRY_PREFIX + ".eureka";
+ String REGISTRY_REDIS_PREFIX = REGISTRY_PREFIX + ".redis";
+ String REGISTRY_ZK_PREFIX = REGISTRY_PREFIX + ".zk";
+ String REGISTRY_CONSUL_PREFIX = REGISTRY_PREFIX + ".consul";
+ String REGISTRY_NAMINGSERVER_PREFIX = REGISTRY_PREFIX + ".seata";
+ String REGISTRY_ETCD3_PREFIX = REGISTRY_PREFIX + ".etcd3";
+ String REGISTRY_SOFA_PREFIX = REGISTRY_PREFIX + ".sofa";
+ String REGISTRY_CUSTOM_PREFIX = REGISTRY_PREFIX + ".custom";
+
+ String CONFIG_PREFIX = SEATA_PREFIX + ".config";
+ String CONFIG_NACOS_PREFIX = CONFIG_PREFIX + ".nacos";
+ String CONFIG_CONSUL_PREFIX = CONFIG_PREFIX + ".consul";
+ String CONFIG_ETCD3_PREFIX = CONFIG_PREFIX + ".etcd3";
+ String CONFIG_APOLLO_PREFIX = CONFIG_PREFIX + ".apollo";
+ String CONFIG_ZK_PREFIX = CONFIG_PREFIX + ".zk";
+ String CONFIG_FILE_PREFIX = CONFIG_PREFIX + ".file";
+ String CONFIG_CUSTOM_PREFIX = CONFIG_PREFIX + ".custom";
+
+
+ String SERVER_PREFIX = SEATA_PREFIX + ".server";
+ String SERVER_UNDO_PREFIX = SERVER_PREFIX + ".undo";
+ String SERVER_RAFT_PREFIX = SERVER_PREFIX + ".raft";
+ String SERVER_RECOVERY_PREFIX = SERVER_PREFIX + ".recovery";
+
+ String METRICS_PREFIX = SEATA_PREFIX + ".metrics";
+
+ String STORE_PREFIX = SEATA_PREFIX + ".store";
+ String STORE_SESSION_PREFIX = STORE_PREFIX + ".session";
+ String STORE_LOCK_PREFIX = STORE_PREFIX + ".lock";
+ String STORE_FILE_PREFIX = STORE_PREFIX + ".file";
+ String STORE_DB_PREFIX = STORE_PREFIX + ".db";
+ String STORE_REDIS_PREFIX = STORE_PREFIX + ".redis";
+ String STORE_REDIS_SINGLE_PREFIX = STORE_REDIS_PREFIX + ".single";
+ String STORE_REDIS_SENTINEL_PREFIX = STORE_REDIS_PREFIX + ".sentinel";
+
+ String SESSION_PREFIX = SERVER_PREFIX + ".session";
+
+ String REGEX_SPLIT_CHAR = ";";
+
+
+ int MAP_CAPACITY = 64;
+ HashMap> PROPERTY_BEAN_MAP = new HashMap<>(MAP_CAPACITY);
+ /**
+ * The following special keys need to be normalized.
+ */
+ String SPECIAL_KEY_GROUPLIST = "grouplist";
+ String SPECIAL_KEY_SERVICE = "service";
+ String SPECIAL_KEY_VGROUP_MAPPING = "vgroupMapping";
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/PropertiesHelper.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/PropertiesHelper.java
new file mode 100644
index 00000000000..29c0c1aac14
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/PropertiesHelper.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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.apache.seata.solon.autoconfigure.properties.client.*;
+import org.apache.seata.solon.autoconfigure.properties.config.*;
+import org.apache.seata.solon.autoconfigure.properties.core.LogProperties;
+import org.apache.seata.solon.autoconfigure.properties.core.ShutdownProperties;
+import org.apache.seata.solon.autoconfigure.properties.core.ThreadFactoryProperties;
+import org.apache.seata.solon.autoconfigure.properties.core.TransportProperties;
+import org.apache.seata.solon.autoconfigure.properties.registry.*;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.*;
+
+public class PropertiesHelper {
+ public static void initBeanMap() {
+ PROPERTY_BEAN_MAP.put(CONFIG_PREFIX, ConfigProperties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_FILE_PREFIX, ConfigFileProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_PREFIX, RegistryProperties.class);
+
+ PROPERTY_BEAN_MAP.put(CONFIG_NACOS_PREFIX, ConfigNacosProperties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_CONSUL_PREFIX, ConfigConsulProperties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_ZK_PREFIX, ConfigZooKeeperProperties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_APOLLO_PREFIX, ConfigApolloProperties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_ETCD3_PREFIX, ConfigEtcd3Properties.class);
+ PROPERTY_BEAN_MAP.put(CONFIG_CUSTOM_PREFIX, ConfigCustomProperties.class);
+
+ PROPERTY_BEAN_MAP.put(REGISTRY_CONSUL_PREFIX, RegistryConsulProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_ETCD3_PREFIX, RegistryEtcd3Properties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_EUREKA_PREFIX, RegistryEurekaProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_NACOS_PREFIX, RegistryNacosProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_NAMINGSERVER_PREFIX, RegistryNamingServerProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_REDIS_PREFIX, RegistryRedisProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_SOFA_PREFIX, RegistrySofaProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_ZK_PREFIX, RegistryZooKeeperProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_CUSTOM_PREFIX, RegistryCustomProperties.class);
+ PROPERTY_BEAN_MAP.put(REGISTRY_RAFT_PREFIX, RegistryRaftProperties.class);
+
+ PROPERTY_BEAN_MAP.put(THREAD_FACTORY_PREFIX, ThreadFactoryProperties.class);
+ PROPERTY_BEAN_MAP.put(TRANSPORT_PREFIX, TransportProperties.class);
+ PROPERTY_BEAN_MAP.put(SHUTDOWN_PREFIX, ShutdownProperties.class);
+ PROPERTY_BEAN_MAP.put(LOG_PREFIX, LogProperties.class);
+
+
+ PROPERTY_BEAN_MAP.put(SEATA_PREFIX, SeataProperties.class);
+
+ PROPERTY_BEAN_MAP.put(CLIENT_RM_PREFIX, RmProperties.class);
+ PROPERTY_BEAN_MAP.put(CLIENT_TM_PREFIX, TmProperties.class);
+ PROPERTY_BEAN_MAP.put(LOCK_PREFIX, LockProperties.class);
+ PROPERTY_BEAN_MAP.put(SERVICE_PREFIX, ServiceProperties.class);
+ PROPERTY_BEAN_MAP.put(UNDO_PREFIX, UndoProperties.class);
+ PROPERTY_BEAN_MAP.put(COMPRESS_PREFIX, UndoCompressProperties.class);
+ PROPERTY_BEAN_MAP.put(LOAD_BALANCE_PREFIX, LoadBalanceProperties.class);
+ PROPERTY_BEAN_MAP.put(SAGA_ASYNC_THREAD_POOL_PREFIX, SagaAsyncThreadPoolProperties.class);
+ PROPERTY_BEAN_MAP.put(TCC_PREFIX, SeataTccProperties.class);
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolProperties.java
new file mode 100644
index 00000000000..cda02f6fdec
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolProperties.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SAGA_ASYNC_THREAD_POOL_PREFIX;
+
+/**
+ * Saga state machine async thread pool properties.
+ */
+@Configuration
+@Inject(value = "${" + SAGA_ASYNC_THREAD_POOL_PREFIX + "}",required = false)
+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;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataProperties.java
new file mode 100644
index 00000000000..ab6a682e11f
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataProperties.java
@@ -0,0 +1,193 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.apache.seata.common.DefaultValues;
+import org.noear.solon.Solon;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SEATA_PREFIX;
+
+@Configuration
+@Inject(value = "${" + SEATA_PREFIX + "}",required = false)
+public class SeataProperties {
+ /**
+ * whether enable auto configuration
+ */
+ private boolean enabled = true;
+ /**
+ * application id
+ */
+ private String applicationId;
+ /**
+ * transaction service group
+ */
+ private String txServiceGroup;
+ /**
+ * Whether enable auto proxying of datasource bean
+ */
+ private boolean enableAutoDataSourceProxy = true;
+ /**
+ * data source proxy mode
+ */
+ private String dataSourceProxyMode = DefaultValues.DEFAULT_DATA_SOURCE_PROXY_MODE;
+ /**
+ * Whether use JDK proxy instead of CGLIB proxy
+ */
+ private boolean useJdkProxy = false;
+ /**
+ * Whether to expose the proxy object through AopContext.
+ * Setting this to true allows AopContext.currentProxy() to be used to obtain the current proxy,
+ * which can be useful for invoking methods annotated with @GlobalTransactional within the same class.
+ */
+ private boolean exposeProxy = false;
+ /**
+ * The scan packages. If empty, will scan all beans.
+ */
+ private String[] scanPackages = {};
+ /**
+ * Specifies beans that won't be scanned in the GlobalTransactionScanner
+ */
+ private String[] excludesForScanning = {};
+ /**
+ * Specifies which datasource bean are not eligible for auto-proxying
+ */
+ private String[] excludesForAutoProxying = {};
+
+ /**
+ * used for aliyun accessKey
+ */
+ private String accessKey;
+
+ /**
+ * used for aliyun secretKey
+ */
+ private String secretKey;
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public SeataProperties setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ public String getApplicationId() {
+ if (applicationId == null) {
+ applicationId = Solon.cfg().appName();
+ }
+ return applicationId;
+ }
+
+ public SeataProperties setApplicationId(String applicationId) {
+ this.applicationId = applicationId;
+ return this;
+ }
+
+ public String getTxServiceGroup() {
+ if (txServiceGroup == null) {
+ txServiceGroup = DefaultValues.DEFAULT_TX_GROUP;
+ }
+ return txServiceGroup;
+ }
+
+ public SeataProperties setTxServiceGroup(String txServiceGroup) {
+ this.txServiceGroup = txServiceGroup;
+ return this;
+ }
+
+ public boolean isEnableAutoDataSourceProxy() {
+ return enableAutoDataSourceProxy;
+ }
+
+ public SeataProperties setEnableAutoDataSourceProxy(boolean enableAutoDataSourceProxy) {
+ this.enableAutoDataSourceProxy = enableAutoDataSourceProxy;
+ return this;
+ }
+
+ public String getDataSourceProxyMode() {
+ return dataSourceProxyMode;
+ }
+
+ public void setDataSourceProxyMode(String dataSourceProxyMode) {
+ this.dataSourceProxyMode = dataSourceProxyMode;
+ }
+
+ public boolean isUseJdkProxy() {
+ return useJdkProxy;
+ }
+
+ public SeataProperties setUseJdkProxy(boolean useJdkProxy) {
+ this.useJdkProxy = useJdkProxy;
+ return this;
+ }
+
+ public boolean isExposeProxy() {
+ return exposeProxy;
+ }
+
+ public void setExposeProxy(boolean exposeProxy) {
+ this.exposeProxy = exposeProxy;
+ }
+
+ public String[] getExcludesForAutoProxying() {
+ return excludesForAutoProxying;
+ }
+
+ public SeataProperties setExcludesForAutoProxying(String[] excludesForAutoProxying) {
+ this.excludesForAutoProxying = excludesForAutoProxying;
+ return this;
+ }
+
+ public String[] getScanPackages() {
+ return scanPackages;
+ }
+
+ public SeataProperties setScanPackages(String[] scanPackages) {
+ this.scanPackages = scanPackages;
+ return this;
+ }
+
+ public String[] getExcludesForScanning() {
+ return excludesForScanning;
+ }
+
+ public SeataProperties setExcludesForScanning(String[] excludesForScanning) {
+ this.excludesForScanning = excludesForScanning;
+ return this;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public SeataProperties setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ return this;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public SeataProperties setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataTccProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataTccProperties.java
new file mode 100644
index 00000000000..fe3b43a74a8
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/SeataTccProperties.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.TCC_PREFIX;
+
+@Configuration
+@Inject(value = "${" + TCC_PREFIX + "}",required = false)
+public class SeataTccProperties {
+ private String contextJsonParserType;
+
+ public String getContextJsonParserType() {
+ return contextJsonParserType;
+ }
+
+ public void setContextJsonParserType(String contextJsonParserType) {
+ this.contextJsonParserType = contextJsonParserType;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalanceProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalanceProperties.java
new file mode 100644
index 00000000000..8e74184b6d1
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalanceProperties.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.DEFAULT_LOAD_BALANCE;
+import static org.apache.seata.common.DefaultValues.VIRTUAL_NODES_DEFAULT;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.LOAD_BALANCE_PREFIX_KEBAB_STYLE;
+
+@Configuration
+@Inject(value = "${" + LOAD_BALANCE_PREFIX_KEBAB_STYLE + "}",required = false)
+public class LoadBalanceProperties {
+ /**
+ * the load balance
+ */
+ private String type = DEFAULT_LOAD_BALANCE;
+ /**
+ * the load balance virtual nodes
+ */
+ private int virtualNodes = VIRTUAL_NODES_DEFAULT;
+
+
+ public String getType() {
+ return type;
+ }
+
+ public LoadBalanceProperties setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public int getVirtualNodes() {
+ return virtualNodes;
+ }
+
+ public LoadBalanceProperties setVirtualNodes(int virtualNodes) {
+ this.virtualNodes = virtualNodes;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LockProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LockProperties.java
new file mode 100644
index 00000000000..7745af78579
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/LockProperties.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.LOCK_PREFIX;
+
+@Configuration
+@Inject(value = "${" + LOCK_PREFIX + "}",required = false)
+public class LockProperties {
+ private int retryInterval = DEFAULT_CLIENT_LOCK_RETRY_INTERVAL;
+ private int retryTimes = DEFAULT_CLIENT_LOCK_RETRY_TIMES;
+ private boolean retryPolicyBranchRollbackOnConflict = DEFAULT_CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT;
+
+ public int getRetryInterval() {
+ return retryInterval;
+ }
+
+ public LockProperties setRetryInterval(int retryInterval) {
+ this.retryInterval = retryInterval;
+ return this;
+ }
+
+ public int getRetryTimes() {
+ return retryTimes;
+ }
+
+ public LockProperties setRetryTimes(int retryTimes) {
+ this.retryTimes = retryTimes;
+ return this;
+ }
+
+ public boolean isRetryPolicyBranchRollbackOnConflict() {
+ return retryPolicyBranchRollbackOnConflict;
+ }
+
+ public LockProperties setRetryPolicyBranchRollbackOnConflict(boolean retryPolicyBranchRollbackOnConflict) {
+ this.retryPolicyBranchRollbackOnConflict = retryPolicyBranchRollbackOnConflict;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/RmProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/RmProperties.java
new file mode 100644
index 00000000000..2fdcf70750c
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/RmProperties.java
@@ -0,0 +1,172 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.apache.seata.sqlparser.SqlParserType;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CLIENT_RM_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CLIENT_RM_PREFIX + "}",required = false)
+public class RmProperties {
+ private int asyncCommitBufferLimit = DEFAULT_CLIENT_ASYNC_COMMIT_BUFFER_LIMIT;
+ private int reportRetryCount = DEFAULT_CLIENT_REPORT_RETRY_COUNT;
+ private boolean tableMetaCheckEnable = DEFAULT_CLIENT_TABLE_META_CHECK_ENABLE;
+ private long tableMetaCheckerInterval = DEFAULT_TABLE_META_CHECKER_INTERVAL;
+ private boolean reportSuccessEnable = DEFAULT_CLIENT_REPORT_SUCCESS_ENABLE;
+ private boolean sagaBranchRegisterEnable = DEFAULT_CLIENT_SAGA_BRANCH_REGISTER_ENABLE;
+ private String sagaJsonParser = DEFAULT_SAGA_JSON_PARSER;
+ private boolean sagaRetryPersistModeUpdate = DEFAULT_CLIENT_SAGA_RETRY_PERSIST_MODE_UPDATE;
+ private boolean sagaCompensatePersistModeUpdate = DEFAULT_CLIENT_SAGA_COMPENSATE_PERSIST_MODE_UPDATE;
+ private int tccActionInterceptorOrder = TCC_ACTION_INTERCEPTOR_ORDER;
+ private int branchExecutionTimeoutXA = DEFAULT_XA_BRANCH_EXECUTION_TIMEOUT;
+ private int connectionTwoPhaseHoldTimeoutXA = DEFAULT_XA_CONNECTION_TWO_PHASE_HOLD_TIMEOUT;
+ private String sqlParserType = SqlParserType.SQL_PARSER_TYPE_DRUID;
+
+ private Boolean applicationDataLimitCheck = false;
+ private Integer applicationDataLimit = DEFAULT_APPLICATION_DATA_SIZE_LIMIT;
+
+ public int getAsyncCommitBufferLimit() {
+ return asyncCommitBufferLimit;
+ }
+
+ public RmProperties setAsyncCommitBufferLimit(int asyncCommitBufferLimit) {
+ this.asyncCommitBufferLimit = asyncCommitBufferLimit;
+ return this;
+ }
+
+ public int getReportRetryCount() {
+ return reportRetryCount;
+ }
+
+ public RmProperties setReportRetryCount(int reportRetryCount) {
+ this.reportRetryCount = reportRetryCount;
+ return this;
+ }
+
+ public boolean isTableMetaCheckEnable() {
+ return tableMetaCheckEnable;
+ }
+
+ public RmProperties setTableMetaCheckEnable(boolean tableMetaCheckEnable) {
+ this.tableMetaCheckEnable = tableMetaCheckEnable;
+ return this;
+ }
+
+ public boolean isReportSuccessEnable() {
+ return reportSuccessEnable;
+ }
+
+ public RmProperties setReportSuccessEnable(boolean reportSuccessEnable) {
+ this.reportSuccessEnable = reportSuccessEnable;
+ return this;
+ }
+
+ public boolean isSagaBranchRegisterEnable() {
+ return sagaBranchRegisterEnable;
+ }
+
+ public void setSagaBranchRegisterEnable(boolean sagaBranchRegisterEnable) {
+ this.sagaBranchRegisterEnable = sagaBranchRegisterEnable;
+ }
+
+ public String getSagaJsonParser() {
+ return sagaJsonParser;
+ }
+
+ public void setSagaJsonParser(String sagaJsonParser) {
+ this.sagaJsonParser = sagaJsonParser;
+ }
+
+
+ public long getTableMetaCheckerInterval() {
+ return tableMetaCheckerInterval;
+ }
+
+ public void setTableMetaCheckerInterval(long tableMetaCheckerInterval) {
+ this.tableMetaCheckerInterval = tableMetaCheckerInterval;
+ }
+
+ public boolean isSagaRetryPersistModeUpdate() {
+ return sagaRetryPersistModeUpdate;
+ }
+
+ public void setSagaRetryPersistModeUpdate(boolean sagaRetryPersistModeUpdate) {
+ this.sagaRetryPersistModeUpdate = sagaRetryPersistModeUpdate;
+ }
+
+ public boolean isSagaCompensatePersistModeUpdate() {
+ return sagaCompensatePersistModeUpdate;
+ }
+
+ public void setSagaCompensatePersistModeUpdate(boolean sagaCompensatePersistModeUpdate) {
+ this.sagaCompensatePersistModeUpdate = sagaCompensatePersistModeUpdate;
+ }
+
+ public int getTccActionInterceptorOrder() {
+ return tccActionInterceptorOrder;
+ }
+
+ public RmProperties setTccActionInterceptorOrder(int tccActionInterceptorOrder) {
+ this.tccActionInterceptorOrder = tccActionInterceptorOrder;
+ return this;
+ }
+
+ public String getSqlParserType() {
+ return sqlParserType;
+ }
+
+ public RmProperties setSqlParserType(String sqlParserType) {
+ this.sqlParserType = sqlParserType;
+ return this;
+ }
+
+ public int getBranchExecutionTimeoutXA() {
+ return branchExecutionTimeoutXA;
+ }
+
+ public void setBranchExecutionTimeoutXA(int branchExecutionTimeoutXA) {
+ this.branchExecutionTimeoutXA = branchExecutionTimeoutXA;
+ }
+
+ public int getConnectionTwoPhaseHoldTimeoutXA() {
+ return connectionTwoPhaseHoldTimeoutXA;
+ }
+
+ public void setConnectionTwoPhaseHoldTimeoutXA(int connectionTwoPhaseHoldTimeoutXA) {
+ this.connectionTwoPhaseHoldTimeoutXA = connectionTwoPhaseHoldTimeoutXA;
+ }
+
+ public Boolean getApplicationDataLimitCheck() {
+ return applicationDataLimitCheck;
+ }
+
+ public void setApplicationDataLimitCheck(Boolean applicationDataLimitCheck) {
+ this.applicationDataLimitCheck = applicationDataLimitCheck;
+ }
+
+ public Integer getApplicationDataLimit() {
+ return applicationDataLimit;
+ }
+
+ public void setApplicationDataLimit(Integer applicationDataLimit) {
+ this.applicationDataLimit = applicationDataLimit;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/ServiceProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/ServiceProperties.java
new file mode 100644
index 00000000000..4abc3669707
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/ServiceProperties.java
@@ -0,0 +1,81 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SERVICE_PREFIX;
+
+@Configuration
+@Inject(value = "${" + SERVICE_PREFIX + "}",required = false)
+public class ServiceProperties {
+ /**
+ * vgroup->rgroup
+ */
+ private Map vgroupMapping = new HashMap<>();
+ /**
+ * group list
+ */
+ private Map grouplist = new HashMap<>();
+
+ /**
+ * disable globalTransaction
+ */
+ private boolean disableGlobalTransaction = DEFAULT_DISABLE_GLOBAL_TRANSACTION;
+
+ public Map getVgroupMapping() {
+ return vgroupMapping;
+ }
+
+ public void setVgroupMapping(Map vgroupMapping) {
+ this.vgroupMapping = vgroupMapping;
+ }
+
+ public Map getGrouplist() {
+ return grouplist;
+ }
+
+ public void setGrouplist(Map grouplist) {
+ this.grouplist = grouplist;
+ }
+
+ public boolean isDisableGlobalTransaction() {
+ return disableGlobalTransaction;
+ }
+
+ public ServiceProperties setDisableGlobalTransaction(boolean disableGlobalTransaction) {
+ this.disableGlobalTransaction = disableGlobalTransaction;
+ return this;
+ }
+
+ public void afterPropertiesSet() {
+ if (0 == vgroupMapping.size()) {
+ vgroupMapping.put(DEFAULT_TX_GROUP, DEFAULT_TC_CLUSTER);
+ //compatible with old value, will remove next version
+ vgroupMapping.put(DEFAULT_TX_GROUP_OLD, DEFAULT_TC_CLUSTER);
+ }
+
+ if (0 == grouplist.size()) {
+ grouplist.put(DEFAULT_TC_CLUSTER, DEFAULT_GROUPLIST);
+ }
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/TmProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/TmProperties.java
new file mode 100644
index 00000000000..3421467d54c
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/TmProperties.java
@@ -0,0 +1,97 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CLIENT_TM_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CLIENT_TM_PREFIX + "}",required = false)
+public class TmProperties {
+ private int commitRetryCount = DEFAULT_TM_COMMIT_RETRY_COUNT;
+ private int rollbackRetryCount = DEFAULT_TM_ROLLBACK_RETRY_COUNT;
+ private int defaultGlobalTransactionTimeout = DEFAULT_GLOBAL_TRANSACTION_TIMEOUT;
+ private boolean degradeCheck = DEFAULT_TM_DEGRADE_CHECK;
+ private int degradeCheckAllowTimes = DEFAULT_TM_DEGRADE_CHECK_ALLOW_TIMES;
+ private int degradeCheckPeriod = DEFAULT_TM_DEGRADE_CHECK_PERIOD;
+ private int interceptorOrder = TM_INTERCEPTOR_ORDER;
+
+ public int getCommitRetryCount() {
+ return commitRetryCount;
+ }
+
+ public TmProperties setCommitRetryCount(int commitRetryCount) {
+ this.commitRetryCount = commitRetryCount;
+ return this;
+ }
+
+ public int getRollbackRetryCount() {
+ return rollbackRetryCount;
+ }
+
+ public TmProperties setRollbackRetryCount(int rollbackRetryCount) {
+ this.rollbackRetryCount = rollbackRetryCount;
+ return this;
+ }
+
+ public int getDefaultGlobalTransactionTimeout() {
+ return defaultGlobalTransactionTimeout;
+ }
+
+ public TmProperties setDefaultGlobalTransactionTimeout(int defaultGlobalTransactionTimeout) {
+ this.defaultGlobalTransactionTimeout = defaultGlobalTransactionTimeout;
+ return this;
+ }
+
+ public boolean isDegradeCheck() {
+ return degradeCheck;
+ }
+
+ public TmProperties setDegradeCheck(boolean degradeCheck) {
+ this.degradeCheck = degradeCheck;
+ return this;
+ }
+
+ public int getDegradeCheckPeriod() {
+ return degradeCheckPeriod;
+ }
+
+ public TmProperties setDegradeCheckPeriod(int degradeCheckPeriod) {
+ this.degradeCheckPeriod = degradeCheckPeriod;
+ return this;
+ }
+
+ public int getDegradeCheckAllowTimes() {
+ return degradeCheckAllowTimes;
+ }
+
+ public void setDegradeCheckAllowTimes(int degradeCheckAllowTimes) {
+ this.degradeCheckAllowTimes = degradeCheckAllowTimes;
+ }
+
+ public int getInterceptorOrder() {
+ return interceptorOrder;
+ }
+
+ public TmProperties setInterceptorOrder(int interceptorOrder) {
+ this.interceptorOrder = interceptorOrder;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressProperties.java
new file mode 100644
index 00000000000..f4ad62d4f3c
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressProperties.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.apache.seata.common.DefaultValues;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.COMPRESS_PREFIX;
+
+@Configuration
+@Inject(value = "${" + COMPRESS_PREFIX + "}",required = false)
+public class UndoCompressProperties {
+ private boolean enable = DefaultValues.DEFAULT_CLIENT_UNDO_COMPRESS_ENABLE;
+ private String type = DefaultValues.DEFAULT_CLIENT_UNDO_COMPRESS_TYPE;
+ private String threshold = DefaultValues.DEFAULT_CLIENT_UNDO_COMPRESS_THRESHOLD;
+
+ public boolean isEnable() {
+ return enable;
+ }
+
+ public UndoCompressProperties setEnable(boolean enable) {
+ this.enable = enable;
+ return this;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public UndoCompressProperties setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getThreshold() {
+ return threshold;
+ }
+
+ public UndoCompressProperties setThreshold(String threshold) {
+ this.threshold = threshold;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoProperties.java
new file mode 100644
index 00000000000..9b0d7d524f8
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/client/UndoProperties.java
@@ -0,0 +1,68 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.UNDO_PREFIX;
+
+@Configuration
+@Inject(value = "${" + UNDO_PREFIX + "}", required = false)
+public class UndoProperties {
+ private boolean dataValidation = DEFAULT_TRANSACTION_UNDO_DATA_VALIDATION;
+ private String logSerialization = DEFAULT_TRANSACTION_UNDO_LOG_SERIALIZATION;
+ private String logTable = DEFAULT_TRANSACTION_UNDO_LOG_TABLE;
+ private boolean onlyCareUpdateColumns = DEFAULT_ONLY_CARE_UPDATE_COLUMNS;
+
+ public boolean isDataValidation() {
+ return dataValidation;
+ }
+
+ public UndoProperties setDataValidation(boolean dataValidation) {
+ this.dataValidation = dataValidation;
+ return this;
+ }
+
+ public String getLogSerialization() {
+ return logSerialization;
+ }
+
+ public UndoProperties setLogSerialization(String logSerialization) {
+ this.logSerialization = logSerialization;
+ return this;
+ }
+
+ public String getLogTable() {
+ return logTable;
+ }
+
+ public UndoProperties setLogTable(String logTable) {
+ this.logTable = logTable;
+ return this;
+ }
+
+ public boolean isOnlyCareUpdateColumns() {
+ return onlyCareUpdateColumns;
+ }
+
+ public UndoProperties setOnlyCareUpdateColumns(boolean onlyCareUpdateColumns) {
+ this.onlyCareUpdateColumns = onlyCareUpdateColumns;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigApolloProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigApolloProperties.java
new file mode 100644
index 00000000000..261a5cb8090
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigApolloProperties.java
@@ -0,0 +1,86 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_APOLLO_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_APOLLO_PREFIX + "}",required = false)
+public class ConfigApolloProperties {
+ private String appId = "seata-server";
+ private String apolloMeta;
+ private String namespace = "application";
+ private String apolloAccessKeySecret;
+ private String apolloConfigService;
+ private String cluster;
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public ConfigApolloProperties setAppId(String appId) {
+ this.appId = appId;
+ return this;
+ }
+
+ public String getApolloMeta() {
+ return apolloMeta;
+ }
+
+ public ConfigApolloProperties setApolloMeta(String apolloMeta) {
+ this.apolloMeta = apolloMeta;
+ return this;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public ConfigApolloProperties setNamespace(String namespace) {
+ this.namespace = namespace;
+ return this;
+ }
+
+ public String getApolloAccessKeySecret() {
+ return apolloAccessKeySecret;
+ }
+
+ public ConfigApolloProperties setApolloAccessKeySecret(String apolloAccessKeySecret) {
+ this.apolloAccessKeySecret = apolloAccessKeySecret;
+ return this;
+ }
+
+ public String getApolloConfigService() {
+ return apolloConfigService;
+ }
+
+ public ConfigApolloProperties setApolloConfigService(String apolloConfigService) {
+ this.apolloConfigService = apolloConfigService;
+ return this;
+ }
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public ConfigApolloProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigConsulProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigConsulProperties.java
new file mode 100644
index 00000000000..d2fc7765aa3
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigConsulProperties.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_CONSUL_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_CONSUL_PREFIX + "}",required = false)
+public class ConfigConsulProperties {
+ private String serverAddr;
+ private String key = "seata.properties";
+ private String aclToken;
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public ConfigConsulProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public ConfigConsulProperties setKey(String key) {
+ this.key = key;
+ return this;
+ }
+ public String getAclToken() {
+ return aclToken;
+ }
+
+ public ConfigConsulProperties setAclToken(String aclToken) {
+ this.aclToken = aclToken;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigCustomProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigCustomProperties.java
new file mode 100644
index 00000000000..7757f19fbbd
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigCustomProperties.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_CUSTOM_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_CUSTOM_PREFIX + "}",required = false)
+public class ConfigCustomProperties {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public ConfigCustomProperties setName(String name) {
+ this.name = name;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigEtcd3Properties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigEtcd3Properties.java
new file mode 100644
index 00000000000..c08008325b1
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigEtcd3Properties.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_ETCD3_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_ETCD3_PREFIX + "}",required = false)
+public class ConfigEtcd3Properties {
+ private String serverAddr;
+ private String key = "seata.properties";
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public ConfigEtcd3Properties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public ConfigEtcd3Properties setKey(String key) {
+ this.key = key;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigFileProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigFileProperties.java
new file mode 100644
index 00000000000..a140bd8a309
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigFileProperties.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_FILE_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_FILE_PREFIX + "}",required = false)
+public class ConfigFileProperties {
+ private String name = "file.conf";
+
+ public String getName() {
+ return name;
+ }
+
+ public ConfigFileProperties setName(String name) {
+ this.name = name;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigNacosProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigNacosProperties.java
new file mode 100644
index 00000000000..3e24d70f0db
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigNacosProperties.java
@@ -0,0 +1,127 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.LOAD_BALANCE_PREFIX_KEBAB_STYLE;
+
+@Configuration
+@Inject(value = "${" + LOAD_BALANCE_PREFIX_KEBAB_STYLE + "}",required = false)
+public class ConfigNacosProperties {
+ private String serverAddr;
+ private String namespace;
+ private String group = "SEATA_GROUP";
+ private String username;
+ private String password;
+ private String accessKey;
+ private String secretKey;
+ private String ramRoleName;
+ private String dataId = "seata.properties";
+ private String contextPath;
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public ConfigNacosProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public ConfigNacosProperties setNamespace(String namespace) {
+ this.namespace = namespace;
+ return this;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public ConfigNacosProperties setGroup(String group) {
+ this.group = group;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public ConfigNacosProperties setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public ConfigNacosProperties setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public String getDataId() {
+ return dataId;
+ }
+
+ public ConfigNacosProperties setDataId(String dataId) {
+ this.dataId = dataId;
+ return this;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public ConfigNacosProperties setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ return this;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public ConfigNacosProperties setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ return this;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public ConfigNacosProperties setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ return this;
+ }
+
+ public String getRamRoleName() {
+ return ramRoleName;
+ }
+
+ public ConfigNacosProperties setRamRoleName(String ramRoleName) {
+ this.ramRoleName = ramRoleName;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigProperties.java
new file mode 100644
index 00000000000..8487075c457
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigProperties.java
@@ -0,0 +1,53 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_PREFIX + "}",required = false)
+public class ConfigProperties {
+ /**
+ * file, nacos, apollo, zk, consul, etcd3, springCloudConfig
+ */
+ private String type = "file";
+ /**
+ * properties,yaml(only type in nacos, zk, consul, etcd3)
+ */
+ private String dataType ;
+
+ public String getType() {
+ return type;
+ }
+
+ public ConfigProperties setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getDataType() {
+ return dataType;
+ }
+
+ public ConfigProperties setDataType(String dataType) {
+ this.dataType = dataType;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigZooKeeperProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigZooKeeperProperties.java
new file mode 100644
index 00000000000..901fb06eaea
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/config/ConfigZooKeeperProperties.java
@@ -0,0 +1,87 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.config;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.CONFIG_ZK_PREFIX;
+
+@Configuration
+@Inject(value = "${" + CONFIG_ZK_PREFIX + "}",required = false)
+public class ConfigZooKeeperProperties {
+ private String serverAddr;
+ private int sessionTimeout = 6000;
+ private int connectTimeout = 2000;
+ private String username;
+ private String password;
+ private String nodePath = "/seata/seata.properties";
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public ConfigZooKeeperProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public long getSessionTimeout() {
+ return sessionTimeout;
+ }
+
+ public ConfigZooKeeperProperties setSessionTimeout(int sessionTimeout) {
+ this.sessionTimeout = sessionTimeout;
+ return this;
+ }
+
+ public int getConnectTimeout() {
+ return connectTimeout;
+ }
+
+ public ConfigZooKeeperProperties setConnectTimeout(int connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public ConfigZooKeeperProperties setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public ConfigZooKeeperProperties setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public String getNodePath() {
+ return nodePath;
+ }
+
+ public ConfigZooKeeperProperties setNodePath(String nodePath) {
+ this.nodePath = nodePath;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/LogProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/LogProperties.java
new file mode 100644
index 00000000000..e7cf912fc98
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/LogProperties.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.core;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.DEFAULT_LOG_EXCEPTION_RATE;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.LOG_PREFIX;
+
+@Configuration
+@Inject(value = "${" + LOG_PREFIX + "}",required = false)
+public class LogProperties {
+
+ private int exceptionRate = DEFAULT_LOG_EXCEPTION_RATE;
+
+ public int getExceptionRate() {
+ return exceptionRate;
+ }
+
+ public LogProperties setExceptionRate(int exceptionRate) {
+ this.exceptionRate = exceptionRate;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ShutdownProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ShutdownProperties.java
new file mode 100644
index 00000000000..3937a4db441
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ShutdownProperties.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.core;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.DEFAULT_SHUTDOWN_TIMEOUT_SEC;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SHUTDOWN_PREFIX;
+
+@Configuration
+@Inject(value = "${" + SHUTDOWN_PREFIX + "}",required = false)
+public class ShutdownProperties {
+ /**
+ * when destroy server, wait seconds
+ */
+ private int wait = DEFAULT_SHUTDOWN_TIMEOUT_SEC;
+
+ public int getWait() {
+ return wait;
+ }
+
+ public ShutdownProperties setWait(int wait) {
+ this.wait = wait;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ThreadFactoryProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ThreadFactoryProperties.java
new file mode 100644
index 00000000000..14b27a196ac
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/ThreadFactoryProperties.java
@@ -0,0 +1,125 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.core;
+
+import org.apache.seata.core.rpc.netty.NettyBaseConfig.WorkThreadMode;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.THREAD_FACTORY_PREFIX_KEBAB_STYLE;
+
+@Configuration
+@Inject(value = "${" + THREAD_FACTORY_PREFIX_KEBAB_STYLE + "}",required = false)
+public class ThreadFactoryProperties {
+ private String bossThreadPrefix = DEFAULT_BOSS_THREAD_PREFIX;
+ private String workerThreadPrefix = DEFAULT_NIO_WORKER_THREAD_PREFIX;
+ private String serverExecutorThreadPrefix = DEFAULT_EXECUTOR_THREAD_PREFIX;
+ private boolean shareBossWorker = false;
+ private String clientSelectorThreadPrefix = DEFAULT_SELECTOR_THREAD_PREFIX;
+ private int clientSelectorThreadSize = DEFAULT_SELECTOR_THREAD_SIZE;
+ private String clientWorkerThreadPrefix = DEFAULT_WORKER_THREAD_PREFIX;
+ /**
+ * netty boss thread size
+ */
+ private int bossThreadSize = DEFAULT_BOSS_THREAD_SIZE;
+ /**
+ * auto default pin or 8
+ */
+ private String workerThreadSize = WorkThreadMode.Default.name();
+
+ public String getBossThreadPrefix() {
+ return bossThreadPrefix;
+ }
+
+ public ThreadFactoryProperties setBossThreadPrefix(String bossThreadPrefix) {
+ this.bossThreadPrefix = bossThreadPrefix;
+ return this;
+ }
+
+ public String getWorkerThreadPrefix() {
+ return workerThreadPrefix;
+ }
+
+ public ThreadFactoryProperties setWorkerThreadPrefix(String workerThreadPrefix) {
+ this.workerThreadPrefix = workerThreadPrefix;
+ return this;
+ }
+
+ public String getServerExecutorThreadPrefix() {
+ return serverExecutorThreadPrefix;
+ }
+
+ public ThreadFactoryProperties setServerExecutorThreadPrefix(String serverExecutorThreadPrefix) {
+ this.serverExecutorThreadPrefix = serverExecutorThreadPrefix;
+ return this;
+ }
+
+ public boolean isShareBossWorker() {
+ return shareBossWorker;
+ }
+
+ public ThreadFactoryProperties setShareBossWorker(boolean shareBossWorker) {
+ this.shareBossWorker = shareBossWorker;
+ return this;
+ }
+
+ public String getClientSelectorThreadPrefix() {
+ return clientSelectorThreadPrefix;
+ }
+
+ public ThreadFactoryProperties setClientSelectorThreadPrefix(String clientSelectorThreadPrefix) {
+ this.clientSelectorThreadPrefix = clientSelectorThreadPrefix;
+ return this;
+ }
+
+ public String getClientWorkerThreadPrefix() {
+ return clientWorkerThreadPrefix;
+ }
+
+ public ThreadFactoryProperties setClientWorkerThreadPrefix(String clientWorkerThreadPrefix) {
+ this.clientWorkerThreadPrefix = clientWorkerThreadPrefix;
+ return this;
+ }
+
+ public int getClientSelectorThreadSize() {
+ return clientSelectorThreadSize;
+ }
+
+ public ThreadFactoryProperties setClientSelectorThreadSize(int clientSelectorThreadSize) {
+ this.clientSelectorThreadSize = clientSelectorThreadSize;
+ return this;
+ }
+
+ public int getBossThreadSize() {
+ return bossThreadSize;
+ }
+
+ public ThreadFactoryProperties setBossThreadSize(int bossThreadSize) {
+ this.bossThreadSize = bossThreadSize;
+ return this;
+ }
+
+ public String getWorkerThreadSize() {
+ return workerThreadSize;
+ }
+
+ public ThreadFactoryProperties setWorkerThreadSize(String workerThreadSize) {
+ this.workerThreadSize = workerThreadSize;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/TransportProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/TransportProperties.java
new file mode 100644
index 00000000000..e7c5cee77b2
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/core/TransportProperties.java
@@ -0,0 +1,198 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.core;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.TRANSPORT_PREFIX;
+
+@Configuration
+@Inject(value = "${" + TRANSPORT_PREFIX + "}",required = false)
+public class TransportProperties {
+ /**
+ * tcp, unix-domain-socket
+ */
+ private String type = "TCP";
+ /**
+ * NIO, NATIVE
+ */
+ private String server = "NIO";
+ /**
+ * enable heartbeat
+ */
+ private boolean heartbeat = DEFAULT_TRANSPORT_HEARTBEAT;
+ /**
+ * serialization
+ */
+ private String serialization = "seata";
+ /**
+ * compressor
+ */
+ private String compressor = "none";
+
+ private String protocol = "seata";
+
+ /**
+ * enable client batch send request
+ */
+ private boolean enableClientBatchSendRequest = DEFAULT_ENABLE_CLIENT_BATCH_SEND_REQUEST;
+
+ /**
+ * enable TM client batch send request
+ */
+ private boolean enableTmClientBatchSendRequest = DEFAULT_ENABLE_TM_CLIENT_BATCH_SEND_REQUEST;
+
+ /**
+ * enable RM client batch send request
+ */
+ private boolean enableRmClientBatchSendRequest = DEFAULT_ENABLE_RM_CLIENT_BATCH_SEND_REQUEST;
+
+ /**
+ * enable TC server batch send response
+ */
+ private boolean enableTcServerBatchSendResponse = DEFAULT_ENABLE_TC_SERVER_BATCH_SEND_RESPONSE;
+
+ /**
+ * rpcRmRequestTimeout
+ */
+ private long rpcRmRequestTimeout = DEFAULT_RPC_RM_REQUEST_TIMEOUT;
+
+ /**
+ * rpcRmRequestTimeout
+ */
+ private long rpcTmRequestTimeout = DEFAULT_RPC_TM_REQUEST_TIMEOUT;
+
+ /**
+ * rpcTcRequestTimeout
+ */
+ private long rpcTcRequestTimeout = DEFAULT_RPC_TC_REQUEST_TIMEOUT;
+
+
+ public String getType() {
+ return type;
+ }
+
+ public TransportProperties setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getServer() {
+ return server;
+ }
+
+ public TransportProperties setServer(String server) {
+ this.server = server;
+ return this;
+ }
+
+ public boolean isHeartbeat() {
+ return heartbeat;
+ }
+
+ public TransportProperties setHeartbeat(boolean heartbeat) {
+ this.heartbeat = heartbeat;
+ return this;
+ }
+
+ public String getSerialization() {
+ return serialization;
+ }
+
+ public TransportProperties setSerialization(String serialization) {
+ this.serialization = serialization;
+ return this;
+ }
+
+ public String getCompressor() {
+ return compressor;
+ }
+
+ public TransportProperties setCompressor(String compressor) {
+ this.compressor = compressor;
+ return this;
+ }
+
+ public boolean isEnableClientBatchSendRequest() {
+ return enableClientBatchSendRequest;
+ }
+
+ public TransportProperties setEnableClientBatchSendRequest(boolean enableClientBatchSendRequest) {
+ this.enableClientBatchSendRequest = enableClientBatchSendRequest;
+ return this;
+ }
+
+ public boolean isEnableTmClientBatchSendRequest() {
+ return enableTmClientBatchSendRequest;
+ }
+
+ public TransportProperties setEnableTmClientBatchSendRequest(boolean enableTmClientBatchSendRequest) {
+ this.enableTmClientBatchSendRequest = enableTmClientBatchSendRequest;
+ return this;
+ }
+
+ public boolean isEnableRmClientBatchSendRequest() {
+ return enableRmClientBatchSendRequest;
+ }
+
+ public TransportProperties setEnableRmClientBatchSendRequest(boolean enableRmClientBatchSendRequest) {
+ this.enableRmClientBatchSendRequest = enableRmClientBatchSendRequest;
+ return this;
+ }
+
+ public boolean isEnableTcServerBatchSendResponse() {
+ return enableTcServerBatchSendResponse;
+ }
+
+ public void setEnableTcServerBatchSendResponse(boolean enableTcServerBatchSendResponse) {
+ this.enableTcServerBatchSendResponse = enableTcServerBatchSendResponse;
+ }
+
+ public long getRpcRmRequestTimeout() {
+ return rpcRmRequestTimeout;
+ }
+
+ public void setRpcRmRequestTimeout(long rpcRmRequestTimeout) {
+ this.rpcRmRequestTimeout = rpcRmRequestTimeout;
+ }
+
+ public long getRpcTmRequestTimeout() {
+ return rpcTmRequestTimeout;
+ }
+
+ public void setRpcTmRequestTimeout(long rpcTmRequestTimeout) {
+ this.rpcTmRequestTimeout = rpcTmRequestTimeout;
+ }
+
+ public long getRpcTcRequestTimeout() {
+ return rpcTcRequestTimeout;
+ }
+
+ public void setRpcTcRequestTimeout(long rpcTcRequestTimeout) {
+ this.rpcTcRequestTimeout = rpcTcRequestTimeout;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryConsulProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryConsulProperties.java
new file mode 100644
index 00000000000..8a0f66455a4
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryConsulProperties.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_CONSUL_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_CONSUL_PREFIX + "}",required = false)
+public class RegistryConsulProperties {
+ private String cluster = "default";
+ private String serverAddr = "127.0.0.1:8500";
+ private String aclToken;
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryConsulProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryConsulProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getAclToken() {
+ return aclToken;
+ }
+
+ public RegistryConsulProperties setAclToken(String aclToken) {
+ this.aclToken = aclToken;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryCustomProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryCustomProperties.java
new file mode 100644
index 00000000000..c527fd52a09
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryCustomProperties.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_CUSTOM_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_CUSTOM_PREFIX + "}",required = false)
+public class RegistryCustomProperties {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public RegistryCustomProperties setName(String name) {
+ this.name = name;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEtcd3Properties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEtcd3Properties.java
new file mode 100644
index 00000000000..bafb3bb8b81
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEtcd3Properties.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_ETCD3_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_ETCD3_PREFIX + "}",required = false)
+public class RegistryEtcd3Properties {
+ private String cluster = "default";
+ private String serverAddr = "http://localhost:2379";
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryEtcd3Properties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryEtcd3Properties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEurekaProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEurekaProperties.java
new file mode 100644
index 00000000000..42c746f03ba
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryEurekaProperties.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_EUREKA_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_EUREKA_PREFIX + "}",required = false)
+public class RegistryEurekaProperties {
+ private String serviceUrl = "http://localhost:8761/eureka";
+ private String application = "default";
+ private String weight = "1";
+
+ public String getServiceUrl() {
+ return serviceUrl;
+ }
+
+ public RegistryEurekaProperties setServiceUrl(String serviceUrl) {
+ this.serviceUrl = serviceUrl;
+ return this;
+ }
+
+ public String getApplication() {
+ return application;
+ }
+
+ public RegistryEurekaProperties setApplication(String application) {
+ this.application = application;
+ return this;
+ }
+
+ public String getWeight() {
+ return weight;
+ }
+
+ public RegistryEurekaProperties setWeight(String weight) {
+ this.weight = weight;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNacosProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNacosProperties.java
new file mode 100644
index 00000000000..f84a45963d8
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNacosProperties.java
@@ -0,0 +1,155 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_NACOS_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_NACOS_PREFIX + "}",required = false)
+public class RegistryNacosProperties {
+ private String serverAddr = "localhost:8848";
+ private String namespace;
+ private String group = "SEATA_GROUP";
+ private String cluster = "default";
+ private String username;
+ private String password;
+ private String accessKey;
+ private String secretKey;
+ private String ramRoleName;
+ private String application = "seata-server";
+ private String slbPattern;
+ private String contextPath;
+ private String clientApplication;
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryNacosProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public RegistryNacosProperties setNamespace(String namespace) {
+ this.namespace = namespace;
+ return this;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryNacosProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public RegistryNacosProperties setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public RegistryNacosProperties setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public String getApplication() {
+ return application;
+ }
+
+ public RegistryNacosProperties setApplication(String application) {
+ this.application = application;
+ return this;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public RegistryNacosProperties setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ return this;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public RegistryNacosProperties setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ return this;
+ }
+
+ public String getSlbPattern() {
+ return slbPattern;
+ }
+
+ public RegistryNacosProperties setSlbPattern(String slbPattern) {
+ this.slbPattern = slbPattern;
+ return this;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public RegistryNacosProperties setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ return this;
+ }
+
+ public String getClientApplication() {
+ return clientApplication;
+ }
+
+ public RegistryNacosProperties setClientApplication(String clientApplication) {
+ this.clientApplication = clientApplication;
+ return this;
+ }
+
+ public String getRamRoleName() {
+ return ramRoleName;
+ }
+
+ public RegistryNacosProperties setRamRoleName(String ramRoleName) {
+ this.ramRoleName = ramRoleName;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNamingServerProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNamingServerProperties.java
new file mode 100644
index 00000000000..f18714d1ba8
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryNamingServerProperties.java
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_NAMINGSERVER_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_NAMINGSERVER_PREFIX + "}",required = false)
+public class RegistryNamingServerProperties {
+ private String cluster = "default";
+ private String serverAddr = "127.0.0.1:8081";
+ private String namespace = "public";
+
+ private int heartbeatPeriod = 5000;
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryNamingServerProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryNamingServerProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public int getHeartbeatPeriod() {
+ return heartbeatPeriod;
+ }
+
+ public void setHeartbeatPeriod(int heartbeatPeriod) {
+ this.heartbeatPeriod = heartbeatPeriod;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryProperties.java
new file mode 100644
index 00000000000..1a24532e7df
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryProperties.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_PREFIX + "}",required = false)
+public class RegistryProperties {
+ /**
+ * file, nacos, eureka, redis, zk, consul, etcd3, sofa
+ */
+ private String type = "file";
+
+ private String preferredNetworks;
+
+ public String getType() {
+ return type;
+ }
+
+ public RegistryProperties setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getPreferredNetworks() {
+ return preferredNetworks;
+ }
+
+ public RegistryProperties setPreferredNetworks(String preferredNetworks) {
+ this.preferredNetworks = preferredNetworks;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRaftProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRaftProperties.java
new file mode 100644
index 00000000000..a88711d0311
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRaftProperties.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_RAFT_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_RAFT_PREFIX + "}",required = false)
+public class RegistryRaftProperties {
+ private String serverAddr;
+
+ private Long metadataMaxAgeMs = 30000L;
+
+ private String username;
+
+ private String password;
+
+ private Long tokenValidityInMilliseconds = 29 * 60 * 1000L;
+
+ public Long getMetadataMaxAgeMs() {
+ return metadataMaxAgeMs;
+ }
+
+ public void setMetadataMaxAgeMs(Long metadataMaxAgeMs) {
+ this.metadataMaxAgeMs = metadataMaxAgeMs;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Long getTokenValidityInMilliseconds() {
+ return tokenValidityInMilliseconds;
+ }
+
+ public void setTokenValidityInMilliseconds(Long tokenValidityInMilliseconds) {
+ this.tokenValidityInMilliseconds = tokenValidityInMilliseconds;
+ }
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryRaftProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRedisProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRedisProperties.java
new file mode 100644
index 00000000000..1a3f7f67c3b
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryRedisProperties.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_REDIS_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_REDIS_PREFIX + "}",required = false)
+public class RegistryRedisProperties {
+ private String serverAddr = "localhost:6379";
+ private int db = 0;
+ private String password;
+ private String cluster = "default";
+ private int timeout = 0;
+
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryRedisProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public int getDb() {
+ return db;
+ }
+
+ public RegistryRedisProperties setDb(int db) {
+ this.db = db;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public RegistryRedisProperties setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryRedisProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public RegistryRedisProperties setTimeout(int timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistrySofaProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistrySofaProperties.java
new file mode 100644
index 00000000000..108084d0782
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistrySofaProperties.java
@@ -0,0 +1,97 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_SOFA_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_SOFA_PREFIX + "}",required = false)
+public class RegistrySofaProperties {
+ private String serverAddr = "127.0.0.1:9603";
+ private String application = "default";
+ private String region = "DEFAULT_ZONE";
+ private String datacenter = "DefaultDataCenter";
+ private String cluster = "default";
+ private String group = "SEATA_GROUP";
+ private String addressWaitTime = "3000";
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistrySofaProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public String getApplication() {
+ return application;
+ }
+
+ public RegistrySofaProperties setApplication(String application) {
+ this.application = application;
+ return this;
+ }
+
+ public String getRegion() {
+ return region;
+ }
+
+ public RegistrySofaProperties setRegion(String region) {
+ this.region = region;
+ return this;
+ }
+
+ public String getDatacenter() {
+ return datacenter;
+ }
+
+ public RegistrySofaProperties setDatacenter(String datacenter) {
+ this.datacenter = datacenter;
+ return this;
+ }
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistrySofaProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public RegistrySofaProperties setGroup(String group) {
+ this.group = group;
+ return this;
+ }
+
+ public String getAddressWaitTime() {
+ return addressWaitTime;
+ }
+
+ public RegistrySofaProperties setAddressWaitTime(String addressWaitTime) {
+ this.addressWaitTime = addressWaitTime;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryZooKeeperProperties.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryZooKeeperProperties.java
new file mode 100644
index 00000000000..098c15041e4
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/properties/registry/RegistryZooKeeperProperties.java
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.registry;
+
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.REGISTRY_ZK_PREFIX;
+
+@Configuration
+@Inject(value = "${" + REGISTRY_ZK_PREFIX + "}",required = false)
+public class RegistryZooKeeperProperties {
+ private String cluster = "default";
+ private String serverAddr = "127.0.0.1:2181";
+ private int sessionTimeout = 6000;
+ private int connectTimeout = 2000;
+ private String username;
+ private String password;
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public RegistryZooKeeperProperties setCluster(String cluster) {
+ this.cluster = cluster;
+ return this;
+ }
+
+ public String getServerAddr() {
+ return serverAddr;
+ }
+
+ public RegistryZooKeeperProperties setServerAddr(String serverAddr) {
+ this.serverAddr = serverAddr;
+ return this;
+ }
+
+ public int getSessionTimeout() {
+ return sessionTimeout;
+ }
+
+ public RegistryZooKeeperProperties setSessionTimeout(int sessionTimeout) {
+ this.sessionTimeout = sessionTimeout;
+ return this;
+ }
+
+ public int getConnectTimeout() {
+ return connectTimeout;
+ }
+
+ public RegistryZooKeeperProperties setConnectTimeout(int connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ return this;
+ }
+ public String getUsername() {
+ return username;
+ }
+
+ public RegistryZooKeeperProperties setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+ public String getPassword() {
+ return password;
+ }
+
+ public RegistryZooKeeperProperties setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/provider/SolonConfigurationProvider.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/provider/SolonConfigurationProvider.java
new file mode 100644
index 00000000000..378ddfee685
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/autoconfigure/provider/SolonConfigurationProvider.java
@@ -0,0 +1,252 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.provider;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.time.Duration;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+import org.apache.seata.common.exception.ShouldNeverHappenException;
+import org.apache.seata.common.util.CollectionUtils;
+import org.apache.seata.common.util.ReflectionUtil;
+import org.apache.seata.config.Configuration;
+import org.apache.seata.config.ExtConfigurationProvider;
+import org.apache.commons.lang.StringUtils;
+import org.noear.solon.Solon;
+import org.noear.solon.core.AppClassLoader;
+import org.noear.solon.core.util.ConvertUtil;
+import org.noear.solon.lang.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.seata.common.util.StringFormatUtils.DOT;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.PROPERTY_BEAN_MAP;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SEATA_PREFIX;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SERVICE_PREFIX;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SPECIAL_KEY_GROUPLIST;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SPECIAL_KEY_SERVICE;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.SPECIAL_KEY_VGROUP_MAPPING;
+
+
+public class SolonConfigurationProvider implements ExtConfigurationProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SolonConfigurationProvider.class);
+
+ private static final String INTERCEPT_METHOD_PREFIX = "get";
+
+ private static final Map PROPERTY_BEAN_INSTANCE_MAP = new ConcurrentHashMap<>(64);
+
+ @Override
+ public Configuration provide(Configuration originalConfiguration) {
+ return (Configuration)Proxy.newProxyInstance(AppClassLoader.global(), new Class[]{Configuration.class}, (InvocationHandler) (proxy, method, args) -> {
+ if (method.getName().startsWith(INTERCEPT_METHOD_PREFIX) && args.length > 0) {
+ Object result;
+ String rawDataId = (String)args[0];
+ Class> dataType = ReflectionUtil.getWrappedClass(method.getReturnType());
+
+ // 1. Get config value from the system property
+ result = originalConfiguration.getConfigFromSys(rawDataId);
+
+ if (result == null) {
+ String dataId = convertDataId(rawDataId);
+
+ // 2. Get config value from the springboot environment
+ result = getConfigFromEnvironment(dataId, dataType);
+ if (result != null) {
+ return result;
+ }
+
+ // 3. Get config defaultValue from the arguments
+ if (args.length > 1) {
+ result = args[1];
+
+ if (result != null) {
+ // See Configuration#getConfig(String dataId, long timeoutMills)
+ if (dataType.isAssignableFrom(result.getClass())) {
+ return result;
+ } else {
+ result = null;
+ }
+ }
+ }
+
+ // 4. Get config defaultValue from the property object
+ try {
+ result = getDefaultValueFromPropertyObject(dataId);
+ } catch (Throwable t) {
+ LOGGER.error("Get config '{}' default value from the property object failed:", dataId, t);
+ }
+ }
+
+ if (result != null) {
+ if (dataType.isAssignableFrom(result.getClass())) {
+ return result;
+ }
+
+ // Convert type
+ return this.convertType(result, dataType);
+ }
+ }
+
+ return method.invoke(originalConfiguration, args);
+ });
+ }
+
+ private Object getDefaultValueFromPropertyObject(String dataId) throws IllegalAccessException {
+ String propertyPrefix = getPropertyPrefix(dataId);
+ String propertySuffix = getPropertySuffix(dataId);
+
+ // Get the property class
+ final Class> propertyClass = PROPERTY_BEAN_MAP.get(propertyPrefix);
+ if (propertyClass == null) {
+ throw new ShouldNeverHappenException("PropertyClass for prefix: [" + propertyPrefix + "] should not be null.");
+ }
+
+ // Instantiate the property object
+ Object propertyObj = CollectionUtils.computeIfAbsent(PROPERTY_BEAN_INSTANCE_MAP, propertyPrefix, k -> {
+ try {
+ return propertyClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ LOGGER.warn("PropertyClass for prefix: [" + propertyPrefix + "] should not be null. error :" + e.getMessage(), e);
+ }
+ return null;
+ });
+ Objects.requireNonNull(propertyObj, () -> "Instantiate the property object fail: " + propertyClass.getName());
+
+ // Get defaultValue from the property object
+ return getDefaultValueFromPropertyObject(propertyObj, propertySuffix);
+ }
+
+ /**
+ * Get defaultValue from the property object
+ *
+ * @param propertyObj the property object
+ * @param fieldName the field name
+ * @return defaultValue
+ */
+ @Nullable
+ private Object getDefaultValueFromPropertyObject(Object propertyObj, String fieldName) throws IllegalAccessException {
+ Optional fieldOptional = Stream.of(propertyObj.getClass().getDeclaredFields())
+ .filter(f -> f.getName().equalsIgnoreCase(fieldName)).findAny();
+
+ // Get defaultValue from the field
+ if (fieldOptional.isPresent()) {
+ Field field = fieldOptional.get();
+ if (!Map.class.isAssignableFrom(field.getType())) {
+ field.setAccessible(true);
+ return field.get(propertyObj);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * convert data id
+ *
+ * @param rawDataId
+ * @return dataId
+ */
+ private String convertDataId(String rawDataId) {
+ if (rawDataId.endsWith(SPECIAL_KEY_GROUPLIST)) {
+ String suffix = StringUtils.removeStart(StringUtils.removeEnd(rawDataId, DOT + SPECIAL_KEY_GROUPLIST),
+ SPECIAL_KEY_SERVICE + DOT);
+ // change the format of default.grouplist to grouplist.default
+ return SERVICE_PREFIX + DOT + SPECIAL_KEY_GROUPLIST + DOT + suffix;
+ }
+ return SEATA_PREFIX + DOT + rawDataId;
+ }
+
+ /**
+ * Get property prefix
+ *
+ * @param dataId
+ * @return propertyPrefix
+ */
+ private String getPropertyPrefix(String dataId) {
+ if (dataId.contains(SPECIAL_KEY_VGROUP_MAPPING)) {
+ return SERVICE_PREFIX;
+ }
+ if (dataId.contains(SPECIAL_KEY_GROUPLIST)) {
+ return SERVICE_PREFIX;
+ }
+ return StringUtils.substringBeforeLast(dataId, String.valueOf(DOT));
+ }
+
+ /**
+ * Get property suffix
+ *
+ * @param dataId
+ * @return propertySuffix
+ */
+ private String getPropertySuffix(String dataId) {
+ if (dataId.contains(SPECIAL_KEY_VGROUP_MAPPING)) {
+ return SPECIAL_KEY_VGROUP_MAPPING;
+ }
+ if (dataId.contains(SPECIAL_KEY_GROUPLIST)) {
+ return SPECIAL_KEY_GROUPLIST;
+ }
+ return StringUtils.substringAfterLast(dataId, String.valueOf(DOT));
+ }
+
+ /**
+ * get spring config
+ *
+ * @param dataId data id
+ * @param dataType data type
+ * @return object
+ */
+ @Nullable
+ private Object getConfigFromEnvironment(String dataId, Class> dataType) {
+ String val = Solon.cfg().get(dataId);
+
+ if (val == null) {
+ return null;
+ } else {
+ return ConvertUtil.tryTo(dataType, val);
+ }
+ }
+
+ private Object convertType(Object configValue, Class> dataType) {
+ if (String.class.equals(dataType)) {
+ return String.valueOf(configValue);
+ }
+ if (Long.class.equals(dataType)) {
+ return Long.parseLong(String.valueOf(configValue));
+ }
+ if (Integer.class.equals(dataType)) {
+ return Integer.parseInt(String.valueOf(configValue));
+ }
+ if (Short.class.equals(dataType)) {
+ return Short.parseShort(String.valueOf(configValue));
+ }
+ if (Boolean.class.equals(dataType)) {
+ return Boolean.parseBoolean(String.valueOf(configValue));
+ }
+ if (Duration.class.equals(dataType)) {
+ return Duration.parse(String.valueOf(configValue));
+ }
+ return configValue;
+ }
+
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/SeataPlugin.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/SeataPlugin.java
new file mode 100644
index 00000000000..307176de7e5
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/SeataPlugin.java
@@ -0,0 +1,82 @@
+/*
+ * 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 org.apache.seata.solon.integration;
+
+import org.apache.seata.solon.annotation.GlobalTransactionalInterceptor;
+import org.apache.seata.solon.annotation.datasource.SeataAutoDataSourceProxyCreator;
+import org.apache.seata.solon.autoconfigure.properties.PropertiesHelper;
+import org.apache.seata.solon.autoconfigure.SeataAutoConfiguration;
+import org.apache.seata.solon.autoconfigure.properties.client.ServiceProperties;
+import org.apache.seata.solon.integration.intercept.SeataHttpExtension;
+import org.apache.seata.solon.integration.intercept.SeataNamiFilter;
+import org.apache.seata.solon.integration.intercept.SeataSolonRouterInterceptor;
+import org.apache.seata.solon.autoconfigure.properties.SeataProperties;
+import org.apache.seata.spring.annotation.GlobalLock;
+import org.apache.seata.spring.annotation.GlobalTransactional;
+import org.noear.nami.NamiManager;
+import org.noear.solon.core.AppContext;
+import org.noear.solon.core.Plugin;
+import org.noear.solon.core.util.ClassUtil;
+import org.noear.solon.net.http.HttpExtensionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Seata for solon plugin (like module lifecycle)
+ *
+ * @author noear 2024/10/25 created
+ */
+public class SeataPlugin implements Plugin {
+ @Override
+ public void start(AppContext context) throws Throwable {
+ context.getBeanAsync(ServiceProperties.class, bean -> {
+ bean.afterPropertiesSet();
+ });
+
+ PropertiesHelper.initBeanMap();
+
+ //for autoconfigure
+ context.beanScan(PropertiesHelper.class);
+ context.beanMake(SeataAutoConfiguration.class);
+
+ SeataProperties seataProperties = context.getBean(SeataProperties.class);
+ SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator = new SeataAutoDataSourceProxyCreator(seataProperties.getDataSourceProxyMode());
+
+ //for dataSource proxy
+ context.subWrapsOfType(DataSource.class, bw -> {
+ bw.proxySet(seataAutoDataSourceProxyCreator);
+ }, Integer.MIN_VALUE);
+
+ //for nami
+ if (ClassUtil.hasClass(() -> NamiManager.class)) {
+ NamiManager.reg(new SeataNamiFilter());
+ }
+
+ //for http-utils
+ if (ClassUtil.hasClass(() -> HttpExtensionManager.class)) {
+ HttpExtensionManager.add(new SeataHttpExtension());
+ }
+
+ //for solon
+ context.app().routerInterceptor(Integer.MIN_VALUE, new SeataSolonRouterInterceptor());
+
+ //for annotation
+ GlobalTransactionalInterceptor globalTransactionalInterceptor = new GlobalTransactionalInterceptor();
+ context.beanInterceptorAdd(GlobalLock.class, globalTransactionalInterceptor);
+ context.beanInterceptorAdd(GlobalTransactional.class, globalTransactionalInterceptor);
+ }
+}
\ No newline at end of file
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataHttpExtension.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataHttpExtension.java
new file mode 100644
index 00000000000..caa0f3457ed
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataHttpExtension.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.seata.solon.integration.intercept;
+
+import org.apache.seata.core.context.RootContext;
+import org.noear.solon.net.http.HttpExtension;
+import org.noear.solon.net.http.HttpUtils;
+
+/**
+ * @author noear 2024/10/25 created
+ */
+public class SeataHttpExtension implements HttpExtension {
+ @Override
+ public void onInit(HttpUtils httpUtils, String url) {
+ String xid = RootContext.getXID();
+
+ if (xid != null) {
+ httpUtils.header(RootContext.KEY_XID, xid);
+ httpUtils.header(RootContext.KEY_BRANCH_TYPE, RootContext.getBranchType().name());
+ }
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataNamiFilter.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataNamiFilter.java
new file mode 100644
index 00000000000..bc5b85c240a
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataNamiFilter.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.seata.solon.integration.intercept;
+
+import org.apache.seata.core.context.RootContext;
+import org.noear.nami.Filter;
+import org.noear.nami.Invocation;
+import org.noear.nami.Result;
+
+/**
+ * @author noear 2024/10/25 created
+ */
+public class SeataNamiFilter implements Filter {
+ @Override
+ public Result doFilter(Invocation inv) throws Throwable {
+ String xid = RootContext.getXID();
+
+ if (xid != null) {
+ inv.headers.put(RootContext.KEY_XID, xid);
+ inv.headers.put(RootContext.KEY_BRANCH_TYPE, RootContext.getBranchType().name());
+ }
+
+ return inv.invoke();
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataSolonRouterInterceptor.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataSolonRouterInterceptor.java
new file mode 100644
index 00000000000..10b3fb875d9
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/SeataSolonRouterInterceptor.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.seata.solon.integration.intercept;
+
+import org.apache.seata.common.util.StringUtils;
+import org.apache.seata.core.context.RootContext;
+import org.noear.solon.core.handle.Context;
+import org.noear.solon.core.handle.Handler;
+import org.noear.solon.core.route.RouterInterceptor;
+import org.noear.solon.core.route.RouterInterceptorChain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author noear 2024/10/25 created
+ */
+public class SeataSolonRouterInterceptor implements RouterInterceptor {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SeataSolonRouterInterceptor.class);
+
+ @Override
+ public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
+ String rpcXid = ctx.header(RootContext.KEY_XID);
+ this.bindXid(rpcXid);
+
+ try {
+ chain.doIntercept(ctx, mainHandler);
+ } finally {
+ if (RootContext.inGlobalTransaction()) {
+ this.cleanXid(rpcXid);
+ }
+ }
+ }
+
+ protected boolean bindXid(String rpcXid) {
+ String xid = RootContext.getXID();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("xid in RootContext[{}] xid in HttpContext[{}]", xid, rpcXid);
+ }
+ if (StringUtils.isBlank(xid) && StringUtils.isNotBlank(rpcXid)) {
+ RootContext.bind(rpcXid);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("bind[{}] to RootContext", rpcXid);
+ }
+ }
+
+ return true;
+ }
+
+ protected void cleanXid(String rpcXid) {
+ XidResource.cleanXid(rpcXid);
+ }
+}
diff --git a/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/XidResource.java b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/XidResource.java
new file mode 100644
index 00000000000..dd6aee5dd5d
--- /dev/null
+++ b/integration/solon-plugin/src/main/java/org/apache/seata/solon/integration/intercept/XidResource.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.apache.seata.solon.integration.intercept;
+
+import org.apache.seata.common.util.StringUtils;
+import org.apache.seata.core.context.RootContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Xid handler.
+ *
+ */
+public class XidResource {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(XidResource.class);
+
+
+ public static void cleanXid(String rpcXid) {
+ String xid = RootContext.getXID();
+ if (StringUtils.isNotBlank(xid)) {
+ String unbindXid = RootContext.unbind();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("unbind[{}] from RootContext", unbindXid);
+ }
+
+ if (!StringUtils.equalsIgnoreCase(rpcXid, unbindXid)) {
+ LOGGER.warn("xid in change during RPC from {} to {}", rpcXid, unbindXid);
+ if (StringUtils.isNotBlank(unbindXid)) {
+ RootContext.bind(unbindXid);
+ LOGGER.warn("bind [{}] back to RootContext", unbindXid);
+ }
+ }
+ }
+ }
+}
diff --git a/integration/solon-plugin/src/main/resources/META-INF/services/org.apache.seata.config.ExtConfigurationProvider b/integration/solon-plugin/src/main/resources/META-INF/services/org.apache.seata.config.ExtConfigurationProvider
new file mode 100644
index 00000000000..940f241907f
--- /dev/null
+++ b/integration/solon-plugin/src/main/resources/META-INF/services/org.apache.seata.config.ExtConfigurationProvider
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+org.apache.seata.solon.autoconfigure.provider.SolonConfigurationProvider
\ No newline at end of file
diff --git a/integration/solon-plugin/src/main/resources/META-INF/solon/seata-solon-plugin.properties b/integration/solon-plugin/src/main/resources/META-INF/solon/seata-solon-plugin.properties
new file mode 100644
index 00000000000..8f6da3ace6b
--- /dev/null
+++ b/integration/solon-plugin/src/main/resources/META-INF/solon/seata-solon-plugin.properties
@@ -0,0 +1,3 @@
+solon.plugin=org.apache.seata.solon.integration.SeataPlugin
+# gt solon-data
+solon.plugin.priority=31
\ No newline at end of file
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/ClientPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/ClientPropertiesTest.java
new file mode 100644
index 00000000000..08e4c7e6930
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/ClientPropertiesTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure;
+
+import org.apache.seata.core.constants.ConfigurationKeys;
+import org.apache.seata.solon.autoconfigure.properties.SeataProperties;
+import org.apache.seata.solon.autoconfigure.properties.client.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.noear.solon.SimpleSolonApp;
+
+import java.util.Map;
+
+import static org.apache.seata.common.DefaultValues.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+
+public class ClientPropertiesTest {
+ static SimpleSolonApp solonApp;
+ @BeforeAll
+ public static void initContext() throws Throwable {
+ solonApp = new SimpleSolonApp(ClientPropertiesTest.class).start(app -> {
+ System.setProperty(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, "true");
+
+ app.enableHttp(false);
+ app.enableScanning(false);
+ app.context().beanScan("org.apache.seata.solon.autoconfigure.properties");
+ });
+ }
+
+
+ @AfterAll
+ public static void closeContext() {
+ solonApp.stop();
+ }
+
+ @Test
+ public void testSeataProperties() {
+ assertTrue(solonApp.context().getBean(SeataProperties.class).isEnabled());
+ assertNotNull(solonApp.context().getBean(SeataProperties.class).getApplicationId());
+ assertEquals(DEFAULT_TX_GROUP, solonApp.context().getBean(SeataProperties.class).getTxServiceGroup());
+ assertTrue(solonApp.context().getBean(SeataProperties.class).isEnableAutoDataSourceProxy());
+ assertEquals("AT", solonApp.context().getBean(SeataProperties.class).getDataSourceProxyMode());
+ assertFalse(solonApp.context().getBean(SeataProperties.class).isUseJdkProxy());
+ }
+
+
+ @Test
+ public void testLockProperties() {
+ assertEquals(10, solonApp.context().getBean(LockProperties.class).getRetryInterval());
+ assertEquals(30, solonApp.context().getBean(LockProperties.class).getRetryTimes());
+ assertTrue(solonApp.context().getBean(LockProperties.class).isRetryPolicyBranchRollbackOnConflict());
+ }
+
+ @Test
+ public void testRmProperties() {
+ Assertions.assertEquals(10000, solonApp.context().getBean(RmProperties.class).getAsyncCommitBufferLimit());
+ assertEquals(5, solonApp.context().getBean(RmProperties.class).getReportRetryCount());
+ assertTrue(solonApp.context().getBean(RmProperties.class).isTableMetaCheckEnable());
+ assertFalse(solonApp.context().getBean(RmProperties.class).isReportSuccessEnable());
+ assertEquals(60000L, solonApp.context().getBean(RmProperties.class).getTableMetaCheckerInterval());
+ assertFalse(solonApp.context().getBean(RmProperties.class).isSagaRetryPersistModeUpdate());
+ assertFalse(solonApp.context().getBean(RmProperties.class).isSagaCompensatePersistModeUpdate());
+ }
+
+ @Test
+ public void testServiceProperties() {
+ ServiceProperties serviceProperties = solonApp.context().getBean(ServiceProperties.class);
+ Map vgroupMapping = serviceProperties.getVgroupMapping();
+ Map grouplist = serviceProperties.getGrouplist();
+ assertEquals("default", vgroupMapping.get(DEFAULT_TX_GROUP));
+ assertEquals("127.0.0.1:8091", grouplist.get("default"));
+ assertFalse(serviceProperties.isDisableGlobalTransaction());
+ }
+
+
+ @Test
+ public void testTmProperties() {
+ assertEquals(DEFAULT_TM_COMMIT_RETRY_COUNT, solonApp.context().getBean(TmProperties.class).getCommitRetryCount());
+ assertEquals(DEFAULT_TM_ROLLBACK_RETRY_COUNT, solonApp.context().getBean(TmProperties.class).getRollbackRetryCount());
+ assertEquals(DEFAULT_GLOBAL_TRANSACTION_TIMEOUT, solonApp.context().getBean(TmProperties.class).getDefaultGlobalTransactionTimeout());
+ }
+
+ @Test
+ public void testUndoProperties() {
+ assertTrue(solonApp.context().getBean(UndoProperties.class).isDataValidation());
+ assertEquals("jackson", solonApp.context().getBean(UndoProperties.class).getLogSerialization());
+ assertEquals(DEFAULT_TRANSACTION_UNDO_LOG_TABLE, solonApp.context().getBean(UndoProperties.class).getLogTable());
+ }
+
+ @Test
+ public void testLoadBalanceProperties() {
+ assertEquals("XID", solonApp.context().getBean(LoadBalanceProperties.class).getType());
+ assertEquals(10, solonApp.context().getBean(LoadBalanceProperties.class).getVirtualNodes());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolPropertiesTest.java
new file mode 100644
index 00000000000..f94b30108db
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SagaAsyncThreadPoolPropertiesTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SagaAsyncThreadPoolPropertiesTest {
+
+ @Test
+ public void testSagaAsyncThreadPoolProperties() {
+ SagaAsyncThreadPoolProperties sagaAsyncThreadPoolProperties = new SagaAsyncThreadPoolProperties();
+ sagaAsyncThreadPoolProperties.setCorePoolSize(1);
+ Assertions.assertEquals(1, sagaAsyncThreadPoolProperties.getCorePoolSize());
+
+ sagaAsyncThreadPoolProperties.setMaxPoolSize(1);
+ Assertions.assertEquals(1, sagaAsyncThreadPoolProperties.getMaxPoolSize());
+
+ sagaAsyncThreadPoolProperties.setKeepAliveTime(1);
+ Assertions.assertEquals(1, sagaAsyncThreadPoolProperties.getKeepAliveTime());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SeataPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SeataPropertiesTest.java
new file mode 100644
index 00000000000..e8a30f34560
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/SeataPropertiesTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SeataPropertiesTest {
+
+ @Test
+ public void testSeataProperties() {
+ SeataProperties seataProperties = new SeataProperties();
+ seataProperties.setEnabled(true);
+ Assertions.assertTrue(seataProperties.isEnabled());
+
+ seataProperties.setApplicationId("applicationId");
+ Assertions.assertEquals("applicationId", seataProperties.getApplicationId());
+
+ seataProperties.setTxServiceGroup("group");
+ Assertions.assertEquals("group", seataProperties.getTxServiceGroup());
+
+ seataProperties.setEnableAutoDataSourceProxy(true);
+ Assertions.assertTrue(seataProperties.isEnableAutoDataSourceProxy());
+
+ seataProperties.setDataSourceProxyMode("AT");
+ Assertions.assertEquals("AT", seataProperties.getDataSourceProxyMode());
+
+ seataProperties.setUseJdkProxy(true);
+ Assertions.assertTrue(seataProperties.isUseJdkProxy());
+
+ String[] excludesForAutoProxying = new String[]{"test"};
+ seataProperties.setExcludesForAutoProxying(excludesForAutoProxying);
+ Assertions.assertEquals(excludesForAutoProxying, seataProperties.getExcludesForAutoProxying());
+
+ String[] scanPackages = new String[]{"com"};
+ seataProperties.setScanPackages(scanPackages);
+ Assertions.assertEquals(scanPackages, seataProperties.getScanPackages());
+
+ String[] excludesForScanning = new String[]{"com"};
+ seataProperties.setExcludesForScanning(excludesForScanning);
+ Assertions.assertEquals(excludesForScanning, seataProperties.getExcludesForScanning());
+
+ seataProperties.setAccessKey("key");
+ Assertions.assertEquals("key", seataProperties.getAccessKey());
+
+ seataProperties.setSecretKey("secret");
+ Assertions.assertEquals("secret", seataProperties.getSecretKey());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalancePropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalancePropertiesTest.java
new file mode 100644
index 00000000000..93feb96f96c
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LoadBalancePropertiesTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.apache.seata.common.loader.EnhancedServiceLoader;
+import org.apache.seata.config.Configuration;
+import org.apache.seata.config.ExtConfigurationProvider;
+import org.apache.seata.config.FileConfiguration;
+import org.apache.seata.core.constants.ConfigurationKeys;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.noear.solon.SimpleSolonApp;
+
+import static org.apache.seata.solon.autoconfigure.StarterConstants.LOAD_BALANCE_PREFIX;
+import static org.apache.seata.solon.autoconfigure.StarterConstants.PROPERTY_BEAN_MAP;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+
+/**
+ **/
+public class LoadBalancePropertiesTest {
+ static SimpleSolonApp solonApp;
+
+ @BeforeAll
+ public static void initContext() throws Throwable {
+ solonApp = new SimpleSolonApp(LoadBalancePropertiesTest.class).start(app -> {
+ System.setProperty(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, "true");
+
+ app.enableHttp(false);
+ app.enableScanning(false);
+ app.context().wrapAndPut(LoadBalanceProperties.class, loadBalanceProperties());
+ });
+ }
+
+ @AfterAll
+ public static void closeContext() {
+ solonApp.stop();
+ }
+
+ public static LoadBalanceProperties loadBalanceProperties() {
+ LoadBalanceProperties loadBalanceProperties = new LoadBalanceProperties();
+ PROPERTY_BEAN_MAP.put(LOAD_BALANCE_PREFIX, LoadBalanceProperties.class);
+ return loadBalanceProperties;
+ }
+
+ @Test
+ public void testLoadBalanceProperties() {
+ FileConfiguration configuration = mock(FileConfiguration.class);
+ Configuration currentConfiguration =
+ EnhancedServiceLoader.load(ExtConfigurationProvider.class).provide(configuration);
+ System.setProperty("seata.client.loadBalance.virtualNodes", "30");
+ assertEquals(30, currentConfiguration.getInt("client.loadBalance.virtualNodes"));
+ System.setProperty("seata.client.loadBalance.type", "test");
+ assertEquals("test", currentConfiguration.getConfig("client.loadBalance.type"));
+
+ LoadBalanceProperties loadBalanceProperties = new LoadBalanceProperties();
+ loadBalanceProperties.setType("type");
+ Assertions.assertEquals("type", loadBalanceProperties.getType());
+
+ loadBalanceProperties.setVirtualNodes(1);
+ Assertions.assertEquals(1, loadBalanceProperties.getVirtualNodes());
+ }
+}
\ No newline at end of file
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LockPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LockPropertiesTest.java
new file mode 100644
index 00000000000..edb9d048f52
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/LockPropertiesTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class LockPropertiesTest {
+
+ @Test
+ public void testLockProperties() {
+ LockProperties lockProperties = new LockProperties();
+ lockProperties.setRetryInterval(1);
+ Assertions.assertEquals(1, lockProperties.getRetryInterval());
+
+ lockProperties.setRetryTimes(1);
+ Assertions.assertEquals(1, lockProperties.getRetryTimes());
+
+ lockProperties.setRetryPolicyBranchRollbackOnConflict(true);
+ Assertions.assertEquals(true, lockProperties.isRetryPolicyBranchRollbackOnConflict());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/RmPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/RmPropertiesTest.java
new file mode 100644
index 00000000000..95fb964a7bb
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/RmPropertiesTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class RmPropertiesTest {
+
+ @Test
+ public void testRmProperties() {
+ RmProperties rmProperties = new RmProperties();
+ rmProperties.setAsyncCommitBufferLimit(1);
+ Assertions.assertEquals(1, rmProperties.getAsyncCommitBufferLimit());
+
+ rmProperties.setReportRetryCount(1);
+ Assertions.assertEquals(1, rmProperties.getReportRetryCount());
+
+ rmProperties.setTableMetaCheckEnable(true);
+ Assertions.assertTrue(rmProperties.isTableMetaCheckEnable());
+
+ rmProperties.setReportSuccessEnable(true);
+ Assertions.assertTrue(rmProperties.isReportSuccessEnable());
+
+ rmProperties.setSagaBranchRegisterEnable(true);
+ Assertions.assertTrue(rmProperties.isSagaBranchRegisterEnable());
+
+ rmProperties.setSagaJsonParser("json");
+ Assertions.assertEquals("json", rmProperties.getSagaJsonParser());
+
+ rmProperties.setTableMetaCheckerInterval(1);
+ Assertions.assertEquals(1, rmProperties.getTableMetaCheckerInterval());
+
+ rmProperties.setSagaRetryPersistModeUpdate(true);
+ Assertions.assertTrue(rmProperties.isSagaRetryPersistModeUpdate());
+
+ rmProperties.setSagaCompensatePersistModeUpdate(true);
+ Assertions.assertTrue(rmProperties.isSagaCompensatePersistModeUpdate());
+
+ rmProperties.setTccActionInterceptorOrder(1);
+ Assertions.assertEquals(1, rmProperties.getTccActionInterceptorOrder());
+
+ rmProperties.setSqlParserType("type");
+ Assertions.assertEquals("type", rmProperties.getSqlParserType());
+
+ rmProperties.setBranchExecutionTimeoutXA(1);
+ Assertions.assertEquals(1, rmProperties.getBranchExecutionTimeoutXA());
+
+ rmProperties.setConnectionTwoPhaseHoldTimeoutXA(1);
+ Assertions.assertEquals(1, rmProperties.getConnectionTwoPhaseHoldTimeoutXA());
+
+ rmProperties.setApplicationDataLimitCheck(true);
+ Assertions.assertTrue(rmProperties.getApplicationDataLimitCheck());
+
+ rmProperties.setApplicationDataLimit(1);
+ Assertions.assertEquals(1, rmProperties.getApplicationDataLimit());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/ServicePropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/ServicePropertiesTest.java
new file mode 100644
index 00000000000..373ec4cb900
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/ServicePropertiesTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ServicePropertiesTest {
+
+ @Test
+ public void testServiceProperties() {
+ ServiceProperties serviceProperties = new ServiceProperties();
+
+ Map vGroupMapping = new HashMap<>();
+ vGroupMapping.put("default_tx_group", "default");
+ serviceProperties.setVgroupMapping(vGroupMapping);
+ Assertions.assertEquals("default", serviceProperties.getVgroupMapping().get("default_tx_group"));
+
+ Map groupList = new HashMap<>();
+ groupList.put("default", "127.0.0.1:8091");
+ serviceProperties.setGrouplist(groupList);
+ Assertions.assertEquals("127.0.0.1:8091", serviceProperties.getGrouplist().get("default"));
+
+ serviceProperties.setDisableGlobalTransaction(true);
+ Assertions.assertTrue(serviceProperties.isDisableGlobalTransaction());
+ }
+
+ @Test
+ public void testAfterPropertiesSet() throws Exception {
+ ServiceProperties serviceProperties = new ServiceProperties();
+ serviceProperties.afterPropertiesSet();
+ Assertions.assertEquals("default", serviceProperties.getVgroupMapping().get("default_tx_group"));
+ Assertions.assertEquals("default", serviceProperties.getVgroupMapping().get("my_test_tx_group"));
+ Assertions.assertEquals("127.0.0.1:8091", serviceProperties.getGrouplist().get("default"));
+
+ serviceProperties = new ServiceProperties();
+
+ Map vGroupMapping = new HashMap<>();
+ vGroupMapping.put("default_tx_group", "default");
+ serviceProperties.setVgroupMapping(vGroupMapping);
+
+ Map groupList = new HashMap<>();
+ groupList.put("default", "127.0.0.1:8091");
+ serviceProperties.setGrouplist(groupList);
+
+ serviceProperties.afterPropertiesSet();
+ Assertions.assertEquals("default", serviceProperties.getVgroupMapping().get("default_tx_group"));
+ Assertions.assertEquals("127.0.0.1:8091", serviceProperties.getGrouplist().get("default"));
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/TmPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/TmPropertiesTest.java
new file mode 100644
index 00000000000..8178c6e1a59
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/TmPropertiesTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TmPropertiesTest {
+
+ @Test
+ public void testTmProperties() {
+ TmProperties tmProperties = new TmProperties();
+ tmProperties.setCommitRetryCount(1);
+ Assertions.assertEquals(1, tmProperties.getCommitRetryCount());
+
+ tmProperties.setRollbackRetryCount(1);
+ Assertions.assertEquals(1, tmProperties.getRollbackRetryCount());
+
+ tmProperties.setDefaultGlobalTransactionTimeout(1);
+ Assertions.assertEquals(1, tmProperties.getDefaultGlobalTransactionTimeout());
+
+ tmProperties.setDegradeCheck(true);
+ Assertions.assertTrue(tmProperties.isDegradeCheck());
+
+ tmProperties.setDegradeCheckPeriod(1);
+ Assertions.assertEquals(1, tmProperties.getDegradeCheckPeriod());
+
+ tmProperties.setDegradeCheckAllowTimes(1);
+ Assertions.assertEquals(1, tmProperties.getDegradeCheckAllowTimes());
+
+ tmProperties.setInterceptorOrder(1);
+ Assertions.assertEquals(1, tmProperties.getInterceptorOrder());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressPropertiesTest.java
new file mode 100644
index 00000000000..453b12937ba
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoCompressPropertiesTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class UndoCompressPropertiesTest {
+
+ @Test
+ public void testUndoCompressProperties() {
+ UndoCompressProperties undoCompressProperties = new UndoCompressProperties();
+ undoCompressProperties.setEnable(true);
+ Assertions.assertTrue(undoCompressProperties.isEnable());
+
+ undoCompressProperties.setType("type");
+ Assertions.assertEquals("type", undoCompressProperties.getType());
+
+ undoCompressProperties.setThreshold("threshold");
+ Assertions.assertEquals("threshold", undoCompressProperties.getThreshold());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoPropertiesTest.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoPropertiesTest.java
new file mode 100644
index 00000000000..9de799b0271
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/autoconfigure/properties/client/UndoPropertiesTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.seata.solon.autoconfigure.properties.client;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class UndoPropertiesTest {
+
+ @Test
+ public void testUndoProperties() {
+ UndoProperties undoProperties = new UndoProperties();
+ undoProperties.setDataValidation(true);
+ Assertions.assertTrue(undoProperties.isDataValidation());
+
+ undoProperties.setLogSerialization("jackson");
+ Assertions.assertEquals("jackson", undoProperties.getLogSerialization());
+
+ undoProperties.setLogTable("table");
+ Assertions.assertEquals("table", undoProperties.getLogTable());
+
+ undoProperties.setOnlyCareUpdateColumns(true);
+ Assertions.assertTrue(undoProperties.isOnlyCareUpdateColumns());
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/App2.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/App2.java
new file mode 100644
index 00000000000..55819cae571
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/App2.java
@@ -0,0 +1,28 @@
+/*
+ * 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 org.apache.seata.solon.demo.app2;
+
+import org.noear.solon.Solon;
+
+/**
+ * @author noear 2024/10/28 created
+ */
+public class App2 {
+ public static void main(String[] args) {
+ Solon.start(App2.class, new String[]{"--cfg=demo/app2.yml"});
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/Controller2.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/Controller2.java
new file mode 100644
index 00000000000..ec22bf477b5
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/app2/Controller2.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.seata.solon.demo.app2;
+
+import org.noear.solon.annotation.Body;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Mapping;
+
+import java.util.Map;
+
+/**
+ * @author noear 2024/10/28 created
+ */
+@Controller
+public class Controller2 {
+ @Mapping("user")
+ public void addUser(@Body Map params) throws Exception {
+ //..
+ }
+
+ @Mapping("order")
+ public void addOrder(@Body Map params) throws Exception {
+ //..
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/App1.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/App1.java
new file mode 100644
index 00000000000..ffde94f4d29
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/App1.java
@@ -0,0 +1,28 @@
+/*
+ * 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 org.apache.seata.solon.demo.main;
+
+import org.noear.solon.Solon;
+
+/**
+ * @author noear 2024/10/28 created
+ */
+public class App1 {
+ public static void main(String[] args) {
+ Solon.start(App1.class, new String[]{"--cfg=demo/app1.yml"});
+ }
+}
diff --git a/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/Controller1.java b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/Controller1.java
new file mode 100644
index 00000000000..13cee65edf2
--- /dev/null
+++ b/integration/solon-plugin/src/test/java/org/apache/seata/solon/demo/main/Controller1.java
@@ -0,0 +1,43 @@
+/*
+ * 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 org.apache.seata.solon.demo.main;
+
+import org.apache.seata.spring.annotation.GlobalTransactional;
+import org.noear.solon.annotation.Body;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Mapping;
+import org.noear.solon.net.http.HttpUtils;
+
+import java.util.Map;
+
+/**
+ * @author noear 2024/10/28 created
+ */
+@Controller
+public class Controller1 {
+ @GlobalTransactional
+ @Mapping
+ public void add(@Body Map params) throws Exception {
+ HttpUtils.http("http://localhost:8082/user")
+ .data(params)
+ .post();
+
+ HttpUtils.http("http://localhost:8082/order")
+ .data(params)
+ .post();
+ }
+}
diff --git a/integration/solon-plugin/src/test/resources/app.properties b/integration/solon-plugin/src/test/resources/app.properties
new file mode 100755
index 00000000000..0db13885ff2
--- /dev/null
+++ b/integration/solon-plugin/src/test/resources/app.properties
@@ -0,0 +1,56 @@
+#
+# 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.
+#
+
+solon.app.group=demo
+solon.app.name=demo-app
+
+seata.config.type=file
+seata.config.data-type=bbb
+seata.config.file.name=aaa
+
+seata.config.consul.server-addr=aaa
+seata.config.consul.acl-token=bbb
+seata.config.consul.key=ccc
+
+seata.config.apollo.apollo-access-key-secret=bbb
+seata.config.apollo.apollo-meta=aaa
+seata.config.apollo.app-id=ccc
+seata.config.apollo.namespace=ddd
+seata.config.apollo.cluster=eee
+seata.config.apollo.apollo-config-service=fff
+
+seata.config.etcd3.server-addr=aaa
+seata.config.etcd3.key=bbb
+
+seata.config.nacos.namespace=ddd
+seata.config.nacos.server-addr=aaa
+seata.config.nacos.group=ccc
+seata.config.nacos.username=eee
+seata.config.nacos.password=fff
+##if use MSE Nacos with auth, mutex with username/password attribute
+#seata.config.nacos.access-key=
+#seata.config.nacos.secret-key=
+seata.config.nacos.data-id=bbb
+
+seata.config.zk.server-addr=bbb
+seata.config.zk.session-timeout=2
+seata.config.zk.connect-timeout=1
+seata.config.zk.username=ccc
+seata.config.zk.password=ddd
+seata.config.zk.node-path=aaa
+
+seata.config.custom.name=aaa
diff --git a/integration/solon-plugin/src/test/resources/demo/app1.yml b/integration/solon-plugin/src/test/resources/demo/app1.yml
new file mode 100644
index 00000000000..8ca6026caaa
--- /dev/null
+++ b/integration/solon-plugin/src/test/resources/demo/app1.yml
@@ -0,0 +1,5 @@
+server.port: 8081
+
+seata:
+ tcc:
+ aa: "a"
\ No newline at end of file
diff --git a/integration/solon-plugin/src/test/resources/demo/app2.yml b/integration/solon-plugin/src/test/resources/demo/app2.yml
new file mode 100644
index 00000000000..61205e72624
--- /dev/null
+++ b/integration/solon-plugin/src/test/resources/demo/app2.yml
@@ -0,0 +1 @@
+server.port: 8082
\ No newline at end of file
diff --git a/integration/solon-plugin/src/test/resources/test/case1.yml b/integration/solon-plugin/src/test/resources/test/case1.yml
new file mode 100644
index 00000000000..a119c2a561e
--- /dev/null
+++ b/integration/solon-plugin/src/test/resources/test/case1.yml
@@ -0,0 +1,55 @@
+solon.app:
+ name: demo-app
+ group: demo
+
+#====================================Seata Config===============================================
+seata:
+ enabled: true
+ application-id: business-seata-example
+ tx-service-group: business-service-seata-service-group
+ client:
+ rm-report-success-enable: true
+ rm-table-meta-check-enable: false
+ rm-report-retry-count: 5
+ rm-async-commit-buffer-limit: 10000
+ rm:
+ lock:
+ lock-retry-internal: 10
+ lock-retry-times: 30
+ lock-retry-policy-branch-rollback-on-conflict: true
+ tm-commit-retry-count: 3
+ tm-rollback-retry-count: 3
+ undo:
+ undo-data-validation: true
+ undo-log-serialization: jackson
+ undo-log-table: undo_log
+ log:
+ exceptionRate: 100
+ support:
+ spring:
+ datasource-autoproxy: true
+ service:
+ vgroup-mapping:
+ my_test_tx_group: default
+ enable-degrade: false
+ disable-global-transaction: false
+ grouplist:
+ default: 127.0.0.1:8091
+ transport:
+ shutdown:
+ wait: 3
+ thread-factory:
+ boss-thread-prefix: NettyBoss
+ worker-thread-prefix: NettyServerNIOWorker
+ server-executor-thread-prefix: NettyServerBizHandler
+ share-boss-worker: false
+ client-selector-thread-prefix: NettyClientSelector
+ client-selector-thread-size: 1
+ client-worker-thread-prefix: NettyClientWorkerThread
+ type: TCP
+ server: NIO
+ heartbeat: true
+ serialization: seata
+ compressor: none
+ enable-client-batch-send-request: true
+
diff --git a/pom.xml b/pom.xml
index 958e9d497b1..d984d7a362b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,7 @@
integration/http-jakarta
integration/hsf
integration/brpc
+ integration/solon-plugin
rm
rm-datasource
rocketmq