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