diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index e3945b4b978..5940b569f7d 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -11,6 +11,8 @@ Add changes here for all PR submitted to the 2.x branch. ### bugfix: - [[#7104](https://github.com/apache/incubator-seata/pull/7104)] fix impl of supportsSourceType is not defined +- [[#7116](https://github.com/apache/incubator-seata/pull/7116)] fix prefix: seata.server.raft.ssl should not be null +- [[#7112](https://github.com/apache/incubator-seata/pull/7112)] bugfix: remove the condition that IPv6 must start with fe80 ### optimize: @@ -45,6 +47,7 @@ Thanks to these contributors for their code commits. Please report an unintended - [PeppaO](https://github.com/PeppaO) - [funky-eyes](https://github.com/funky-eyes) - [psxjoy](https://github.com/psxjoy) +- [xiaoxiangyeyu0](https://github.com/xiaoxiangyeyu0) Also, we receive many valuable issues, questions and advices from our community. Thanks for you all. \ No newline at end of file diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 5ef696ff1fa..13e4e531831 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -11,6 +11,8 @@ ### bugfix: - [[#7104](https://github.com/apache/incubator-seata/pull/7104)] 修复SeataApplicationListener在低版本springboot未实现supportsSourceType方法的问题 +- [[#7116](https://github.com/apache/incubator-seata/pull/7116)] 修复 seata.server.raft.ssl 前缀不存在的问题 +- [[#7112](https://github.com/apache/incubator-seata/pull/7112)] 校验是否IPv6网络ip取消必须以fe80开始的条件 ### optimize: @@ -44,5 +46,6 @@ - [PeppaO](https://github.com/PeppaO) - [funky-eyes](https://github.com/funky-eyes) - [psxjoy](https://github.com/psxjoy) +- [xiaoxiangyeyu0](https://github.com/xiaoxiangyeyu0) 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。 \ No newline at end of file diff --git a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java index 3bb4c9873ff..297d64167b5 100644 --- a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java +++ b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java @@ -966,14 +966,24 @@ public interface ConfigurationKeys { /** - * The constant SERVER_RAFT_SSL_KEYSTORE_TYPE. + * The constant SERVER_RAFT_SSL_CLIENT_KEYSTORE_TYPE. */ - String SERVER_RAFT_SSL_KEYSTORE_TYPE = SERVER_RAFT_SSL + "keystore.type"; + String SERVER_RAFT_SSL_CLIENT_KEYSTORE_TYPE = SERVER_RAFT_SSL_CLIENT + "keystore.type"; + + /** + * The constant SERVER_RAFT_SSL_SERVER_KEYSTORE_TYPE. + */ + String SERVER_RAFT_SSL_SERVER_KEYSTORE_TYPE = SERVER_RAFT_SSL_SERVER + "keystore.type"; + + /** + * The constant SERVER_RAFT_SSL_KMF_ALGORITHM. + */ + String SERVER_RAFT_SSL_KMF_ALGORITHM = SERVER_RAFT_SSL + "kmfAlgorithm"; /** * The constant SERVER_RAFT_SSL_KMF_ALGORITHM. */ - String SERVER_RAFT_SSL_KMF_ALGORITHM = SERVER_RAFT_SSL + "kmf.algorithm"; + String SERVER_RAFT_SSL_TMF_ALGORITHM = SERVER_RAFT_SSL + "tmfAlgorithm"; /** * The constant SERVER_RAFT_MAX_APPEND_BUFFER_SIZE. diff --git a/common/src/main/java/org/apache/seata/common/util/NetAddressValidatorUtil.java b/common/src/main/java/org/apache/seata/common/util/NetAddressValidatorUtil.java index 8b6c8399d38..d1ddfa73d7f 100644 --- a/common/src/main/java/org/apache/seata/common/util/NetAddressValidatorUtil.java +++ b/common/src/main/java/org/apache/seata/common/util/NetAddressValidatorUtil.java @@ -30,14 +30,10 @@ public class NetAddressValidatorUtil { private static final String DOUBLE_COLON_FFFF = "::ffff:"; - private static final String FE80 = "fe80:"; - private static final int ZERO = 0; private static final int SEVEN = 7; - private static final int FIVE = 5; - private static final Pattern IPV4_PATTERN = Pattern .compile("^" + "(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)" + "(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}" + "$"); @@ -133,19 +129,17 @@ public static boolean isIPv6IPv4MappedAddress(final String input) { } /** - * Check if input is a link local IPv6 address starting with "fe80:" and containing + * Check if input is a link local IPv6 address containing * a zone index with "%xxx". The zone index will not be checked. * * @param input ip-address to check * @return true if address part of input is in correct IPv6 notation. */ public static boolean isLinkLocalIPv6WithZoneIndex(String input) { - if (input.length() > FIVE && input.substring(ZERO, FIVE).equalsIgnoreCase(FE80)) { - int lastIndex = input.lastIndexOf(PERCENT); - if (lastIndex > ZERO && lastIndex < (input.length() - 1)) { - String ipPart = input.substring(ZERO, lastIndex); - return isIPv6StdAddress(ipPart) || isIPv6HexCompressedAddress(ipPart); - } + int lastIndex = input.lastIndexOf(PERCENT); + if (lastIndex > ZERO && lastIndex < (input.length() - 1)) { + String ipPart = input.substring(ZERO, lastIndex); + return isIPv6StdAddress(ipPart) || isIPv6HexCompressedAddress(ipPart); } return false; } diff --git a/common/src/test/java/org/apache/seata/common/util/NetAddressValidatorUtilTest.java b/common/src/test/java/org/apache/seata/common/util/NetAddressValidatorUtilTest.java index 6c39ff6062f..c23e1973680 100644 --- a/common/src/test/java/org/apache/seata/common/util/NetAddressValidatorUtilTest.java +++ b/common/src/test/java/org/apache/seata/common/util/NetAddressValidatorUtilTest.java @@ -53,4 +53,10 @@ public void isIPv4Address() { assertThat(NetAddressValidatorUtil.isIPv4Address("127.0.0.1")).isTrue(); assertThat(NetAddressValidatorUtil.isIPv4Address("999.999.999.999")).isFalse(); } + + @Test + public void isLinkLocalIPv6WithZoneIndex() { + assertThat(NetAddressValidatorUtil.isLinkLocalIPv6WithZoneIndex("2409:8a5c:6730:4490:f0e8:b9ad:3b3d:e739%br0")).isTrue(); + assertThat(NetAddressValidatorUtil.isLinkLocalIPv6WithZoneIndex("2409:8a5c:6730:4490:f0e8:b9ad:3b3d:e739%")).isFalse(); + } } diff --git a/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java b/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java index f8fa9d25d95..7e6b74328e0 100644 --- a/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java +++ b/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java @@ -32,6 +32,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import javax.annotation.PostConstruct; import com.github.benmanes.caffeine.cache.Caffeine; @@ -42,6 +43,7 @@ import org.apache.http.entity.ContentType; import org.apache.http.protocol.HTTP; import org.apache.seata.common.metadata.Cluster; +import org.apache.seata.common.metadata.ClusterRole; import org.apache.seata.common.metadata.Node; import org.apache.seata.common.metadata.namingserver.NamingServerNode; import org.apache.seata.common.metadata.namingserver.Unit; @@ -152,7 +154,9 @@ public Result createGroup(String namespace, String vGroup, String cluste LOGGER.error("no instance in cluster {}", clusterName); return new Result<>("301", "no instance in cluster" + clusterName); } else { - Node node = nodeList.get(0); + Node node = + nodeList.stream().filter(n -> n.getRole() == ClusterRole.LEADER || n.getRole() == ClusterRole.MEMBER) + .collect(Collectors.toList()).get(0); String controlHost = node.getControl().getHost(); int controlPort = node.getControl().getPort(); String httpUrl = NamingServerConstants.HTTP_PREFIX + controlHost + NamingServerConstants.IP_PORT_SPLIT_CHAR @@ -253,16 +257,14 @@ public boolean registerInstance(NamingServerNode node, String namespace, String // if extended metadata includes vgroup mapping relationship, add it in clusterData if (mappingObj instanceof Map) { Map vGroups = (Map)mappingObj; - if (!CollectionUtils.isEmpty(vGroups)) { - vGroups.forEach((k, v) -> { - // In non-raft mode, a unit is one-to-one with a node, and the unitName is stored on the node. - // In raft mode, the unitName is equal to the raft-group, so the node's unitName cannot be used. - boolean changed = addGroup(namespace, clusterName, StringUtils.isBlank(v) ? unitName : v, k); - if (hasChanged || changed) { - notifyClusterChange(k, namespace, clusterName, unitName, node.getTerm()); - } - }); - } + vGroups.forEach((k, v) -> { + // In non-raft mode, a unit is one-to-one with a node, and the unitName is stored on the node. + // In raft mode, the unitName is equal to the raft-group, so the node's unitName cannot be used. + boolean changed = addGroup(namespace, clusterName, StringUtils.isBlank(v) ? unitName : v, k); + if (hasChanged || changed) { + notifyClusterChange(k, namespace, clusterName, unitName, node.getTerm()); + } + }); } instanceLiveTable.put( new InetSocketAddress(node.getTransaction().getHost(), node.getTransaction().getPort()), diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java index db09911af18..7a6c3c24e41 100644 --- a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java @@ -73,6 +73,9 @@ public interface StarterConstants { String SERVER_PREFIX = SEATA_PREFIX + ".server"; String SERVER_UNDO_PREFIX = SERVER_PREFIX + ".undo"; String SERVER_RAFT_PREFIX = SERVER_PREFIX + ".raft"; + String SERVER_RAFT_SSL_PREFIX = SERVER_RAFT_PREFIX + ".ssl"; + String SERVER_RAFT_SSL_CLIENT_KEYSTORE_PREFIX = SERVER_RAFT_SSL_PREFIX + ".client.keystore"; + String SERVER_RAFT_SSL_SERVER_KEYSTORE_PREFIX = SERVER_RAFT_SSL_PREFIX + ".server.keystore"; String SERVER_RECOVERY_PREFIX = SERVER_PREFIX + ".recovery"; String METRICS_PREFIX = SEATA_PREFIX + ".metrics"; diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java index 9749a003d81..f20268cf0dd 100644 --- a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java @@ -17,10 +17,13 @@ package org.apache.seata.spring.boot.autoconfigure; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftSSLClientProperties; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftSSLProperties; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftSSLServerProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.MetricsProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.ServerProperties; -import org.apache.seata.spring.boot.autoconfigure.properties.server.ServerRaftProperties; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.ServerRecoveryProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.ServerUndoProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.session.SessionProperties; @@ -38,6 +41,9 @@ import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.PROPERTY_BEAN_MAP; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_PREFIX; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_CLIENT_KEYSTORE_PREFIX; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_PREFIX; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_SERVER_KEYSTORE_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RECOVERY_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_UNDO_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SESSION_PREFIX; @@ -79,6 +85,9 @@ public static void init() { PROPERTY_BEAN_MAP.put(STORE_REDIS_SINGLE_PREFIX, StoreRedisProperties.Single.class); PROPERTY_BEAN_MAP.put(STORE_REDIS_SENTINEL_PREFIX, StoreRedisProperties.Sentinel.class); PROPERTY_BEAN_MAP.put(SERVER_RAFT_PREFIX, ServerRaftProperties.class); + PROPERTY_BEAN_MAP.put(SERVER_RAFT_SSL_SERVER_KEYSTORE_PREFIX, ServerRaftSSLServerProperties.class); + PROPERTY_BEAN_MAP.put(SERVER_RAFT_SSL_PREFIX, ServerRaftSSLProperties.class); + PROPERTY_BEAN_MAP.put(SERVER_RAFT_SSL_CLIENT_KEYSTORE_PREFIX, ServerRaftSSLClientProperties.class); PROPERTY_BEAN_MAP.put(SESSION_PREFIX, SessionProperties.class); PROPERTY_BEAN_MAP.put(STORE_PREFIX, StoreProperties.class); } diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftProperties.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftProperties.java similarity index 98% rename from seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftProperties.java rename to seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftProperties.java index 5121b0dff85..6164d6daa96 100644 --- a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftProperties.java +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftProperties.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.seata.spring.boot.autoconfigure.properties.server; +package org.apache.seata.spring.boot.autoconfigure.properties.server.raft; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -29,7 +29,7 @@ public class ServerRaftProperties { private String serverAddr; - private String group; + private String group = "default"; private Boolean autoJoin = false; diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLClientProperties.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLClientProperties.java new file mode 100644 index 00000000000..3c91211857b --- /dev/null +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLClientProperties.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.spring.boot.autoconfigure.properties.server.raft; + +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_CLIENT_KEYSTORE_PREFIX; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = SERVER_RAFT_SSL_CLIENT_KEYSTORE_PREFIX) +public class ServerRaftSSLClientProperties { + + private String path = "ssl/cbolt.pfx"; + + private String password; + + private String type = "pkcs12"; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLProperties.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLProperties.java new file mode 100644 index 00000000000..2239393525d --- /dev/null +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLProperties.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.spring.boot.autoconfigure.properties.server.raft; + +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_PREFIX; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = SERVER_RAFT_SSL_PREFIX) +public class ServerRaftSSLProperties { + + private Boolean enabled = false; + + private String kmfAlgorithm = "SunX509"; + + private String tmfAlgorithm = "SunX509"; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getKmfAlgorithm() { + return kmfAlgorithm; + } + + public void setKmfAlgorithm(String kmfAlgorithm) { + this.kmfAlgorithm = kmfAlgorithm; + } + + public String getTmfAlgorithm() { + return tmfAlgorithm; + } + + public void setTmfAlgorithm(String tmfAlgorithm) { + this.tmfAlgorithm = tmfAlgorithm; + } +} diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLServerProperties.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLServerProperties.java new file mode 100644 index 00000000000..8b4a2efc0d3 --- /dev/null +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/raft/ServerRaftSSLServerProperties.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.spring.boot.autoconfigure.properties.server.raft; + +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_SERVER_KEYSTORE_PREFIX; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = SERVER_RAFT_SSL_SERVER_KEYSTORE_PREFIX) +public class ServerRaftSSLServerProperties { + + private String path = "ssl/cbolt.pfx"; + + private String password; + + private String type = "pkcs12"; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftPropertiesTest.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftPropertiesTest.java index 7c7e76892c6..51e6df64ae1 100644 --- a/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftPropertiesTest.java +++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/ServerRaftPropertiesTest.java @@ -16,6 +16,7 @@ */ package org.apache.seata.spring.boot.autoconfigure.properties.server; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftProperties; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/server/src/main/java/org/apache/seata/server/cluster/raft/RaftServer.java b/server/src/main/java/org/apache/seata/server/cluster/raft/RaftServer.java index ff3113e4298..e2f6592afe3 100644 --- a/server/src/main/java/org/apache/seata/server/cluster/raft/RaftServer.java +++ b/server/src/main/java/org/apache/seata/server/cluster/raft/RaftServer.java @@ -40,11 +40,13 @@ import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_REPORTER_INITIAL_DELAY; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_CLIENT_KEYSTORE_PASSWORD; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_CLIENT_KEYSTORE_PATH; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_CLIENT_KEYSTORE_TYPE; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_ENABLED; -import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_KEYSTORE_TYPE; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_KMF_ALGORITHM; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_SERVER_KEYSTORE_PASSWORD; import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_SERVER_KEYSTORE_PATH; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_SERVER_KEYSTORE_TYPE; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_TMF_ALGORITHM; import static org.apache.seata.common.DefaultValues.DEFAULT_RAFT_SSL_ENABLED; /** @@ -143,13 +145,13 @@ private void enableSSL() { setSystemProperty("bolt.server.ssl.keystore", instance.getConfig(SERVER_RAFT_SSL_SERVER_KEYSTORE_PATH)); setSystemProperty("bolt.server.ssl.keystore.password", instance.getConfig(SERVER_RAFT_SSL_SERVER_KEYSTORE_PASSWORD)); - setSystemProperty("bolt.server.ssl.keystore.type", instance.getConfig(SERVER_RAFT_SSL_KEYSTORE_TYPE)); + setSystemProperty("bolt.server.ssl.keystore.type", instance.getConfig(SERVER_RAFT_SSL_SERVER_KEYSTORE_TYPE)); setSystemProperty("bolt.server.ssl.kmf.algorithm", instance.getConfig(SERVER_RAFT_SSL_KMF_ALGORITHM)); setSystemProperty("bolt.client.ssl.keystore", instance.getConfig(SERVER_RAFT_SSL_CLIENT_KEYSTORE_PATH)); setSystemProperty("bolt.client.ssl.keystore.password", instance.getConfig(SERVER_RAFT_SSL_CLIENT_KEYSTORE_PASSWORD)); - setSystemProperty("bolt.client.ssl.keystore.type", instance.getConfig(SERVER_RAFT_SSL_KEYSTORE_TYPE)); - setSystemProperty("bolt.client.ssl.tmf.algorithm", instance.getConfig(SERVER_RAFT_SSL_KMF_ALGORITHM)); + setSystemProperty("bolt.client.ssl.keystore.type", instance.getConfig(SERVER_RAFT_SSL_CLIENT_KEYSTORE_TYPE)); + setSystemProperty("bolt.client.ssl.tmf.algorithm", instance.getConfig(SERVER_RAFT_SSL_TMF_ALGORITHM)); logger.info("Enable ssl communication between raft nodes"); } diff --git a/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupAddExecute.java b/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupAddExecute.java index 6a5f8b3de7d..47ccf9e12b6 100644 --- a/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupAddExecute.java +++ b/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupAddExecute.java @@ -19,6 +19,7 @@ import org.apache.seata.server.cluster.raft.execute.AbstractRaftMsgExecute; import org.apache.seata.server.cluster.raft.sync.msg.RaftBaseMsg; import org.apache.seata.server.cluster.raft.sync.msg.RaftVGroupSyncMsg; +import org.apache.seata.server.storage.raft.sore.RaftVGroupMappingStoreManager; /** */ @@ -27,7 +28,7 @@ public class VGroupAddExecute extends AbstractRaftMsgExecute { @Override public Boolean execute(RaftBaseMsg syncMsg) throws Throwable { RaftVGroupSyncMsg vGroupSyncMsg = (RaftVGroupSyncMsg)syncMsg; - raftVGroupMappingStoreManager.addVGroup(vGroupSyncMsg.getMappingDO()); + ((RaftVGroupMappingStoreManager)raftVGroupMappingStoreManager).localAddVGroup(vGroupSyncMsg.getMappingDO()); return true; } diff --git a/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupRemoveExecute.java b/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupRemoveExecute.java index 7fcc8e2fde0..42d2e8dfe96 100644 --- a/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupRemoveExecute.java +++ b/server/src/main/java/org/apache/seata/server/cluster/raft/execute/vgroup/VGroupRemoveExecute.java @@ -19,6 +19,7 @@ import org.apache.seata.server.cluster.raft.execute.AbstractRaftMsgExecute; import org.apache.seata.server.cluster.raft.sync.msg.RaftBaseMsg; import org.apache.seata.server.cluster.raft.sync.msg.RaftVGroupSyncMsg; +import org.apache.seata.server.storage.raft.sore.RaftVGroupMappingStoreManager; /** */ @@ -27,7 +28,7 @@ public class VGroupRemoveExecute extends AbstractRaftMsgExecute { @Override public Boolean execute(RaftBaseMsg syncMsg) throws Throwable { RaftVGroupSyncMsg vGroupSyncMsg = (RaftVGroupSyncMsg)syncMsg; - raftVGroupMappingStoreManager.removeVGroup(vGroupSyncMsg.getMappingDO().getVGroup()); + ((RaftVGroupMappingStoreManager)raftVGroupMappingStoreManager).localRemoveVGroup(vGroupSyncMsg.getMappingDO().getVGroup()); return true; } diff --git a/server/src/main/java/org/apache/seata/server/cluster/raft/sync/msg/RaftVGroupSyncMsg.java b/server/src/main/java/org/apache/seata/server/cluster/raft/sync/msg/RaftVGroupSyncMsg.java index bc3779ec378..a41e8961a14 100644 --- a/server/src/main/java/org/apache/seata/server/cluster/raft/sync/msg/RaftVGroupSyncMsg.java +++ b/server/src/main/java/org/apache/seata/server/cluster/raft/sync/msg/RaftVGroupSyncMsg.java @@ -22,6 +22,9 @@ public class RaftVGroupSyncMsg extends RaftBaseMsg { MappingDO mappingDO; + public RaftVGroupSyncMsg() { + } + public RaftVGroupSyncMsg(MappingDO mappingDO, RaftSyncMsgType raftSyncMsgType) { this.msgType = raftSyncMsgType; this.mappingDO = mappingDO; diff --git a/server/src/main/java/org/apache/seata/server/config/SeataNamingserverWebConfig.java b/server/src/main/java/org/apache/seata/server/config/SeataNamingserverWebConfig.java new file mode 100644 index 00000000000..96d98387e33 --- /dev/null +++ b/server/src/main/java/org/apache/seata/server/config/SeataNamingserverWebConfig.java @@ -0,0 +1,35 @@ +/* + * 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.server.config; + +import org.apache.seata.server.filter.RaftGroupFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SeataNamingserverWebConfig { + + @Bean + public FilterRegistrationBean raftGroupFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new RaftGroupFilter()); + registrationBean.addUrlPatterns("/vgroup/v1/*"); + return registrationBean; + } + +} diff --git a/server/src/main/java/org/apache/seata/server/filter/RaftGroupFilter.java b/server/src/main/java/org/apache/seata/server/filter/RaftGroupFilter.java new file mode 100644 index 00000000000..8e818ce2ae6 --- /dev/null +++ b/server/src/main/java/org/apache/seata/server/filter/RaftGroupFilter.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.server.filter; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import org.apache.seata.server.cluster.raft.context.SeataClusterContext; + +public class RaftGroupFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String unit = httpRequest.getParameter("unit"); + if (unit != null) { + SeataClusterContext.bindGroup(unit); + } + try { + chain.doFilter(request, response); + } finally { + SeataClusterContext.unbindGroup(); + } + } + + @Override + public void destroy() { + } + +} diff --git a/server/src/main/java/org/apache/seata/server/instance/AbstractSeataInstanceStrategy.java b/server/src/main/java/org/apache/seata/server/instance/AbstractSeataInstanceStrategy.java index 02adb2e927c..c770b35fe77 100644 --- a/server/src/main/java/org/apache/seata/server/instance/AbstractSeataInstanceStrategy.java +++ b/server/src/main/java/org/apache/seata/server/instance/AbstractSeataInstanceStrategy.java @@ -74,7 +74,9 @@ public void init(){ EXECUTOR_SERVICE = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("scheduledExcuter", 1, true)); EXECUTOR_SERVICE.scheduleAtFixedRate(() -> { try { - SessionHolder.getRootVGroupMappingManager().notifyMapping(); + if (instance.getTerm() > 0) { + SessionHolder.getRootVGroupMappingManager().notifyMapping(); + } } catch (Exception e) { LOGGER.error("Naming server register Exception", e); } diff --git a/server/src/main/java/org/apache/seata/server/instance/RaftServerInstanceStrategy.java b/server/src/main/java/org/apache/seata/server/instance/RaftServerInstanceStrategy.java index 00ad2b26bf3..ab8ccd651cd 100644 --- a/server/src/main/java/org/apache/seata/server/instance/RaftServerInstanceStrategy.java +++ b/server/src/main/java/org/apache/seata/server/instance/RaftServerInstanceStrategy.java @@ -19,14 +19,16 @@ import javax.annotation.Resource; import org.apache.seata.common.XID; import org.apache.seata.common.holder.ObjectHolder; +import org.apache.seata.common.metadata.ClusterRole; import org.apache.seata.common.metadata.Node; import org.apache.seata.common.metadata.Instance; import org.apache.seata.server.cluster.listener.ClusterChangeEvent; import org.apache.seata.server.cluster.listener.ClusterChangeListener; import org.apache.seata.server.cluster.raft.RaftServerManager; +import org.apache.seata.server.cluster.raft.RaftStateMachine; import org.apache.seata.server.session.SessionHolder; import org.apache.seata.server.store.StoreConfig; -import org.apache.seata.spring.boot.autoconfigure.properties.server.ServerRaftProperties; +import org.apache.seata.spring.boot.autoconfigure.properties.server.raft.ServerRaftProperties; import org.springframework.context.event.EventListener; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; @@ -62,9 +64,10 @@ public Instance serverInstanceInit() { // load cluster type String clusterType = String.valueOf(StoreConfig.getSessionMode()); instance.addMetadata("cluster-type", "raft".equals(clusterType) ? clusterType : "default"); + RaftStateMachine stateMachine = RaftServerManager.getRaftServer(unit).getRaftStateMachine(); long term = RaftServerManager.getRaftServer(unit).getRaftStateMachine().getCurrentTerm().get(); instance.setTerm(term); - + instance.setRole(stateMachine.isLeader() ? ClusterRole.LEADER : ClusterRole.FOLLOWER); // load node Endpoint instance.setControl(new Node.Endpoint(XID.getIpAddress(), serverProperties.getPort(), "http")); @@ -98,6 +101,7 @@ public int getOrder() { @Async public void onChangeEvent(ClusterChangeEvent event) { Instance.getInstance().setTerm(event.getTerm()); + Instance.getInstance().setRole(event.isLeader() ? ClusterRole.LEADER : ClusterRole.FOLLOWER); SessionHolder.getRootVGroupMappingManager().notifyMapping(); } diff --git a/server/src/main/java/org/apache/seata/server/storage/raft/sore/RaftVGroupMappingStoreManager.java b/server/src/main/java/org/apache/seata/server/storage/raft/sore/RaftVGroupMappingStoreManager.java index 6dbc6aa5e2c..6faa711b45c 100644 --- a/server/src/main/java/org/apache/seata/server/storage/raft/sore/RaftVGroupMappingStoreManager.java +++ b/server/src/main/java/org/apache/seata/server/storage/raft/sore/RaftVGroupMappingStoreManager.java @@ -21,9 +21,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; import com.alipay.sofa.jraft.Closure; import org.apache.seata.common.XID; import org.apache.seata.common.loader.LoadLevel; @@ -44,30 +41,14 @@ public class RaftVGroupMappingStoreManager implements VGroupMappingStoreManager private final static Map> VGROUP_MAPPING = new HashMap<>(); - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final Lock readLock = lock.readLock(); - - private final Lock writeLock = lock.writeLock(); - public boolean localAddVGroup(MappingDO mappingDO) { - writeLock.lock(); - try { - return VGROUP_MAPPING.computeIfAbsent(mappingDO.getUnit(), k -> new HashMap<>()).put(mappingDO.getVGroup(), - mappingDO) != null; - } finally { - writeLock.unlock(); - } + return VGROUP_MAPPING.computeIfAbsent(mappingDO.getUnit(), k -> new HashMap<>()).put(mappingDO.getVGroup(), + mappingDO) != null; } public void localAddVGroups(Map vGroups, String unit) { - writeLock.lock(); - try { - VGROUP_MAPPING.computeIfAbsent(unit, k -> new HashMap<>()).putAll(vGroups); - } finally { - writeLock.unlock(); - } + VGROUP_MAPPING.computeIfAbsent(unit, k -> new HashMap<>()).putAll(vGroups); } @Override @@ -117,35 +98,23 @@ public boolean removeVGroup(String vGroup) { } public boolean localRemoveVGroup(String vGroup) { - writeLock.lock(); - try { - VGROUP_MAPPING.forEach((unit, vgroup) -> vgroup.remove(vGroup)); - } finally { - writeLock.unlock(); - } + VGROUP_MAPPING.forEach((unit, vgroup) -> vgroup.remove(vGroup)); return true; } @Override public Map loadVGroups() { Map result = new HashMap<>(); - String clusterName = Instance.getInstance().getClusterName(); - readLock.lock(); - try { - result.put(clusterName, VGROUP_MAPPING); - } finally { - readLock.unlock(); - } + VGROUP_MAPPING.forEach((unit, vgroup) -> { + for (String group : vgroup.keySet()) { + result.put(group, unit); + } + }); return result; } public Map loadVGroupsByUnit(String unit) { - readLock.lock(); - try { - return VGROUP_MAPPING.getOrDefault(unit, Collections.emptyMap()); - } finally { - readLock.unlock(); - } + return VGROUP_MAPPING.getOrDefault(unit, Collections.emptyMap()); } @Override diff --git a/server/src/main/resources/application.raft.example.yml b/server/src/main/resources/application.raft.example.yml index 241820a1d21..c427dce5760 100644 --- a/server/src/main/resources/application.raft.example.yml +++ b/server/src/main/resources/application.raft.example.yml @@ -97,17 +97,15 @@ seata: client: keystore: path: ssl/cbolt.pfx - password: seata + password: type: pkcs12 server: keystore: path: ssl/bolt.pfx - password: seata + password: type: pkcs12 - kmf: - algorithm: SunX509 - tmf: - algorithm: SunX509 + kmf-algorithm: SunX509 + tmf-algorithm: SunX509 service-port: 8091 #If not configured, the default is '${server.port} + 1000' max-commit-retry-timeout: -1 max-rollback-retry-timeout: -1 diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 546fb53d90a..dad4e4ba7f0 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -43,12 +43,7 @@ seata: type: file registry: # support: nacos, eureka, redis, zk, consul, etcd3, sofa - type: seata - seata: - server-addr: 127.0.0.1:8081 - cluster: default - namespace: public - heartbeat-period: 5000 + type: file store: # support: file 、 db 、 redis 、 raft mode: file diff --git a/server/src/test/java/org/apache/seata/server/raft/RaftServerTest.java b/server/src/test/java/org/apache/seata/server/raft/RaftServerTest.java index a85de536066..4633a2d5000 100644 --- a/server/src/test/java/org/apache/seata/server/raft/RaftServerTest.java +++ b/server/src/test/java/org/apache/seata/server/raft/RaftServerTest.java @@ -19,6 +19,7 @@ import org.apache.seata.common.ConfigurationKeys; import org.apache.seata.common.XID; import org.apache.seata.config.ConfigurationCache; +import org.apache.seata.config.ConfigurationFactory; import org.apache.seata.server.cluster.raft.RaftServerManager; import org.apache.seata.server.lock.LockerManagerFactory; import org.apache.seata.server.session.SessionHolder; @@ -30,6 +31,14 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; + +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_CLIENT_KEYSTORE_PATH; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_ENABLED; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_KMF_ALGORITHM; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_SERVER_KEYSTORE_PATH; +import static org.apache.seata.common.ConfigurationKeys.SERVER_RAFT_SSL_TMF_ALGORITHM; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.SERVER_RAFT_SSL_PREFIX; + @SpringBootTest public class RaftServerTest { @@ -51,6 +60,11 @@ public void destroy() { @Test public void initRaftServerStart() { + Assertions.assertDoesNotThrow(()-> ConfigurationFactory.getInstance().getConfig(SERVER_RAFT_SSL_ENABLED)); + Assertions.assertDoesNotThrow(()-> ConfigurationFactory.getInstance().getConfig(SERVER_RAFT_SSL_CLIENT_KEYSTORE_PATH)); + Assertions.assertDoesNotThrow(()-> ConfigurationFactory.getInstance().getConfig(SERVER_RAFT_SSL_SERVER_KEYSTORE_PATH)); + Assertions.assertDoesNotThrow(()-> ConfigurationFactory.getInstance().getConfig(SERVER_RAFT_SSL_KMF_ALGORITHM)); + Assertions.assertDoesNotThrow(()-> ConfigurationFactory.getInstance().getConfig(SERVER_RAFT_SSL_TMF_ALGORITHM)); System.setProperty("server.raftPort", "9091"); System.setProperty(ConfigurationKeys.SERVER_RAFT_SERVER_ADDR, XID.getIpAddress() + ":9091" + "," + XID.getIpAddress() + ":9092" + "," + XID.getIpAddress() + ":9093");