This is an automated email from the ASF dual-hosted git repository.
tydhot pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 3625d85 [new: feature] register shenyu instance by zookeeper (#2437)
3625d85 is described below
commit 3625d8571eba163e6a6ffde49a0e3c6f60b0ff0f
Author: xiaoyu <[email protected]>
AuthorDate: Wed Nov 24 10:52:10 2021 +0800
[new: feature] register shenyu instance by zookeeper (#2437)
* [new: feature] register shenyu instance by zookeeper
* fix checkstyle
* fix checkstyle
---
shenyu-bootstrap/pom.xml | 8 +
.../src/main/resources/application-local.yml | 5 +
.../apache/shenyu/common/config/ShenyuConfig.java | 127 ++++++++++++
shenyu-register-center/pom.xml | 1 +
.../register/common/dto/InstanceRegisterDTO.java | 224 +++++++++++++++++++++
.../common/path/RegisterPathConstants.java | 18 +-
.../{ => shenyu-register-instance}/pom.xml | 18 +-
.../shenyu-register-instance-api}/pom.xml | 36 ++--
.../api/ShenyuInstanceRegisterRepository.java | 50 +++++
.../shenyu-register-instance-core}/pom.xml | 29 ++-
.../ShenyuInstanceRegisterRepositoryFactory.java | 47 +++++
.../shenyu-register-instance-zookeeper}/pom.xml | 39 ++--
.../ZookeeperInstanceRegisterRepository.java | 105 ++++++++++
...r.instance.api.ShenyuInstanceRegisterRepository | 17 ++
shenyu-spring-boot-starter/pom.xml | 1 +
.../shenyu-spring-boot-starter-instance/pom.xml | 56 ++++++
.../starter/instance/InstanceRegisterListener.java | 87 ++++++++
.../instance/ShenyuInstanceConfiguration.java | 42 ++++
.../src/main/resources/META-INF/spring.factories | 3 +
.../src/main/resources/META-INF/spring.provides | 1 +
20 files changed, 855 insertions(+), 59 deletions(-)
diff --git a/shenyu-bootstrap/pom.xml b/shenyu-bootstrap/pom.xml
index 9dbb81a..16174a0 100644
--- a/shenyu-bootstrap/pom.xml
+++ b/shenyu-bootstrap/pom.xml
@@ -409,6 +409,14 @@
<version>${project.version}</version>
</dependency>
<!--shenyu param mapping end-->
+
+ <!--shenyu instance start-->
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-instance</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--shenyu instance end-->
</dependencies>
<profiles>
diff --git a/shenyu-bootstrap/src/main/resources/application-local.yml
b/shenyu-bootstrap/src/main/resources/application-local.yml
index 0ee69b7..00cef3c 100644
--- a/shenyu-bootstrap/src/main/resources/application-local.yml
+++ b/shenyu-bootstrap/src/main/resources/application-local.yml
@@ -47,6 +47,11 @@ management:
enabled: false
shenyu:
+ instance:
+ enabled: false
+ registerType: zookeeper #etcd #consul
+ serverLists: localhost:2181 #http://localhost:2379 #localhost:8848
+ props:
cross:
enabled: true
allowedHeaders:
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
index ddb56ee..981c7d1 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
@@ -22,6 +22,7 @@ import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -45,6 +46,26 @@ public class ShenyuConfig {
private CrossFilterConfig cross = new CrossFilterConfig();
+ private InstanceConfig instance = new InstanceConfig();
+
+ /**
+ * Gets instance.
+ *
+ * @return the instance
+ */
+ public InstanceConfig getInstance() {
+ return instance;
+ }
+
+ /**
+ * Sets instance.
+ *
+ * @param instance the instance
+ */
+ public void setInstance(final InstanceConfig instance) {
+ this.instance = instance;
+ }
+
/**
* Gets switch config.
*
@@ -793,4 +814,110 @@ public class ShenyuConfig {
this.allowCredentials = allowCredentials;
}
}
+
+ /**
+ * The type Instance config.
+ */
+ public static class InstanceConfig {
+
+ private Boolean enabled = false;
+
+ private String registerType;
+
+ private String serverLists;
+
+ private Properties props = new Properties();
+
+ /**
+ * Instantiates a new Instance config.
+ */
+ public InstanceConfig() {
+
+ }
+
+ /**
+ * Instantiates a new Instance config.
+ *
+ * @param registerType the register type
+ * @param serverLists the server lists
+ * @param props the props
+ */
+ public InstanceConfig(final String registerType, final String
serverLists, final Properties props) {
+ this.registerType = registerType;
+ this.serverLists = serverLists;
+ this.props = props;
+ }
+
+ /**
+ * Gets enabled.
+ *
+ * @return the enabled
+ */
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Sets enabled.
+ *
+ * @param enabled the enabled
+ */
+ public void setEnabled(final Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ /**
+ * getRegisterType.
+ *
+ * @return String register type
+ */
+ public String getRegisterType() {
+ return registerType;
+ }
+
+ /**
+ * setRegisterType.
+ *
+ * @param registerType registerType
+ */
+ public void setRegisterType(final String registerType) {
+ this.registerType = registerType;
+ }
+
+ /**
+ * getServerLists.
+ *
+ * @return String server lists
+ */
+ public String getServerLists() {
+ return serverLists;
+ }
+
+ /**
+ * setServerLists.
+ *
+ * @param serverLists serverLists
+ */
+ public void setServerLists(final String serverLists) {
+ this.serverLists = serverLists;
+ }
+
+ /**
+ * getProps.
+ *
+ * @return String props
+ */
+ public Properties getProps() {
+ return props;
+ }
+
+ /**
+ * setProps.
+ *
+ * @param props props
+ */
+ public void setProps(final Properties props) {
+ this.props = props;
+ }
+ }
}
diff --git a/shenyu-register-center/pom.xml b/shenyu-register-center/pom.xml
index cbffeac..911c9f5 100644
--- a/shenyu-register-center/pom.xml
+++ b/shenyu-register-center/pom.xml
@@ -30,6 +30,7 @@
<module>shenyu-register-common</module>
<module>shenyu-register-client</module>
<module>shenyu-register-server</module>
+ <module>shenyu-register-instance</module>
</modules>
</project>
\ No newline at end of file
diff --git
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/InstanceRegisterDTO.java
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/InstanceRegisterDTO.java
new file mode 100644
index 0000000..3920483
--- /dev/null
+++
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/InstanceRegisterDTO.java
@@ -0,0 +1,224 @@
+/*
+ * 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.shenyu.register.common.dto;
+
+import java.util.Objects;
+
+/**
+ * The type Instance register dto.
+ */
+public class InstanceRegisterDTO {
+
+ private String appName;
+
+ private String host;
+
+ private Integer port;
+
+ /**
+ * Instantiates a new Instance register dto.
+ *
+ * @param appName the app name
+ * @param host the host
+ * @param port the port
+ */
+ public InstanceRegisterDTO(final String appName, final String host, final
Integer port) {
+ this.appName = appName;
+ this.host = host;
+ this.port = port;
+ }
+
+ /**
+ * Instantiates a new Instance register dto.
+ */
+ public InstanceRegisterDTO() {
+ }
+
+ private InstanceRegisterDTO(final Builder builder) {
+ appName = builder.appName;
+ host = builder.host;
+ port = builder.port;
+ }
+
+ /**
+ * Trans form uri register dto.
+ *
+ * @param metaDataRegisterDTO the meta data register dto
+ * @return the uri register dto
+ */
+ public static InstanceRegisterDTO transForm(final MetaDataRegisterDTO
metaDataRegisterDTO) {
+ return InstanceRegisterDTO.builder()
+ .appName(metaDataRegisterDTO.getAppName())
+ .host(metaDataRegisterDTO.getHost())
+ .port(metaDataRegisterDTO.getPort()).build();
+ }
+
+ /**
+ * return builder.
+ *
+ * @return Builder builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * getAppName.
+ *
+ * @return String app name
+ */
+ public String getAppName() {
+ return appName;
+ }
+
+ /**
+ * setAppName.
+ *
+ * @param appName appName
+ */
+ public void setAppName(final String appName) {
+ this.appName = appName;
+ }
+
+ /**
+ * getHost.
+ *
+ * @return String host
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * setHost.
+ *
+ * @param host host
+ */
+ public void setHost(final String host) {
+ this.host = host;
+ }
+
+ /**
+ * getPort.
+ *
+ * @return String port
+ */
+ public Integer getPort() {
+ return port;
+ }
+
+ /**
+ * setPort.
+ *
+ * @param port port
+ */
+ public void setPort(final Integer port) {
+ this.port = port;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return Boolean.TRUE;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return Boolean.FALSE;
+ }
+
+ InstanceRegisterDTO that = (InstanceRegisterDTO) o;
+ return Objects.equals(getAppName(), that.getAppName())
+ && Objects.equals(getHost(), that.getHost())
+ && Objects.equals(getPort(), that.getPort());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getAppName(), getHost(), getPort());
+ }
+
+ @Override
+ public String toString() {
+ return "URIRegisterDTO{"
+ + "appName='"
+ + appName
+ + ", host='"
+ + host
+ + ", port="
+ + port
+ + '}';
+ }
+
+ /**
+ * The type Builder.
+ */
+ public static final class Builder {
+
+ private String appName;
+
+ private String host;
+
+ private Integer port;
+
+ private Builder() {
+ }
+
+ /**
+ * appName.
+ *
+ * @param appName appName
+ * @return Builder builder
+ */
+ public Builder appName(final String appName) {
+ this.appName = appName;
+ return this;
+ }
+
+ /**
+ * host.
+ *
+ * @param host host
+ * @return Builder builder
+ */
+ public Builder host(final String host) {
+ this.host = host;
+ return this;
+ }
+
+ /**
+ * port.
+ *
+ * @param port port
+ * @return Builder builder
+ */
+ public Builder port(final Integer port) {
+ this.port = port;
+ return this;
+ }
+
+ /**
+ * build.
+ *
+ * @return Builder instance register dto
+ */
+ public InstanceRegisterDTO build() {
+ return new InstanceRegisterDTO(this);
+ }
+ }
+}
diff --git
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/path/RegisterPathConstants.java
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/path/RegisterPathConstants.java
index 79cf881..ef269bd 100644
---
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/path/RegisterPathConstants.java
+++
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/path/RegisterPathConstants.java
@@ -80,7 +80,17 @@ public class RegisterPathConstants {
public static String buildURIParentPath(final String rpcType, final String
contextPath) {
return String.join(SEPARATOR, ROOT_PATH, "uri", rpcType, contextPath);
}
-
+
+ /**
+ * Build instance parent path string.
+ * build child path of "/shenyu/register/instance/
+ *
+ * @return the string
+ */
+ public static String buildInstanceParentPath() {
+ return String.join(SEPARATOR, ROOT_PATH, "instance");
+ }
+
/**
* Build real node string.
*
@@ -91,7 +101,7 @@ public class RegisterPathConstants {
public static String buildRealNode(final String nodePath, final String
nodeName) {
return String.join(SEPARATOR, nodePath, nodeName);
}
-
+
/**
* Build nacos instance service path string.
* build child path of "shenyu.register.service.{rpcType}".
@@ -103,7 +113,7 @@ public class RegisterPathConstants {
return String.join(SEPARATOR, ROOT_PATH, "service", rpcType)
.replace("/", DOT_SEPARATOR).substring(1);
}
-
+
/**
* Build nacos config service path string.
* build child path of "shenyu.register.service.{rpcType}.{contextPath}".
@@ -121,7 +131,7 @@ public class RegisterPathConstants {
}
return serviceConfigPathAfterSubstring;
}
-
+
/**
* Build node name by DOT_SEPARATOR.
*
diff --git a/shenyu-register-center/pom.xml
b/shenyu-register-center/shenyu-register-instance/pom.xml
similarity index 67%
copy from shenyu-register-center/pom.xml
copy to shenyu-register-center/shenyu-register-instance/pom.xml
index cbffeac..ed95075 100644
--- a/shenyu-register-center/pom.xml
+++ b/shenyu-register-center/shenyu-register-instance/pom.xml
@@ -16,20 +16,22 @@
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.shenyu</groupId>
- <artifactId>shenyu</artifactId>
+ <artifactId>shenyu-register-center</artifactId>
<version>2.4.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>shenyu-register-center</artifactId>
+ <artifactId>shenyu-register-instance</artifactId>
<packaging>pom</packaging>
-
+
<modules>
- <module>shenyu-register-common</module>
- <module>shenyu-register-client</module>
- <module>shenyu-register-server</module>
+ <module>shenyu-register-instance-api</module>
+ <module>shenyu-register-instance-core</module>
+ <module>shenyu-register-instance-zookeeper</module>
</modules>
-
+
</project>
\ No newline at end of file
diff --git a/shenyu-spring-boot-starter/pom.xml
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/pom.xml
similarity index 55%
copy from shenyu-spring-boot-starter/pom.xml
copy to
shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/pom.xml
index 75c1713..ade9aaf 100644
--- a/shenyu-spring-boot-starter/pom.xml
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/pom.xml
@@ -16,29 +16,33 @@
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.shenyu</groupId>
- <artifactId>shenyu</artifactId>
+ <artifactId>shenyu-register-instance</artifactId>
<version>2.4.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>shenyu-spring-boot-starter</artifactId>
- <packaging>pom</packaging>
-
- <modules>
- <module>shenyu-spring-boot-starter-gateway</module>
- <module>shenyu-spring-boot-starter-plugin</module>
- <module>shenyu-spring-boot-starter-sync-data-center</module>
- <module>shenyu-spring-boot-starter-client</module>
- </modules>
+ <artifactId>shenyu-register-instance-api</artifactId>
<dependencies>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-register-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-common</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
-
-</project>
+
+</project>
\ No newline at end of file
diff --git
a/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/src/main/java/org/apache/shenyu/register/instance/api/ShenyuInstanceRegisterRepository.java
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/src/main/java/org/apache/shenyu/register/instance/api/ShenyuInstanceRegisterRepository.java
new file mode 100644
index 0000000..785badd
--- /dev/null
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-api/src/main/java/org/apache/shenyu/register/instance/api/ShenyuInstanceRegisterRepository.java
@@ -0,0 +1,50 @@
+/*
+ * 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.shenyu.register.instance.api;
+
+import org.apache.shenyu.common.config.ShenyuConfig.InstanceConfig;
+import org.apache.shenyu.register.common.dto.InstanceRegisterDTO;
+import org.apache.shenyu.spi.SPI;
+
+/**
+ * Shenyu instance register repository.
+ */
+@SPI
+public interface ShenyuInstanceRegisterRepository {
+
+ /**
+ * Init.
+ *
+ * @param config the config
+ */
+ default void init(InstanceConfig config) {
+ }
+
+ /**
+ * Persist instance.
+ *
+ * @param instance instance
+ */
+ void persistInstance(InstanceRegisterDTO instance);
+
+ /**
+ * Close.
+ */
+ default void close() {
+ }
+}
diff --git a/shenyu-spring-boot-starter/pom.xml
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/pom.xml
similarity index 58%
copy from shenyu-spring-boot-starter/pom.xml
copy to
shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/pom.xml
index 75c1713..a0793a7 100644
--- a/shenyu-spring-boot-starter/pom.xml
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/pom.xml
@@ -16,29 +16,28 @@
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.shenyu</groupId>
- <artifactId>shenyu</artifactId>
+ <artifactId>shenyu-register-instance</artifactId>
<version>2.4.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>shenyu-spring-boot-starter</artifactId>
- <packaging>pom</packaging>
-
- <modules>
- <module>shenyu-spring-boot-starter-gateway</module>
- <module>shenyu-spring-boot-starter-plugin</module>
- <module>shenyu-spring-boot-starter-sync-data-center</module>
- <module>shenyu-spring-boot-starter-client</module>
- </modules>
+ <artifactId>shenyu-register-instance-core</artifactId>
<dependencies>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-register-instance-zookeeper</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
-</project>
+</project>
\ No newline at end of file
diff --git
a/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/src/main/java/org/apache/shenyu/register/instance/core/ShenyuInstanceRegisterRepositoryFactory.java
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/src/main/java/org/apache/shenyu/register/instance/core/ShenyuInstanceRegisterRepositoryFactory.java
new file mode 100644
index 0000000..9c5a961
--- /dev/null
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-core/src/main/java/org/apache/shenyu/register/instance/core/ShenyuInstanceRegisterRepositoryFactory.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.shenyu.register.instance.core;
+
+import
org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository;
+import org.apache.shenyu.spi.ExtensionLoader;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * The type Shenyu instance register repository factory.
+ */
+public final class ShenyuInstanceRegisterRepositoryFactory {
+
+ private static final Map<String, ShenyuInstanceRegisterRepository>
REPOSITORY_MAP = new ConcurrentHashMap<>();
+
+ /**
+ * New instance shenyu instance register repository.
+ *
+ * @param registerType the config
+ * @return the shenyu instance register repository
+ */
+ public static ShenyuInstanceRegisterRepository newInstance(final String
registerType) {
+ if (!REPOSITORY_MAP.containsKey(registerType)) {
+ ShenyuInstanceRegisterRepository result =
ExtensionLoader.getExtensionLoader(ShenyuInstanceRegisterRepository.class).getJoin(registerType);
+ REPOSITORY_MAP.put(registerType, result);
+ return result;
+ }
+ return REPOSITORY_MAP.get(registerType);
+ }
+}
diff --git a/shenyu-spring-boot-starter/pom.xml
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/pom.xml
similarity index 51%
copy from shenyu-spring-boot-starter/pom.xml
copy to
shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/pom.xml
index 75c1713..337212c 100644
--- a/shenyu-spring-boot-starter/pom.xml
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/pom.xml
@@ -16,29 +16,36 @@
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.shenyu</groupId>
- <artifactId>shenyu</artifactId>
+ <artifactId>shenyu-register-instance</artifactId>
<version>2.4.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>shenyu-spring-boot-starter</artifactId>
- <packaging>pom</packaging>
-
- <modules>
- <module>shenyu-spring-boot-starter-gateway</module>
- <module>shenyu-spring-boot-starter-plugin</module>
- <module>shenyu-spring-boot-starter-sync-data-center</module>
- <module>shenyu-spring-boot-starter-client</module>
- </modules>
+ <artifactId>shenyu-register-instance-zookeeper</artifactId>
<dependencies>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-register-instance-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.101tec</groupId>
+ <artifactId>zkclient</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
-
-</project>
+</project>
\ No newline at end of file
diff --git
a/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/java/org/apache/shenyu/register/instance/zookeeper/ZookeeperInstanceRegisterRepository.java
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/java/org/apache/shenyu/register/instance/zookeeper/ZookeeperInstanceRegisterRepository.java
new file mode 100644
index 0000000..94d34d7
--- /dev/null
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/java/org/apache/shenyu/register/instance/zookeeper/ZookeeperInstanceRegisterRepository.java
@@ -0,0 +1,105 @@
+/*
+ * 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.shenyu.register.instance.zookeeper;
+
+import org.I0Itec.zkclient.IZkStateListener;
+import org.I0Itec.zkclient.ZkClient;
+import org.apache.shenyu.common.config.ShenyuConfig.InstanceConfig;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.register.common.dto.InstanceRegisterDTO;
+import org.apache.shenyu.register.common.path.RegisterPathConstants;
+import
org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository;
+import org.apache.shenyu.spi.Join;
+import org.apache.zookeeper.Watcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * The type Zookeeper instance register repository.
+ */
+@Join
+public class ZookeeperInstanceRegisterRepository implements
ShenyuInstanceRegisterRepository {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(ZookeeperInstanceRegisterRepository.class);
+
+ private ZkClient zkClient;
+
+ private final Map<String, String> nodeDataMap = new HashMap<>();
+
+ @Override
+ public void init(final InstanceConfig config) {
+ Properties props = config.getProps();
+ int sessionTimeout =
Integer.parseInt(props.getProperty("sessionTimeout", "3000"));
+ int connectionTimeout =
Integer.parseInt(props.getProperty("connectionTimeout", "3000"));
+ this.zkClient = new ZkClient(config.getServerLists(), sessionTimeout,
connectionTimeout);
+ this.zkClient.subscribeStateChanges(new ZkStateListener());
+ }
+
+ @Override
+ public void persistInstance(final InstanceRegisterDTO instance) {
+ String uriNodeName = buildURINodeName(instance);
+ String instancePath = RegisterPathConstants.buildInstanceParentPath();
+ if (!zkClient.exists(instancePath)) {
+ zkClient.createPersistent(instancePath, true);
+ }
+ String realNode = RegisterPathConstants.buildRealNode(instancePath,
uriNodeName);
+ if (!zkClient.exists(realNode)) {
+ String nodeData = GsonUtils.getInstance().toJson(instance);
+ nodeDataMap.put(realNode, nodeData);
+ zkClient.createEphemeral(realNode, nodeData);
+ }
+ }
+
+ @Override
+ public void close() {
+ zkClient.close();
+ }
+
+ private String buildURINodeName(final InstanceRegisterDTO instance) {
+ String host = instance.getHost();
+ int port = instance.getPort();
+ return String.join(Constants.COLONS, host, Integer.toString(port));
+ }
+
+ private class ZkStateListener implements IZkStateListener {
+ @Override
+ public void handleStateChanged(final Watcher.Event.KeeperState
keeperState) {
+ if (Watcher.Event.KeeperState.SyncConnected.equals(keeperState)) {
+ nodeDataMap.forEach((k, v) -> {
+ if (!zkClient.exists(k)) {
+ zkClient.createEphemeral(k, v);
+ LOGGER.info("zookeeper client register success: {}",
v);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void handleNewSession() {
+ }
+
+ @Override
+ public void handleSessionEstablishmentError(final Throwable throwable)
{
+ }
+ }
+}
diff --git
a/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/resources/META-INF/shenyu/org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/resources/META-INF/shenyu/org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository
new file mode 100644
index 0000000..92fbfb1
--- /dev/null
+++
b/shenyu-register-center/shenyu-register-instance/shenyu-register-instance-zookeeper/src/main/resources/META-INF/shenyu/org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository
@@ -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.
+
+zookeeper=org.apache.shenyu.register.instance.zookeeper.ZookeeperInstanceRegisterRepository
diff --git a/shenyu-spring-boot-starter/pom.xml
b/shenyu-spring-boot-starter/pom.xml
index 75c1713..9a1ec86 100644
--- a/shenyu-spring-boot-starter/pom.xml
+++ b/shenyu-spring-boot-starter/pom.xml
@@ -31,6 +31,7 @@
<module>shenyu-spring-boot-starter-plugin</module>
<module>shenyu-spring-boot-starter-sync-data-center</module>
<module>shenyu-spring-boot-starter-client</module>
+ <module>shenyu-spring-boot-starter-instance</module>
</modules>
<dependencies>
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/pom.xml
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/pom.xml
new file mode 100644
index 0000000..d1e844a
--- /dev/null
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter</artifactId>
+ <version>2.4.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shenyu-spring-boot-starter-instance</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-register-instance-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-webflux</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/InstanceRegisterListener.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/InstanceRegisterListener.java
new file mode 100644
index 0000000..30bffaa
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/InstanceRegisterListener.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.shenyu.springboot.starter.instance;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.common.config.ShenyuConfig.InstanceConfig;
+import org.apache.shenyu.common.exception.ShenyuException;
+import org.apache.shenyu.common.utils.IpUtils;
+import org.apache.shenyu.register.common.dto.InstanceRegisterDTO;
+import
org.apache.shenyu.register.instance.api.ShenyuInstanceRegisterRepository;
+import
org.apache.shenyu.register.instance.core.ShenyuInstanceRegisterRepositoryFactory;
+import org.springframework.boot.web.context.WebServerInitializedEvent;
+import org.springframework.context.ApplicationListener;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * The type Instance register listener.
+ */
+public class InstanceRegisterListener implements
ApplicationListener<WebServerInitializedEvent> {
+
+ private final AtomicBoolean registered = new AtomicBoolean(false);
+
+ private final String host;
+
+ private final String appName;
+
+ private final Properties props;
+
+ private final ShenyuInstanceRegisterRepository repository;
+
+ /**
+ * Instantiates a new Instance register listener.
+ *
+ * @param config the config
+ */
+ public InstanceRegisterListener(final InstanceConfig config) {
+ String registerType = config.getRegisterType();
+ String serverLists = config.getServerLists();
+ if (StringUtils.isBlank(registerType) ||
StringUtils.isBlank(serverLists)) {
+ throw new ShenyuException("please config the registerType and
serverList");
+ }
+ repository =
ShenyuInstanceRegisterRepositoryFactory.newInstance(config.getRegisterType());
+ repository.init(config);
+ this.props = config.getProps();
+ String name = props.getProperty("name");
+ this.appName = StringUtils.isBlank(name) ? "shenyu-gateway" : name;
+ String host = props.getProperty("host");
+ this.host = StringUtils.isBlank(host) ? IpUtils.getHost() : host;
+ }
+
+ @Override
+ public void onApplicationEvent(final WebServerInitializedEvent event) {
+ if (!registered.compareAndSet(false, true)) {
+ return;
+ }
+ String configPort = props.getProperty("port");
+ int port = StringUtils.isBlank(configPort) ?
event.getWebServer().getPort() : Integer.parseInt(configPort);
+ InstanceRegisterDTO registerDTO = buildInstanceRegisterDTO(port);
+ repository.persistInstance(registerDTO);
+ }
+
+ private InstanceRegisterDTO buildInstanceRegisterDTO(final int port) {
+ String host = IpUtils.isCompleteHost(this.host) ? this.host :
IpUtils.getHost(this.host);
+ return InstanceRegisterDTO.builder()
+ .appName(appName)
+ .host(host)
+ .port(port)
+ .build();
+ }
+}
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/ShenyuInstanceConfiguration.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/ShenyuInstanceConfiguration.java
new file mode 100644
index 0000000..0ab5853
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/java/org/apache/shenyu/springboot/starter/instance/ShenyuInstanceConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * 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.shenyu.springboot.starter.instance;
+
+import org.apache.shenyu.common.config.ShenyuConfig;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * The type Shenyu instance configuration.
+ */
+@Configuration
+public class ShenyuInstanceConfiguration {
+
+ /**
+ * Instance register listener.
+ *
+ * @param config the config
+ * @return the instance register listener
+ */
+ @Bean
+ @ConditionalOnProperty(name = "shenyu.instance.enabled", havingValue =
"true")
+ public InstanceRegisterListener instanceRegisterListener(final
ShenyuConfig config) {
+ return new InstanceRegisterListener(config.getInstance());
+ }
+}
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.factories
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..4b4777c
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.shenyu.springboot.starter.instance.ShenyuInstanceConfiguration
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.provides
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000..23291ec
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-instance/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: shenyu-spring-boot-starter-instance
\ No newline at end of file