From 0268eb00e0d66abd4a8cc6df80ca685bdcef45b1 Mon Sep 17 00:00:00 2001 From: hongqiaowei Date: Thu, 23 Dec 2021 16:05:27 +0800 Subject: [PATCH] Multi service registry center --- README.en-us.md | 3 +- README.md | 3 +- fizz-bootstrap/pom.xml | 15 +- .../java/we/FizzBootstrapApplication.java | 3 +- .../src/main/resources/application.yml | 29 ++-- .../src/main/resources/log4j2-spring.xml | 4 +- fizz-common/src/main/java/we/util/Consts.java | 1 + .../src/main/java/we/util/FileUtils.java | 34 ++++ .../main/java/we/util/PropertiesUtils.java | 70 ++++++++ .../src/main/java/we/util/YmlUtils.java | 34 ++++ fizz-core/pom.xml | 4 + .../DedicatedLineServiceRegistration.java | 131 ++++++++------- .../main/java/we/filter/CallbackFilter.java | 13 +- .../src/main/java/we/filter/RouteFilter.java | 6 +- .../main/java/we/plugin/auth/ApiConfig.java | 39 +++-- .../main/java/we/plugin/auth/Receiver.java | 18 +- .../main/java/we/proxy/CallbackService.java | 8 +- .../src/main/java/we/proxy/FizzWebClient.java | 50 ++++-- fizz-core/src/main/java/we/proxy/Route.java | 7 + .../main/java/we/proxy/ServiceInstance.java | 4 +- .../main/java/we/proxy/ServiceTypePath.java | 18 +- .../FizzServiceRegistration.java | 56 ++++++ .../we/service_registry/RegistryCenter.java | 119 +++++++++++++ .../RegistryCenterService.java | 147 ++++++++++++++++ .../eureka/FizzEurekaHelper.java | 106 ++++++++---- .../eureka/FizzEurekaProperties.java | 159 ------------------ .../eureka/FizzEurekaServiceRegistration.java | 116 +++++++++++-- .../nacos/FizzNacosHelper.java | 49 ++++-- .../nacos/FizzNacosProperties.java | 19 ++- .../nacos/FizzNacosServiceRegistration.java | 87 +++++++++- .../RegistryCenterServiceTests.java | 63 +++++++ .../src/test/java/we/util/YmlUtilsTest.java | 30 ++++ fizz-core/src/test/resources/eureka.yml | 10 ++ fizz-spring-boot-starter/pom.xml | 16 ++ pom.xml | 16 +- 35 files changed, 1126 insertions(+), 361 deletions(-) create mode 100644 fizz-common/src/main/java/we/util/FileUtils.java create mode 100644 fizz-common/src/main/java/we/util/PropertiesUtils.java create mode 100644 fizz-common/src/main/java/we/util/YmlUtils.java create mode 100644 fizz-core/src/main/java/we/service_registry/FizzServiceRegistration.java create mode 100644 fizz-core/src/main/java/we/service_registry/RegistryCenter.java create mode 100644 fizz-core/src/main/java/we/service_registry/RegistryCenterService.java delete mode 100644 fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaProperties.java create mode 100644 fizz-core/src/test/java/we/service_registry/RegistryCenterServiceTests.java create mode 100644 fizz-core/src/test/java/we/util/YmlUtilsTest.java create mode 100644 fizz-core/src/test/resources/eureka.yml diff --git a/README.en-us.md b/README.en-us.md index e4e486c..8b9b6d6 100644 --- a/README.en-us.md +++ b/README.en-us.md @@ -4,7 +4,7 @@ English | [简体中文](./README.md)

- Version + Version Documentation @@ -111,6 +111,7 @@ Starting from v1.3.0, the frontend and backend of the management backend are mer | v2.3.2 | v2.3.2 | | v2.3.3 | v2.3.3 | | v2.4.0 | v2.4.0 | +| v2.4.1 | v2.4.1 | Please download the corresponding management backend version according to the version of the community version diff --git a/README.md b/README.md index cf9ed5a..4d51e91 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- Version + Version Documentation @@ -113,6 +113,7 @@ API地址:http://demo.fizzgate.com/proxy/[服务名]/[API_Path] | v2.3.2 | v2.3.2 | | v2.3.3 | v2.3.3 | | v2.4.0 | v2.4.0 | +| v2.4.1 | v2.4.1 | 请根据社区版的版本下载对应的管理后台版本 diff --git a/fizz-bootstrap/pom.xml b/fizz-bootstrap/pom.xml index 559d934..dedc737 100644 --- a/fizz-bootstrap/pom.xml +++ b/fizz-bootstrap/pom.xml @@ -16,13 +16,13 @@ 1.8 - 5.2.18.RELEASE + 5.2.19.RELEASE Dragonfruit-SR3 Dysprosium-SR25 5.3.7.RELEASE - 4.1.70.Final - 4.4.14 - 2.14.1 + 4.1.72.Final + 4.4.15 + 2.17.0 1.7.32 3.12.0 1.18.22 @@ -37,6 +37,7 @@ 2.0.46.Final 2.2.9.RELEASE 1.7.1 + 1.30 @@ -99,6 +100,12 @@ resilience4j-reactor ${resilience4j.version} + + + io.netty + netty-tcnative-classes + ${netty-tcnative.version} + diff --git a/fizz-bootstrap/src/main/java/we/FizzBootstrapApplication.java b/fizz-bootstrap/src/main/java/we/FizzBootstrapApplication.java index ef0e335..e54ab0c 100644 --- a/fizz-bootstrap/src/main/java/we/FizzBootstrapApplication.java +++ b/fizz-bootstrap/src/main/java/we/FizzBootstrapApplication.java @@ -186,7 +186,8 @@ public class FizzBootstrapApplication { private static final Logger LOGGER = LoggerFactory.getLogger(FizzBootstrapApplication.class); public static void main(String[] args) { - System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); + System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); + System.setProperty("log4j2.formatMsgNoLookups", "true"); SpringApplication springApplication = new SpringApplication(FizzBootstrapApplication.class); springApplication.setApplicationContextClass(CustomReactiveWebServerApplicationContext.class); diff --git a/fizz-bootstrap/src/main/resources/application.yml b/fizz-bootstrap/src/main/resources/application.yml index d461f2e..1b2886f 100644 --- a/fizz-bootstrap/src/main/resources/application.yml +++ b/fizz-bootstrap/src/main/resources/application.yml @@ -20,7 +20,7 @@ eureka: enabled: false #use Eureka? (default:false) serviceUrl: # need replace - defaultZone: http://localhost:6600/eureka/ #please input the eureka client serviceUrl defaultZone (default:http://localhost:6600/eureka/) + defaultZone: http://6.6.6.6:6600/eureka/ #please input the eureka client serviceUrl defaultZone (default:http://localhost:6600/eureka/) instance: prefer-ip-address: true ################################################### Eureka config end ################################################### @@ -52,7 +52,7 @@ spring: aggregate: redis: # need replace - host: 6.6.6.6 #please input the redis host (default:localhost) + host: 1.1.1.1 #please input the redis host (default:localhost) # need replace port: 6379 #please input the redis port (default:6379) # need replace @@ -127,15 +127,22 @@ fizz: retry-count: 0 # default no retry retry-interval: 0 # default no retry interval crypto: true # if true, client will encrypt request body and decrypt response body -# service-registration: -# type: eureka # service registration type, can be eureka or nacos -# application: ax # register the name of this application to server -# port: 8601 # the port to be registered -# service-url: http://6.6.6.6:6600/eureka/ # server address -# type: nacos -# application: ax -# port: 8601 -# service-url: 6.6.6.6:8848 + service-registration: +# eureka: +# server-port: 8601 +# client: +# enabled: true +# serviceUrl: +# defaultZone: http://3.3.3.3:6600/eureka +# instance: +# appname: fizz-dedicated-line +# prefer-ip-address: true +# nacos: +# discovery: +# enabled: true +# service: fizz-dedicated-line +# port: 8601 +# server-addr: 2.2.2.2:8848 fizz-trace-id: header: X-Trace-Id diff --git a/fizz-bootstrap/src/main/resources/log4j2-spring.xml b/fizz-bootstrap/src/main/resources/log4j2-spring.xml index fdd5dce..b948186 100644 --- a/fizz-bootstrap/src/main/resources/log4j2-spring.xml +++ b/fizz-bootstrap/src/main/resources/log4j2-spring.xml @@ -7,10 +7,10 @@ - + - + diff --git a/fizz-common/src/main/java/we/util/Consts.java b/fizz-common/src/main/java/we/util/Consts.java index b6e05f0..e9a1852 100644 --- a/fizz-common/src/main/java/we/util/Consts.java +++ b/fizz-common/src/main/java/we/util/Consts.java @@ -27,6 +27,7 @@ public final class Consts { } public static final class S { + public static final String DEFAULT = "default"; public static final String TRUE = "true"; public static final String FALSE = "false"; public static final String TRUE1 = "1"; diff --git a/fizz-common/src/main/java/we/util/FileUtils.java b/fizz-common/src/main/java/we/util/FileUtils.java new file mode 100644 index 0000000..9a31fa1 --- /dev/null +++ b/fizz-common/src/main/java/we/util/FileUtils.java @@ -0,0 +1,34 @@ +package we.util; + +import java.io.File; +import java.util.Objects; + +/** + * @author hongqiaowei + */ + +public abstract class FileUtils { + + private FileUtils() { + } + + public static String getAppRootDir() { + return new File(Consts.S.EMPTY).getAbsolutePath(); + } + + public static String getAbsoluteDir(Class cls) { + return new File(Objects.requireNonNull(cls.getResource(Consts.S.EMPTY)).getPath()).getAbsolutePath(); + } + + public static String getAbsolutePath(Class cls) { + String absoluteDir = getAbsoluteDir(cls); + return absoluteDir + File.separatorChar + cls.getSimpleName() + ".class"; + } + + /** + * @param file relative to src or resource dir, eg: we/util/FileUtils.class and application.yml + */ + public static String getAbsolutePath(String file) { + return new File(Objects.requireNonNull(FileUtils.class.getClassLoader().getResource(file)).getPath()).getAbsolutePath(); + } +} diff --git a/fizz-common/src/main/java/we/util/PropertiesUtils.java b/fizz-common/src/main/java/we/util/PropertiesUtils.java new file mode 100644 index 0000000..6510412 --- /dev/null +++ b/fizz-common/src/main/java/we/util/PropertiesUtils.java @@ -0,0 +1,70 @@ +package we.util; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.beans.PropertyAccessor; + +import java.util.Map; +import java.util.Properties; + +/** + * @author hongqiaowei + */ + +public abstract class PropertiesUtils { + + private PropertiesUtils() { + } + + public static String normalize(String propertyName) { + char[] chars = propertyName.toCharArray(); + StringBuilder b = new StringBuilder(chars.length); + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (c == Consts.S.DASH) { + b.append(Character.toUpperCase(chars[++i])); + } else { + b.append(c); + } + } + return b.toString(); + } + + public static Properties remove(Properties properties, String prefix) { + Properties result = new Properties(); + properties.forEach( + (k, v) -> { + String s = k.toString(); + int idx = s.indexOf(prefix); + if (idx > -1) { + s = s.substring(prefix.length() + 1); + } + result.setProperty(s, v.toString()); + } + ); + return result; + } + + public static void setBeanPropertyValue(Object bean, Properties properties) { + setBeanPropertyValue(bean, properties, null); + } + + public static void setBeanPropertyValue(Object bean, Properties properties, Map> propertyTypeHint) { + BeanWrapperImpl beanWrapper = new BeanWrapperImpl(bean); + for (String propertyName : properties.stringPropertyNames()) { + if (beanWrapper.isWritableProperty(propertyName)) { + beanWrapper.setPropertyValue(propertyName, properties.get(propertyName)); + } else if (propertyTypeHint != null) { + int dotPos = propertyName.lastIndexOf(Consts.S.DOT); + if (dotPos > -1) { + String prefix = propertyName.substring(0, dotPos); + Class aClass = propertyTypeHint.get(prefix); + if (aClass != null && Map.class.isAssignableFrom(aClass)) { + String newPropertyName = prefix + PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR + propertyName.substring(dotPos + 1) + PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR; + beanWrapper.setPropertyValue(newPropertyName, properties.get(propertyName)); + } + } + } + } + } +} diff --git a/fizz-common/src/main/java/we/util/YmlUtils.java b/fizz-common/src/main/java/we/util/YmlUtils.java new file mode 100644 index 0000000..91112f8 --- /dev/null +++ b/fizz-common/src/main/java/we/util/YmlUtils.java @@ -0,0 +1,34 @@ +package we.util; + +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import java.util.Properties; + +/** + * @author hongqiaowei + */ + +public abstract class YmlUtils { + + private YmlUtils() { + } + + public static Properties file2properties(String file) { + Resource resource = new ClassPathResource(file); + return getProperties(resource); + } + + public static Properties string2properties(String config) { + Resource resource = new ByteArrayResource(config.getBytes()); + return getProperties(resource); + } + + private static Properties getProperties(Resource resource) { + YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); + yamlPropertiesFactoryBean.setResources(resource); + return yamlPropertiesFactoryBean.getObject(); + } +} diff --git a/fizz-core/pom.xml b/fizz-core/pom.xml index 053c530..ead62d6 100644 --- a/fizz-core/pom.xml +++ b/fizz-core/pom.xml @@ -329,6 +329,10 @@ io.netty netty-tcnative-boringssl-static + + io.netty + netty-tcnative-classes + diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java index a474b6b..4869c0a 100644 --- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java +++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java @@ -19,27 +19,25 @@ package we.dedicated_line; import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration; import lombok.SneakyThrows; -import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.env.OriginTrackedMapPropertySource; import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.cloud.commons.util.InetUtils; import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.PropertySource; import we.config.SystemConfig; +import we.service_registry.FizzServiceRegistration; import we.service_registry.eureka.FizzEurekaHelper; -import we.service_registry.eureka.FizzEurekaProperties; -import we.service_registry.eureka.FizzEurekaServiceRegistration; import we.service_registry.nacos.FizzNacosHelper; -import we.service_registry.nacos.FizzNacosProperties; -import we.service_registry.nacos.FizzNacosServiceRegistration; import javax.annotation.PreDestroy; +import java.util.Properties; /** * @author hongqiaowei @@ -51,9 +49,9 @@ import javax.annotation.PreDestroy; @AutoConfigureAfter({EurekaClientAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class}) public class DedicatedLineServiceRegistration implements ApplicationListener { - private ServiceRegistry serviceRegistry; + private static final Logger log = LoggerFactory.getLogger(DedicatedLineServiceRegistration.class); - private Registration registration; + private FizzServiceRegistration fizzServiceRegistration; @SneakyThrows @Override @@ -62,70 +60,75 @@ public class DedicatedLineServiceRegistration implements ApplicationListener propertySource : env.getPropertySources()) { + if (propertySource instanceof OriginTrackedMapPropertySource) { + OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource; + String[] propertyNames = originTrackedMapPropertySource.getPropertyNames(); + for (String propertyName : propertyNames) { + if (propertyName.length() > 55) { + int eurekaPos = propertyName.indexOf("eureka"); + if (eurekaPos > -1) { + eurekaProperties.setProperty(propertyName.substring(eurekaPos), originTrackedMapPropertySource.getProperty(propertyName).toString()); + find = true; + } + } + } + if (find) { + break; + } + } + } + if (!find) { + log.error("no eureka config"); + return; + } + fizzServiceRegistration = FizzEurekaHelper.getServiceRegistration(applicationContext, eurekaProperties); } - if ("nacos".equals(type)) { - String application = env.getProperty(prefix + ".application"); - String ipAddress = env.getProperty(prefix + ".ip-address"); - String port = env.getProperty(prefix + ".port"); - String serviceUrl = env.getProperty(prefix + ".service-url"); - String namespace = env.getProperty(prefix + ".namespace", ""); - String group = env.getProperty(prefix + ".group", "DEFAULT_GROUP"); - String clusterName = env.getProperty(prefix + ".clusterName", "DEFAULT"); - - FizzNacosProperties fizzNacosProperties = new FizzNacosProperties(); - fizzNacosProperties.setApplicationContext(applicationContext); - fizzNacosProperties.setId(application + ':' + serviceUrl); - fizzNacosProperties.setService(application); - fizzNacosProperties.setIp(ipAddress == null ? applicationContext.getBean(InetUtils.class).findFirstNonLoopbackAddress().getHostAddress() : ipAddress); - fizzNacosProperties.setPort(Integer.parseInt(port)); - fizzNacosProperties.setNamespace(namespace.equals("") ? null : namespace); - fizzNacosProperties.setGroup(group); - fizzNacosProperties.setClusterName(clusterName); - fizzNacosProperties.setNamespace(""); - fizzNacosProperties.setSecretKey(""); - fizzNacosProperties.setAccessKey(""); - fizzNacosProperties.setUsername(""); - fizzNacosProperties.setPassword(""); - fizzNacosProperties.setEndpoint(""); - fizzNacosProperties.setLogName(""); - fizzNacosProperties.setNamingLoadCacheAtStart("false"); - fizzNacosProperties.setServerAddr(serviceUrl); - - FizzNacosServiceRegistration fizzNacosServiceRegistration = FizzNacosHelper.getServiceRegistration(fizzNacosProperties); - serviceRegistry = fizzNacosServiceRegistration.serviceRegistry; - registration = fizzNacosServiceRegistration.registration; + if (nacos) { + Properties nacosProperties = new Properties(); + boolean find = false; + for (PropertySource propertySource : env.getPropertySources()) { + if (propertySource instanceof OriginTrackedMapPropertySource) { + OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource; + String[] propertyNames = originTrackedMapPropertySource.getPropertyNames(); + for (String propertyName : propertyNames) { + if (propertyName.length() > 64) { + int naocsPos = propertyName.indexOf("nacos"); + if (naocsPos > -1) { + nacosProperties.setProperty(propertyName.substring(naocsPos), originTrackedMapPropertySource.getProperty(propertyName).toString()); + find = true; + } + } + } + if (find) { + break; + } + } + } + if (!find) { + log.error("no nacos config"); + return; + } + fizzServiceRegistration = FizzNacosHelper.getServiceRegistration(applicationContext, nacosProperties); } - serviceRegistry.register(registration); + fizzServiceRegistration.register(); } } @PreDestroy public void stop() { - if (serviceRegistry != null) { - serviceRegistry.deregister(registration); + if (fizzServiceRegistration != null) { + fizzServiceRegistration.deregister(); } } } diff --git a/fizz-core/src/main/java/we/filter/CallbackFilter.java b/fizz-core/src/main/java/we/filter/CallbackFilter.java index 57fa36b..8ee27da 100644 --- a/fizz-core/src/main/java/we/filter/CallbackFilter.java +++ b/fizz-core/src/main/java/we/filter/CallbackFilter.java @@ -43,6 +43,7 @@ import we.plugin.auth.Receiver; import we.proxy.CallbackService; import we.proxy.DiscoveryClientUriSelector; import we.proxy.ServiceInstance; +import we.service_registry.RegistryCenterService; import we.util.Consts; import we.util.NettyDataBufferUtils; import we.util.ThreadContext; @@ -75,6 +76,9 @@ public class CallbackFilter extends FizzWebFilter { @Resource private CallbackFilterProperties callbackFilterProperties; + @Resource + private RegistryCenterService registryCenterService; + @Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE) private ReactiveStringRedisTemplate rt; @@ -142,7 +146,14 @@ public class CallbackFilter extends FizzWebFilter { List receivers = ac.callbackConfig.receivers; for (Receiver r : receivers) { if (r.type == ApiConfig.Type.SERVICE_DISCOVERY) { - ServiceInstance inst = discoveryClientSelector.getNextInstance(r.service); + ServiceInstance inst = null; + if (r.registryCenter == null) { + inst = discoveryClientSelector.getNextInstance(r.service); + } else { + String instance = registryCenterService.getInstance(r.registryCenter, r.service); + String[] ipAndPort = StringUtils.split(instance, Consts.S.COLON); + inst = new ServiceInstance(ipAndPort[0], Integer.parseInt(ipAndPort[1])); + } service2instMap.put(r.service, inst); } } diff --git a/fizz-core/src/main/java/we/filter/RouteFilter.java b/fizz-core/src/main/java/we/filter/RouteFilter.java index 93d4f0f..45f2f99 100644 --- a/fizz-core/src/main/java/we/filter/RouteFilter.java +++ b/fizz-core/src/main/java/we/filter/RouteFilter.java @@ -115,7 +115,11 @@ public class RouteFilter extends FizzWebFilter { } else if (route.type == ApiConfig.Type.SERVICE_DISCOVERY) { String pathQuery = getBackendPathQuery(req, route); - return fizzWebClient.send2service(traceId, route.method, route.backendService, pathQuery, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval) + String svc = route.backendService; + if (route.registryCenter != null) { + svc = route.registryCenter + Consts.S.COMMA + route.backendService; + } + return fizzWebClient.send2service(traceId, route.method, svc, pathQuery, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval) .flatMap(genServerResponse(exchange)); } else if (route.type == ApiConfig.Type.REVERSE_PROXY) { diff --git a/fizz-core/src/main/java/we/plugin/auth/ApiConfig.java b/fizz-core/src/main/java/we/plugin/auth/ApiConfig.java index e992875..b12fd84 100644 --- a/fizz-core/src/main/java/we/plugin/auth/ApiConfig.java +++ b/fizz-core/src/main/java/we/plugin/auth/ApiConfig.java @@ -25,6 +25,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.server.ServerWebExchange; import we.plugin.PluginConfig; import we.proxy.Route; +import we.util.Consts; import we.util.JacksonUtils; import we.util.UrlTransformUtils; @@ -71,6 +72,8 @@ public class ApiConfig { public String service; + public String registryCenter; + public String backendService; public Object fizzMethod = ALL_METHOD; @@ -141,6 +144,17 @@ public class ApiConfig { firstGatewayGroup = gatewayGroups.iterator().next(); } + @JsonProperty("registryName") + public void setRegistryCenter(String rc) { + if (StringUtils.isNotBlank(rc)) { + if (rc.equals(Consts.S.DEFAULT)) { + registryCenter = Consts.S.DEFAULT; + } else { + registryCenter = rc; + } + } + } + public void setPath(String p) { if (StringUtils.isNotBlank(p)) { if ("/".equals(p)) { @@ -209,18 +223,19 @@ public class ApiConfig { public Route getRoute(ServerWebExchange exchange, @Nullable List gatewayGroupPluginConfigs) { ServerHttpRequest request = exchange.getRequest(); - Route r = new Route().dedicatedLine( this.dedicatedLine) - .type( this.type) - .method( request.getMethod()) - .backendService(this.backendService) - .backendPath( this.backendPath) - .rpcMethod( this.rpcMethod) - .rpcParamTypes( this.rpcParamTypes) - .rpcGroup( this.rpcGroup) - .rpcVersion( this.rpcVersion) - .timeout( this.timeout) - .retryCount( this.retryCount) - .retryInterval( this.retryInterval); + Route r = new Route().dedicatedLine( this.dedicatedLine) + .type( this.type) + .method( request.getMethod()) + .registryCenter( this.registryCenter) + .backendService( this.backendService) + .backendPath( this.backendPath) + .rpcMethod( this.rpcMethod) + .rpcParamTypes( this.rpcParamTypes) + .rpcGroup( this.rpcGroup) + .rpcVersion( this.rpcVersion) + .timeout( this.timeout) + .retryCount( this.retryCount) + .retryInterval( this.retryInterval); if (gatewayGroupPluginConfigs == null || gatewayGroupPluginConfigs.isEmpty()) { r.pluginConfigs = this.pluginConfigs; diff --git a/fizz-core/src/main/java/we/plugin/auth/Receiver.java b/fizz-core/src/main/java/we/plugin/auth/Receiver.java index f3347c0..43e165a 100644 --- a/fizz-core/src/main/java/we/plugin/auth/Receiver.java +++ b/fizz-core/src/main/java/we/plugin/auth/Receiver.java @@ -17,6 +17,9 @@ package we.plugin.auth; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.StringUtils; +import we.util.Consts; import we.util.JacksonUtils; /** @@ -27,10 +30,23 @@ public class Receiver { public String service; - public int type; + public String registryCenter; + + public int type; public String path; + @JsonProperty("registryName") + public void setRegistryCenter(String rc) { + if (StringUtils.isNotBlank(rc)) { + if (rc.equals(Consts.S.DEFAULT)) { + registryCenter = Consts.S.DEFAULT; + } else { + registryCenter = rc; + } + } + } + @Override public String toString() { return JacksonUtils.writeValueAsString(this); diff --git a/fizz-core/src/main/java/we/proxy/CallbackService.java b/fizz-core/src/main/java/we/proxy/CallbackService.java index 3b0f6f7..ec0468a 100644 --- a/fizz-core/src/main/java/we/proxy/CallbackService.java +++ b/fizz-core/src/main/java/we/proxy/CallbackService.java @@ -242,7 +242,13 @@ public class CallbackService { for (ServiceTypePath stp : req.assignServices) { if (stp.type == ApiConfig.Type.SERVICE_DISCOVERY) { - send = fizzWebClient.send2service(req.id, req.method, stp.service, stp.path, req.headers, req.body) + String svc = null; + if (stp.registryCenter == null) { + svc = stp.service; + } else { + svc = stp.registryCenter + Consts.S.COMMA + stp.service; + } + send = fizzWebClient.send2service(req.id, req.method, svc, stp.path, req.headers, req.body) .onErrorResume( crError(req, stp.service, stp.path) ); } else { String traceId = CommonConstants.TRACE_ID_PREFIX + req.id; diff --git a/fizz-core/src/main/java/we/proxy/FizzWebClient.java b/fizz-core/src/main/java/we/proxy/FizzWebClient.java index f310ec1..4fb6807 100644 --- a/fizz-core/src/main/java/we/proxy/FizzWebClient.java +++ b/fizz-core/src/main/java/we/proxy/FizzWebClient.java @@ -17,12 +17,6 @@ package we.proxy; -import java.time.Duration; -import java.util.Collections; -import java.util.List; - -import javax.annotation.Resource; - import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +29,6 @@ import org.springframework.web.reactive.function.BodyInserter; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; @@ -44,10 +37,16 @@ import we.config.SystemConfig; import we.exception.ExternalService4xxException; import we.fizz.exception.FizzRuntimeException; import we.flume.clients.log4j2appender.LogService; +import we.service_registry.RegistryCenterService; import we.util.Consts; import we.util.ThreadContext; import we.util.WebUtils; +import javax.annotation.Resource; +import java.time.Duration; +import java.util.Collections; +import java.util.List; + /** * @author hongqiaowei */ @@ -67,6 +66,9 @@ public class FizzWebClient { @Resource private DiscoveryClientUriSelector discoveryClientUriSelector; + @Resource + private RegistryCenterService registryCenterService; + @Resource(name = ProxyWebClientConfig.proxyWebClient) private WebClient webClient; @@ -83,13 +85,22 @@ public class FizzWebClient { String s = extractServiceOrAddress(uriOrSvc); Mono cr = Mono.just(Consts.S.EMPTY).flatMap(dummy -> { - if (isService(s)) { - String path = uriOrSvc.substring(uriOrSvc.indexOf(Consts.S.FORWARD_SLASH, 10)); - String uri = discoveryClientUriSelector.getNextUri(s, path); - return send2uri(traceId, method, uri, headers, body, timeout); - } else { - return send2uri(traceId, method, uriOrSvc, headers, body, timeout); - } + if (isService(s)) { + String path = uriOrSvc.substring(uriOrSvc.indexOf(Consts.S.FORWARD_SLASH, 10)); + String uri = null; + int commaPos = s.indexOf(Consts.S.COMMA); + if (commaPos > -1) { + String rc = s.substring(0, commaPos); + String svc = s.substring(commaPos + 1); + String instance = registryCenterService.getInstance(rc, svc); + uri = ThreadContext.getStringBuilder().append(Consts.S.HTTP_PROTOCOL_PREFIX).append(instance).append(path).toString(); + } else { + uri = discoveryClientUriSelector.getNextUri(s, path); + } + return send2uri(traceId, method, uri, headers, body, timeout); + } else { + return send2uri(traceId, method, uriOrSvc, headers, body, timeout); + } }); if (numRetries > 0) { @@ -123,7 +134,16 @@ public class FizzWebClient { long timeout, long numRetries, long retryInterval) { Mono cr = Mono.just(Consts.S.EMPTY).flatMap(dummy -> { - String uri = discoveryClientUriSelector.getNextUri(service, relativeUri); + String uri = null; + int commaPos = service.indexOf(Consts.S.COMMA); + if (commaPos > -1) { + String rc = service.substring(0, commaPos); + String s = service.substring(commaPos + 1); + String instance = registryCenterService.getInstance(rc, s); + uri = ThreadContext.getStringBuilder().append(Consts.S.HTTP_PROTOCOL_PREFIX).append(instance).append(relativeUri).toString(); + } else { + uri = discoveryClientUriSelector.getNextUri(service, relativeUri); + } return send2uri(traceId, method, uri, headers, body, timeout); }); if (numRetries > 0) { diff --git a/fizz-core/src/main/java/we/proxy/Route.java b/fizz-core/src/main/java/we/proxy/Route.java index 5dbb7fb..269e339 100644 --- a/fizz-core/src/main/java/we/proxy/Route.java +++ b/fizz-core/src/main/java/we/proxy/Route.java @@ -36,6 +36,8 @@ public class Route { public HttpMethod method; + public String registryCenter; + public String backendService; public String backendPath; @@ -81,6 +83,11 @@ public class Route { return this; } + public Route registryCenter(String rc) { + registryCenter = rc; + return this; + } + public Route backendService(String bs) { backendService = bs; return this; diff --git a/fizz-core/src/main/java/we/proxy/ServiceInstance.java b/fizz-core/src/main/java/we/proxy/ServiceInstance.java index b30b460..278dd13 100644 --- a/fizz-core/src/main/java/we/proxy/ServiceInstance.java +++ b/fizz-core/src/main/java/we/proxy/ServiceInstance.java @@ -27,13 +27,13 @@ public class ServiceInstance { public String ip; - public int port; + public int port; public ServiceInstance() { } public ServiceInstance(String ip, int port) { - this.ip = ip; + this.ip = ip; this.port = port; } diff --git a/fizz-core/src/main/java/we/proxy/ServiceTypePath.java b/fizz-core/src/main/java/we/proxy/ServiceTypePath.java index 44b79c8..9f4af80 100644 --- a/fizz-core/src/main/java/we/proxy/ServiceTypePath.java +++ b/fizz-core/src/main/java/we/proxy/ServiceTypePath.java @@ -17,6 +17,9 @@ package we.proxy; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.StringUtils; +import we.util.Consts; import we.util.JacksonUtils; /** @@ -25,11 +28,24 @@ import we.util.JacksonUtils; public class ServiceTypePath { + public String registryCenter; + public String service; public String path; - public int type; + public int type; + + @JsonProperty("registryName") + public void setRegistryCenter(String rc) { + if (StringUtils.isNotBlank(rc)) { + if (rc.equals(Consts.S.DEFAULT)) { + registryCenter = Consts.S.DEFAULT; + } else { + registryCenter = rc; + } + } + } @Override public String toString() { diff --git a/fizz-core/src/main/java/we/service_registry/FizzServiceRegistration.java b/fizz-core/src/main/java/we/service_registry/FizzServiceRegistration.java new file mode 100644 index 0000000..113cc9a --- /dev/null +++ b/fizz-core/src/main/java/we/service_registry/FizzServiceRegistration.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package we.service_registry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; + +/** + * @author hongqiaowei + */ + +public abstract class FizzServiceRegistration { + + protected static final Logger log = LoggerFactory.getLogger(FizzServiceRegistration.class); + + protected String id; + + private Registration registration; + + private ServiceRegistry serviceRegistry; + + public FizzServiceRegistration(String id, Registration registration, ServiceRegistry serviceRegistry) { + this.id = id; + this.registration = registration; + this.serviceRegistry = serviceRegistry; + } + + public void register() { + serviceRegistry.register(registration); + } + + public void deregister() { + serviceRegistry.deregister(registration); + } + + public abstract RegistryCenter.Status getRegistryCenterStatus(); + + public abstract String getInstance(String service); +} diff --git a/fizz-core/src/main/java/we/service_registry/RegistryCenter.java b/fizz-core/src/main/java/we/service_registry/RegistryCenter.java new file mode 100644 index 0000000..1bc2878 --- /dev/null +++ b/fizz-core/src/main/java/we/service_registry/RegistryCenter.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package we.service_registry; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PropertiesLoaderUtils; +import we.Fizz; +import we.service_registry.eureka.FizzEurekaHelper; +import we.service_registry.nacos.FizzNacosHelper; +import we.util.JacksonUtils; +import we.util.YmlUtils; + +import java.io.IOException; +import java.util.Properties; + +/** + * @author hongqiaowei + */ + +public class RegistryCenter { + + public enum Status { + UP, + DOWN, + STARTING, + OUT_OF_SERVICE, + UNKNOWN; + } + + public static final int EUREKA = 1; + public static final int NACOS = 2; + + public static final int YML = 1; + public static final int PROPERTIES = 2; + + @JsonProperty( + access = JsonProperty.Access.WRITE_ONLY + ) + public boolean isDeleted = false; + public long id; + public String name; + public int type; + public int clientConfigFormat; + public String clientConfig; + + private FizzServiceRegistration fizzServiceRegistration; + + @JsonCreator + public RegistryCenter( + @JsonProperty("isDeleted") int isDeleted, + @JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("type") int type, + @JsonProperty("format") int clientConfigFormat, + @JsonProperty("content") String clientConfig + ) { + + if (isDeleted == 1) { + this.isDeleted = true; + } + this.id = id; + this.name = name; + this.type = type; + this.clientConfigFormat = clientConfigFormat; + this.clientConfig = clientConfig; + } + + @JsonIgnore + public FizzServiceRegistration getFizzServiceRegistration() { + if (fizzServiceRegistration == null) { + Properties properties; + if (this.clientConfigFormat == YML) { + properties = YmlUtils.string2properties(clientConfig); + } else { + Resource resource = new ByteArrayResource(clientConfig.getBytes()); + try { + properties = PropertiesLoaderUtils.loadProperties(resource); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + if (type == EUREKA) { + fizzServiceRegistration = FizzEurekaHelper.getServiceRegistration(Fizz.context, properties); + } else { + fizzServiceRegistration = FizzNacosHelper.getServiceRegistration(Fizz.context, properties); + } + } + return fizzServiceRegistration; + } + + @JsonIgnore + public String getInstance(String service) { + return fizzServiceRegistration.getInstance(service); + } + + @Override + public String toString() { + return JacksonUtils.writeValueAsString(this); + } +} diff --git a/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java b/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java new file mode 100644 index 0000000..b7d1a4d --- /dev/null +++ b/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2020 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package we.service_registry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.redis.core.ReactiveStringRedisTemplate; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import we.config.AggregateRedisConfig; +import we.util.JacksonUtils; +import we.util.Result; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author hongqiaowei + */ + +@Service +public class RegistryCenterService { + + private static final Logger log = LoggerFactory.getLogger(RegistryCenterService.class); + + private Map registryCenterMap = new HashMap<>(); + + @Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE) + private ReactiveStringRedisTemplate rt; + + @PostConstruct + public void init() { + Result result = initRegistryCenter(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } + result = lsnRegistryCenterChange(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } + } + + private Result initRegistryCenter() { + Result result = Result.succ(); + Flux> registryCenterEntries = rt.opsForHash().entries("fizz_registry"); + registryCenterEntries.collectList() + .defaultIfEmpty(Collections.emptyList()) + .flatMap( + es -> { + if (!es.isEmpty()) { + String json = null; + try { + for (Map.Entry e : es) { + json = (String) e.getValue(); + RegistryCenter rc = JacksonUtils.readValue(json, RegistryCenter.class); + registryCenterMap.put(rc.name, rc); + log.info("init registry center {}", rc.name); + } + } catch (Throwable t) { + result.code = Result.FAIL; + result.msg = "init registry center error, json: " + json; + result.t = t; + } + } else { + log.info("no registry center"); + } + return Mono.empty(); + } + ) + .onErrorReturn( + throwable -> { + result.code = Result.FAIL; + result.msg = "init registry center error"; + result.t = throwable; + return true; + }, + result + ) + .block(); + return result; + } + + private Result lsnRegistryCenterChange() { + Result result = Result.succ(); + String channel = "fizz_registry_channel"; + rt.listenToChannel(channel) + .doOnError( + t -> { + result.code = Result.FAIL; + result.msg = "lsn error, channel: " + channel; + result.t = t; + log.error("lsn channel {} error", channel, t); + } + ) + .doOnSubscribe( + s -> { + log.info("success to lsn on {}", channel); + } + ) + .doOnNext( + msg -> { + String message = msg.getMessage(); + try { + RegistryCenter rc = JacksonUtils.readValue(message, RegistryCenter.class); + if (rc.isDeleted) { + registryCenterMap.remove(rc.name); + log.info("remove registry center {}", rc.name); + } else { + registryCenterMap.put(rc.name, rc); + log.info("update registry center {}", rc.name); + } + } catch (Throwable t) { + log.error("update registry center error, {}", message, t); + } + } + ) + .subscribe(); + return result; + } + + public RegistryCenter getRegistryCenter(String name) { + return registryCenterMap.get(name); + } + + public String getInstance(String registryCenter, String service) { + return registryCenterMap.get(registryCenter).getInstance(service); + } +} diff --git a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaHelper.java b/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaHelper.java index c814c22..f8b18fc 100644 --- a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaHelper.java +++ b/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaHelper.java @@ -20,7 +20,9 @@ package we.service_registry.eureka; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.HealthCheckHandler; import com.netflix.appinfo.InstanceInfo; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.cloud.commons.util.InetUtilsProperties; import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; import org.springframework.cloud.netflix.eureka.CloudEurekaClient; import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; @@ -28,10 +30,13 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.cloud.netflix.eureka.InstanceInfoFactory; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry; +import org.springframework.context.ApplicationContext; +import we.util.Consts; +import we.util.PropertiesUtils; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.Properties; /** * @author hongqiaowei @@ -39,61 +44,88 @@ import java.util.Map; public abstract class FizzEurekaHelper { + private static final int el = "eureka." .length(); + private static final int ecl = "eureka.client." .length(); + private static final int eil = "eureka.instance." .length(); + private FizzEurekaHelper() { } - public static FizzEurekaServiceRegistration getServiceRegistration(FizzEurekaProperties fizzEurekaProperties) { + public static FizzEurekaServiceRegistration getServiceRegistration(ApplicationContext applicationContext, Properties eurekaProperties) { - InetUtils inetUtils = fizzEurekaProperties.applicationContext.getBean(InetUtils.class); + Properties eurekaProps = new Properties(); + for (String propertyName : eurekaProperties.stringPropertyNames()) { + String pn = null; + if (propertyName.charAt(ecl - 1) == Consts.S.DOT) { + pn = propertyName.substring(ecl); + } else if (propertyName.charAt(eil - 1) == Consts.S.DOT) { + pn = propertyName.substring(eil); + } else { + pn = propertyName.substring(el); + } + if (pn.indexOf(Consts.S.DASH) > -1) { + pn = PropertiesUtils.normalize(pn); + } + eurekaProps.setProperty(pn, eurekaProperties.getProperty(propertyName)); + } + + InetUtils inetUtils = null; + try { + inetUtils = applicationContext.getBean(InetUtils.class); + } catch (NoSuchBeanDefinitionException e) { + inetUtils = new InetUtils(new InetUtilsProperties()); + } EurekaInstanceConfigBean eurekaInstanceConfig = new EurekaInstanceConfigBean(inetUtils); - eurekaInstanceConfig.setAppname(fizzEurekaProperties.appName); - eurekaInstanceConfig.setVirtualHostName(fizzEurekaProperties.getVirtualHostName()); - eurekaInstanceConfig.setNonSecurePort(fizzEurekaProperties.nonSecurePort); + PropertiesUtils.setBeanPropertyValue(eurekaInstanceConfig, eurekaProps); - String ip = fizzEurekaProperties.ipAddress; - String instanceId; - if (ip == null) { - ip = inetUtils.findFirstNonLoopbackAddress().getHostAddress(); - instanceId = ip + ':' + fizzEurekaProperties.appName + ':' + fizzEurekaProperties.nonSecurePort; - } else { - instanceId = ip + ':' + fizzEurekaProperties.appName + ':' + fizzEurekaProperties.nonSecurePort; - fizzEurekaProperties.instanceId(instanceId); + String appname = eurekaInstanceConfig.getAppname(); + if (appname == null) { + appname = applicationContext.getApplicationName(); + eurekaInstanceConfig.setAppname(appname); } - eurekaInstanceConfig.setIpAddress(ip); - eurekaInstanceConfig.setInstanceId(instanceId); - eurekaInstanceConfig.setPreferIpAddress(fizzEurekaProperties.preferIpAddress); - eurekaInstanceConfig.setSecurePortEnabled(fizzEurekaProperties.securePortEnabled); - String healthCheckUrl = fizzEurekaProperties.getHealthCheckUrl(); - if (healthCheckUrl != null) { - eurekaInstanceConfig.setHealthCheckUrl(healthCheckUrl); + // VirtualHostName + String virtualHostName = eurekaInstanceConfig.getVirtualHostName(); + + if (virtualHostName.equals("unknown")) { + eurekaInstanceConfig.setVirtualHostName(appname); + } + + String serverPort = eurekaProps.getProperty("serverPort"); + if (serverPort == null) { + serverPort = applicationContext.getEnvironment().getProperty("server.port"); + } + assert serverPort != null; + eurekaInstanceConfig.setNonSecurePort(Integer.parseInt(serverPort)); + + String ipAddress = eurekaInstanceConfig.getIpAddress(); + if (ipAddress == null) { + ipAddress = inetUtils.findFirstNonLoopbackAddress().getHostAddress(); + eurekaInstanceConfig.setIpAddress(ipAddress); + } + + String instanceId = eurekaInstanceConfig.getInstanceId(); + if (instanceId == null) { + eurekaInstanceConfig.setInstanceId(ipAddress + ':' + appname + ':' + serverPort); } - eurekaInstanceConfig.setDataCenterInfo(fizzEurekaProperties.dataCenterInfo); InstanceInfo instanceInfo = new InstanceInfoFactory().create(eurekaInstanceConfig); - ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(eurekaInstanceConfig, instanceInfo); EurekaClientConfigBean eurekaClientConfig = new EurekaClientConfigBean(); - eurekaClientConfig.setRegion(fizzEurekaProperties.region); - Map serviceUrlMap = new HashMap<>(); - serviceUrlMap.put(fizzEurekaProperties.zone, fizzEurekaProperties.serviceUrl); - eurekaClientConfig.setServiceUrl(serviceUrlMap); + Map> propertyTypeHint = new HashMap<>(); + propertyTypeHint.put("serviceUrl", Map.class); + PropertiesUtils.setBeanPropertyValue(eurekaClientConfig, eurekaProps, propertyTypeHint); - CloudEurekaClient eurekaClient = new CloudEurekaClient(applicationInfoManager, eurekaClientConfig, null, fizzEurekaProperties.applicationContext); + CloudEurekaClient eurekaClient = new CloudEurekaClient(applicationInfoManager, eurekaClientConfig, null, applicationContext); SimpleObjectProvider healthCheckHandler = new SimpleObjectProvider<>(null); EurekaRegistration eurekaRegistration = EurekaRegistration.builder(eurekaInstanceConfig).with(applicationInfoManager).with(healthCheckHandler).with(eurekaClient).build(); EurekaServiceRegistry serviceRegistry = new EurekaServiceRegistry(); - return new FizzEurekaServiceRegistration(fizzEurekaProperties.getId(), eurekaRegistration, serviceRegistry, eurekaClient); - } - - public static Map getServiceRegistration(List fizzEurekaPropertiesList) { - Map result = new HashMap<>(); - for (FizzEurekaProperties properties : fizzEurekaPropertiesList) { - FizzEurekaServiceRegistration fizzEurekaServiceRegistration = getServiceRegistration(properties); - result.put(properties.getId(), fizzEurekaServiceRegistration); + String registerCenter = eurekaProps.getProperty("register-center"); + if (registerCenter == null) { + registerCenter = eurekaClientConfig.getServiceUrl().get(EurekaClientConfigBean.DEFAULT_ZONE); } - return result; + return new FizzEurekaServiceRegistration(registerCenter, eurekaRegistration, serviceRegistry, eurekaClient); } } diff --git a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaProperties.java b/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaProperties.java deleted file mode 100644 index e190f22..0000000 --- a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaProperties.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package we.service_registry.eureka; - -import com.netflix.appinfo.DataCenterInfo; -import com.netflix.appinfo.MyDataCenterInfo; -import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * @author hongqiaowei - */ - -public class FizzEurekaProperties { - - public ConfigurableApplicationContext applicationContext; - - private String id; - - public String appName; - - private String virtualHostName; - - public String ipAddress; - - public int nonSecurePort = 80; - - private String instanceId; - - public boolean preferIpAddress = true; - - public boolean securePortEnabled = false; - - private String healthCheckUrl; - - public DataCenterInfo dataCenterInfo = new MyDataCenterInfo( - DataCenterInfo.Name.MyOwn); - - public String region = "default"; - - public String zone = EurekaClientConfigBean.DEFAULT_ZONE; - - public String serviceUrl; - - public int securePort = 443; - - public FizzEurekaProperties applicationContext(ConfigurableApplicationContext applicationContext) { - this.applicationContext = applicationContext; - return this; - } - - public FizzEurekaProperties id(String id) { - this.id = id; - return this; - } - - public String getId() { - if (id == null) { - id = appName + ':' + serviceUrl; - } - return id; - } - - public FizzEurekaProperties appName(String appName) { - this.appName = appName; - return this; - } - - public FizzEurekaProperties virtualHostName(String virtualHostName) { - this.virtualHostName = virtualHostName; - return this; - } - - public String getVirtualHostName() { - if (virtualHostName == null) { - virtualHostName = appName; - } - return virtualHostName; - } - - public FizzEurekaProperties ipAddress(String ipAddress) { - this.ipAddress = ipAddress; - return this; - } - - public FizzEurekaProperties nonSecurePort(int nonSecurePort) { - this.nonSecurePort = nonSecurePort; - return this; - } - - public FizzEurekaProperties instanceId(String instanceId) { - this.instanceId = instanceId; - return this; - } - - public String getInstanceId() { - /*if (instanceId == null) { - instanceId = ipAddress + ':' + appName + ':' + nonSecurePort; - }*/ - return instanceId; - } - - public FizzEurekaProperties preferIpAddress(boolean preferIpAddress) { - this.preferIpAddress = preferIpAddress; - return this; - } - - public FizzEurekaProperties securePortEnabled(boolean securePortEnabled) { - this.securePortEnabled = securePortEnabled; - return this; - } - - public FizzEurekaProperties healthCheckUrl(String healthCheckUrl) { - this.healthCheckUrl = healthCheckUrl; - return this; - } - - public String getHealthCheckUrl() { - /*if (healthCheckUrl == null) { - healthCheckUrl = "http://" + ipAddress + ':' + nonSecurePort + "/actuator/info"; - }*/ - return healthCheckUrl; - } - - public FizzEurekaProperties region(String region) { - this.region = region; - return this; - } - - public FizzEurekaProperties zone(String zone) { - this.zone = zone; - return this; - } - - public FizzEurekaProperties serviceUrl(String serviceUrl) { - this.serviceUrl = serviceUrl; - return this; - } - - public FizzEurekaProperties securePort(int securePort) { - this.securePort = securePort; - return this; - } -} diff --git a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaServiceRegistration.java b/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaServiceRegistration.java index 2d8a62b..cbdeb21 100644 --- a/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaServiceRegistration.java +++ b/fizz-core/src/main/java/we/service_registry/eureka/FizzEurekaServiceRegistration.java @@ -17,28 +17,122 @@ package we.service_registry.eureka; +import com.netflix.appinfo.InstanceInfo; +import com.netflix.discovery.DiscoveryClient; +import com.netflix.discovery.EurekaClientConfig; +import com.netflix.discovery.shared.Application; +import com.netflix.discovery.shared.Applications; +import org.apache.commons.lang3.StringUtils; import org.springframework.cloud.netflix.eureka.CloudEurekaClient; +import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry; +import org.springframework.util.CollectionUtils; +import we.service_registry.FizzServiceRegistration; +import we.service_registry.RegistryCenter; +import we.util.Consts; +import we.util.Utils; + +import java.util.List; /** * @author hongqiaowei */ -public class FizzEurekaServiceRegistration { +public class FizzEurekaServiceRegistration extends FizzServiceRegistration { - public String id; - - public EurekaRegistration registration; - - public EurekaServiceRegistry serviceRegistry; - - public CloudEurekaClient client; + private final CloudEurekaClient client; public FizzEurekaServiceRegistration(String id, EurekaRegistration registration, EurekaServiceRegistry serviceRegistry, CloudEurekaClient client) { - this.id = id; - this.registration = registration; - this.serviceRegistry = serviceRegistry; + super(id, registration, serviceRegistry); this.client = client; } + + public DiscoveryClient getDiscoveryClient() { + return client; + } + + @Override + public RegistryCenter.Status getRegistryCenterStatus() { + EurekaClientConfig eurekaClientConfig = client.getEurekaClientConfig(); + List eurekaServerServiceUrls = eurekaClientConfig.getEurekaServerServiceUrls(EurekaClientConfigBean.DEFAULT_ZONE); + boolean f = false; + for (String serviceUrl : eurekaServerServiceUrls) { + String vip; + int port; + int begin = serviceUrl.indexOf('p') + 4; + int colon = serviceUrl.indexOf(':', begin); + if (colon > -1) { + int end = serviceUrl.indexOf('/', colon); + vip = serviceUrl.substring(begin, colon); + port = Integer.parseInt(serviceUrl.substring(colon + 1, end)); + } else { + int end = serviceUrl.indexOf('/', begin); + vip = serviceUrl.substring(begin, end); + port = 80; + } + + Applications applications = client.getApplications(serviceUrl); + for (Application registeredApplication : applications.getRegisteredApplications()) { + List instances = registeredApplication.getInstances(); + for (InstanceInfo instance : instances) { + String vipAddress = instance.getVIPAddress(); + String ipAddr = instance.getIPAddr(); + if (vipAddress.equals(vip) || ipAddr.equals(vip)) { + int p = instance.getPort(); + if (p == port) { + f = true; + break; + } + } + } + if (f) { + for (InstanceInfo instance : instances) { + InstanceInfo.InstanceStatus status = instance.getStatus(); + if (status != InstanceInfo.InstanceStatus.UP) { + return transfrom(status); + } + } + return transfrom(InstanceInfo.InstanceStatus.UP); + } + } + } + + String join = StringUtils.join(eurekaServerServiceUrls, ','); + throw Utils.runtimeExceptionWithoutStack("can't find any server with " + join); + } + + private RegistryCenter.Status transfrom(InstanceInfo.InstanceStatus status) { + if ( status == InstanceInfo.InstanceStatus.UP) { + return RegistryCenter.Status.UP; + + } else if (status == InstanceInfo.InstanceStatus.DOWN) { + return RegistryCenter.Status.DOWN; + + } else if (status == InstanceInfo.InstanceStatus.OUT_OF_SERVICE) { + return RegistryCenter.Status.OUT_OF_SERVICE; + + } else if (status == InstanceInfo.InstanceStatus.STARTING) { + return RegistryCenter.Status.STARTING; + + } else { + return RegistryCenter.Status.UNKNOWN; + } + } + + @Override + public String getInstance(String service) { + InstanceInfo inst = getInstanceInfo(service); + return inst.getIPAddr() + Consts.S.COLON + inst.getPort(); + } + + public InstanceInfo getInstanceInfo(String service) { + List insts = client.getInstancesByVipAddress(service, false); + if (CollectionUtils.isEmpty(insts)) { + throw Utils.runtimeExceptionWithoutStack(id + " eureka no " + service); + } + Applications apps = client.getApplications(); + int index = (int) (apps.getNextIndex(service.toUpperCase(), false).incrementAndGet() % insts.size()); + return insts.get(index); + } } diff --git a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java index f7e6871..61a72ab 100644 --- a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java +++ b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java @@ -21,11 +21,13 @@ import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.registry.NacosRegistration; import com.alibaba.cloud.nacos.registry.NacosServiceRegistry; import com.alibaba.nacos.api.naming.NamingService; +import org.springframework.context.ApplicationContext; +import we.util.Consts; +import we.util.JacksonUtils; +import we.util.PropertiesUtils; import we.util.ReflectionUtils; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.Properties; /** * @author hongqiaowei @@ -33,25 +35,44 @@ import java.util.Map; public abstract class FizzNacosHelper { + private static final int ndl = "nacos.discovery.".length(); + private FizzNacosHelper() { } - public static FizzNacosServiceRegistration getServiceRegistration(FizzNacosProperties fizzNacosProperties) { + public static FizzNacosServiceRegistration getServiceRegistration(ApplicationContext applicationContext, Properties nacosProperties) { + + Properties ps = new Properties(); + for (String propertyName : nacosProperties.stringPropertyNames()) { + String pn = propertyName.substring(ndl); + if (pn.indexOf(Consts.S.DASH) > -1) { + pn = PropertiesUtils.normalize(pn); + } + ps.setProperty(pn, nacosProperties.getProperty(propertyName)); + } + + FizzNacosProperties fizzNacosProperties = new FizzNacosProperties(); + PropertiesUtils.setBeanPropertyValue(fizzNacosProperties, ps); + + fizzNacosProperties.setApplicationContext(applicationContext); + if (fizzNacosProperties.getId() == null) { + fizzNacosProperties.setId(fizzNacosProperties.getServerAddr()); + } + if (fizzNacosProperties.getService() == null) { + fizzNacosProperties.setService(applicationContext.getApplicationName()); + } + if (fizzNacosProperties.getPort() == -1) { + fizzNacosProperties.setPort(Integer.parseInt(applicationContext.getEnvironment().getProperty("server.port"))); + } + fizzNacosProperties.setNamingLoadCacheAtStart("false"); + fizzNacosProperties.init(); + NacosServiceRegistry nacosServiceRegistry = new NacosServiceRegistry(fizzNacosProperties); NacosServiceManager nacosServiceManager = new NacosServiceManager(); ReflectionUtils.set(nacosServiceRegistry, "nacosServiceManager", nacosServiceManager); - NacosRegistration nacosRegistration = new NacosRegistration(null, fizzNacosProperties, fizzNacosProperties.getApplicationContext()); + NacosRegistration nacosRegistration = new NacosRegistration(null, fizzNacosProperties, applicationContext); NamingService namingService = nacosServiceManager.getNamingService(fizzNacosProperties.getNacosProperties()); return new FizzNacosServiceRegistration(fizzNacosProperties.getId(), nacosRegistration, nacosServiceRegistry, namingService); } - - public static Map getServiceRegistration(List fizzNacosPropertiesList) { - Map result = new HashMap<>(); - for (FizzNacosProperties properties : fizzNacosPropertiesList) { - FizzNacosServiceRegistration fizzNacosServiceRegistration = getServiceRegistration(properties); - result.put(properties.getId(), fizzNacosServiceRegistration); - } - return result; - } } diff --git a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosProperties.java b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosProperties.java index 5cf9529..f006c59 100644 --- a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosProperties.java +++ b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosProperties.java @@ -21,6 +21,7 @@ import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.nacos.api.naming.PreservedMetadataKeys; import com.alibaba.nacos.client.naming.utils.UtilAndComs; import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.StringUtils; @@ -38,23 +39,23 @@ import static com.alibaba.nacos.api.PropertyKeyConst.*; public class FizzNacosProperties extends NacosDiscoveryProperties { - private ConfigurableApplicationContext applicationContext; + private ApplicationContext applicationContext; private String id; private String serverAddr; - private String username; + private String username = ""; - private String password; + private String password = ""; - private String endpoint; + private String endpoint = ""; private String namespace; private long watchDelay = 30000; - private String logName; + private String logName = ""; private String service; @@ -78,9 +79,9 @@ public class FizzNacosProperties extends NacosDiscoveryProperties { private boolean secure = false; - private String accessKey; + private String accessKey = ""; - private String secretKey; + private String secretKey = ""; private Integer heartBeatInterval; @@ -143,11 +144,11 @@ public class FizzNacosProperties extends NacosDiscoveryProperties { init = true; } - public void setApplicationContext(ConfigurableApplicationContext applicationContext) { + public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } - public ConfigurableApplicationContext getApplicationContext() { + public ApplicationContext getApplicationContext() { return applicationContext; } diff --git a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java index 60dce81..af22658 100644 --- a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java +++ b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java @@ -17,28 +17,99 @@ package we.service_registry.nacos; +import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.registry.NacosRegistration; import com.alibaba.cloud.nacos.registry.NacosServiceRegistry; +import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import org.springframework.util.StringUtils; +import we.service_registry.FizzServiceRegistration; +import we.service_registry.RegistryCenter; +import we.util.Consts; +import we.util.Utils; + +import java.util.Collections; +import java.util.List; /** * @author hongqiaowei */ -public class FizzNacosServiceRegistration { +public class FizzNacosServiceRegistration extends FizzServiceRegistration { - public String id; + private NamingService namingService; - public NacosRegistration registration; + private final String groupName; - public NacosServiceRegistry serviceRegistry; + private List clusterNameList; - public NamingService namingService; + private boolean useGroupName; + + private boolean userClusterName; public FizzNacosServiceRegistration(String id, NacosRegistration registration, NacosServiceRegistry serviceRegistry, NamingService namingService) { - this.id = id; - this.registration = registration; - this.serviceRegistry = serviceRegistry; + super(id, registration, serviceRegistry); this.namingService = namingService; + NacosDiscoveryProperties discoveryProperties = registration.getNacosDiscoveryProperties(); + groupName = discoveryProperties.getGroup(); + if (StringUtils.hasText(groupName)) { + useGroupName = true; + } + String clusterName = discoveryProperties.getClusterName(); + if (StringUtils.hasText(clusterName)) { + userClusterName = true; + clusterNameList = Collections.singletonList(clusterName); + } + } + + public NamingService getNamingService() { + return namingService; + } + + @Override + public RegistryCenter.Status getRegistryCenterStatus() { + String status = namingService.getServerStatus(); + return transfrom(status); + } + + private RegistryCenter.Status transfrom(String status) { + if (status.equals("UP")) { + return RegistryCenter.Status.UP; + + } else if (status.equals("DOWN")) { + return RegistryCenter.Status.DOWN; + + } else { + log.warn("{} status is {}", id, status); + return RegistryCenter.Status.UNKNOWN; + } + } + + @Override + public String getInstance(String service) { + Instance instance = getInstanceInfo(service); + return instance.getIp() + Consts.S.COLON + instance.getPort(); + } + + public Instance getInstanceInfo(String service) { + Instance instance = null; + try { + if (useGroupName && userClusterName) { + instance = namingService.selectOneHealthyInstance(service, groupName, clusterNameList); + } else if (useGroupName) { + instance = namingService.selectOneHealthyInstance(service, groupName); + } else if (userClusterName) { + instance = namingService.selectOneHealthyInstance(service, clusterNameList); + } else { + instance = namingService.selectOneHealthyInstance(service); + } + } catch (NacosException e) { + throw new RuntimeException(e); + } + if (instance == null) { + throw Utils.runtimeExceptionWithoutStack(id + " nacos no " + service); + } + return instance; } } diff --git a/fizz-core/src/test/java/we/service_registry/RegistryCenterServiceTests.java b/fizz-core/src/test/java/we/service_registry/RegistryCenterServiceTests.java new file mode 100644 index 0000000..f0b45e4 --- /dev/null +++ b/fizz-core/src/test/java/we/service_registry/RegistryCenterServiceTests.java @@ -0,0 +1,63 @@ +package we.service_registry; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.data.redis.core.ReactiveStringRedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import we.Fizz; +import we.redis.RedisProperties; +import we.redis.RedisServerConfiguration; +import we.redis.RedisTemplateConfiguration; +import we.service_registry.eureka.FizzEurekaServiceRegistration; +import we.util.ReflectionUtils; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * @author hongqiaowei + */ + +@TestPropertySource("/application.properties") +@SpringJUnitConfig(classes = {RedisProperties.class, RedisTemplateConfiguration.class, RedisServerConfiguration.class}) +public class RegistryCenterServiceTests { + + @Resource + StringRedisTemplate stringRedisTemplate; + + @Resource + ReactiveStringRedisTemplate reactiveStringRedisTemplate; + + RegistryCenterService registryCenterService; + + // @BeforeEach + void beforeEach() throws NoSuchFieldException { + registryCenterService = new RegistryCenterService(); + ReflectionUtils.set(registryCenterService, "rt", reactiveStringRedisTemplate); + } + + // @Test + void initTest() throws Throwable { + + System.setProperty("server.port", "8866"); + Fizz.context = new GenericApplicationContext(); + Fizz.context.refresh(); + + Map registryCenterServiceMap = new HashMap<>(); + String yml = FileUtil.readString("eureka.yml", CharsetUtil.CHARSET_UTF_8); + registryCenterServiceMap.put("1", "{\"id\":1,\"name\":\"default\",\"type\":1,\"format\":1,\"content\":\"" + yml + "\",\"isDeleted\":0}"); + stringRedisTemplate.opsForHash().putAll("fizz_registry", registryCenterServiceMap); + + registryCenterService.init(); + RegistryCenter def = registryCenterService.getRegistryCenter("default"); + FizzServiceRegistration fizzServiceRegistration = def.getFizzServiceRegistration(); + fizzServiceRegistration.register(); + // Thread.currentThread().join(); + } +} diff --git a/fizz-core/src/test/java/we/util/YmlUtilsTest.java b/fizz-core/src/test/java/we/util/YmlUtilsTest.java new file mode 100644 index 0000000..ecb6b9a --- /dev/null +++ b/fizz-core/src/test/java/we/util/YmlUtilsTest.java @@ -0,0 +1,30 @@ +package we.util; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import org.junit.jupiter.api.Test; +import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +public class YmlUtilsTest { + + @Test + void config2bean() throws IOException { + String s = FileUtil.readString("eureka.yml", CharsetUtil.CHARSET_UTF_8); + Properties properties = YmlUtils.string2properties(s); + // System.err.println("properties: \n" + properties); + properties = PropertiesUtils.remove(properties, "eureka.client"); + EurekaClientConfigBean eurekaClientConfig = new EurekaClientConfigBean(); + Map> propertyTypeHint = new HashMap<>(); + propertyTypeHint.put("serviceUrl", Map.class); + PropertiesUtils.setBeanPropertyValue(eurekaClientConfig, properties, propertyTypeHint); + // System.err.println(JacksonUtils.writeValueAsString(eurekaClientConfig)); + + // ClassPathResource resource = new ClassPathResource("application.properties"); + // properties = PropertiesLoaderUtils.loadProperties(resource); + } +} diff --git a/fizz-core/src/test/resources/eureka.yml b/fizz-core/src/test/resources/eureka.yml new file mode 100644 index 0000000..a26e47a --- /dev/null +++ b/fizz-core/src/test/resources/eureka.yml @@ -0,0 +1,10 @@ + +eureka: + client: + enabled: true + serviceUrl: + defaultZone: http://6.6.6.6:6600/eureka,http://8.8.8.8:6600/eureka + instance: + appname: abc + prefer-ip-address: true + lease-renewal-interval-in-seconds: 66 diff --git a/fizz-spring-boot-starter/pom.xml b/fizz-spring-boot-starter/pom.xml index 64c65bc..51aec0b 100644 --- a/fizz-spring-boot-starter/pom.xml +++ b/fizz-spring-boot-starter/pom.xml @@ -179,6 +179,12 @@ org.apache.dubbo dubbo + + + netty-tcnative-classes + io.netty + + @@ -218,6 +224,10 @@ log4j log4j + + netty-tcnative-classes + io.netty + @@ -245,6 +255,12 @@ com.fizzgate fizz-core + + + netty-tcnative-classes + io.netty + + com.fizzgate diff --git a/pom.xml b/pom.xml index 742127d..867e242 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ 2.2.13.RELEASE - 5.2.18.RELEASE + 5.2.19.RELEASE Dysprosium-SR25 5.3.7.RELEASE 2.2.6.RELEASE - 4.1.70.Final - 4.4.14 - 2.14.1 + 4.1.72.Final + 4.4.15 + 2.17.0 1.7.32 2.7.5 1.16.1 @@ -25,6 +25,7 @@ 2.0.46.Final 2.2.9.RELEASE 1.7.1 + 1.30 @@ -433,11 +434,16 @@ netty-tcnative-boringssl-static ${netty-tcnative.version} + + io.netty + netty-tcnative-classes + ${netty-tcnative.version} + cn.hutool hutool-crypto - 5.7.16 + 5.7.17