This is an automated email from the ASF dual-hosted git repository.
xiaoyu 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 1405a9d [ISSUE #2860] spring cloud client auto set port (#2861)
1405a9d is described below
commit 1405a9d5f500a7bf358e62935a108f5105d063cb
Author: dragon-zhang <[email protected]>
AuthorDate: Fri Feb 11 19:52:11 2022 +0800
[ISSUE #2860] spring cloud client auto set port (#2861)
* spring cloud client auto set port
* add note
* fix code style
* compatible with springboot 1.x
---
.../springcloud/init/ContextRegisterListener.java | 80 +++++++++++++++++-----
.../src/main/resources/application.yml | 2 +-
2 files changed, 63 insertions(+), 19 deletions(-)
diff --git
a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/ContextRegisterListener.java
b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/ContextRegisterListener.java
index 9958d47..ebd993c 100644
---
a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/ContextRegisterListener.java
+++
b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/ContextRegisterListener.java
@@ -22,41 +22,50 @@ import
org.apache.shenyu.client.core.constant.ShenyuClientConstants;
import
org.apache.shenyu.client.core.disruptor.ShenyuClientRegisterEventPublisher;
import
org.apache.shenyu.client.core.exception.ShenyuClientIllegalArgumentException;
import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.common.exception.ShenyuException;
import org.apache.shenyu.common.utils.IpUtils;
import org.apache.shenyu.register.common.config.PropertiesConfig;
import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
import org.apache.shenyu.register.common.dto.URIRegisterDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.Environment;
import org.springframework.lang.NonNull;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* The type Context register listener.
*/
-public class ContextRegisterListener implements
ApplicationListener<ContextRefreshedEvent> {
-
+public class ContextRegisterListener implements
ApplicationListener<ContextRefreshedEvent>, BeanFactoryAware {
+
private static final Logger LOG =
LoggerFactory.getLogger(ContextRegisterListener.class);
-
+
private final ShenyuClientRegisterEventPublisher publisher =
ShenyuClientRegisterEventPublisher.getInstance();
-
+
private final AtomicBoolean registered = new AtomicBoolean(false);
-
+
private final Boolean isFull;
-
+
private final String host;
-
+
private final String contextPath;
-
+
private final String appName;
-
+
private final Integer port;
-
+
+ private BeanFactory beanFactory;
+
/**
* Instantiates a new Context register listener.
*
@@ -74,23 +83,59 @@ public class ContextRegisterListener implements
ApplicationListener<ContextRefre
throw new ShenyuClientIllegalArgumentException(errorMsg);
}
}
- port = Integer.parseInt(props.getProperty(ShenyuClientConstants.PORT));
+ this.port =
Integer.parseInt(Optional.ofNullable(props.getProperty(ShenyuClientConstants.PORT)).orElseGet(()
-> "-1"));
this.appName = env.getProperty("spring.application.name");
this.host = props.getProperty(ShenyuClientConstants.HOST);
}
-
+
@Override
- public void onApplicationEvent(@NonNull final ContextRefreshedEvent
contextRefreshedEvent) {
+ public void setBeanFactory(final BeanFactory beanFactory) throws
BeansException {
+ this.beanFactory = beanFactory;
+ }
+
+ @Override
+ public void onApplicationEvent(@NonNull final ContextRefreshedEvent
webServerInitializedEvent) {
if (!registered.compareAndSet(false, true)) {
return;
}
if (Boolean.TRUE.equals(isFull)) {
publisher.publishEvent(buildMetaDataDTO());
}
- publisher.publishEvent(buildUriRegisterDTO());
+ final int mergedPort = port <= 0 ? findPort() : port;
+ publisher.publishEvent(buildUriRegisterDTO(mergedPort));
+ }
+
+ /**
+ * Note: springboot 1.x version has been made compatible.
+ * Note: In this way, no matter what container is actually used,
+ * you can get the port that is actually started in the end.
+ *
+ * @see
org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer#getPort()
+ * @see
org.springframework.boot.web.server.AbstractConfigurableWebServerFactory#getPort()
+ */
+ @SuppressWarnings("all")
+ private int findPort() {
+ try {
+ //works fine for springboot 2.x
+ return
getPort("org.springframework.boot.web.server.AbstractConfigurableWebServerFactory");
+ } catch (Exception e) {
+ try {
+ //works fine for springboot 1.x
+ return
getPort("org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer");
+ } catch (Exception exception) {
+ throw new ShenyuException("can not find port automatically !
try to config ${shenyu.client.springCloud.props.port}");
+ }
+ }
+ }
+
+ private int getPort(final String className) throws ClassNotFoundException,
NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ final Class<?> clazz = Class.forName(className);
+ final Method method = clazz.getMethod("getPort");
+ final Object bean = beanFactory.getBean(clazz);
+ return (int) method.invoke(bean);
}
-
- private URIRegisterDTO buildUriRegisterDTO() {
+
+ private URIRegisterDTO buildUriRegisterDTO(final int port) {
return URIRegisterDTO.builder()
.contextPath(this.contextPath)
.appName(appName)
@@ -98,9 +143,8 @@ public class ContextRegisterListener implements
ApplicationListener<ContextRefre
.port(port)
.rpcType(RpcTypeEnum.SPRING_CLOUD.getName())
.build();
-
}
-
+
private MetaDataRegisterDTO buildMetaDataDTO() {
return MetaDataRegisterDTO.builder()
.contextPath(contextPath)
diff --git
a/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
b/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
index 46e6892..7ed8571 100644
---
a/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
+++
b/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
@@ -47,7 +47,7 @@ shenyu:
springCloud:
props:
contextPath: /springcloud
- port: 8884
+# port: 8884
logging:
level: