diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/WebIpAndPortInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/WebIpAndPortInfo.java new file mode 100644 index 00000000..a2dce703 --- /dev/null +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/WebIpAndPortInfo.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 cn.hippo4j.common.model; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * web ip and port info + */ +@Data +@Slf4j +public class WebIpAndPortInfo { + + protected static final String ALL = "*"; + protected static final String SPOT = "\\."; + protected static final String COLON = ":"; + private String ip; + private String port; + private String[] ipSegment; + + public WebIpAndPortInfo(String ip, String port) { + this.ip = ip; + this.port = port; + this.ipSegment = ip.split(SPOT); + } + + public static WebIpAndPortInfo build(String node) { + if (ALL.equals(node)) { + return new WebIpAndPortInfo(ALL, ALL); + } + String[] ipPort = node.split(COLON); + if (ipPort.length != 2) { + log.error("The IP address format is error : {}", node); + return null; + } + return new WebIpAndPortInfo(ipPort[0], ipPort[1]); + } + + /** + * check + * + * @param appIpSegment application ip segment + * @param port application port + */ + public boolean check(String[] appIpSegment, String port) { + return checkPort(port) && checkIp(appIpSegment); + } + + /** + * check ip + * + * @param appIpSegment application ip segment + */ + protected boolean checkIp(String[] appIpSegment) { + if (ALL.equals(this.ip)) { + return true; + } + boolean flag = true; + for (int i = 0; i < ipSegment.length && flag; i++) { + String propIp = ipSegment[i]; + String appIp = appIpSegment[i]; + flag = contrastSegment(appIp, propIp); + } + return flag; + } + + /** + * check port + * + * @param port application port + */ + protected boolean checkPort(String port) { + return contrastSegment(port, this.port); + } + + /** + * Check whether the strings are the same + * + * @param appIp appIp + * @param propIp propIp + */ + protected boolean contrastSegment(String appIp, String propIp) { + return ALL.equals(propIp) || appIp.equals(propIp); + } +} \ No newline at end of file diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java index a42793a5..5a8c9468 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/AbstractRefreshListener.java @@ -17,14 +17,14 @@ package cn.hippo4j.config.springboot.starter.refresher.event; +import cn.hippo4j.adapter.web.WebThreadPoolHandlerChoose; +import cn.hippo4j.adapter.web.WebThreadPoolService; import cn.hippo4j.common.config.ApplicationContextHolder; +import cn.hippo4j.common.model.WebIpAndPortInfo; import cn.hippo4j.common.toolkit.Assert; import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.core.toolkit.inet.InetUtils; -import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.context.event.EventListener; import java.util.Arrays; import java.util.Objects; @@ -36,33 +36,33 @@ import java.util.Objects; public abstract class AbstractRefreshListener implements RefreshListener { protected static final String ALL = "*"; - - protected static final String SPOT = "\\."; - protected static final String SEPARATOR = ","; - protected static final String COLON = ":"; - - /** - * application ip - */ - protected final String[] ipSegment; - /** - * application post + * application ip and application post */ - protected String port; + protected static volatile WebIpAndPortInfo webIpAndPort; + + protected void initIpAndPort() { + if (webIpAndPort == null) { + synchronized (AbstractRefreshListener.class) { + if (webIpAndPort == null) { + webIpAndPort = getWebIpAndPortInfo(); + } + } + } + } - AbstractRefreshListener() { + private WebIpAndPortInfo getWebIpAndPortInfo() { InetUtils inetUtils = ApplicationContextHolder.getBean(InetUtils.class); InetUtils.HostInfo loopBackHostInfo = inetUtils.findFirstNonLoopBackHostInfo(); Assert.notNull(loopBackHostInfo, "Unable to get the application IP address"); - ipSegment = loopBackHostInfo.getIpAddress().split(SPOT); - } - - @EventListener(WebServerInitializedEvent.class) - public void webServerInitializedListener(WebServerInitializedEvent event) { - port = String.valueOf(event.getWebServer().getPort()); + String ip = loopBackHostInfo.getIpAddress(); + WebThreadPoolHandlerChoose webThreadPoolHandlerChoose = ApplicationContextHolder.getBean(WebThreadPoolHandlerChoose.class); + WebThreadPoolService webThreadPoolService = webThreadPoolHandlerChoose.choose(); + // when get the port at startup, can get the message: "port xxx was already in use" or use two ports + String port = String.valueOf(webThreadPoolService.getWebServer().getPort()); + return new WebIpAndPortInfo(ip, port); } /** @@ -81,6 +81,9 @@ public abstract class AbstractRefreshListener implements RefreshListener implements RefreshListener i.check(ipSegment, port)); + .anyMatch(i -> i.check(webIpAndPort.getIpSegment(), webIpAndPort.getPort())); } /** @@ -103,79 +106,4 @@ public abstract class AbstractRefreshListener implements RefreshListener { if (Objects.equals(val.mark(), each.getMark())) { val.updateThreadPool(BeanUtil.toBean(each, ThreadPoolAdapterParameter.class));