diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e02a719..0000000 --- a/.gitignore +++ /dev/null @@ -1,74 +0,0 @@ -# Compiled source # -################### -*.com -*.class -*.dll -*.exe -*.o -*.so - -# Packages # -############ -# it's better to unpack these files and commit the raw source -# git has its own built in compression methods -*.7z -*.dmg -*.gz -*.iso -*.jar -*.rar -*.tar -*.zip - -# Logs and databases # -###################### -*.log - -# OS generated files # -###################### -.DS_Store* -ehthumbs.db -Icon? -Thumbs.db - -# Editor Files # -################ -*~ -*.swp - -# Gradle Files # -################ -.gradle -.m2 - -# Build output directies -/target -*/target -/build -*/build -/bin -*/bin -classes - -# -# # IntelliJ specific files/directories - -# IntelliJ specific files/directories -out -.idea -*.ipr -*.iws -*.iml -atlassian-ide-plugin.xml - -# Eclipse specific files/directories -.classpath -.project -.settings -.metadata - -# NetBeans specific files/directories -.nbattrs - -# publishing secrets -secrets/signing-key diff --git a/README.md b/README.md index f2b5f9d..f9bb55b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,90 @@ -# Pantheon -Pantheon is inspired by Eureka and Nacos, aiming to build a better Service Registry Center +# AndroidArchitectureCollection +安卓架构文章合集(a collection of android Architecture) -Numerous terrific code snippets and architecture ideas from RocketMq, Zookeeper, ElasticSearch, Redis,Eureka,Nacos, Dubbo...... -are introduced into this project. \ No newline at end of file +###博客原地址: ++ [简书博客](http://www.jianshu.com/p/1f21e1d375aa) + +###github地址: ++ [AndroidArchitectureCollection github地址](https://github.com/CameloeAnthony/AndroidArchitectureCollection) +请关注github,后续会在github上面更新 + +这是从各大平台上参考的android架构文章,文章数据,主要参考自Info,推荐关注: ++ [http://www.infoq.com/cn/](http://www.infoq.com/cn/) + +#1 Android官方架构: ++ [googlesamples/android-architecture](https://github.com/googlesamples/android-architecture)(google官方android架构项目) + +#2 国内各大平台架构: ++ [App工程结构搭建:几种常见Android代码架构分析](http://www.uml.org.cn/mobiledev/201310211.asp) ++ [携程Mobile架构演化(视频)](http://www.infoq.com/cn/presentations/ctrip-mobile-architecture-evolution) ++ [携程Android App插件化和动态加载实践](http://www.infoq.com/cn/articles/ctrip-android-dynamic-loading) ++ [陶钧谈淘宝客户端应用框架实践](http://www.infoq.com/cn/interviews/tj-taobao-client-arch) ++ [QCon旧金山演讲总结:阿里无线技术架构演进](http://www.infoq.com/cn/articles/alibaba-mobile-infrastructure) ++ [手机淘宝构架演化实践](http://www.infoq.com/cn/news/2014/12/taobao-app-evolution) ++ [手机淘宝Android客户端架构](http://www.open-open.com/lib/view/open1436316754208.html) ++ [漫谈移动应用架构设计](http://club.alibabatech.org/resource_detail.htm?topicId=124) ++ [大规模团队的Android开发](http://club.alibabatech.org/resource_detail.htm?topicId=130) ++ [支付宝钱包客户端技术架构](http://club.alibabatech.org/resource_detail.htm?topicId=155) ++ [手机百度Android平台平台化解决方案](http://www.infoq.com/cn/presentations/mobile-baidu-android-platform-solutions) ++ [涅盘新生—Android QQ音乐架构演进](http://www.infoq.com/cn/presentations/evolution-of-android-qq-music-architecture) ++ [微信Android客户端架构演进之路](http://www.infoq.com/cn/articles/wechat-android-app-architecture) ++ [饿了么移动APP的架构演进](https://mp.weixin.qq.com/s?__biz=MzAxNDUwMzU3Mw==&mid=401044540&idx=1&sn=24b7d8fb655ae6dd5d989d0cb3c08e90&scene=2&srcid=0106EtxRjD2jHxzomxVPTwY3&from=timeline&isappinstalled=0&uin=NzgwODIwNDgw&key=&devicetype=webwx&version=70000001&lang=zh_CN&pass_ticket=46hW44w3Hxd7VY9rutz7mgLu1JGe2T1AAKNQpxNoYOSGi8NpmNYr%2BAZj%2BiXtRX2F) ++ [糯米移动组件架构演进之路](https://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112195&idx=1&sn=27fa638e90b09a107057e4a5e8d01ab1&scene=0&key=b28b03434249256bfa802f640871a1d36fcc58d62fbdae43d4cf0bb232988312ebd980373392cdb72dff355da09201bf&ascene=0&uin=Mjc3OTU3Nzk1&devicetype=iMac+MacBookPro10%2C1+OSX+OSX+10.10.5+build%2814F1713%29&version=11020201&pass_ticket=fVNELMIhboNqtKbXT0UAQtJy1MNge%2F0s6VqFTdnuSJvfHsNGCxh1X%2FVk7UdXna7W) ++ [英语流利说 Android 架构演进](http://mp.weixin.qq.com/s?__biz=MzI0NjIzNDkwOA==&mid=2247483673&idx=1&sn=ba9cf498ab78646f1a9c9e711f65c360&scene=2&srcid=0527JyTxU6ucKtlLVyl7REaB&from=timeline&isappinstalled=0#wechat_redirect) ++ [七牛云存储-千万级用户的 ANDROID 客户端是如何养成的](http://blog.qiniu.com/archives/6017) + +#2 MVVM & MVP & MVC + ++ [ANDROID DATABINDING: GOODBYE PRESENTER, HELLO VIEWMODEL](http://tech.vg.no/2015/07/17/android-databinding-goodbye-presenter-hello-viewmodel/) +(viewmodel,安卓中的databinding) ++ [MVVM-in-Android](http://www.codeproject.com/Articles/166952/MVVM-in-Android)(android中的mvvm) ++ [ ZhiHuMVP github 地址](https://github.com/CameloeAnthony/ZhiHuMVP)(MVP架构思想,Retrofit RESTful API 框架的配合,RxJava 响应式编程) ++ [ androidmvp github地址](https://github.com/antoniolg/androidmvp)(star2000+的MVP实例) ++ [MVP for Android: how to organize the presentation layer](http://antonioleiva.com/mvp-android/)(上面这个github对应的文章) ++ [ Introduction-to-Model-View-Presenter-on-Android](https://github.com/konmik/konmik.github.io/wiki/Introduction-to-Model-View-Presenter-on-Android)(MVP的介绍,MVP必读经典) ++ [Introduction-to-Model-View-Presenter-on-Android 中文翻译版](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0425/2782.html) ++ [ActivityFragmentMVP github地址](https://github.com/spengilley/ActivityFragmentMVP)(MVP处理Activity和Fragment,使用了Dagger 注入) ++ [ EffectiveAndroidUI github地址](https://github.com/pedrovgs/EffectiveAndroidUI)(star 3000+的mvp,mvvm实例) ++ [ MvpCleanArchitecture github地址](https://github.com/glomadrian/MvpCleanArchitecture)(使用clean architecture 和mvp的实例) ++ [ Material-Movies github地址](https://github.com/saulmm/Material-Movies)( 使用material design +MVP实现的Material-Movies) ++ [EffectiveAndroid github地址](https://github.com/rallat/EffectiveAndroid)(MVP+clean Architecture 项目) ++ [AndroidMVPDemo github地址](https://github.com/CameloeAnthony/AndroidMVPDemo)(本文作者MVP demo github地址) ++ [MVVM on Android: What You Need to Know](http://willowtreeapps.com/blog/mvvm-on-android-what-you-need-to-know/)(MVVM介绍,这个博客很不错) ++ [data-bingding guide](https://developer.android.com/tools/data-binding/guide.html)(data-binding guide官网) ++ [Android应用开发架构概述](http://www.liuguangli.win/archives/299) ++ [MVVM介绍](http://objccn.io/issue-13-1/)(iOS中MVVM的一种实现,对概念的理解有帮助) ++ [Android Architecture](https://medium.com/android-news/android-architecture-2f12e1c7d4db#.ta695te6a)(区分andrtoid项目中的MVVM,MVP,MVC) ++ [Web开发的MVVM模式](http://www.cnblogs.com/dxy1982/p/3793895.html)(web开发中的MVC VS. MVP VS. MVVM) ++ [M — Model in MVC, MVP, MVVC in Android](https://medium.com/@artem_zin/m-model-from-mvc-mvp-in-android-flow-and-mortar-bd1e50c45395#.5kbw4q5psd)(android工程MVC,MVVC,MVVM中的Model角色讲解) ++ [Android MVP架构中的Presentation层应该怎么设计](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=402868193&idx=1&sn=790e12f84dfcea171528e6d3789c69ed#rd)(如果你面临部分代码不知道放到Presentation层还是UI层的问题,甚至你不知道某段代码是否属于业务代码。不知道如何分清MVP中的代码职责,参考这篇文章) + +#3 Android中的设计模式: ++ [Software design pattern on android](http://www.slideshare.net/PedroVicenteGmezSnch/software-design-patterns-on-android)(安卓中的设计模式,英文ppt) ++ 强烈推荐书籍《Android 源码设计模式解析与实战》 + +#4 Clean Architecture ++ [The Clean Architecture](https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html)(clean architecture出处) ++ [Android-CleanArchitecture github地址](https://github.com/android10/Android-CleanArchitecture)(The Clean Architecture文章的例子) ++ [Android Application Architecture原文](https://medium.com/ribot-labs/android-application-architecture-8b6e34acda65#.b29vhtdm2) ++ [Android Application Architecture中文翻译](http://www.jianshu.com/p/8ca27934c6e6) ++ [Architecting Android…The evolution](http://fernandocejas.com/2015/07/18/architecting-android-the-evolution/) ++ [Architecting Android…The evolution中文翻译](http://www.devtf.cn/?p=1083) + +#5 Flux +* [flux and android](https://armueller.github.io/android/2015/03/29/flux-and-android.html) +* [rxflux android architecture](https://medium.com/swlh/rxflux-android-architecture-94f77c857aa2#.sfjwchwok) +* [why rxflux](https://medium.com/swlh/why-rxflux-5b687f062709#.ltlnlr4cl) +* [android flux todo app](https://github.com/lgvalle/android-flux-todo-app)([中文翻译](http://www.devtf.cn/?p=1028)) +* [RxFlux](https://github.com/skimarxall/RxFlux) +* [android-flux](https://github.com/naodroid/android-flux) + +#6 其它 ++ [Artchitecture Library](https://github.com/Juude/Awesome-Android-Architecture/blob/master/Library.md) ++ [Design for Offline: Android App Architecture Best Practices](https://plus.google.com/+AndroidDevelopers/posts/3C4GPowmWLb) ++ [Robust and readable architecture for an Android App](http://blog.joanzapata.com/robust-architecture-for-an-android-app/) ++ [Android application architecture](https://events.google.com/io2015/schedule?sid=358c9f91-b6d4-e411-b87f-00155d5066d7#day1/358c9f91-b6d4-e411-b87f-00155d5066d7) ++ [google官方MVP架构示例项目解析](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=403539764&idx=1&sn=d30d89e6848a8e13d4da0f5639100e5f#rd)(google官网架构中文解析) ++ [jiangqqlmj](https://github.com/jiangqqlmj)/**[FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)** (android快速开发框架) ++ [知乎:Android 开发有什么好的架构么?](https://www.zhihu.com/question/21406685) ++ [知乎:如果从0创建一个Android APP,设计思路是什么?(架构、activity、layout等复用性的考虑),感觉无从下手](https://www.zhihu.com/question/28564947) ++ [AndroidTDDBootStrap Github地址](https://github.com/Piasy/AndroidTDDBootStrap)(AndroidTDDBootStrap 是一个Android TDD 引导项目,使用一些新技术,灵感来自于一些最流行的框架,有许多方便的开发工具,遵循最佳实践。) diff --git a/pantheon-client/pom.xml b/pantheon-client/pom.xml deleted file mode 100644 index c8e2a3c..0000000 --- a/pantheon-client/pom.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - - 4.0.0 - pantheon-client - jar - pantheon-client ${project.version} - - - - 8 - 8 - - - - - - javax.jms - jms - 1.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - log4j - log4j - 1.2.17 - - - com.alibaba - fastjson - 1.2.71 - - - io.netty - netty-all - 4.0.42.Final - - - com.netflix.archaius - archaius-core - 0.7.6 - - - commons-configuration - commons-configuration - 1.8 - - - ${project.groupId} - pantheon-remoting - 1.0-SNAPSHOT - - - ${project.groupId} - pantheon-common - 1.0-SNAPSHOT - - - org.springframework - spring-context - 4.3.18.RELEASE - compile - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.8 - 1.8 - - - - - \ No newline at end of file diff --git a/pantheon-client/src/main/java/com/pantheon/client/CacheRefreshedEvent.java b/pantheon-client/src/main/java/com/pantheon/client/CacheRefreshedEvent.java deleted file mode 100644 index 76eddf7..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/CacheRefreshedEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.pantheon.client; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc - **/ -public class CacheRefreshedEvent implements PantheonEvent { - public CacheRefreshedEvent() { - } - - public String toString() { - return "CacheRefreshedEvent[timestamp=" + System.currentTimeMillis()+ "]"; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/ClientBootStrap.java b/pantheon-client/src/main/java/com/pantheon/client/ClientBootStrap.java deleted file mode 100644 index 20460a9..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/ClientBootStrap.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.pantheon.client; - -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.common.ShutdownHookThread; -import com.pantheon.common.lifecycle.Lifecycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.Callable; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class ClientBootStrap { - private static final Logger logger = LoggerFactory.getLogger(ClientBootStrap.class); - - public static void main(String[] args) { - logger.info("InstanceBootStrap initializing......"); - DiscoveryClientNode discoveryClientNode = ClientManager.getInstance().getOrCreateClientNode(DefaultInstanceConfig.getInstance()); - - discoveryClientNode.start(); - if (!discoveryClientNode.lifecycleState().equals(Lifecycle.State.STARTED)) { - discoveryClientNode.stop(); - System.exit(-3); - } - Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(logger, (Callable) () -> { - discoveryClientNode.stop(); - return null; - })); - } - - public static void shutdown(final DiscoveryClientNode discoveryClientNode) { - discoveryClientNode.stop(); - } - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/ClientManager.java b/pantheon-client/src/main/java/com/pantheon/client/ClientManager.java deleted file mode 100644 index fd47016..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/ClientManager.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.pantheon.client; - -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.remoting.netty.NettyClientConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author Anthony - * @create 2021/12/5 - * @desc singleton to manage all clients - */ -public class ClientManager { - private static final Logger logger = LoggerFactory.getLogger(ClientManager.class); - - private ConcurrentMap factoryTable = - new ConcurrentHashMap<>(); - private NettyClientConfig nettyClientConfig; - - private static ClientManager instance = new ClientManager(); - private DefaultInstanceConfig instanceConfig; - - private ClientManager() { - - } - - public static ClientManager getInstance() { - return instance; - } - - public DiscoveryClientNode getOrCreateClientNode() { - this.instanceConfig = DefaultInstanceConfig.getInstance(); - nettyClientConfig = new NettyClientConfig(); - - String clientId = getInstance().buildClientId(); - DiscoveryClientNode instance = this.factoryTable.get(clientId); - if (null == instance) { - instance = new DiscoveryClientNode(nettyClientConfig, instanceConfig, clientId); - DiscoveryClientNode prev = this.factoryTable.putIfAbsent(clientId, instance); - if (prev != null) { - instance = prev; - logger.warn("Returned Previous ClientNode for clientId:[{}]", clientId); - } else { - logger.info("Created new ClientNode for clientId:[{}]", clientId); - } - } - - return instance; - - } - - - public DiscoveryClientNode getOrCreateClientNode(DefaultInstanceConfig instanceConfig) { - this.instanceConfig = instanceConfig; - nettyClientConfig = new NettyClientConfig(); - - String clientId = getInstance().buildClientId(); - DiscoveryClientNode instance = this.factoryTable.get(clientId); - if (null == instance) { - instance = new DiscoveryClientNode(nettyClientConfig, instanceConfig, clientId); - DiscoveryClientNode prev = this.factoryTable.putIfAbsent(clientId, instance); - if (prev != null) { - instance = prev; - logger.warn("Returned Previous ClientNode for clientId:[{}]", clientId); - } else { - logger.info("Created new ClientNode for clientId:[{}]", clientId); - } - } - - return instance; - - } - - public String buildClientId() { - StringBuilder sb = new StringBuilder(); - sb.append(instanceConfig.getInstanceIpAddress()); - - sb.append(":"); - sb.append(instanceConfig.getServiceName()); - sb.append(":"); - sb.append(instanceConfig.getInstancePort()); - - return sb.toString(); - } - - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/DiscoveryClientNode.java b/pantheon-client/src/main/java/com/pantheon/client/DiscoveryClientNode.java deleted file mode 100644 index 0755fb4..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/DiscoveryClientNode.java +++ /dev/null @@ -1,708 +0,0 @@ -package com.pantheon.client; - -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.appinfo.LeaseInfo; -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.client.discovery.DiscoveryClient; -import com.pantheon.client.transport.ClientAPIImpl; -import com.pantheon.client.transport.ClientRemotingProcessor; -import com.pantheon.client.transport.HeartBeatSender; -import com.pantheon.client.transport.Server; -import com.pantheon.common.ObjectUtils; -import com.pantheon.common.ThreadFactoryImpl; -import com.pantheon.common.lifecycle.AbstractLifecycleComponent; -import com.pantheon.remoting.exception.RemotingCommandException; -import com.pantheon.remoting.exception.RemotingConnectException; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.netty.NettyClientConfig; -import io.netty.bootstrap.ServerBootstrap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc todo load specific instances not all - * todo throw PantheonException - **/ -public class DiscoveryClientNode extends AbstractLifecycleComponent implements DiscoveryClient, HeartBeatSender { - public static final int INSTANCE_REQUEST_TIMOUT_MILLS = 10000; - private NettyClientConfig nettyClientConfig; - private PantheonInstanceConfig instanceConfig; - private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl( - "InstanceControllerScheduledThread")); - private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); - private ClientAPIImpl clientAPI; - private Server server; - private String serviceName; - private final Lock lockHeartbeat = new ReentrantLock(); - private final String clientId; - private final AtomicLong fetchRegistryGeneration; - private final AtomicReference localRegionApps = new AtomicReference(); - private final ConcurrentHashMap appMap = new ConcurrentHashMap<>(); - private volatile int registrySize = 0; - private volatile long lastSuccessfulRegistryFetchTimestamp = -1; - private volatile long lastSuccessfulHeartbeatTimestamp = -1; - private final Lock fetchRegistryUpdateLock = new ReentrantLock(); - private InstanceInfo instanceInfo; - private volatile InstanceInfo.InstanceStatus lastRemoteInstanceStatus = InstanceInfo.InstanceStatus.UNKNOWN; - private final AtomicBoolean isShutdown = new AtomicBoolean(false); - - private final CopyOnWriteArraySet eventListeners = new CopyOnWriteArraySet<>(); - - public DiscoveryClientNode(PantheonInstanceConfig instanceConfig) { - this.nettyClientConfig = new NettyClientConfig(); - this.instanceConfig = instanceConfig; - this.clientId = ClientManager.getInstance().buildClientId(); - fetchRegistryGeneration = new AtomicLong(0); - localRegionApps.set(new Applications()); - clientAPI = new ClientAPIImpl(nettyClientConfig, instanceConfig, new ClientRemotingProcessor(), null); - } - - public DiscoveryClientNode(DefaultInstanceConfig instanceConfig, String clientId) { - this.nettyClientConfig = new NettyClientConfig(); - this.instanceConfig = instanceConfig; - this.clientId = clientId; - fetchRegistryGeneration = new AtomicLong(0); - localRegionApps.set(new Applications()); - clientAPI = new ClientAPIImpl(nettyClientConfig, instanceConfig, new ClientRemotingProcessor(), null); - } - - - public DiscoveryClientNode(NettyClientConfig nettyClientConfig, DefaultInstanceConfig instanceConfig, String clientId) { - this.nettyClientConfig = nettyClientConfig; - this.instanceConfig = instanceConfig; - this.clientId = clientId; - fetchRegistryGeneration = new AtomicLong(0); - localRegionApps.set(new Applications()); - clientAPI = new ClientAPIImpl(nettyClientConfig, instanceConfig, new ClientRemotingProcessor(), null); - } - - @Override - protected void doStart() { - this.checkConfig(); - clientAPI.start(); - - //choose a controller candidate from local config - String controllerCandidate = this.clientAPI.chooseControllerCandidate(); -// Integer nodeId = null; - try { -// nodeId = this.clientAPI.fetchServerNodeId(controllerCandidate, INSTANCE_REQUEST_TIMOUT_MILLS); -// logger.info("fetchServerNodeId successful load nodeId: " + nodeId); - Map> integerListMap = this.clientAPI.fetchSlotsAllocation(controllerCandidate, INSTANCE_REQUEST_TIMOUT_MILLS); - logger.info("fetchSlotsAllocation response : " + integerListMap); - - Map serverMap = this.clientAPI.fetchServerAddresses(controllerCandidate, INSTANCE_REQUEST_TIMOUT_MILLS); - logger.info("fetchServerAddresses response: " + serverMap); - - String serviceName = instanceConfig.getServiceName(); - server = this.clientAPI.routeServer(serviceName); - - sendRegister(); - - this.startScheduledTask(); - } catch (RemotingConnectException e) { - e.printStackTrace(); - } catch (RemotingSendRequestException e) { - e.printStackTrace(); - } catch (RemotingTimeoutException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (RemotingCommandException e) { - e.printStackTrace(); - } - } - - @Override - protected void doStop() { - if (isShutdown.compareAndSet(false, true)) { - if (this.clientAPI != null) { - this.clientAPI.shutdown(); - } - if (scheduledExecutorService != null) { - scheduledExecutorService.shutdown(); - } - if (this.instanceInfo != null) { - this.instanceInfo.setInstanceStatus(InstanceInfo.InstanceStatus.DOWN); - sendUnRegister(); - } - logger.info("Completed the shutdown of PantheonClient"); - } - } - - @Override - protected void doClose() throws IOException { - - } - - private void checkConfig() { - //todo check the config basically need - - } - - private void startScheduledTask() { - if (instanceConfig.shouldFetchRegistry()) { - boolean fetchRegistryResult = fetchRegistry(true); - if (fetchRegistryResult) { - logger.info("service fetch registry success!!!"); - if (localRegionApps.get().size() > 0) { - logger.info("register success , then fetch {} apps !!!", localRegionApps.get()); - } - } - scheduledExecutorService.scheduleAtFixedRate(new CacheRefreshThread(), instanceConfig.getRegistryFetchIntervalSeconds(), instanceConfig.getRegistryFetchIntervalSeconds(), TimeUnit.SECONDS); - } - - this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - sendHeartbeat(); - } - }, 1000, intervalMs(), TimeUnit.MILLISECONDS); - //heartbeat - } - - - @Override - public boolean sendHeartbeat(){ - if (this.lockHeartbeat.tryLock()) { - try { - boolean successResult = this.clientAPI.sendHeartBeatToServer(getServer(), getInstanceInfo().getAppName(), this.getClientId(), 3000L); - return successResult; - } catch (final Exception e) { - logger.error("sendHeartBeatToServer exception", e); - } finally { - this.lockHeartbeat.unlock(); - } - } else { - logger.warn("lock heartBeat, but failed. [{}]", instanceConfig.getServiceName()); - } - return false; - } - - @Override - public long intervalMs() { - return instanceConfig.getLeaseRenewalIntervalInSeconds() * 1000; - } - - private void sendUnRegister() { - try { - boolean unRegister = this.clientAPI.unRegister(getServer(), getServiceName(), getInstanceInfo().getInstanceId(), 3000); - if (unRegister) { - logger.info("unregister to server: {} successfully with instance info: {}", server, instanceInfo); - } else { - logger.info("unregister to server: {} failed with instance info: {}", server, instanceInfo); - } - } catch (RemotingConnectException e) { - e.printStackTrace(); - } catch (RemotingSendRequestException e) { - e.printStackTrace(); - } catch (RemotingTimeoutException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * default 30s to refresh registry info - */ - public void sendRegister() { - try { - boolean register = this.clientAPI.register(getServer(), getInstanceInfo(), INSTANCE_REQUEST_TIMOUT_MILLS); - if (register) { - logger.info("register to server: {} successfully with instance info: {}", server, instanceInfo); - //todo unregister process in thread,which is just for test , - new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - sendUnRegister(); - } - }).start(); - - } else { - logger.info("register to server: {} failed with instance info: {}", server, instanceInfo); - } - } catch (RemotingConnectException e) { - e.printStackTrace(); - } catch (RemotingSendRequestException e) { - e.printStackTrace(); - } catch (RemotingTimeoutException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - } - - private InstanceInfo getInstanceInfo() throws InterruptedException { - if (instanceInfo == null) { - instanceInfo = buildInstanceInfo(); - } - return instanceInfo; - } - - public synchronized InstanceInfo buildInstanceInfo() throws InterruptedException { - if (instanceInfo == null) { - // Build the lease information to be passed to the server based on config - LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder() - .setRenewalIntervalInSecs(instanceConfig.getLeaseRenewalIntervalInSeconds()) - .setDurationInSecs(instanceConfig.getLeaseExpirationDurationInSeconds()); - - // Builder the instance information to be registered with pantheon server - InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - - // set the appropriate id for the InstanceInfo - String instanceId = instanceConfig.getServiceName(); - - if (server == null) { - server = getServer(); - } - Integer slotNum = server.getSlotNum(); - - String defaultAddress = instanceConfig.getInstanceHostName(); - - - if (defaultAddress == null || defaultAddress.isEmpty()) { - defaultAddress = instanceConfig.getInstanceIpAddress(); - } - InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.UP; - - builder.setInstanceId(instanceId) - .setSlotNum(slotNum) - .setAppName(getServiceName()) - .setIPAddr(instanceConfig.getInstanceIpAddress()) - .setHostName(defaultAddress) - .setPort(instanceConfig.getInstancePort()).setStatus(initialStatus); - - - instanceInfo = builder.build(); - instanceInfo.setLeaseInfo(leaseInfoBuilder.build()); - } - return instanceInfo; - } - - /** - * The task that fetches the registry information at specified intervals. - */ - class CacheRefreshThread implements Runnable { - public void run() { - refreshRegistry(); - } - } - - void refreshRegistry() { - try { - boolean success = fetchRegistry(true); - if (success) { - registrySize = localRegionApps.get().size(); - lastSuccessfulRegistryFetchTimestamp = System.currentTimeMillis(); - } - - } catch (Throwable e) { - logger.error("Cannot fetch registry from server", e); - } - } - - - /** - * Fetches the registry information. - * - *

- * This method tries to get only deltas after the first fetch unless there - * is an issue in reconciling pantheon server and client registry information. - *

- * todo load delta with correct step - * - * @param forceFullRegistryFetch Forces a full registry fetch. - * @return true if the registry was fetched - */ - private boolean fetchRegistry(boolean forceFullRegistryFetch) { - - try { - // If the delta is disabled or if it is the first time, get all - // applications - Applications applications = getApplications(); - - if (forceFullRegistryFetch - || (applications == null) - || (applications.getRegisteredApplications().size() == 0)) { - logger.info("Force full registry fetch : {}", forceFullRegistryFetch); - logger.info("Application is null : {}", (applications == null)); - logger.info("Registered Applications size is zero : {}", - (applications.getRegisteredApplications().size() == 0)); - getAndStoreFullRegistry(); - } else { - getAndUpdateDelta(applications); - } - applications.setAppsHashCode(applications.getReconcileHashCode()); - logTotalInstances(); - } catch (Throwable e) { - logger.error("ClientNode was unable to refresh its cache! status = " + e.getMessage(), e); - return false; - } - - // Notify about cache refresh before updating the instance remote status - onCacheRefreshed(); - - // Update remote status based on refreshed data held in the cache - updateInstanceRemoteStatus(); - - // registry was fetched successfully, so return true - return true; - } - - /** - * Logs the total number of non-filtered instances stored locally. - */ - private void logTotalInstances() { - if (logger.isDebugEnabled()) { - int totInstances = 0; - for (Application application : getApplications().getRegisteredApplications()) { - totInstances += application.getInstancesAsIsFromPantheon().size(); - } - logger.debug("The total number of all instances in the client now is {}", totInstances); - } - } - - /** - * Invoked every time the local registry cache is refreshed (whether changes have - * been detected or not). - *

- * Subclasses may override this method to implement custom behavior if needed. - */ - protected void onCacheRefreshed() { - fireEvent(new CacheRefreshedEvent()); - } - - /** - * Send the given event on the EventBus if one is available - * - * @param event the event to send on the eventBus - */ - protected void fireEvent(final PantheonEvent event) { - for (PantheonEventListener listener : eventListeners) { - listener.onEvent(event); - } - } - - - private synchronized void updateInstanceRemoteStatus() { - // Determine this instance's status for this app and set to UNKNOWN if not found - InstanceInfo.InstanceStatus currentRemoteInstanceStatus = null; - if (instanceInfo.getAppName() != null) { - Application app = getApplication(instanceInfo.getAppName()); - if (app != null) { - InstanceInfo remoteInstanceInfo = app.getByInstanceId(instanceInfo.getId()); - if (remoteInstanceInfo != null) { - currentRemoteInstanceStatus = remoteInstanceInfo.getStatus(); - } - } - } - if (currentRemoteInstanceStatus == null) { - currentRemoteInstanceStatus = InstanceInfo.InstanceStatus.UNKNOWN; - } - - // Notify if status changed - if (lastRemoteInstanceStatus != currentRemoteInstanceStatus) { - onRemoteStatusChanged(lastRemoteInstanceStatus, currentRemoteInstanceStatus); - lastRemoteInstanceStatus = currentRemoteInstanceStatus; - } - } - - public Applications getApplications() { - return localRegionApps.get(); - } - - @Override - public Applications getSubscribeApplications(String serviceId) { - return appMap.get(serviceId); - } - - @Override - public void shutdown() { - super.close(); - } - - @Override - public PantheonInstanceConfig getPantheonClientConfig() { - return instanceConfig; - } - - public Application getApplication(String appName) { - return getApplications().getRegisteredApplications(appName); - } - - /** - * Gets the full registry information from the pantheon server and stores it locally. - * When applying the full registry, the following flow is observed: - *

- * if (update generation have not advanced (due to another thread)) - * atomically set the registry to the new registry - * fi - * - * @return the full registry information. - * @throws Throwable on error. - */ - private void getAndStoreFullRegistry() throws Throwable { - long currentUpdateGeneration = fetchRegistryGeneration.get(); - - logger.info("Getting all instance registry info from the pantheon server"); - - Applications apps = this.clientAPI.getApplications(server, 3000L); - - if (apps == null) { - logger.error("The application is null for some reason. Not storing this information"); - //AtomicLong fetchRegistryGeneration to fix multi-thread data conflict - } else if (fetchRegistryGeneration.compareAndSet(currentUpdateGeneration, currentUpdateGeneration + 1)) { - apps.shuffleInstances(instanceConfig.shouldFilterOnlyUpInstances()); - localRegionApps.set(apps); - - logger.debug("Got full registry with apps hashcode {}", apps.getAppsHashCode()); - } else { - logger.warn("Not updating applications as another thread is updating it already"); - } - } - - - /** - * Get the delta registry information from the pantheon server and update it locally. - * When applying the delta, the following flow is observed: - *

- * if (update generation have not advanced (due to another thread)) - * atomically try to: update application with the delta and get reconcileHashCode - * abort entire processing otherwise - * do reconciliation if reconcileHashCode clash - * fi - * - * @return the client response - * @throws Throwable on error - */ - private void getAndUpdateDelta(Applications applications) throws Throwable { - long currentUpdateGeneration = fetchRegistryGeneration.get(); - - Applications delta = this.clientAPI.getDelta(server, 3000L); - - if (delta == null) { - logger.warn("The server does not allow the delta revision to be applied because it is not safe. " - + "Hence got the full registry."); - getAndStoreFullRegistry(); - } else if (fetchRegistryGeneration.compareAndSet(currentUpdateGeneration, currentUpdateGeneration + 1)) { - logger.debug("Got delta update with apps hashcode {}", delta.getAppsHashCode()); - String reconcileHashCode = ""; - if (fetchRegistryUpdateLock.tryLock()) { - try { - updateDelta(delta); - reconcileHashCode = getReconcileHashCode(applications); - } finally { - fetchRegistryUpdateLock.unlock(); - } - } else { - logger.warn("Cannot acquire update lock, aborting getAndUpdateDelta"); - } - // There is a diff in number of instances for some reason - if (!reconcileHashCode.equals(delta.getAppsHashCode())) { - reconcileAndLogDifference(delta, reconcileHashCode); // this makes a remoteCall - } - } else { - logger.warn("Not updating application delta as another thread is updating it already"); - logger.debug("Ignoring delta update with apps hashcode {}, as another thread is updating it already", delta.getAppsHashCode()); - } - } - - - private String getReconcileHashCode(Applications applications) { - - TreeMap instanceCountMap = new TreeMap(); - applications.populateInstanceCountMap(instanceCountMap); - return Applications.getReconcileHashCode(instanceCountMap); - } - - /** - * Reconcile the pantheon server and client registry information and logs the differences if any. - * When reconciling, the following flow is observed: - *

- * 1. make a remote call to the server for the full registry - * 2. calculate and log differences - * 3. if (update generation have not advanced (due to another thread) atomically set the registry to the new registry - * - * @param delta the last delta registry information received from the pantheon - * server. - * @param reconcileHashCode the hashcode generated by the server for reconciliation. - * @return ClientResponse the HTTP response object. - * @throws Throwable on any error. - */ - private void reconcileAndLogDifference(Applications delta, String reconcileHashCode) throws Throwable { - logger.debug("The Reconcile hashcodes do not match, client : {}, server : {}. Getting the full registry", - reconcileHashCode, delta.getAppsHashCode()); - - - long currentUpdateGeneration = fetchRegistryGeneration.get(); - - Applications serverApps = getApplications(); - - if (serverApps == null) { - logger.warn("Cannot fetch full registry from the server; reconciliation failure"); - return; - } - - if (logger.isDebugEnabled()) { - try { - Map> reconcileDiffMap = getApplications().getReconcileMapDiff(serverApps); - StringBuilder reconcileBuilder = new StringBuilder(""); - for (Map.Entry> mapEntry : reconcileDiffMap.entrySet()) { - reconcileBuilder.append(mapEntry.getKey()).append(": "); - for (String displayString : mapEntry.getValue()) { - reconcileBuilder.append(displayString); - } - reconcileBuilder.append('\n'); - } - String reconcileString = reconcileBuilder.toString(); - logger.debug("The reconcile string is {}", reconcileString); - } catch (Throwable e) { - logger.error("Could not calculate reconcile string ", e); - } - } - - if (fetchRegistryGeneration.compareAndSet(currentUpdateGeneration, currentUpdateGeneration + 1)) { - serverApps.shuffleInstances(true); - localRegionApps.set(serverApps); - logger.debug( - "The Reconcile hashcodes after complete sync up, client : {}, server : {}.", - getApplications().getReconcileHashCode(), - delta.getAppsHashCode()); - } else { - logger.warn("Not setting the applications map as another thread has advanced the update generation"); - } - } - - - /** - * Updates the delta information fetches from the pantheon server into the - * local cache. - * - * @param delta the delta information received from pantheon server in the last - * poll cycle. - */ - private void updateDelta(Applications delta) { - int deltaCount = 0; - for (Application app : delta.getRegisteredApplications()) { - for (InstanceInfo instance : app.getInstances()) { - Applications applications = getApplications(); - - ++deltaCount; - if (InstanceInfo.ActionType.ADDED.equals(instance.getActionType())) { - Application existingApp = applications.getRegisteredApplications(instance.getAppName()); - if (existingApp == null) { - applications.addApplication(app); - } - logger.debug("Added instance {} to the existing apps ", instance.getId()); - applications.getRegisteredApplications(instance.getAppName()).addInstance(instance); - } else if (InstanceInfo.ActionType.MODIFIED.equals(instance.getActionType())) { - Application existingApp = applications.getRegisteredApplications(instance.getAppName()); - if (existingApp == null) { - applications.addApplication(app); - } - logger.debug("Modified instance {} to the existing apps ", instance.getId()); - - applications.getRegisteredApplications(instance.getAppName()).addInstance(instance); - - } else if (InstanceInfo.ActionType.DELETED.equals(instance.getActionType())) { - Application existingApp = applications.getRegisteredApplications(instance.getAppName()); - if (existingApp == null) { - applications.addApplication(app); - } - logger.debug("Deleted instance {} to the existing apps ", instance.getId()); - applications.getRegisteredApplications(instance.getAppName()).removeInstance(instance); - } - } - } - logger.debug("The total number of instances fetched by the delta processor : {}", deltaCount); - - getApplications().shuffleInstances(instanceConfig.shouldFilterOnlyUpInstances()); - - } - - /** - * Invoked when the remote status of this client has changed. - * Subclasses may override this method to implement custom behavior if needed. - * - * @param oldStatus the previous remote {@link InstanceInfo.InstanceStatus} - * @param newStatus the new remote {@link InstanceInfo.InstanceStatus} - */ - protected void onRemoteStatusChanged(InstanceInfo.InstanceStatus oldStatus, InstanceInfo.InstanceStatus newStatus) { - fireEvent(new StatusChangeEvent(oldStatus, newStatus)); - } - - @Override - public boolean unregisterEventListener(PantheonEventListener eventListener) { - return this.eventListeners.remove(eventListener); - } - - @Override - public void registerEventListener(PantheonEventListener eventListener) { - this.eventListeners.add(eventListener); - } - - public Server getServer() throws InterruptedException { - if (ObjectUtils.isEmpty(server)) { - synchronized (this) { - while (ObjectUtils.isEmpty(server)) { - server = this.clientAPI.routeServer(getServiceName()); - Thread.sleep(10); - } - } - } - return server; - } - - public String getServiceName() { - if (ObjectUtils.isEmpty(serviceName)) { - serviceName = instanceConfig.getServiceName(); - } - return serviceName; - } - - public String getClientId() { - return clientId; - } - - - @Override - public List getInstance(String address) { - return null; - } - - public InstanceInfo.InstanceStatus getInstanceRemoteStatus() { - return lastRemoteInstanceStatus; - } - - public long getLastSuccessfulRegistryFetchTimePeriod() { - return lastSuccessfulRegistryFetchTimestamp < 0 - ? lastSuccessfulRegistryFetchTimestamp - : System.currentTimeMillis() - lastSuccessfulRegistryFetchTimestamp; - } - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/PantheonEvent.java b/pantheon-client/src/main/java/com/pantheon/client/PantheonEvent.java deleted file mode 100644 index 6442b48..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/PantheonEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.pantheon.client; - -/** - * Marker interface for Pantheon events - * - * @see {@link PantheonEventListener} - */ -public interface PantheonEvent { -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/PantheonEventListener.java b/pantheon-client/src/main/java/com/pantheon/client/PantheonEventListener.java deleted file mode 100644 index f03568e..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/PantheonEventListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.pantheon.client; - -/** - * Listener for receiving {@link DiscoveryClientNode} events such as {@link StatusChangeEvent}. Register - * a listener by calling {@link DiscoveryClientNode#registerEventListener(PantheonEventListener)} - */ -public interface PantheonEventListener { - /** - * Notification of an event within the {@link DiscoveryClientNode}. - * - * {@link PantheonEventListener#onEvent} is called from the context of an internal pantheon thread - * and must therefore return as quickly as possible without blocking. - * - * @param event - */ - public void onEvent(PantheonEvent event); -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/RebalanceService.java b/pantheon-client/src/main/java/com/pantheon/client/RebalanceService.java deleted file mode 100644 index 4ebdda7..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/RebalanceService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.pantheon.client; - -/** - * @author Anthony - * @create 2021/11/27 - * @desc todo Rebalance service - */ -public class RebalanceService { -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/StatusChangeEvent.java b/pantheon-client/src/main/java/com/pantheon/client/StatusChangeEvent.java deleted file mode 100644 index 00f2604..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/StatusChangeEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.pantheon.client; - -import com.pantheon.client.appinfo.InstanceInfo; - -/** - * Event containing the latest instance status information. This event - * is sent to the {@link com.netflix.eventbus.spi.EventBus} by {@link DiscoveryClientNode ) whenever - * a status change is identified from the remote Pantheon server response. - */ -public class StatusChangeEvent implements PantheonEvent{ - // System time when the event happened - private final long timestamp; - private final InstanceInfo.InstanceStatus current; - private final InstanceInfo.InstanceStatus previous; - - public StatusChangeEvent(InstanceInfo.InstanceStatus previous, InstanceInfo.InstanceStatus current) { - this.timestamp = System.currentTimeMillis(); - this.current = current; - this.previous = previous; - } - - - /** - * @return Return the system time in milliseconds when the event happened. - */ - public final long getTimestamp() { - return this.timestamp; - } - - /** - * Return the up current when the event was generated. - * @return true if current is up or false for ALL other current values - */ - public boolean isUp() { - return this.current.equals(InstanceInfo.InstanceStatus.UP); - } - - /** - * @return The current at the time the event is generated. - */ - public InstanceInfo.InstanceStatus getStatus() { - return current; - } - - /** - * @return Return the client status immediately before the change - */ - public InstanceInfo.InstanceStatus getPreviousStatus() { - return previous; - } - - @Override - public String toString() { - return "StatusChangeEvent [timestamp=" + getTimestamp() + ", current=" + current + ", previous=" - + previous + "]"; - } - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/appinfo/Application.java b/pantheon-client/src/main/java/com/pantheon/client/appinfo/Application.java deleted file mode 100644 index 0ef5733..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/appinfo/Application.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.pantheon.client.appinfo; - -import com.pantheon.client.config.DefaultInstanceConfig; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author Anthony - * @create 2021/11/28 - * @desc - * The Application class holds the list of instances for a particular - * application. - */ -public class Application { - - @Override - public String toString() { - return "Application [name=" + name + ", isDirty=" + isDirty - + ", instances=" + instances + ", instancesMap=" + instancesMap + "]"; - } - - - - private String name; - - private volatile boolean isDirty = false; - - private AtomicReference> shuffledInstances = new AtomicReference>(); - - - private final Set instances; - - private Map instancesMap; - - public Application() { - instances = new LinkedHashSet(); - instancesMap = new ConcurrentHashMap(); - } - - public Application(String name) { - this.name = name; - instancesMap = new ConcurrentHashMap(); - instances = new LinkedHashSet(); - } - - public Application(String name, - List instances) { - this(name); - for (InstanceInfo instanceInfo : instances) { - addInstance(instanceInfo); - } - } - - /** - * Add the given instance info the list. - * - * @param i the instance info object to be added. - */ - public void addInstance(InstanceInfo i) { - instancesMap.put(i.getId(), i); - synchronized (instances) { - instances.remove(i); - instances.add(i); - isDirty = true; - } - } - - /** - * Remove the given instance info the list. - * - * @param i the instance info object to be removed. - */ - public void removeInstance(InstanceInfo i) { - removeInstance(i, true); - } - - - /** - * Get the instance info that matches the given id. - * - * @param id the id for which the instance info needs to be returned. - * @return the instance info object. - */ - public InstanceInfo getByInstanceId(String id) { - return instancesMap.get(id); - } - - /** - * Gets the name of the application. - * - * @return the name of the application. - */ - public String getName() { - return name; - } - - /** - * Sets the name of the application. - * - * @param name the name of the application. - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the number of instances in this application - */ - public int size() { - return instances.size(); - } - - - /** - * Gets the list of non-shuffled and non-filtered instances associated with this particular - * application. - * - * @return list of non-shuffled and non-filtered instances associated with this particular - * application. - */ - public List getInstancesAsIsFromPantheon() { - synchronized (instances) { - return new ArrayList(this.instances); - } - } - /** - * Gets the list of instances associated with this particular application. - *

- * Note that the instances are always returned with random order after - * shuffling to avoid traffic to the same instances during startup. The - * shuffling always happens once after every fetch cycle as specified in - * {@link DefaultInstanceConfig#getRegistryFetchIntervalSeconds()}. - *

- * - * @return the list of shuffled instances associated with this application. - */ - public List getInstances() { - if (this.shuffledInstances.get() == null) { - return this.getInstancesAsIsFromPantheon(); - } else { - return this.shuffledInstances.get(); - } - } - - - /** - * Shuffles the list of instances in the application and stores it for - * future retrievals. - * - * @param filterUpInstances - * indicates whether only the instances with status - * {@link InstanceInfo.InstanceStatus#UP} needs to be stored. - */ - public void shuffleAndStoreInstances(boolean filterUpInstances) { - _shuffleAndStoreInstances(filterUpInstances); - } - - private void _shuffleAndStoreInstances(boolean filterUpInstances) { - List instanceInfoList; - synchronized (instances) { - instanceInfoList = new ArrayList(instances); - } - if (filterUpInstances) { - Iterator it = instanceInfoList.iterator(); - while (it.hasNext()) { - InstanceInfo instanceInfo = it.next(); - if (filterUpInstances && !InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())) { - it.remove(); - } - } - - } - Collections.shuffle(instanceInfoList); - this.shuffledInstances.set(instanceInfoList); - } - - private void removeInstance(InstanceInfo i, boolean markAsDirty) { - instancesMap.remove(i.getId()); - synchronized (instances) { - instances.remove(i); - if (markAsDirty) { - isDirty = true; - } - } - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/appinfo/Applications.java b/pantheon-client/src/main/java/com/pantheon/client/appinfo/Applications.java deleted file mode 100644 index 956775a..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/appinfo/Applications.java +++ /dev/null @@ -1,321 +0,0 @@ -package com.pantheon.client.appinfo; - -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.remoting.protocol.RemotingSerializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author Anthony - * @create 2021/11/28 - * @desc The class that wraps all the registry information returned by Pantheon server. - * - *

- * Note that the registry information is fetched from pantheon server as specified - * in {@link DefaultInstanceConfig#getRegistryFetchIntervalSeconds()}. Once the - * information is fetched it is shuffled and also filtered for instances with - * {@link InstanceInfo.InstanceStatus#UP} status as specified by the configuration - * {@link DefaultInstanceConfig#shouldFilterOnlyUpInstances()}. - *

- */ -public class Applications extends RemotingSerializable { - private static final String APP_INSTANCEID_DELIMITER = "$$"; - private static final Logger logger = LoggerFactory.getLogger(Applications.class); - private static final String STATUS_DELIMITER = "_"; - - private Long versionDelta = Long.valueOf(-1); - - - private AbstractQueue applications; - - private Map appNameApplicationMap = new ConcurrentHashMap(); - - private String appsHashCode; - - /** - * Create a new, empty Pantheon application list. - */ - public Applications() { - this.applications = new ConcurrentLinkedQueue<>(); - } - - /** - * Note that appsHashCode and versionDelta key names are formatted in a custom/configurable way. - */ - public Applications( - String appsHashCode, - Long versionDelta, - List registeredApplications) { - this.applications = new ConcurrentLinkedQueue<>(); - for (Application app : registeredApplications) { - this.addApplication(app); - } - this.appsHashCode = appsHashCode; - this.versionDelta = versionDelta; - } - - /** - * Create a new Pantheon application list, based on the provided applications. The provided container is - * not modified. - * - * @param apps the initial list of apps to store in this applications list - */ - public Applications(List apps) { - this.applications = new ConcurrentLinkedQueue(); - this.applications.addAll(apps); - } - - /** - * Add the application to the list. - * - * @param app the application to be added. - */ - public void addApplication(Application app) { - appNameApplicationMap.put(app.getName().toUpperCase(Locale.ROOT), app); - applications.add(app); - } - - - /** - * Gets the list of all registered applications from pantheon. - * - * @return list containing all applications registered with pantheon. - */ - public List getRegisteredApplications() { - List list = new ArrayList(); - list.addAll(this.applications); - return list; - } - - /** - * Gets the list of all registered applications for the given - * application name. - * - * @param appName the application name for which the result need to be fetched. - * @return the list of registered applications for the given application - * name. - */ - public Application getRegisteredApplications(String appName) { - return appNameApplicationMap.get(appName.toUpperCase(Locale.ROOT)); - } - - - /** - * @return a weakly consistent size of the number of instances in all the applications - */ - public int size() { - int result = 0; - for (Application application : applications) { - result += application.size(); - } - - return result; - } - - - /** - * Used by the pantheon server. Not for external use. - * - * @param hashCode the hash code to assign for this app collection - */ - public void setAppsHashCode(String hashCode) { - this.appsHashCode = hashCode; - } - - /** - * Used by the pantheon server. Not for external use. - * - * @return the string indicating the hashcode based on the applications stored. - */ - public String getAppsHashCode() { - return this.appsHashCode; - } - - /** - * Gets the hash code for this applications instance. Used for - * comparison of instances between pantheon server and pantheon client. - * - * @return the internal hash code representation indicating the information - * about the instances. - */ - public String getReconcileHashCode() { - TreeMap instanceCountMap = new TreeMap(); - populateInstanceCountMap(instanceCountMap); - return getReconcileHashCode(instanceCountMap); - } - - /** - * Populates the provided instance count map. The instance count map is used as part of the general - * app list synchronization mechanism. - * - * @param instanceCountMap the map to populate - */ - public void populateInstanceCountMap(TreeMap instanceCountMap) { - for (Application app : this.getRegisteredApplications()) { - for (InstanceInfo info : app.getInstancesAsIsFromPantheon()) { - AtomicInteger instanceCount = instanceCountMap.get(info.getStatus().name()); - if (instanceCount == null) { - instanceCount = new AtomicInteger(0); - instanceCountMap.put(info.getStatus().name(), instanceCount); - } - instanceCount.incrementAndGet(); - } - } - } - - /** - * Gets the reconciliation hashcode. The hashcode is used to determine whether the applications list - * has changed since the last time it was acquired. - * - * @param instanceCountMap the instance count map to use for generating the hash - * @return the hash code for this instance - */ - public static String getReconcileHashCode(TreeMap instanceCountMap) { - String reconcileHashCode = ""; - for (Map.Entry mapEntry : instanceCountMap.entrySet()) { - reconcileHashCode = reconcileHashCode + mapEntry.getKey() - + STATUS_DELIMITER + mapEntry.getValue().get() - + STATUS_DELIMITER; - } - return reconcileHashCode; - } - - /** - * Gets the exact difference between this applications instance and another - * one. - * - * @param apps the applications for which to compare this one. - * @return a map containing the differences between the two. - */ - public Map> getReconcileMapDiff(Applications apps) { - Map> diffMap = new TreeMap>(); - Set allInstanceAppInstanceIds = new HashSet(); - for (Application otherApp : apps.getRegisteredApplications()) { - Application thisApp = this.getRegisteredApplications(otherApp.getName()); - if (thisApp == null) { - logger.warn("Application not found in local cache : {}", otherApp.getName()); - continue; - } - for (InstanceInfo instanceInfo : thisApp.getInstancesAsIsFromPantheon()) { - allInstanceAppInstanceIds.add(new Pair(thisApp.getName(), - instanceInfo.getId())); - } - for (InstanceInfo otherInstanceInfo : otherApp.getInstancesAsIsFromPantheon()) { - InstanceInfo thisInstanceInfo = thisApp.getByInstanceId(otherInstanceInfo.getId()); - if (thisInstanceInfo == null) { - List diffList = diffMap.get(InstanceInfo.ActionType.DELETED.name()); - if (diffList == null) { - diffList = new ArrayList(); - diffMap.put(InstanceInfo.ActionType.DELETED.name(), diffList); - } - diffList.add(otherInstanceInfo.getId()); - } else if (!thisInstanceInfo.getStatus().name() - .equalsIgnoreCase(otherInstanceInfo.getStatus().name())) { - List diffList = diffMap.get(InstanceInfo.ActionType.MODIFIED.name()); - if (diffList == null) { - diffList = new ArrayList(); - diffMap.put(InstanceInfo.ActionType.MODIFIED.name(), diffList); - } - diffList.add(thisInstanceInfo.getId() - + APP_INSTANCEID_DELIMITER - + thisInstanceInfo.getStatus().name() - + APP_INSTANCEID_DELIMITER - + otherInstanceInfo.getStatus().name()); - } - allInstanceAppInstanceIds.remove(new Pair(otherApp.getName(), otherInstanceInfo.getId())); - } - } - for (Pair pair : allInstanceAppInstanceIds) { - Application app = new Application(pair.getItem1()); - InstanceInfo thisInstanceInfo = app.getByInstanceId(pair.getItem2()); - if (thisInstanceInfo != null) { - List diffList = diffMap.get(InstanceInfo.ActionType.ADDED.name()); - if (diffList == null) { - diffList = new ArrayList(); - diffMap.put(InstanceInfo.ActionType.ADDED.name(), diffList); - } - diffList.add(thisInstanceInfo.getId()); - } - } - return diffMap; - - } - - private static final class Pair { - private final String item1; - private final String item2; - - public Pair(String item1, String item2) { - super(); - this.item1 = item1; - this.item2 = item2; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((item1 == null) ? 0 : item1.hashCode()); - result = prime * result - + ((item2 == null) ? 0 : item2.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Pair other = (Pair) obj; - if (item1 == null) { - if (other.item1 != null) { - return false; - } - } else if (!item1.equals(other.item1)) { - return false; - } - if (item2 == null) { - if (other.item2 != null) { - return false; - } - } else if (!item2.equals(other.item2)) { - return false; - } - return true; - } - - public String getItem1() { - return item1; - } - - public String getItem2() { - return item2; - } - } - - /** - * Shuffles the provided instances so that they will not always be returned in the same order. - * - * @param filterUpInstances whether to return only UP instances - */ - public void shuffleInstances(boolean filterUpInstances) { - for (Application application : appNameApplicationMap.values()) { - application.shuffleAndStoreInstances(filterUpInstances); - } - } - - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/appinfo/InstanceInfo.java b/pantheon-client/src/main/java/com/pantheon/client/appinfo/InstanceInfo.java deleted file mode 100644 index 59f92a3..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/appinfo/InstanceInfo.java +++ /dev/null @@ -1,657 +0,0 @@ -package com.pantheon.client.appinfo; - -import com.pantheon.remoting.protocol.RemotingSerializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Anthony - * @create 2021/11/28 - * @desc The class that holds information required for registration - */ -public class InstanceInfo extends RemotingSerializable { - - private String hostName; - - // one instance bind to one slot - private Integer slotNum; - - private LeaseInfo leaseInfo; - private InstanceStatus instanceStatus = InstanceStatus.UP; - - - private static final Logger logger = LoggerFactory.getLogger(InstanceInfo.class); - - public static final int DEFAULT_PORT = 7001; - public static final int DEFAULT_SECURE_PORT = 7002; - public static final int DEFAULT_COUNTRY_ID = 1; // US - - // The (fixed) instanceId for this instanceInfo. This should be unique within the scope of the appName. - private volatile String instanceId; - - private volatile String appName; - - private volatile String appGroupName; - - private volatile String ipAddr; - - - private volatile int port = DEFAULT_PORT; - private volatile int securePort = DEFAULT_SECURE_PORT; - - private volatile InstanceStatus status = InstanceStatus.UP; - private volatile InstanceStatus overriddenstatus = InstanceStatus.UNKNOWN; - private volatile boolean isInstanceInfoDirty = false; - private volatile Long lastUpdatedTimestamp = System.currentTimeMillis(); - private volatile Long lastDirtyTimestamp = System.currentTimeMillis(); - private volatile ActionType actionType; - private volatile Map metadata = new ConcurrentHashMap(); - - public InstanceInfo(){ - - } - public InstanceInfo(InstanceInfo ii) { - this.port = 7001; - this.securePort = 7002; - this.status = InstanceInfo.InstanceStatus.UP; - this.overriddenstatus = InstanceInfo.InstanceStatus.UNKNOWN; - this.isInstanceInfoDirty = false; - this.metadata = new ConcurrentHashMap(); - this.lastUpdatedTimestamp = System.currentTimeMillis(); - this.lastDirtyTimestamp = System.currentTimeMillis(); - this.instanceId = ii.instanceId; - this.appName = ii.appName; - this.appGroupName = ii.appGroupName; - this.ipAddr = ii.ipAddr; - this.port = ii.port; - this.securePort = ii.securePort; - this.hostName = ii.hostName; - this.status = ii.status; - this.overriddenstatus = ii.overriddenstatus; - this.isInstanceInfoDirty = ii.isInstanceInfoDirty; - this.leaseInfo = ii.leaseInfo; - this.metadata = ii.metadata; - this.lastUpdatedTimestamp = ii.lastUpdatedTimestamp; - this.lastDirtyTimestamp = ii.lastDirtyTimestamp; - this.actionType = ii.actionType; - } - - public enum InstanceStatus { - UP, // Ready to receive traffic - DOWN, // Do not send traffic- healthcheck callback failed - STARTING, // Just about starting- initializations to be done - do not - // send traffic - OUT_OF_SERVICE, // Intentionally shutdown for traffic - UNKNOWN; - - public static InstanceStatus toEnum(String s) { - for (InstanceStatus e : InstanceStatus.values()) { - if (e.name().equalsIgnoreCase(s)) { - return e; - } - } - return UNKNOWN; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - InstanceInfo other = (InstanceInfo) obj; - if (getId() == null) { - if (other.getId() != null) { - return false; - } - } else if (!getId().equals(other.getId())) { - return false; - } - return true; - } - - - public static final class Builder { - private static final String COLON = ":"; - private static final String HTTPS_PROTOCOL = "https://"; - private static final String HTTP_PROTOCOL = "http://"; - - private InstanceInfo result; - - public Builder setInstanceId(String instanceId) { - result.instanceId = instanceId; - return this; - } - - public Builder setSlotNum(Integer slotNum) { - result.slotNum = slotNum; - return this; - } - - public static Builder newBuilder() { - return new Builder(new InstanceInfo()); - } - - public static Builder newBuilder(InstanceInfo instanceInfo) { - return new Builder(instanceInfo); - } - - public Builder(InstanceInfo result) { - this.result = result; - } - - /** - * Set the application name of the instance.This is mostly used in - * querying of instances. - * - * @param appName the application name. - * @return the instance info builder. - */ - public Builder setAppName(String appName) { - result.appName = appName; - return this; - } - - public Builder setAppGroupName(String appGroupName) { - result.appGroupName = appGroupName; - return this; - } - - /** - * Sets the fully qualified hostname of this running instance.This is - * mostly used in constructing the {@link java.net.URL} for communicating with - * the instance. - * - * @param hostName the host name of the instance. - * @return the {@link InstanceInfo} builder. - */ - public Builder setHostName(String hostName) { - result.hostName = hostName; - return this; - } - - /** - * Sets the status of the instances.If the status is UP, that is when - * the instance is ready to service requests. - * - * @param status the {@link InstanceStatus} of the instance. - * @return the {@link InstanceInfo} builder. - */ - public Builder setStatus(InstanceStatus status) { - result.status = status; - return this; - } - - /** - * Sets the status overridden by some other external process.This is - * mostly used in putting an instance out of service to block traffic to - * it. - * - * @param status the overridden {@link InstanceStatus} of the instance. - * @return @return the {@link InstanceInfo} builder. - */ - public Builder setOverriddenStatus(InstanceStatus status) { - result.overriddenstatus = status; - return this; - } - - /** - * Sets the ip address of this running instance. - * - * @param ip the ip address of the instance. - * @return the {@link InstanceInfo} builder. - */ - public Builder setIPAddr(String ip) { - result.ipAddr = ip; - return this; - } - - /** - * Sets the port number that is used to service requests. - * - * @param port the port number that is used to service requests. - * @return the {@link InstanceInfo} builder. - */ - public Builder setPort(int port) { - result.port = port; - return this; - } - - - /** - * Set the instance lease information. - * - * @param info the lease information for this instance. - */ - public Builder setLeaseInfo(LeaseInfo info) { - result.leaseInfo = info; - return this; - } - - /** - * Add arbitrary metadata to running instance. - * - * @param key The key of the metadata. - * @param val The value of the metadata. - * @return the {@link InstanceInfo} builder. - */ - public Builder add(String key, String val) { - result.metadata.put(key, val); - return this; - } - - - /** - * Returns the encapsulated instance info even if it is not built fully. - * - * @return the existing information about the instance. - */ - public InstanceInfo getRawInstance() { - return result; - } - - /** - * Build the {@link InstanceInfo} object. - * - * @return the {@link InstanceInfo} that was built based on the - * information supplied. - */ - public InstanceInfo build() { - if (!isInitialized()) { - throw new IllegalStateException("name is required!"); - } - return result; - } - - public boolean isInitialized() { - return (result.appName != null); - } - - - public Builder setLastUpdatedTimestamp(long lastUpdatedTimestamp) { - result.lastUpdatedTimestamp = lastUpdatedTimestamp; - return this; - } - - public Builder setLastDirtyTimestamp(long lastDirtyTimestamp) { - result.lastDirtyTimestamp = lastDirtyTimestamp; - return this; - } - - public Builder setActionType(ActionType actionType) { - result.actionType = actionType; - return this; - } - - - } - - public void setHostName(String hostName) { - this.hostName = hostName; - } - - public InstanceStatus getInstanceStatus() { - return instanceStatus; - } - - public void setInstanceStatus(InstanceStatus instanceStatus) { - this.instanceStatus = instanceStatus; - } - - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - - public void setAppName(String appName) { - this.appName = appName; - } - - public void setAppGroupName(String appGroupName) { - this.appGroupName = appGroupName; - } - - public String getIpAddr() { - return ipAddr; - } - - public void setIpAddr(String ipAddr) { - this.ipAddr = ipAddr; - } - - public void setPort(int port) { - this.port = port; - } - - public int getSecurePort() { - return securePort; - } - - public void setSecurePort(int securePort) { - this.securePort = securePort; - } - - public InstanceStatus getOverriddenstatus() { - return overriddenstatus; - } - - public void setOverriddenstatus(InstanceStatus overriddenstatus) { - this.overriddenstatus = overriddenstatus; - } - - public boolean isInstanceInfoDirty() { - return isInstanceInfoDirty; - } - - public void setInstanceInfoDirty(boolean instanceInfoDirty) { - isInstanceInfoDirty = instanceInfoDirty; - } - - public void setLastUpdatedTimestamp(Long lastUpdatedTimestamp) { - this.lastUpdatedTimestamp = lastUpdatedTimestamp; - } - - /** - * @return the raw instanceId. For compatibility, prefer to use {@link #getId()} - */ - public String getInstanceId() { - return instanceId; - } - - /** - * Return the name of the application registering with discovery. - * - * @return the string denoting the application name. - */ - public String getAppName() { - return appName; - } - - public String getAppGroupName() { - return appGroupName; - } - - - /** - * Return the default network address to connect to this instance. - */ - public String getHostName() { - return hostName; - } - - - /** - * Returns the unique id of the instance. - * (Note) now that id is set at creation time within the instanceProvider, why do the other checks? - * This is still necessary for backwards compatibility when upgrading in a deployment with multiple - * client versions (some with the change, some without). - * - * @return the unique id. - */ - public String getId() { - if (instanceId != null && !instanceId.isEmpty()) { - return instanceId; - } - return hostName; - } - - /** - * Returns the ip address of the instance. - * - * @return - the ip address, in AWS scenario it is a private IP. - */ - public String getIPAddr() { - return ipAddr; - } - - /** - * Returns the port number that is used for servicing requests. - * - * @return - the non-secure port number. - */ - public int getPort() { - return port; - } - - /** - * Returns the status of the instance. - * - * @return the status indicating whether the instance can handle requests. - */ - public InstanceStatus getStatus() { - return status; - } - - /** - * Returns the overridden status if any of the instance. - * - * @return the status indicating whether an external process has changed the - * status. - */ - public InstanceStatus getOverriddenStatus() { - return overriddenstatus; - } - - /** - * Returns the lease information regarding when it expires. - * - * @return the lease information of this instance. - */ - public LeaseInfo getLeaseInfo() { - return leaseInfo; - } - - /** - * Sets the lease information regarding when it expires. - * - * @param info the lease information of this instance. - */ - public void setLeaseInfo(LeaseInfo info) { - leaseInfo = info; - } - - - /** - * Returns the time elapsed since epoch since the instance status has been - * last updated. - * - * @return the time elapsed since epoch since the instance has been last - * updated. - */ - public long getLastUpdatedTimestamp() { - return lastUpdatedTimestamp; - } - - /** - * Set the update time for this instance when the status was update. - */ - public void setLastUpdatedTimestamp() { - this.lastUpdatedTimestamp = System.currentTimeMillis(); - } - - - /** - * Gets the last time stamp when this instance was touched. - * - * @return last timestamp when this instance was touched. - */ - public Long getLastDirtyTimestamp() { - return lastDirtyTimestamp; - } - - /** - * Set the time indicating that the instance was touched. - * - * @param lastDirtyTimestamp time when the instance was touched. - */ - public void setLastDirtyTimestamp(Long lastDirtyTimestamp) { - this.lastDirtyTimestamp = lastDirtyTimestamp; - } - - /** - * Set the status for this instance. - * - * @param status status for this instance. - * @return the prev status if a different status from the current was set, null otherwise - */ - public synchronized InstanceStatus setStatus(InstanceStatus status) { - if (this.status != status) { - InstanceStatus prev = this.status; - this.status = status; - setIsDirty(); - return prev; - } - return null; - } - - /** - * Set the status for this instance without updating the dirty timestamp. - * - * @param status status for this instance. - */ - public synchronized void setStatusWithoutDirty(InstanceStatus status) { - if (this.status != status) { - this.status = status; - } - } - - /** - * Sets the overridden status for this instance.Normally set by an external - * process to disable instance from taking traffic. - * - * @param status overridden status for this instance. - */ - public synchronized void setOverriddenStatus(InstanceStatus status) { - if (this.overriddenstatus != status) { - this.overriddenstatus = status; - } - } - - /** - * Returns whether any state changed so that client side can - * check whether to retransmit info or not on the next heartbeat. - * - * @return true if the {@link InstanceInfo} is dirty, false otherwise. - */ - public boolean isDirty() { - return isInstanceInfoDirty; - } - - /** - * @return the lastDirtyTimestamp if is dirty, null otherwise. - */ - public synchronized Long isDirtyWithTime() { - if (isInstanceInfoDirty) { - return lastDirtyTimestamp; - } else { - return null; - } - } - - /** - * @param isDirty true if dirty, false otherwise. - * @deprecated use {@link #setIsDirty()} and {@link #unsetIsDirty(long)} to set and unset - *

- * Sets the dirty flag so that the instance information can be carried to - * the discovery server on the next heartbeat. - */ - @Deprecated - public synchronized void setIsDirty(boolean isDirty) { - if (isDirty) { - setIsDirty(); - } else { - isInstanceInfoDirty = false; - // else don't update lastDirtyTimestamp as we are setting isDirty to false - } - } - - /** - * Sets the dirty flag so that the instance information can be carried to - * the discovery server on the next heartbeat. - */ - public synchronized void setIsDirty() { - isInstanceInfoDirty = true; - lastDirtyTimestamp = System.currentTimeMillis(); - } - - /** - * Set the dirty flag, and also return the timestamp of the isDirty event - * - * @return the timestamp when the isDirty flag is set - */ - public synchronized long setIsDirtyWithTime() { - setIsDirty(); - return lastDirtyTimestamp; - } - - - /** - * Unset the dirty flag if the unsetDirtyTimestamp matches the lastDirtyTimestamp. No-op if - * lastDirtyTimestamp > unsetDirtyTimestamp - * - * @param unsetDirtyTimestamp the expected lastDirtyTimestamp to unset. - */ - public synchronized void unsetIsDirty(long unsetDirtyTimestamp) { - if (lastDirtyTimestamp <= unsetDirtyTimestamp) { - isInstanceInfoDirty = false; - } else { - } - } - - /** - * Returns the type of action done on the instance in the server.Primarily - * used for updating deltas in the client - * instance. - * - * @return action type done on the instance. - */ - public ActionType getActionType() { - return actionType; - } - - /** - * Set the action type performed on this instance in the server. - * - * @param actionType action type done on the instance. - */ - public void setActionType(ActionType actionType) { - this.actionType = actionType; - } - - public Integer getSlotNum() { - return slotNum; - } - - /** - * Returns all application specific metadata set on the instance. - * - * @return application specific metadata. - */ - public Map getMetadata() { - return metadata; - } - - - public enum ActionType { - ADDED, // Added in the discovery server - MODIFIED, // Changed in the discovery server - DELETED - // Deleted from the discovery server - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/appinfo/LeaseInfo.java b/pantheon-client/src/main/java/com/pantheon/client/appinfo/LeaseInfo.java deleted file mode 100644 index 1fac78d..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/appinfo/LeaseInfo.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.pantheon.client.appinfo; - -import com.pantheon.remoting.protocol.RemotingSerializable; - -/** - * @author Anthony - * @create 2021/11/28 - * @desc Represents the lease information with Pantheon. - */ -public class LeaseInfo extends RemotingSerializable { - - public static final int DEFAULT_LEASE_RENEWAL_INTERVAL = 3; - public static final int DEFAULT_LEASE_DURATION = 5; - - // Client settings - private int renewalIntervalInSecs = DEFAULT_LEASE_RENEWAL_INTERVAL; - private int durationInSecs = DEFAULT_LEASE_DURATION; - - // Server populated - private long registrationTimestamp; - private long lastRenewalTimestamp; - private long evictionTimestamp; - private long serviceUpTimestamp; - - public static final class Builder { - - private LeaseInfo result; - - private Builder() { - result = new LeaseInfo(); - } - - public static Builder newBuilder() { - return new Builder(); - } - - /** - * Sets the registration timestamp. - * - * @param ts - * time when the lease was first registered. - * @return the {@link LeaseInfo} builder. - */ - public Builder setRegistrationTimestamp(long ts) { - result.registrationTimestamp = ts; - return this; - } - - /** - * Sets the last renewal timestamp of lease. - * - * @param ts - * time when the lease was last renewed. - * @return the {@link LeaseInfo} builder. - */ - public Builder setRenewalTimestamp(long ts) { - result.lastRenewalTimestamp = ts; - return this; - } - - /** - * Sets the de-registration timestamp. - * - * @param ts - * time when the lease was removed. - * @return the {@link LeaseInfo} builder. - */ - public Builder setEvictionTimestamp(long ts) { - result.evictionTimestamp = ts; - return this; - } - - /** - * Sets the service UP timestamp. - * - * @param ts - * time when the leased service marked as UP. - * @return the {@link LeaseInfo} builder. - */ - public Builder setServiceUpTimestamp(long ts) { - result.serviceUpTimestamp = ts; - return this; - } - - /** - * Sets the client specified setting for eviction (e.g. how long to wait - * without renewal event). - * - * @param d - * time in seconds after which the lease would expire without - * renewa. - * @return the {@link LeaseInfo} builder. - */ - public Builder setDurationInSecs(int d) { - if (d <= 0) { - result.durationInSecs = DEFAULT_LEASE_DURATION; - } else { - result.durationInSecs = d; - } - return this; - } - - /** - * Sets the client specified setting for renew interval. - * - * @param i - * the time interval with which the renewals will be renewed. - * @return the {@link LeaseInfo} builder. - */ - public Builder setRenewalIntervalInSecs(int i) { - if (i <= 0) { - result.renewalIntervalInSecs = DEFAULT_LEASE_RENEWAL_INTERVAL; - } else { - result.renewalIntervalInSecs = i; - } - return this; - } - - /** - * Build the {@link InstanceInfo}. - * - * @return the {@link LeaseInfo} information built based on the supplied - * information. - */ - public LeaseInfo build() { - return result; - } - } - - private LeaseInfo() { - } - - - public LeaseInfo(int renewalIntervalInSecs, - int durationInSecs, - long registrationTimestamp, - Long lastRenewalTimestamp, - long lastRenewalTimestampLegacy, - long evictionTimestamp, - long serviceUpTimestamp) { - this.renewalIntervalInSecs = renewalIntervalInSecs; - this.durationInSecs = durationInSecs; - this.registrationTimestamp = registrationTimestamp; - this.evictionTimestamp = evictionTimestamp; - this.serviceUpTimestamp = serviceUpTimestamp; - - if (lastRenewalTimestamp == null) { - this.lastRenewalTimestamp = lastRenewalTimestampLegacy; - } else { - this.lastRenewalTimestamp = lastRenewalTimestamp; - } - } - - /** - * Returns the registration timestamp. - * - * @return time in milliseconds since epoch. - */ - public long getRegistrationTimestamp() { - return registrationTimestamp; - } - - /** - * Returns the last renewal timestamp of lease. - * - * @return time in milliseconds since epoch. - */ - public long getRenewalTimestamp() { - return lastRenewalTimestamp; - } - - /** - * Returns the de-registration timestamp. - * - * @return time in milliseconds since epoch. - */ - public long getEvictionTimestamp() { - return evictionTimestamp; - } - - /** - * Returns the service UP timestamp. - * - * @return time in milliseconds since epoch. - */ - public long getServiceUpTimestamp() { - return serviceUpTimestamp; - } - - /** - * Returns client specified setting for renew interval. - * - * @return time in milliseconds since epoch. - */ - public int getRenewalIntervalInSecs() { - return renewalIntervalInSecs; - } - - /** - * Returns client specified setting for eviction (e.g. how long to wait w/o - * renewal event) - * - * @return time in milliseconds since epoch. - */ - public int getDurationInSecs() { - return durationInSecs; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/config/AbstractInstanceConfig.java b/pantheon-client/src/main/java/com/pantheon/client/config/AbstractInstanceConfig.java deleted file mode 100644 index c846745..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/config/AbstractInstanceConfig.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.pantheon.client.config; - -import com.pantheon.client.utils.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Map; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc An abstract instance info configuration with some DEFAULT VALUE to get the users - * started quickly.The users have to override only a few methods to register - * their instance with pantheon server. - **/ -public abstract class AbstractInstanceConfig implements PantheonInstanceConfig { - private static final Logger logger = LoggerFactory.getLogger(AbstractInstanceConfig.class); - - private static final int LEASE_EXPIRATION_DURATION_SECONDS = 10; - private static final int LEASE_RENEWAL_INTERVAL_SECONDS = 3; - private static final int DEFAULT_INSTANCE_PORT = 6755; - - private static final Pair hostInfo = getHostInfo(); - - protected AbstractInstanceConfig() { - - } - - @Override - public String getInstanceHostName() { - return hostInfo.second(); - } - - @Override - public String getInstanceIpAddress() { - return hostInfo.first(); - } - - @Override - public Integer getLeaseRenewalIntervalInSeconds() { - return LEASE_RENEWAL_INTERVAL_SECONDS; - } - - @Override - public Integer getLeaseExpirationDurationInSeconds() { - return LEASE_EXPIRATION_DURATION_SECONDS; - } - - @Override - public Integer getInstancePort() { - return DEFAULT_INSTANCE_PORT; - } - - @Override - public boolean shouldFilterOnlyUpInstances() { - return true; - } - - private static Pair getHostInfo() { - Pair pair; - try { - InetAddress localHost = InetAddress.getLocalHost(); - pair = new Pair(localHost.getHostAddress(), localHost.getHostName()); - } catch (UnknownHostException e) { - logger.error("Cannot get host info", e); - pair = new Pair("", ""); - } - return pair; - } - - @Override - public Map getMetadataMap() { - return null; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/config/DefaultInstanceConfig.java b/pantheon-client/src/main/java/com/pantheon/client/config/DefaultInstanceConfig.java deleted file mode 100644 index 00d7811..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/config/DefaultInstanceConfig.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.pantheon.client.config; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import io.netty.bootstrap.ServerBootstrap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class DefaultInstanceConfig extends AbstractInstanceConfig implements PantheonInstanceConfig { - private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); - private static final String TEST = "test"; - private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - private static final DynamicPropertyFactory configInstance = com.netflix.config.DynamicPropertyFactory - .getInstance(); - private static final DynamicStringProperty PANTHEON_PROPS_FILE = DynamicPropertyFactory - .getInstance().getStringProperty("pantheon.client.props", - "pantheon-client"); - protected String namespace = "pantheon."; - public static final String CONFIG_FILE_NAME = "pantheon-client"; - final String CONFIG_KEY_SERVICE_NAME = namespace + "serviceName"; - final String CONFIG_KEY_INSTANCE_ID = namespace + "instanceId"; - final String CONFIG_KEY_INSTANCE_HOST_NAME = namespace + "instanceHostName"; - final String CONFIG_KEY_IP_ADDRESS = namespace + "instanceIpAddress"; - final String CONFIG_KEY_CONTROLLER_CANDIDATE_SERVERS = namespace + "controllerCandidateServers"; - final String CONFIG_KEY_LEASE_RENEWAL_INTERVAL = namespace + "leaseRenewalInterval"; - final String CONFIG_KEY_LEASE_EXPIRATION_DURATION = namespace + "leaseDuration"; - final String CONFIG_KEY_INSTANCE_PORT = namespace + "instancePort"; - final String CONFIG_KEY_SHOULD_FETCH_REGISTRY = namespace + "shouldFetchRegistry"; - final String CONFIG_KEY_REGISTRY_FETCH_INTERVAL_SECONDS = namespace + "registryFetchIntervalSeconds"; - - - private List serverList = new ArrayList<>(); - - private static class Singleton { - static DefaultInstanceConfig instance = new DefaultInstanceConfig(); - } - - public static DefaultInstanceConfig getInstance() { - return Singleton.instance; - } - - - private DefaultInstanceConfig() { - initConfig(); - validateConfig(); - } - - private DefaultInstanceConfig(String namespace) { - initConfig(); - validateConfig(); - } - - - private void initConfig() { - String env = ConfigurationManager.getConfigInstance().getString( - PANTHEON_ENVIRONMENT, TEST); - ConfigurationManager.getConfigInstance().setProperty( - ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env); - String propsFile = PANTHEON_PROPS_FILE.get(); - try { - //load PANTHEON_PROPS_FILE after application.properties - ConfigurationManager - .loadCascadedPropertiesFromResources(propsFile); - } catch (IOException e) { - logger.warn( - "Cannot find the properties specified : {}. This may be okay if there are other environment " - + "specific properties or the configuration is installed with a different mechanism.", - propsFile); - } - - - } - - private void validateConfig() { -// List serverList = getServerList(); -// logger.info("-------------->" + serverList); - } - - - @Override - public String getServiceName() { - return configInstance.getStringProperty(CONFIG_KEY_SERVICE_NAME, null).get(); - } - - @Override - public String getInstanceId() { - return configInstance.getStringProperty(CONFIG_KEY_INSTANCE_ID, null).get(); - } - - @Override - public List getServerList() { - String servers = getControllerCandidateServers(); - String[] serverArray = servers.split(","); - serverList = Arrays.asList(serverArray); - return serverList; - } - - private String getControllerCandidateServers() { - return configInstance.getStringProperty(CONFIG_KEY_CONTROLLER_CANDIDATE_SERVERS, null).get(); - } - - @Override - public String getInstanceHostName() { - return configInstance.getStringProperty(CONFIG_KEY_INSTANCE_HOST_NAME, null).get(); - } - - @Override - public String getInstanceIpAddress() { - return configInstance.getStringProperty(CONFIG_KEY_IP_ADDRESS, null).get(); - } - - @Override - public Integer getLeaseRenewalIntervalInSeconds() { - return configInstance.getIntProperty(CONFIG_KEY_LEASE_RENEWAL_INTERVAL, super.getLeaseRenewalIntervalInSeconds()).get(); - } - - @Override - public Integer getLeaseExpirationDurationInSeconds() { - return configInstance.getIntProperty(CONFIG_KEY_LEASE_EXPIRATION_DURATION, super.getLeaseExpirationDurationInSeconds()).get(); - } - - - @Override - public Integer getInstancePort() { - return configInstance.getIntProperty(CONFIG_KEY_INSTANCE_PORT, super.getInstancePort()).get(); - } - - @Override - public boolean shouldFetchRegistry() { - return configInstance.getBooleanProperty(CONFIG_KEY_SHOULD_FETCH_REGISTRY, true).get(); - } - - public int getRegistryFetchIntervalSeconds() { - return configInstance.getIntProperty(CONFIG_KEY_REGISTRY_FETCH_INTERVAL_SECONDS, 10).get(); - - } - - @Override - public Integer setInstancePort(Integer port) { - return null; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/config/PantheonInstanceConfig.java b/pantheon-client/src/main/java/com/pantheon/client/config/PantheonInstanceConfig.java deleted file mode 100644 index cf84cfe..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/config/PantheonInstanceConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.pantheon.client.config; - -import java.util.List; -import java.util.Map; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc Configuration information required by the instance to register with Pantheon server. - **/ -public interface PantheonInstanceConfig { - - /** - * Get the name of the Service to be registered with pantheon. - */ - String getServiceName(); - - String getInstanceId(); - - /** - * default localhost name - */ - String getInstanceHostName(); - - /** - * default localhost ip address - */ - String getInstanceIpAddress(); - - Integer getLeaseRenewalIntervalInSeconds(); - - Integer getLeaseExpirationDurationInSeconds(); - - /** - * instances connect one of these servers - * - * @return - */ - List getServerList(); - - Integer getInstancePort(); - - Integer setInstancePort(Integer port); - - /** - * should fetch registry ,default true - * @return - */ - boolean shouldFetchRegistry(); - - boolean shouldFilterOnlyUpInstances(); - - /** - * Indicates how often(in seconds) to fetch the registry information from - * the server. - * - * @return the fetch interval in seconds. - */ - int getRegistryFetchIntervalSeconds(); - - Map getMetadataMap(); -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/discovery/DiscoveryClient.java b/pantheon-client/src/main/java/com/pantheon/client/discovery/DiscoveryClient.java deleted file mode 100755 index 1c0bbd2..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/discovery/DiscoveryClient.java +++ /dev/null @@ -1,72 +0,0 @@ - -package com.pantheon.client.discovery; - - -import com.pantheon.client.PantheonEventListener; -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.config.PantheonInstanceConfig; - -import java.util.List; - - -public interface DiscoveryClient { - - /** - * Returns the corresponding {@link Application} object which is basically a - * container of all registered appName {@link InstanceInfo}s. - * - * @param appName - * @return a {@link Application} or null if we couldn't locate any app of - * the requested appName - */ - Application getApplication(String appName); - - /** - * Returns the {@link Applications} object which is basically a container of - * all currently registered {@link Application}s. - * - * @return {@link Applications} - */ - Applications getApplications(); - - /** - * return the {@link Applications} object which the service is subscribing - * - * @param serviceId - * @return - */ - Applications getSubscribeApplications(String serviceId); - - /** - * Shuts down Pantheon Client. Also sends a deregistration request to the pantheon server. - */ - void shutdown(); - - /** - * @return the configuration of this pantheon client - */ - PantheonInstanceConfig getPantheonClientConfig(); - - - - /** - * Gets the list of instances matching the given Address. - * - * @param address The address to match the instances for. - * @return - The list of {@link InstanceInfo} objects matching the criteria - */ - List getInstance(String address); - - - /** - * Return the current instance status as seen on the Pantheon server. - * @return - */ - InstanceInfo.InstanceStatus getInstanceRemoteStatus(); - - void registerEventListener(PantheonEventListener var1); - - boolean unregisterEventListener(PantheonEventListener var1); -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/transport/ClientAPIImpl.java b/pantheon-client/src/main/java/com/pantheon/client/transport/ClientAPIImpl.java deleted file mode 100644 index 119de97..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/transport/ClientAPIImpl.java +++ /dev/null @@ -1,338 +0,0 @@ -package com.pantheon.client.transport; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.common.protocol.RequestCode; -import com.pantheon.common.protocol.ResponseCode; -import com.pantheon.common.protocol.header.*; -import com.pantheon.common.protocol.heartBeat.HeartBeat; -import com.pantheon.remoting.RPCHook; -import com.pantheon.remoting.RemotingClient; -import com.pantheon.remoting.exception.*; -import com.pantheon.remoting.netty.NettyClientConfig; -import com.pantheon.remoting.netty.NettyRemotingClient; -import com.pantheon.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.zip.GZIPInputStream; - -/** - * @author Anthony - * @create 2021/11/27 - * @desc wrapper class for netty request and response - */ -public class ClientAPIImpl { - private static final Logger logger = LoggerFactory.getLogger(ClientAPIImpl.class); - - private final ClientRemotingProcessor clientRemotingProcessor; - private final RemotingClient remotingClient; - private String serverAddress = null; - private NettyClientConfig nettyClientConfig; - private PantheonInstanceConfig pantheonInstanceConfig; - private Map> slotsAllocation; - private static final Integer SLOT_COUNT = 16384; - private PantheonInstanceConfig instanceConfig; - /** - * server addresses - */ - private Map servers = new HashMap(); - - public ClientAPIImpl(final NettyClientConfig nettyClientConfig, PantheonInstanceConfig instanceConfig, ClientRemotingProcessor clientRemotingProcessor, RPCHook rpcHook) { - this.clientRemotingProcessor = clientRemotingProcessor; - this.nettyClientConfig = nettyClientConfig; - this.instanceConfig = instanceConfig; - this.remotingClient = new NettyRemotingClient(nettyClientConfig, null); - this.pantheonInstanceConfig = DefaultInstanceConfig.getInstance(); - this.remotingClient.registerRPCHook(rpcHook); - this.remotingClient.registerProcessor(RequestCode.GET_CONSUMER_RUNNING_INFO, this.clientRemotingProcessor, null); - } - - public void start() { - if (this.remotingClient != null) { - this.remotingClient.start(); - return; - } - throw new RuntimeException("remotingClient cannot be null"); - - } - - - public void shutdown() { - if (remotingClient != null) { - this.remotingClient.shutdown(); - } - } - - /** - * fetch server node id - * - * @param controllerCandidate server address - * @return - */ - public Integer fetchServerNodeId(final String controllerCandidate, final long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, RemotingCommandException { - GetServerNodeIdRequestHeader requestHeader = new GetServerNodeIdRequestHeader(); - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_SERVER_NODE_ID, requestHeader); - RemotingCommand response = this.remotingClient.invokeSync(controllerCandidate, request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - GetServerNodeIdResponseHeader responseHeader = - (GetServerNodeIdResponseHeader) response.decodeCommandCustomHeader(GetServerNodeIdResponseHeader.class); - return responseHeader.getServerNodeId(); - } - default: - break; - } - return null; - } - - /** - * fetch slots allocation - * - * @param controllerCandidate - * @return - */ - public Map> fetchSlotsAllocation(final String controllerCandidate, final long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, RemotingCommandException { - GetSlotsRequestHeader requestHeader = new GetSlotsRequestHeader(); - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_SLOTS_ALLOCATION, requestHeader); - RemotingCommand response = this.remotingClient.invokeSync(controllerCandidate, request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - GetSlotsResponseHeader responseHeader = - (GetSlotsResponseHeader) response.decodeCommandCustomHeader(GetSlotsResponseHeader.class); - slotsAllocation = (Map>) JSON.parse(responseHeader.getSlotsAllocation()); - return slotsAllocation; - } - default: - break; - } - return null; - } - - - /** - * fetch server addresses to local map - * - * @param controllerCandidate - */ - public Map fetchServerAddresses(String controllerCandidate, final long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, RemotingCommandException { - GetServerAddressRequestHeader requestHeader = new GetServerAddressRequestHeader(); - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_SERVER_ADDRESSES, requestHeader); - RemotingCommand response = this.remotingClient.invokeSync(controllerCandidate, request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - GetServerAddressResponseHeader responseHeader = - (GetServerAddressResponseHeader) response.decodeCommandCustomHeader(GetServerAddressResponseHeader.class); - List serverAddresses = (List) JSON.parse(responseHeader.getServerAddresses()); - for (String serverAddress : serverAddresses) { - String[] serverAddressSplited = serverAddress.split(":"); - - String id = serverAddressSplited[0]; - - String ip = serverAddressSplited[1]; - Integer port = Integer.valueOf(serverAddressSplited[2]); - Server server = new Server(id, ip, port); - - servers.put(id, server); - } - return servers; - } - default: - break; - } - return null; - } - - public Server routeServer(String serviceName) { - Integer slot = routeSlot(serviceName); - String serverId = locateServerBySlot(slot); - Server server = servers.get(serverId); - server.setSlotNum(slot); - logger.info(serviceName + " route to serverId: {}", serverId); - logger.info(serviceName + " route to slot: {} to server: {}", slot, server); - return server; - } - - /** - * route server to a specific slot - * - * @return - */ - private Integer routeSlot(String serviceName) { - int hashCode = serviceName.hashCode() & Integer.MAX_VALUE; - Integer slot = hashCode % SLOT_COUNT; - - if (slot == 0) { - slot = slot + 1; - } - - return slot; - } - - - /** - * locate a server node id by slot - * - * @param slot - * @return - */ - private String locateServerBySlot(Integer slot) { - for (String serverNodeId : slotsAllocation.keySet()) { - List slotsList = slotsAllocation.get(serverNodeId); - - for (String slots : slotsList) { - String[] slotsSpited = slots.split(","); - Integer startSlot = Integer.valueOf(slotsSpited[0]); - Integer endSlot = Integer.valueOf(slotsSpited[1]); - - if (slot >= startSlot && slot <= endSlot) { - return serverNodeId; - } - } - } - return null; - } - - - public String chooseControllerCandidate() { - List serverList = instanceConfig.getServerList(); - Random random = new Random(); - boolean chosen = false; - while (!chosen) { - int index = random.nextInt(serverList.size()); - String serverAddress = serverList.get(index); - return serverAddress; - } - - return null; - } - - public boolean sendHeartBeatToServer(final Server server, String appName, String id, final Long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException { - HeartBeat heartBeat = new HeartBeat(); - heartBeat.setServiceName(appName); - heartBeat.setInstanceId(id); - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.SERVICE_HEART_BEAT, null); - request.setBody(heartBeat.encode()); - RemotingCommand response = this.remotingClient.invokeSync(server.getRemoteSocketAddress(), request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - logger.info("heartbeat success!!!"); - return true; - } - case ResponseCode.SYSTEM_ERROR: { - logger.info("heartbeat failed!!! {}", response.getRemark()); - } - default: - break; - } - return false; - } - - - public Applications getApplications(Server server, long timeoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, IOException { - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_APP, null); - RemotingCommand response = this.remotingClient.invokeSync(server.getRemoteSocketAddress(), request, timeoutMills); - - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - String string = unzipBytesToStr(response.getBody()); - logger.info("receive all apps info :{} ", string); - return JSONObject.parseObject(string, Applications.class); - } - default: - break; - } - return null; - } - - - public String unzipBytesToStr(byte[] inputBuf) throws IOException { - ByteArrayInputStream bis = new ByteArrayInputStream(inputBuf); - // Open the compressed stream - GZIPInputStream gin = new GZIPInputStream(bis); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - // Transfer bytes from the compressed stream to the output stream - byte[] buf = new byte[inputBuf.length]; - int len; - while ((len = gin.read(buf)) > 0) { - out.write(buf, 0, len); - } - - // Close the file and stream - gin.close(); - out.close(); - - byte[] bytes = out.toByteArray(); - String string = new String(bytes); - return string; - } - - public Applications getDelta(Server server, long timeoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, IOException { - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_DELTA_APP, null); - RemotingCommand response = this.remotingClient.invokeSync(server.getRemoteSocketAddress(), request, timeoutMills); - - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - String string = unzipBytesToStr(response.getBody()); - logger.info("receive delta apps info :{} ", string); - - return JSONObject.parseObject(string, Applications.class); - } - default: - break; - } - return null; - } - - public boolean register(Server server, InstanceInfo instanceInfo, long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException { - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.SERVICE_REGISTRY, null); - request.setBody(instanceInfo.encode()); - RemotingCommand response = this.remotingClient.invokeSync(server.getRemoteSocketAddress(), request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - return true; - } - default: - break; - } - return false; - } - - public boolean unRegister(Server server, String appName, String instanceId, long timoutMills) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException { - HeartBeat heartBeat = new HeartBeat(); - heartBeat.setInstanceId(instanceId); - heartBeat.setServiceName(appName); - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.SERVICE_UNREGISTER, null); - request.setBody(heartBeat.encode()); - RemotingCommand response = this.remotingClient.invokeSync(server.getRemoteSocketAddress(), request, timoutMills); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - return true; - } - default: - break; - } - return false; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/transport/ClientRemotingProcessor.java b/pantheon-client/src/main/java/com/pantheon/client/transport/ClientRemotingProcessor.java deleted file mode 100644 index a2a4e55..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/transport/ClientRemotingProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.pantheon.client.transport; - -import com.pantheon.common.protocol.RequestCode; -import com.pantheon.common.protocol.ResponseCode; -import com.pantheon.common.protocol.header.GetConsumerRunningInfoRequestHeader; -import com.pantheon.remoting.exception.RemotingCommandException; -import com.pantheon.remoting.netty.AsyncNettyRequestProcessor; -import com.pantheon.remoting.netty.NettyRequestProcessor; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.ChannelHandlerContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Anthony - * @create 2021/11/27 - * @desc - */ -public class ClientRemotingProcessor extends AsyncNettyRequestProcessor implements NettyRequestProcessor { - private static final Logger logger = LoggerFactory.getLogger(ClientRemotingProcessor.class); - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { - switch (request.getCode()) { - case RequestCode.GET_CONSUMER_RUNNING_INFO: - return this.getConsumerRunningInfo(ctx, request); - default: - break; - } - return null; - } - - /** - * server can load consumer state - * @param ctx - * @param request - * @return - */ - private RemotingCommand getConsumerRunningInfo(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - final GetConsumerRunningInfoRequestHeader requestHeader = - (GetConsumerRunningInfoRequestHeader) request.decodeCommandCustomHeader(GetConsumerRunningInfoRequestHeader.class); -// logger.info("receive getConsumerRunningInfo from: {} ,and clientId is {} ", RemotingHelper.parseChannelRemoteAddr(ctx.channel()),requestHeader.getClientId()); - response.setCode(ResponseCode.SUCCESS); - response.setRemark("test remark"); - return response; - } - - @Override - public boolean rejectRequest() { - return false; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/transport/HeartBeatSender.java b/pantheon-client/src/main/java/com/pantheon/client/transport/HeartBeatSender.java deleted file mode 100644 index 6499a55..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/transport/HeartBeatSender.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.pantheon.client.transport; - -/** - * @author Anthony - * @create 2022/1/5 - * @desc The heartbeat sender which is responsible for sending heartbeat to remote server periodically per interval. - */ -public interface HeartBeatSender { - - boolean sendHeartbeat(); - - long intervalMs(); -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/transport/Server.java b/pantheon-client/src/main/java/com/pantheon/client/transport/Server.java deleted file mode 100644 index 5d2ea9a..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/transport/Server.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.pantheon.client.transport; - -/** - * @author Anthony - * @create 2021/11/18 - * @desc - **/ -public class Server { - - /** - * node id - */ - private String id; - /** - * ip/hostname address - */ - private String address; - /** - * server port - */ - private int port; - - /** - * server contains many slots - */ - private int slotNum; - - public Server(String id, String address, int port) { - this.id = id; - this.address = address; - this.port = port; - } - - public Server(String address, int port) { - this.address = address; - this.port = port; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getRemoteSocketAddress() { - return getAddress() + ":" + getPort(); - } - - public int getSlotNum() { - return slotNum; - } - - public void setSlotNum(int slotNum) { - this.slotNum = slotNum; - } - - @Override - public String toString() { - return "Server{" + - "id=" + id + - ", address='" + address + '\'' + - ", port=" + port + - '}'; - } - -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/utils/Archaius1Utils.java b/pantheon-client/src/main/java/com/pantheon/client/utils/Archaius1Utils.java deleted file mode 100644 index a6ae161..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/utils/Archaius1Utils.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.pantheon.client.utils; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -/** - * This is an INTERNAL class not for public use. - * - */ -public final class Archaius1Utils { - - private static final Logger logger = LoggerFactory.getLogger(Archaius1Utils.class); - private static final String TEST = "test"; - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; - - public static DynamicPropertyFactory initConfig(String configName) { - - DynamicPropertyFactory configInstance = DynamicPropertyFactory.getInstance(); - DynamicStringProperty PANTHEON_PROPS_FILE = configInstance.getStringProperty("pantheon.client.props", configName); - - String env = ConfigurationManager.getConfigInstance().getString(PANTHEON_ENVIRONMENT, TEST); - ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env); - - String pantheonPropsFile = PANTHEON_PROPS_FILE.get(); - try { - ConfigurationManager.loadCascadedPropertiesFromResources(pantheonPropsFile); - } catch (IOException e) { - logger.warn( - "Cannot find the properties specified : {}. This may be okay if there are other environment " - + "specific properties or the configuration is installed with a different mechanism.", - pantheonPropsFile); - - } - - return configInstance; - } -} diff --git a/pantheon-client/src/main/java/com/pantheon/client/utils/Pair.java b/pantheon-client/src/main/java/com/pantheon/client/utils/Pair.java deleted file mode 100644 index 43d9c4b..0000000 --- a/pantheon-client/src/main/java/com/pantheon/client/utils/Pair.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.pantheon.client.utils; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc An utility class for stores any information that needs to exist as a pair. - **/ -public class Pair { - public E1 first() { - return first; - } - - public void setFirst(E1 first) { - this.first = first; - } - - public E2 second() { - return second; - } - - public void setSecond(E2 second) { - this.second = second; - } - - private E1 first; - private E2 second; - - public Pair(E1 first, E2 second) { - this.first = first; - this.second = second; - } -} diff --git a/pantheon-client/src/main/resources/pantheon-client-instance1.properties b/pantheon-client/src/main/resources/pantheon-client-instance1.properties deleted file mode 100644 index bd19ad9..0000000 --- a/pantheon-client/src/main/resources/pantheon-client-instance1.properties +++ /dev/null @@ -1,9 +0,0 @@ -pantheon.environment=instance1 -pantheon.serviceName=instance1 -pantheon.instanceHostName=127.0.0.1 -pantheon.instanceIpAddress=127.0.0.1 -pantheon.controllerCandidateServers=127.0.0.1:9961,127.0.0.1:9962 -pantheon.leaseRenewalInterval=4 -pantheon.leaseDuration=8 -pantheon.instancePort=6756 -pantheon.registryFetchIntervalSeconds=10 \ No newline at end of file diff --git a/pantheon-client/src/main/resources/pantheon-client-instance2.properties b/pantheon-client/src/main/resources/pantheon-client-instance2.properties deleted file mode 100644 index 689beac..0000000 --- a/pantheon-client/src/main/resources/pantheon-client-instance2.properties +++ /dev/null @@ -1,9 +0,0 @@ -pantheon.environment=instance2 -pantheon.serviceName=instance2 -pantheon.instanceHostName=127.0.0.1 -pantheon.instanceIpAddress=127.0.0.1 -pantheon.controllerCandidateServers=127.0.0.1:9961,127.0.0.1:9962 -pantheon.leaseRenewalInterval=3 -pantheon.leaseDuration=9 -pantheon.instancePort=6757 -pantheon.registryFetchIntervalSeconds=10 \ No newline at end of file diff --git a/pantheon-client/src/main/resources/pantheon-client.properties b/pantheon-client/src/main/resources/pantheon-client.properties deleted file mode 100644 index 6471147..0000000 --- a/pantheon-client/src/main/resources/pantheon-client.properties +++ /dev/null @@ -1,8 +0,0 @@ -pantheon.environment=instance1 -pantheon.serviceName=instance1 -pantheon.instanceHostName=127.0.0.1 -pantheon.instanceIpAddress=127.0.0.1 -pantheon.controllerCandidateServers=127.0.0.1:9991,127.0.0.1:9992 -pantheon.leaseRenewalInterval=4 -pantheon.leaseDuration=8 -pantheon.registryFetchIntervalSeconds=10 \ No newline at end of file diff --git a/pantheon-common/pom.xml b/pantheon-common/pom.xml deleted file mode 100644 index d470511..0000000 --- a/pantheon-common/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - - 4.0.0 - pantheon-common - jar - pantheon-common ${project.version} - - - - 8 - 8 - - - - javax.jms - jms - 1.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - log4j - log4j - 1.2.17 - - - com.alibaba - fastjson - 1.2.71 - - - io.netty - netty-all - 4.0.42.Final - - - com.netflix.archaius - archaius-core - 0.7.6 - - - commons-configuration - commons-configuration - 1.8 - - - ${project.groupId} - pantheon-remoting - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/pantheon-common/src/main/java/com/pantheon/common/CountDownLatch2.java b/pantheon-common/src/main/java/com/pantheon/common/CountDownLatch2.java deleted file mode 100644 index c6f7bbe..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/CountDownLatch2.java +++ /dev/null @@ -1,179 +0,0 @@ - -package com.pantheon.common; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.AbstractQueuedSynchronizer; - -/** - * Add reset feature for @see java.util.concurrent.CountDownLatch - */ -public class CountDownLatch2 { - private final Sync sync; - - /** - * Constructs a {@code CountDownLatch2} initialized with the given count. - * - * @param count the number of times {@link #countDown} must be invoked before threads can pass through {@link - * #await} - * @throws IllegalArgumentException if {@code count} is negative - */ - public CountDownLatch2(int count) { - if (count < 0) - throw new IllegalArgumentException("count < 0"); - this.sync = new Sync(count); - } - - /** - * Causes the current thread to wait until the latch has counted down to - * zero, unless the thread is {@linkplain Thread#interrupt interrupted}. - * - *

If the current count is zero then this method returns immediately. - * - *

If the current count is greater than zero then the current - * thread becomes disabled for thread scheduling purposes and lies - * dormant until one of two things happen: - *

    - *
  • The count reaches zero due to invocations of the - * {@link #countDown} method; or - *
  • Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - *
- * - *

If the current thread: - *

    - *
  • has its interrupted status set on entry to this method; or - *
  • is {@linkplain Thread#interrupt interrupted} while waiting, - *
- * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * @throws InterruptedException if the current thread is interrupted while waiting - */ - public void await() throws InterruptedException { - sync.acquireSharedInterruptibly(1); - } - - /** - * Causes the current thread to wait until the latch has counted down to - * zero, unless the thread is {@linkplain Thread#interrupt interrupted}, - * or the specified waiting time elapses. - * - *

If the current count is zero then this method returns immediately - * with the value {@code true}. - * - *

If the current count is greater than zero then the current - * thread becomes disabled for thread scheduling purposes and lies - * dormant until one of three things happen: - *

    - *
  • The count reaches zero due to invocations of the - * {@link #countDown} method; or - *
  • Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - *
  • The specified waiting time elapses. - *
- * - *

If the count reaches zero then the method returns with the - * value {@code true}. - * - *

If the current thread: - *

    - *
  • has its interrupted status set on entry to this method; or - *
  • is {@linkplain Thread#interrupt interrupted} while waiting, - *
- * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - *

If the specified waiting time elapses then the value {@code false} - * is returned. If the time is less than or equal to zero, the method - * will not wait at all. - * - * @param timeout the maximum time to wait - * @param unit the time unit of the {@code timeout} argument - * @return {@code true} if the count reached zero and {@code false} if the waiting time elapsed before the count - * reached zero - * @throws InterruptedException if the current thread is interrupted while waiting - */ - public boolean await(long timeout, TimeUnit unit) - throws InterruptedException { - return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); - } - - /** - * Decrements the count of the latch, releasing all waiting threads if - * the count reaches zero. - * - *

If the current count is greater than zero then it is decremented. - * If the new count is zero then all waiting threads are re-enabled for - * thread scheduling purposes. - * - *

If the current count equals zero then nothing happens. - */ - public void countDown() { - sync.releaseShared(1); - } - - /** - * Returns the current count. - * - *

This method is typically used for debugging and testing purposes. - * - * @return the current count - */ - public long getCount() { - return sync.getCount(); - } - - public void reset() { - sync.reset(); - } - - /** - * Returns a string identifying this latch, as well as its state. - * The state, in brackets, includes the String {@code "Count ="} - * followed by the current count. - * - * @return a string identifying this latch, as well as its state - */ - public String toString() { - return super.toString() + "[Count = " + sync.getCount() + "]"; - } - - /** - * Synchronization control For CountDownLatch2. - * Uses AQS state to represent count. - */ - private static final class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 4982264981922014374L; - - private final int startCount; - - Sync(int count) { - this.startCount = count; - setState(count); - } - - int getCount() { - return getState(); - } - - protected int tryAcquireShared(int acquires) { - return (getState() == 0) ? 1 : -1; - } - - protected boolean tryReleaseShared(int releases) { - // Decrement count; signal when transition to zero - for (; ; ) { - int c = getState(); - if (c == 0) - return false; - int nextc = c - 1; - if (compareAndSetState(c, nextc)) - return nextc == 0; - } - } - - protected void reset() { - setState(startCount); - } - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/MessageType.java b/pantheon-common/src/main/java/com/pantheon/common/MessageType.java deleted file mode 100644 index c1e33da..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/MessageType.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.pantheon.common; - - -public class MessageType { - - public static final Integer TERMINATE = -1; - - public static final Integer VOTE = 1; - - public static final Integer SLOTS_ALLOCATION = 2; - - public static final Integer NODE_SLOTS = 3; - - public static final Integer SLOTS_REPLICA_ALLOCATION = 4; - - public static final Integer NODE_SLOTS_REPLICAS = 5; - - public static final Integer REPLICA_NODE_ID = 6; - - public static final Integer REPLICA_REGISTER = 7; - - public static final Integer REPLICA_HEARTBEAT = 8; - - public static final Integer REPLICA_NODE_IDS = 9; - - public static final Integer CONTROLLER_NODE_ID = 10; - - public static final Integer CHANGE_REPLICA_TO_SLOTS = 11; - - public static final Integer REFRESH_REPLICA_NODE_ID = 12; - - public static final Integer REFRESH_REPLICA_SLOTS = 13; - - public static final Integer REQUEST_SLOTS_DATA = 14; - - public static final Integer UPDATE_NODE_SLOTS = 15; - - public static final Integer UPDATE_REPLICA_NODE_ID = 16; - - public static final Integer TRANSFER_SLOTS = 17; - - public static final Integer UPDATE_SLOTS = 18; - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ObjectUtils.java b/pantheon-common/src/main/java/com/pantheon/common/ObjectUtils.java deleted file mode 100644 index f231478..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ObjectUtils.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.pantheon.common; - - -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc - **/ -public class ObjectUtils { - - /** - * Determine whether the given object is empty. - *

This method supports the following object types. - *

    - *
  • {@code Optional}: considered empty if {@link Optional#empty()}
  • - *
  • {@code Array}: considered empty if its length is zero
  • - *
  • {@link CharSequence}: considered empty if its length is zero
  • - *
  • {@link Collection}: delegates to {@link Collection#isEmpty()}
  • - *
  • {@link Map}: delegates to {@link Map#isEmpty()}
  • - *
  • {@link Integer}: considered empty if its num is 0
  • - *
  • {@link Long}: considered empty if its num is 0L
  • - *
- *

If the given object is non-null and not one of the aforementioned - * supported types, this method returns {@code false}. - * - * @param obj the object to check - * @return {@code true} if the object is {@code null} or empty - */ - @SuppressWarnings("rawtypes") - public static boolean isEmpty(Object obj) { - if (obj == null) { - return true; - } - - if (obj instanceof Optional) { - return !((Optional) obj).isPresent(); - } - if (obj instanceof CharSequence) { - return ((CharSequence) obj).length() == 0; - } - if (obj.getClass().isArray()) { - return Array.getLength(obj) == 0; - } - if (obj instanceof Collection) { - return ((Collection) obj).isEmpty(); - } - if (obj instanceof Map) { - return ((Map) obj).isEmpty(); - } - //0 is empty - if (obj instanceof Integer) { - return ((Integer) obj) == 0; - } - if (obj instanceof Long) { - return ((Long) obj) == 0L; - } - // else - return false; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/PantheonVersion.java b/pantheon-common/src/main/java/com/pantheon/common/PantheonVersion.java deleted file mode 100644 index dfdcca6..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/PantheonVersion.java +++ /dev/null @@ -1,30 +0,0 @@ - -package com.pantheon.common; - -public class PantheonVersion { - - public static final int CURRENT_VERSION = Version.V1_0_0_SNAPSHOT.ordinal(); - - public static String getVersionDesc(int value) { - int length = Version.values().length; - if (value >= length) { - return Version.values()[length - 1].name(); - } - - return Version.values()[value].name(); - } - - public static Version value2Version(int value) { - int length = Version.values().length; - if (value >= length) { - return Version.values()[length - 1]; - } - - return Version.values()[value]; - } - - public enum Version { - V1_0_0_SNAPSHOT, - HIGHER_VERSION - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ServerNodeRole.java b/pantheon-common/src/main/java/com/pantheon/common/ServerNodeRole.java deleted file mode 100644 index 3bbaf5d..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ServerNodeRole.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.pantheon.common; - -public enum ServerNodeRole { - - COMMON_NODE, - - CONTROLLER_NODE, - - CONTROLLER_CANDIDATE_NODE; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ServiceState.java b/pantheon-common/src/main/java/com/pantheon/common/ServiceState.java deleted file mode 100644 index 8686084..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ServiceState.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.pantheon.common; - -public enum ServiceState { - /** - * Service just created,not start - */ - CREATE_JUST, - /** - * Service Running - */ - RUNNING, - /** - * Service shutdown - */ - SHUTDOWN_ALREADY, - /** - * Service Start failure - */ - START_FAILED, - - /** - * Service running failure - */ - SERVICE_FAILED; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ServiceThread.java b/pantheon-common/src/main/java/com/pantheon/common/ServiceThread.java deleted file mode 100644 index d89fcf4..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ServiceThread.java +++ /dev/null @@ -1,151 +0,0 @@ - -package com.pantheon.common; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -public abstract class ServiceThread implements Runnable { -private static final Logger log = LoggerFactory.getLogger(ServiceThread.class); - - private static final long JOIN_TIME = 90 * 1000; - - private Thread thread; - protected final CountDownLatch2 waitPoint = new CountDownLatch2(1); - protected volatile AtomicBoolean hasNotified = new AtomicBoolean(false); - protected volatile boolean stopped = false; - protected boolean isDaemon = false; - - //Make it able to restart the thread - private final AtomicBoolean started = new AtomicBoolean(false); - - public ServiceThread() { - - } - - public abstract String getServiceName(); - - public void start() { - log.info("Try to start service thread:{} started:{}", getServiceName(), started.get() ); - log.info("Try to start service thread:{}lastThread:{}", getServiceName(), thread); - if (!started.compareAndSet(false, true)) { - return; - } - stopped = false; - this.thread = new Thread(this, getServiceName()); - this.thread.setDaemon(isDaemon); - this.thread.start(); - } - - public void shutdown() { - this.shutdown(false); - } - - public void shutdown(final boolean interrupt) { - log.info("Try to shutdown service thread:{} started:{}", getServiceName(), started.get() ); - log.info("Try to shutdown service thread:{} lastThread:{}", getServiceName(), thread); - - if (!started.compareAndSet(true, false)) { - return; - } - this.stopped = true; - log.info("shutdown thread " + this.getServiceName() + " interrupt " + interrupt); - - if (hasNotified.compareAndSet(false, true)) { - waitPoint.countDown(); // notify - } - - try { - if (interrupt) { - this.thread.interrupt(); - } - - long beginTime = System.currentTimeMillis(); - if (!this.thread.isDaemon()) { - this.thread.join(this.getJointime()); - } - long elapsedTime = System.currentTimeMillis() - beginTime; - log.info("join thread " + this.getServiceName() + " elapsed time(ms) " + elapsedTime + " " - + this.getJointime()); - } catch (InterruptedException e) { - log.error("Interrupted", e); - } - } - - public long getJointime() { - return JOIN_TIME; - } - - @Deprecated - public void stop() { - this.stop(false); - } - - @Deprecated - public void stop(final boolean interrupt) { - if (!started.get()) { - return; - } - this.stopped = true; - log.info("stop thread " + this.getServiceName() + " interrupt " + interrupt); - - if (hasNotified.compareAndSet(false, true)) { - waitPoint.countDown(); // notify - } - - if (interrupt) { - this.thread.interrupt(); - } - } - - public void makeStop() { - if (!started.get()) { - return; - } - this.stopped = true; - log.info("makestop thread " + this.getServiceName()); - } - - public void wakeup() { - if (hasNotified.compareAndSet(false, true)) { - waitPoint.countDown(); // notify - } - } - - protected void waitForRunning(long interval) { - if (hasNotified.compareAndSet(true, false)) { - this.onWaitEnd(); - return; - } - - //entry to wait - waitPoint.reset(); - - try { - waitPoint.await(interval, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - log.error("Interrupted", e); - } finally { - hasNotified.set(false); - this.onWaitEnd(); - } - } - - protected void onWaitEnd() { - } - - public boolean isStopped() { - return stopped; - } - - public boolean isDaemon() { - return isDaemon; - } - - public void setDaemon(boolean daemon) { - isDaemon = daemon; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ShutdownHookThread.java b/pantheon-common/src/main/java/com/pantheon/common/ShutdownHookThread.java deleted file mode 100644 index 60d89b6..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ShutdownHookThread.java +++ /dev/null @@ -1,55 +0,0 @@ - -package com.pantheon.common; - - -import org.slf4j.Logger; - -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Through {@link Callable} interface, this hook can customization operations in anywhere. - */ -public class ShutdownHookThread extends Thread { - - private volatile boolean hasShutdown = false; - private AtomicInteger shutdownTimes = new AtomicInteger(0); - private final Logger log; - private final Callable callback; - - /** - * Create the standard hook thread, with a call back, by using {@link Callable} interface. - * - * @param log The log instance is used in hook thread. - * @param callback The call back function. - */ - public ShutdownHookThread(Logger log, Callable callback) { - super("ShutdownHook"); - this.log = log; - this.callback = callback; - } - - /** - * Thread run method. - * Invoke when the jvm shutdown. - * 1. count the invocation times. - * 2. execute the {@link ShutdownHookThread#callback}, and time it. - */ - @Override - public void run() { - synchronized (this) { - log.info("shutdown hook was invoked, " + this.shutdownTimes.incrementAndGet() + " times."); - if (!this.hasShutdown) { - this.hasShutdown = true; - long beginTime = System.currentTimeMillis(); - try { - this.callback.call(); - } catch (Exception e) { - log.error("shutdown hook callback invoked failure.", e); - } - long consumingTimeTotal = System.currentTimeMillis() - beginTime; - log.info("shutdown hook done, consuming time total(ms): " + consumingTimeTotal); - } - } - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/ThreadFactoryImpl.java b/pantheon-common/src/main/java/com/pantheon/common/ThreadFactoryImpl.java deleted file mode 100644 index bd6611d..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/ThreadFactoryImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.pantheon.common; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicLong; - -public class ThreadFactoryImpl implements ThreadFactory { - private final AtomicLong threadIndex = new AtomicLong(0); - private final String threadNamePrefix; - private final boolean daemon; - - public ThreadFactoryImpl(final String threadNamePrefix) { - this(threadNamePrefix, false); - } - - public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon) { - this.threadNamePrefix = threadNamePrefix; - this.daemon = daemon; - } - - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet()); - thread.setDaemon(daemon); - return thread; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/entity/Message.java b/pantheon-common/src/main/java/com/pantheon/common/entity/Message.java deleted file mode 100644 index 09928ef..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/entity/Message.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.pantheon.common.entity; - -import java.nio.ByteBuffer; - -/** - * 基础消息接口 - */ -public interface Message { - - ByteBuffer getData(); - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/entity/Request.java b/pantheon-common/src/main/java/com/pantheon/common/entity/Request.java deleted file mode 100644 index ea00a12..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/entity/Request.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.pantheon.common.entity; - -import java.nio.ByteBuffer; - -/** - * 请求接口 - */ -public abstract class Request implements Message { - - /** - * 请求标识 - */ - public static final Integer REQUEST_FLAG = 1; - - /** - * 拉取slots分配数据请求 - */ - public static final Integer FETCH_SLOTS_ALLOCATION = 1; - /** - * 拉取server节点地址列表请求 - */ - public static final Integer FETCH_SERVER_ADDRESSES = 2; - /** - * 服务注册请求 - */ - public static final Integer REGISTER = 3; - /** - * 心跳请求 - */ - public static final Integer HEARTBEAT = 4; - /** - * 拉取server节点id - */ - public static final Integer FETCH_SERVER_NODE_ID = 5; - /** - * 订阅服务 - */ - public static final Integer SUBSCRIBE = 6; - /** - * 服务实例变动 - */ - public static final Integer SERVICE_CHANGED = 7; - - /** - * 请求标识字节数 - */ - public static final Integer REQUEST_FLAG_BYTES = 4; - /** - * 请求长度的字节数 - */ - public static final Integer REQUEST_LENGTH_BYTES = 4; - /** - * 请求类型的字节数 - */ - public static final Integer REQUEST_TYPE_BYTES = 4; - /** - * 请求ID的字节数 - */ - public static final Integer REQUEST_ID_BYTES = 32; - /** - * 字符串类型的请求字段的长度的字节数 - */ - public static final Integer REQUEST_STRING_FIELD_LENGTH_BYTES = 4; - /** - * 整数类型的请求字段的字节数 - */ - public static final Integer REQUEST_INTEGER_FIELD_BYTES = 4; - - /** - * 获取请求id - * @return - */ - public abstract String getId(); - - public static Request deserialize(Integer requestType, ByteBuffer messageBuffer) { - Request request = null; - -// if(requestType.equals(Request.FETCH_SLOTS_ALLOCATION)) { -// request = FetchSlotsAllocationRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.FETCH_SERVER_ADDRESSES)) { -// request = FetchServerAddressesRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.REGISTER)) { -// request = RegisterRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.HEARTBEAT)) { -// request = HeartbeatRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.FETCH_SERVER_NODE_ID)) { -// request = FetchServerNodeIdRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.SUBSCRIBE)) { -// request = SubscribeRequest.deserialize(messageBuffer); -// } else if(requestType.equals(Request.SERVICE_CHANGED)) { -// request = ServiceChangedRequest.deserialize(messageBuffer); -// } - - return request; - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/exception/InitException.java b/pantheon-common/src/main/java/com/pantheon/common/exception/InitException.java deleted file mode 100644 index 85b2dae..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/exception/InitException.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 com.pantheon.common.exception; - -public class InitException extends RuntimeException { - private static final long serialVersionUID = -7256002576788700354L; - - private String status; - private int code; - - public InitException(String status, int code) { - super(); - this.status = status; - this.code = code; - } - - public InitException(String status, int code, String message) { - super(message); - this.status = status; - this.code = code; - } - - public InitException(String message) { - super(message); - } - - public InitException(String message, Throwable throwable) { - super(message, throwable); - } - - public InitException(String status, int code, String message, Throwable throwable) { - super(message, throwable); - this.status = status; - this.code = code; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/AbstractLifecycleComponent.java b/pantheon-common/src/main/java/com/pantheon/common/lifecycle/AbstractLifecycleComponent.java deleted file mode 100644 index ad49a4d..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/AbstractLifecycleComponent.java +++ /dev/null @@ -1,96 +0,0 @@ - -package com.pantheon.common.lifecycle; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -public abstract class AbstractLifecycleComponent implements LifecycleComponent { - - protected final Lifecycle lifecycle = new Lifecycle(); - - private final List listeners = new CopyOnWriteArrayList<>(); - - protected AbstractLifecycleComponent() {} - - @Override - public Lifecycle.State lifecycleState() { - return this.lifecycle.state(); - } - - @Override - public void addLifecycleListener(LifecycleListener listener) { - listeners.add(listener); - } - - @Override - public void removeLifecycleListener(LifecycleListener listener) { - listeners.remove(listener); - } - - @Override - public void start() { - synchronized (lifecycle) { - if (!lifecycle.canMoveToStarted()) { - return; - } - for (LifecycleListener listener : listeners) { - listener.beforeStart(); - } - doStart(); - lifecycle.moveToStarted(); - for (LifecycleListener listener : listeners) { - listener.afterStart(); - } - } - } - - protected abstract void doStart(); - - @Override - public void stop() { - synchronized (lifecycle) { - if (!lifecycle.canMoveToStopped()) { - return; - } - for (LifecycleListener listener : listeners) { - listener.beforeStop(); - } - lifecycle.moveToStopped(); - doStop(); - for (LifecycleListener listener : listeners) { - listener.afterStop(); - } - } - } - - protected abstract void doStop(); - - @Override - public void close() { - synchronized (lifecycle) { - if (lifecycle.started()) { - stop(); - } - if (!lifecycle.canMoveToClosed()) { - return; - } - for (LifecycleListener listener : listeners) { - listener.beforeClose(); - } - lifecycle.moveToClosed(); - try { - doClose(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } finally { - for (LifecycleListener listener : listeners) { - listener.afterClose(); - } - } - } - } - - protected abstract void doClose() throws IOException; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Lifecycle.java b/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Lifecycle.java deleted file mode 100644 index c19d994..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Lifecycle.java +++ /dev/null @@ -1,180 +0,0 @@ - -package com.pantheon.common.lifecycle; - -/** - * Lifecycle state. Allows the following transitions: - *

    - *
  • INITIALIZED -> STARTED, STOPPED, CLOSED
  • - *
  • STARTED -> STOPPED
  • - *
  • STOPPED -> STARTED, CLOSED
  • - *
  • CLOSED ->
  • - *
- *

- * Also allows to stay in the same state. For example, when calling stop on a component, the - * following logic can be applied: - *

- * public void stop() {
- *  if (!lifecycleState.moveToStopped()) {
- *      return;
- *  }
- * // continue with stop logic
- * }
- * 
- *

- * NOTE: The Lifecycle class is thread-safe. It is also possible to prevent concurrent state transitions - * by locking on the Lifecycle object itself. This is typically useful when chaining multiple transitions. - *

- * Note, closed is only allowed to be called when stopped, so make sure to stop the component first. - * Here is how the logic can be applied. A lock of the {@code lifecycleState} object is taken so that - * another thread cannot move the state from {@code STOPPED} to {@code STARTED} before it has moved to - * {@code CLOSED}. - *

- * public void close() {
- *  synchronized (lifecycleState) {
- *      if (lifecycleState.started()) {
- *          stop();
- *      }
- *      if (!lifecycleState.moveToClosed()) {
- *          return;
- *      }
- *  }
- *  // perform close logic here
- * }
- * 
- */ -public class Lifecycle { - - public enum State { - INITIALIZED, - STOPPED, - STARTED, - CLOSED - } - - private volatile State state = State.INITIALIZED; - - public State state() { - return this.state; - } - - /** - * Returns {@code true} if the state is initialized. - */ - public boolean initialized() { - return state == State.INITIALIZED; - } - - /** - * Returns {@code true} if the state is started. - */ - public boolean started() { - return state == State.STARTED; - } - - /** - * Returns {@code true} if the state is stopped. - */ - public boolean stopped() { - return state == State.STOPPED; - } - - /** - * Returns {@code true} if the state is closed. - */ - public boolean closed() { - return state == State.CLOSED; - } - - public boolean stoppedOrClosed() { - State state = this.state; - return state == State.STOPPED || state == State.CLOSED; - } - - public boolean canMoveToStarted() throws IllegalStateException { - State localState = this.state; - if (localState == State.INITIALIZED || localState == State.STOPPED) { - return true; - } - if (localState == State.STARTED) { - return false; - } - if (localState == State.CLOSED) { - throw new IllegalStateException("Can't move to started state when closed"); - } - throw new IllegalStateException("Can't move to started with unknown state"); - } - - - public synchronized boolean moveToStarted() throws IllegalStateException { - State localState = this.state; - if (localState == State.INITIALIZED || localState == State.STOPPED) { - state = State.STARTED; - return true; - } - if (localState == State.STARTED) { - return false; - } - if (localState == State.CLOSED) { - throw new IllegalStateException("Can't move to started state when closed"); - } - throw new IllegalStateException("Can't move to started with unknown state"); - } - - public boolean canMoveToStopped() throws IllegalStateException { - State localState = state; - if (localState == State.STARTED) { - return true; - } - if (localState == State.INITIALIZED || localState == State.STOPPED) { - return false; - } - if (localState == State.CLOSED) { - throw new IllegalStateException("Can't move to stopped state when closed"); - } - throw new IllegalStateException("Can't move to stopped with unknown state"); - } - - public synchronized boolean moveToStopped() throws IllegalStateException { - State localState = state; - if (localState == State.STARTED) { - state = State.STOPPED; - return true; - } - if (localState == State.INITIALIZED || localState == State.STOPPED) { - return false; - } - if (localState == State.CLOSED) { - throw new IllegalStateException("Can't move to stopped state when closed"); - } - throw new IllegalStateException("Can't move to stopped with unknown state"); - } - - public boolean canMoveToClosed() throws IllegalStateException { - State localState = state; - if (localState == State.CLOSED) { - return false; - } - if (localState == State.STARTED) { - throw new IllegalStateException("Can't move to closed before moving to stopped mode"); - } - return true; - } - - public synchronized boolean moveToClosed() throws IllegalStateException { - State localState = state; - if (localState == State.CLOSED) { - return false; - } - if (localState == State.STARTED) { - throw new IllegalStateException("Can't move to closed before moving to stopped mode"); - } - state = State.CLOSED; - return true; - } - - @Override - public String toString() { - return state.toString(); - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleComponent.java b/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleComponent.java deleted file mode 100644 index e672f4a..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleComponent.java +++ /dev/null @@ -1,17 +0,0 @@ - -package com.pantheon.common.lifecycle; - - - -public interface LifecycleComponent extends Releasable { - - Lifecycle.State lifecycleState(); - - void addLifecycleListener(LifecycleListener listener); - - void removeLifecycleListener(LifecycleListener listener); - - void start(); - - void stop(); -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleListener.java b/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleListener.java deleted file mode 100644 index a35718a..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleListener.java +++ /dev/null @@ -1,29 +0,0 @@ - -package com.pantheon.common.lifecycle; - -public abstract class LifecycleListener { - - public void beforeStart() { - - } - - public void afterStart() { - - } - - public void beforeStop() { - - } - - public void afterStop() { - - } - - public void beforeClose() { - - } - - public void afterClose() { - - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Releasable.java b/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Releasable.java deleted file mode 100644 index d21f799..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/lifecycle/Releasable.java +++ /dev/null @@ -1,15 +0,0 @@ - -package com.pantheon.common.lifecycle; - - -import java.io.Closeable; - -/** - * Specialization of {@link AutoCloseable} that may only throw an {@link }. - */ -public interface Releasable extends Closeable { - - @Override - void close(); - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/RemotingSysResponseCode.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/RemotingSysResponseCode.java deleted file mode 100644 index 7520da8..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/RemotingSysResponseCode.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.pantheon.common.protocol; - - -public class RemotingSysResponseCode { - - public static final int SUCCESS = 0; - - public static final int SYSTEM_ERROR = 1; - - public static final int SYSTEM_BUSY = 2; - - public static final int REQUEST_CODE_NOT_SUPPORTED = 3; - - public static final int TRANSACTION_FAILED = 4; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/RequestCode.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/RequestCode.java deleted file mode 100644 index 0e9eaf0..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/RequestCode.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.pantheon.common.protocol; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc - **/ -public class RequestCode { - public static final int GET_SERVER_NODE_ID = 10; - public static final int GET_SLOTS_ALLOCATION = 11; - public static final int GET_SERVER_ADDRESSES= 12; - public static final int GET_CONSUMER_RUNNING_INFO = 13; - public static final int SERVICE_REGISTRY = 14; - public static final int SERVICE_HEART_BEAT = 15; - public static final int SERVICE_UNREGISTER = 16; - public static final int GET_ALL_APP = 17; - public static final int GET_DELTA_APP = 18; - public static final int GET_IN_NEED_APP = 19; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/ResponseCode.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/ResponseCode.java deleted file mode 100644 index bbe1f5d..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/ResponseCode.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.pantheon.common.protocol; - -import com.pantheon.remoting.protocol.RemotingSysResponseCode; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc - **/ -public class ResponseCode extends RemotingSysResponseCode { - public static final int CONSUME_MSG_TIMEOUT = 100; -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressRequestHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressRequestHeader.java deleted file mode 100644 index 91337c1..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressRequestHeader.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class FetchServerAddressRequestHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressResponseHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressResponseHeader.java deleted file mode 100644 index 85f88e6..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressResponseHeader.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class FetchServerAddressResponseHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetConsumerRunningInfoRequestHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetConsumerRunningInfoRequestHeader.java deleted file mode 100644 index 6f9f249..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetConsumerRunningInfoRequestHeader.java +++ /dev/null @@ -1,29 +0,0 @@ - - -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.annotation.CFNotNull; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class GetConsumerRunningInfoRequestHeader implements CommandCustomHeader { - - @CFNotNull - private String clientId; - - - @Override - public void checkFields() throws RemotingCommandException { - } - - - public String getClientId() { - return clientId; - } - - public void setClientId(String clientId) { - this.clientId = clientId; - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressRequestHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressRequestHeader.java deleted file mode 100644 index 27a8152..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressRequestHeader.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class GetServerAddressRequestHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressResponseHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressResponseHeader.java deleted file mode 100644 index 5c98d64..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressResponseHeader.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.annotation.CFNotNull; -import com.pantheon.remoting.exception.RemotingCommandException; - -import java.util.List; - -public class GetServerAddressResponseHeader implements CommandCustomHeader { - @CFNotNull - private String serverAddresses; - - @Override - public void checkFields() throws RemotingCommandException { - } - - public String getServerAddresses() { - return serverAddresses; - } - - public void setServerAddresses(String serverAddresses) { - this.serverAddresses = serverAddresses; - } -} - -// public List getServerAddresses() { -// return serverAddresses; -// } -// -// public void setServerAddresses(List serverAddresses) { -// this.serverAddresses = serverAddresses; -// } -//} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdRequestHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdRequestHeader.java deleted file mode 100644 index 265e18f..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdRequestHeader.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class GetServerNodeIdRequestHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdResponseHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdResponseHeader.java deleted file mode 100644 index 6b86b46..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdResponseHeader.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.annotation.CFNotNull; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class GetServerNodeIdResponseHeader implements CommandCustomHeader { - @CFNotNull - private Integer serverNodeId; - - @Override - public void checkFields() throws RemotingCommandException { - } - - public Integer getServerNodeId() { - return serverNodeId; - } - - public void setServerNodeId(Integer serverNodeId) { - this.serverNodeId = serverNodeId; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsRequestHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsRequestHeader.java deleted file mode 100644 index c66ef40..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsRequestHeader.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -public class GetSlotsRequestHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsResponseHeader.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsResponseHeader.java deleted file mode 100644 index eb38f9d..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsResponseHeader.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -/** - * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ - */ -package com.pantheon.common.protocol.header; - - -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.exception.RemotingCommandException; - -import java.util.List; -import java.util.Map; - -public class GetSlotsResponseHeader implements CommandCustomHeader { - /** - * slots allocation info - */ - private String slotsAllocation; - @Override - public void checkFields() throws RemotingCommandException { - } - - public String getSlotsAllocation() { - return slotsAllocation; - } - - public void setSlotsAllocation(String slotsAllocation) { - this.slotsAllocation = slotsAllocation; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/HeartBeat.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/HeartBeat.java deleted file mode 100644 index 1f4c88b..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/HeartBeat.java +++ /dev/null @@ -1,41 +0,0 @@ - -package com.pantheon.common.protocol.heartBeat; - - -import com.pantheon.remoting.protocol.RemotingSerializable; - -import java.util.HashSet; -import java.util.Set; - -/** - * locate a instance with a appName and instanceId - */ -public class HeartBeat extends RemotingSerializable { - private String serviceName; - private String instanceId; - private Set subscriptionDataSet = new HashSet(); - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getInstanceId() { - return instanceId; - } - - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - - public Set getSubscriptionDataSet() { - return subscriptionDataSet; - } - - public void setSubscriptionDataSet(Set subscriptionDataSet) { - this.subscriptionDataSet = subscriptionDataSet; - } -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/ServiceUnregister.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/ServiceUnregister.java deleted file mode 100644 index d82eb5c..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/ServiceUnregister.java +++ /dev/null @@ -1,30 +0,0 @@ - -package com.pantheon.common.protocol.heartBeat; - - -import com.pantheon.remoting.protocol.RemotingSerializable; - -/** - * locate a instance with a appName and instanceId - */ -public class ServiceUnregister extends RemotingSerializable { - private String serviceName; - private String instanceId; - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getInstanceId() { - return instanceId; - } - - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - -} diff --git a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/SubscriptionData.java b/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/SubscriptionData.java deleted file mode 100644 index 22b88d3..0000000 --- a/pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/SubscriptionData.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.pantheon.common.protocol.heartBeat; - -/** - * @author Anthony - * @create 2021/12/13 - * @desc - */ -public class SubscriptionData { - private Integer slotNum; - private String serviceName; - private String instanceId; - private String clientId; - - public Integer getSlotNum() { - return slotNum; - } - - public void setSlotNum(Integer slotNum) { - this.slotNum = slotNum; - } - - public String getServiceName() { - return serviceName; - } - - public String getInstanceId() { - return instanceId; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - - public String getClientId() { - return clientId; - } - - public void setClientId(String clientId) { - this.clientId = clientId; - } -} diff --git a/pantheon-dubbo-support/pom.xml b/pantheon-dubbo-support/pom.xml deleted file mode 100644 index 92266ec..0000000 --- a/pantheon-dubbo-support/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-dubbo-support - - - 13 - 13 - - - \ No newline at end of file diff --git a/pantheon-remoting/README.md b/pantheon-remoting/README.md deleted file mode 100644 index dd65a21..0000000 --- a/pantheon-remoting/README.md +++ /dev/null @@ -1 +0,0 @@ -Most of the this module introduce the code from [rocketmq github](https://github.com/apache/rocketmq) rocketmq-remoting module \ No newline at end of file diff --git a/pantheon-remoting/pom.xml b/pantheon-remoting/pom.xml deleted file mode 100644 index e6ca9d5..0000000 --- a/pantheon-remoting/pom.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - - 4.0.0 - pantheon-remoting - jar - pantheon-remoting ${project.version} - - - 8 - 8 - - - - - javax.jms - jms - 1.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - log4j - log4j - 1.2.17 - - - com.alibaba - fastjson - 1.2.71 - - - io.netty - netty-all - 4.0.42.Final - - - com.netflix.archaius - archaius-core - 0.7.6 - - - commons-configuration - commons-configuration - 1.8 - - - - - \ No newline at end of file diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/ChannelEventListener.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/ChannelEventListener.java deleted file mode 100644 index 71755b2..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/ChannelEventListener.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting; - -import io.netty.channel.Channel; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc subscribe to this listener to get notified when channel event triggered - **/ -public interface ChannelEventListener { - void onChannelConnect(final String remoteAddr, final Channel channel); - - void onChannelClose(final String remoteAddr, final Channel channel); - - void onChannelException(final String remoteAddr, final Channel channel); - - void onChannelIdle(final String remoteAddr, final Channel channel); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/CommandCustomHeader.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/CommandCustomHeader.java deleted file mode 100644 index 9ffe2c4..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/CommandCustomHeader.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 com.pantheon.remoting; - - -import com.pantheon.remoting.exception.RemotingCommandException; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public interface CommandCustomHeader { - void checkFields() throws RemotingCommandException; -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/InvokeCallback.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/InvokeCallback.java deleted file mode 100644 index 5138c91..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/InvokeCallback.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 com.pantheon.remoting; - -import com.pantheon.remoting.netty.ResponseFuture; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc used for async message - **/ -public interface InvokeCallback { - void operationComplete(final ResponseFuture responseFuture); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/RPCHook.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/RPCHook.java deleted file mode 100644 index 5983ec8..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/RPCHook.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 com.pantheon.remoting; - -import com.pantheon.remoting.protocol.RemotingCommand; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public interface RPCHook { - void doBeforeRequest(final String remoteAddr, final RemotingCommand request); - - void doAfterResponse(final String remoteAddr, final RemotingCommand request, - final RemotingCommand response); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingClient.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingClient.java deleted file mode 100644 index 2f16009..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingClient.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 com.pantheon.remoting; - - -import com.pantheon.remoting.exception.RemotingConnectException; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.exception.RemotingTooMuchRequestException; -import com.pantheon.remoting.netty.NettyRequestProcessor; -import com.pantheon.remoting.protocol.RemotingCommand; - -import java.util.List; -import java.util.concurrent.ExecutorService; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public interface RemotingClient extends RemotingService { - - void updateServerAddressList(final List addrs); - - List getServerAddressList(); - - RemotingCommand invokeSync(final String addr, final RemotingCommand request, - final long timeoutMillis) throws InterruptedException, RemotingConnectException, - RemotingSendRequestException, RemotingTimeoutException; - - void invokeAsync(final String addr, final RemotingCommand request, final long timeoutMillis, - final InvokeCallback invokeCallback) throws InterruptedException, RemotingConnectException, - RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException; - - void invokeOneway(final String addr, final RemotingCommand request, final long timeoutMillis) - throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, - RemotingTimeoutException, RemotingSendRequestException; - - void registerProcessor(final int requestCode, final NettyRequestProcessor processor, - final ExecutorService executor); - - void setCallbackExecutor(final ExecutorService callbackExecutor); - - ExecutorService getCallbackExecutor(); - - boolean isChannelWritable(final String addr); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingServer.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingServer.java deleted file mode 100644 index 8ccef68..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingServer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 com.pantheon.remoting; - -import com.pantheon.remoting.common.Pair; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.exception.RemotingTooMuchRequestException; -import com.pantheon.remoting.netty.NettyRequestProcessor; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.Channel; - -import java.util.concurrent.ExecutorService; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public interface RemotingServer extends RemotingService { - - void registerProcessor(final int requestCode, final NettyRequestProcessor processor, - final ExecutorService executor); - - void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor); - - int localListenPort(); - - Pair getProcessorPair(final int requestCode); - - RemotingCommand invokeSync(final Channel channel, final RemotingCommand request, - final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, - RemotingTimeoutException; - - void invokeAsync(final Channel channel, final RemotingCommand request, final long timeoutMillis, - final InvokeCallback invokeCallback) throws InterruptedException, - RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException; - - void invokeOneway(final Channel channel, final RemotingCommand request, final long timeoutMillis) - throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, - RemotingSendRequestException; - -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingService.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingService.java deleted file mode 100644 index d152b32..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingService.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 com.pantheon.remoting; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public interface RemotingService { - void start(); - - void shutdown(); - - void registerRPCHook(RPCHook rpcHook); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNotNull.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNotNull.java deleted file mode 100644 index 59aef68..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNotNull.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) -public @interface CFNotNull { -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNullable.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNullable.java deleted file mode 100644 index 458f018..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNullable.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) -public @interface CFNullable { -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/Pair.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/Pair.java deleted file mode 100644 index 7da1a30..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/Pair.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 com.pantheon.remoting.common; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class Pair { - private T1 object1; - private T2 object2; - - public Pair(T1 object1, T2 object2) { - this.object1 = object1; - this.object2 = object2; - } - - public T1 getObject1() { - return object1; - } - - public void setObject1(T1 object1) { - this.object1 = object1; - } - - public T2 getObject2() { - return object2; - } - - public void setObject2(T2 object2) { - this.object2 = object2; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingHelper.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingHelper.java deleted file mode 100644 index 2ab09a6..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingHelper.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.pantheon.remoting.common; - -import com.pantheon.remoting.exception.RemotingConnectException; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.Channel; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingHelper { - public static final String PANTHEON_REMOTING = "PantheonRemoting"; - public static final String DEFAULT_CHARSET = "UTF-8"; - - private static final Logger log = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - public static String exceptionSimpleDesc(final Throwable e) { - StringBuffer sb = new StringBuffer(); - if (e != null) { - sb.append(e.toString()); - - StackTraceElement[] stackTrace = e.getStackTrace(); - if (stackTrace != null && stackTrace.length > 0) { - StackTraceElement elment = stackTrace[0]; - sb.append(", "); - sb.append(elment.toString()); - } - } - - return sb.toString(); - } - - public static SocketAddress string2SocketAddress(final String addr) { - int split = addr.lastIndexOf(":"); - String host = addr.substring(0, split); - String port = addr.substring(split + 1); - InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port)); - return isa; - } - - public static RemotingCommand invokeSync(final String addr, final RemotingCommand request, - final long timeoutMillis) throws InterruptedException, RemotingConnectException, - RemotingSendRequestException, RemotingTimeoutException { - long beginTime = System.currentTimeMillis(); - SocketAddress socketAddress = RemotingUtil.string2SocketAddress(addr); - SocketChannel socketChannel = RemotingUtil.connect(socketAddress); - if (socketChannel != null) { - boolean sendRequestOK = false; - - try { - - socketChannel.configureBlocking(true); - - //bugfix http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4614802 - socketChannel.socket().setSoTimeout((int) timeoutMillis); - - ByteBuffer byteBufferRequest = request.encode(); - while (byteBufferRequest.hasRemaining()) { - int length = socketChannel.write(byteBufferRequest); - if (length > 0) { - if (byteBufferRequest.hasRemaining()) { - if ((System.currentTimeMillis() - beginTime) > timeoutMillis) { - - throw new RemotingSendRequestException(addr); - } - } - } else { - throw new RemotingSendRequestException(addr); - } - - Thread.sleep(1); - } - - sendRequestOK = true; - - ByteBuffer byteBufferSize = ByteBuffer.allocate(4); - while (byteBufferSize.hasRemaining()) { - int length = socketChannel.read(byteBufferSize); - if (length > 0) { - if (byteBufferSize.hasRemaining()) { - if ((System.currentTimeMillis() - beginTime) > timeoutMillis) { - - throw new RemotingTimeoutException(addr, timeoutMillis); - } - } - } else { - throw new RemotingTimeoutException(addr, timeoutMillis); - } - - Thread.sleep(1); - } - - int size = byteBufferSize.getInt(0); - ByteBuffer byteBufferBody = ByteBuffer.allocate(size); - while (byteBufferBody.hasRemaining()) { - int length = socketChannel.read(byteBufferBody); - if (length > 0) { - if (byteBufferBody.hasRemaining()) { - if ((System.currentTimeMillis() - beginTime) > timeoutMillis) { - - throw new RemotingTimeoutException(addr, timeoutMillis); - } - } - } else { - throw new RemotingTimeoutException(addr, timeoutMillis); - } - - Thread.sleep(1); - } - - byteBufferBody.flip(); - return RemotingCommand.decode(byteBufferBody); - } catch (IOException e) { - log.error("invokeSync failure", e); - - if (sendRequestOK) { - throw new RemotingTimeoutException(addr, timeoutMillis); - } else { - throw new RemotingSendRequestException(addr); - } - } finally { - try { - socketChannel.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } else { - throw new RemotingConnectException(addr); - } - } - - public static String parseChannelRemoteAddr(final Channel channel) { - if (null == channel) { - return ""; - } - SocketAddress remote = channel.remoteAddress(); - final String addr = remote != null ? remote.toString() : ""; - - if (addr.length() > 0) { - int index = addr.lastIndexOf("/"); - if (index >= 0) { - return addr.substring(index + 1); - } - - return addr; - } - - return ""; - } - - public static String parseSocketAddressAddr(SocketAddress socketAddress) { - if (socketAddress != null) { - final String addr = socketAddress.toString(); - - if (addr.length() > 0) { - return addr.substring(1); - } - } - return ""; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingUtil.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingUtil.java deleted file mode 100644 index 4387a4c..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/RemotingUtil.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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 com.pantheon.remoting.common; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.SocketAddress; -import java.nio.channels.Selector; -import java.nio.channels.SocketChannel; -import java.nio.channels.spi.SelectorProvider; -import java.util.ArrayList; -import java.util.Enumeration; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingUtil { - public static final String OS_NAME = System.getProperty("os.name"); - - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - private static boolean isLinuxPlatform = false; - private static boolean isWindowsPlatform = false; - - static { - if (OS_NAME != null && OS_NAME.toLowerCase().contains("linux")) { - isLinuxPlatform = true; - } - - if (OS_NAME != null && OS_NAME.toLowerCase().contains("windows")) { - isWindowsPlatform = true; - } - } - - public static boolean isWindowsPlatform() { - return isWindowsPlatform; - } - - public static Selector openSelector() throws IOException { - Selector result = null; - - if (isLinuxPlatform()) { - try { - final Class providerClazz = Class.forName("sun.nio.ch.EPollSelectorProvider"); - if (providerClazz != null) { - try { - final Method method = providerClazz.getMethod("provider"); - if (method != null) { - final SelectorProvider selectorProvider = (SelectorProvider) method.invoke(null); - if (selectorProvider != null) { - result = selectorProvider.openSelector(); - } - } - } catch (final Exception e) { - logger.warn("Open ePoll Selector for linux platform exception", e); - } - } - } catch (final Exception e) { - // ignore - } - } - - if (result == null) { - result = Selector.open(); - } - - return result; - } - - public static boolean isLinuxPlatform() { - return isLinuxPlatform; - } - - public static String getLocalAddress() { - try { - // Traversal Network interface to get the first non-loopback and non-private address - Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); - ArrayList ipv4Result = new ArrayList(); - ArrayList ipv6Result = new ArrayList(); - while (enumeration.hasMoreElements()) { - final NetworkInterface networkInterface = enumeration.nextElement(); - final Enumeration en = networkInterface.getInetAddresses(); - while (en.hasMoreElements()) { - final InetAddress address = en.nextElement(); - if (!address.isLoopbackAddress()) { - if (address instanceof Inet6Address) { - ipv6Result.add(normalizeHostAddress(address)); - } else { - ipv4Result.add(normalizeHostAddress(address)); - } - } - } - } - - // prefer ipv4 - if (!ipv4Result.isEmpty()) { - for (String ip : ipv4Result) { - if (ip.startsWith("127.0") || ip.startsWith("192.168")) { - continue; - } - - return ip; - } - - return ipv4Result.get(ipv4Result.size() - 1); - } else if (!ipv6Result.isEmpty()) { - return ipv6Result.get(0); - } - //If failed to find,fall back to localhost - final InetAddress localHost = InetAddress.getLocalHost(); - return normalizeHostAddress(localHost); - } catch (Exception e) { - logger.error("Failed to obtain local address", e); - } - - return null; - } - - public static String normalizeHostAddress(final InetAddress localHost) { - if (localHost instanceof Inet6Address) { - return "[" + localHost.getHostAddress() + "]"; - } else { - return localHost.getHostAddress(); - } - } - - public static SocketAddress string2SocketAddress(final String addr) { - int split = addr.lastIndexOf(":"); - String host = addr.substring(0, split); - String port = addr.substring(split + 1); - InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port)); - return isa; - } - - public static String socketAddress2String(final SocketAddress addr) { - StringBuilder sb = new StringBuilder(); - InetSocketAddress inetSocketAddress = (InetSocketAddress) addr; - sb.append(inetSocketAddress.getAddress().getHostAddress()); - sb.append(":"); - sb.append(inetSocketAddress.getPort()); - return sb.toString(); - } - - public static SocketChannel connect(SocketAddress remote) { - return connect(remote, 1000 * 5); - } - - public static SocketChannel connect(SocketAddress remote, final int timeoutMillis) { - SocketChannel sc = null; - try { - sc = SocketChannel.open(); - sc.configureBlocking(true); - sc.socket().setSoLinger(false, -1); - sc.socket().setTcpNoDelay(true); - sc.socket().setReceiveBufferSize(1024 * 64); - sc.socket().setSendBufferSize(1024 * 64); - sc.socket().connect(remote, timeoutMillis); - sc.configureBlocking(false); - return sc; - } catch (Exception e) { - if (sc != null) { - try { - sc.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - } - } - - return null; - } - - public static void closeChannel(Channel channel) { - final String addrRemote = RemotingHelper.parseChannelRemoteAddr(channel); - channel.close().addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - logger.info("closeChannel: close the connection to remote address[{}] result: {}", addrRemote, - future.isSuccess()); - } - }); - } - -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/SemaphoreReleaseOnlyOnce.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/SemaphoreReleaseOnlyOnce.java deleted file mode 100644 index 66f4a6f..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/SemaphoreReleaseOnlyOnce.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 com.pantheon.remoting.common; - -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class SemaphoreReleaseOnlyOnce { - private final AtomicBoolean released = new AtomicBoolean(false); - private final Semaphore semaphore; - - public SemaphoreReleaseOnlyOnce(Semaphore semaphore) { - this.semaphore = semaphore; - } - - public void release() { - if (this.semaphore != null) { - if (this.released.compareAndSet(false, true)) { - this.semaphore.release(); - } - } - } - - public Semaphore getSemaphore() { - return semaphore; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/ServiceThread.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/ServiceThread.java deleted file mode 100644 index a029020..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/ServiceThread.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 com.pantheon.remoting.common; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * @author Anthony - * @create 2021/11/17 - * @desc Base class for background thread - **/ -public abstract class ServiceThread implements Runnable { - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - private static final long JOIN_TIME = 90 * 1000; - protected final Thread thread; - protected volatile boolean hasNotified = false; - protected volatile boolean stopped = false; - - public ServiceThread() { - this.thread = new Thread(this, this.getServiceName()); - } - - public abstract String getServiceName(); - - public void start() { - this.thread.start(); - } - - public void shutdown() { - this.shutdown(false); - } - - public void shutdown(final boolean interrupt) { - this.stopped = true; - logger.info("shutdown thread " + this.getServiceName() + " interrupt " + interrupt); - synchronized (this) { - if (!this.hasNotified) { - this.hasNotified = true; - this.notify(); - } - } - - try { - if (interrupt) { - this.thread.interrupt(); - } - - long beginTime = System.currentTimeMillis(); - this.thread.join(this.getJointime()); - long elapsedTime = System.currentTimeMillis() - beginTime; - logger.info("join thread " + this.getServiceName() + " elapsed time(ms) " + elapsedTime + " " - + this.getJointime()); - } catch (InterruptedException e) { - logger.error("Interrupted", e); - } - } - - public long getJointime() { - return JOIN_TIME; - } - - public boolean isStopped() { - return stopped; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/TlsMode.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/common/TlsMode.java deleted file mode 100644 index b78dba1..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/common/TlsMode.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 com.pantheon.remoting.common; - -/** - * For server, three SSL modes are supported: disabled, permissive and enforcing. - *
    - *
  1. disabled: SSL is not supported; any incoming SSL handshake will be rejected, causing connection closed.
  2. - *
  3. permissive: SSL is optional, aka, server in this mode can serve client connections with or without SSL;
  4. - *
  5. enforcing: SSL is required, aka, non SSL connection will be rejected.
  6. - *
- */ -public enum TlsMode { - - DISABLED("disabled"), - PERMISSIVE("permissive"), - ENFORCING("enforcing"); - - private String name; - - TlsMode(String name) { - this.name = name; - } - - public static TlsMode parse(String mode) { - for (TlsMode tlsMode : TlsMode.values()) { - if (tlsMode.name.equals(mode)) { - return tlsMode; - } - } - - return PERMISSIVE; - } - - public String getName() { - return name; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingCommandException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingCommandException.java deleted file mode 100644 index bf61402..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingCommandException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingCommandException extends RemotingException { - private static final long serialVersionUID = -6061365915274953096L; - - public RemotingCommandException(String message) { - super(message, null); - } - - public RemotingCommandException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingConnectException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingConnectException.java deleted file mode 100644 index 6cb6f65..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingConnectException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingConnectException extends RemotingException { - private static final long serialVersionUID = -5565366231695911316L; - - public RemotingConnectException(String addr) { - this(addr, null); - } - - public RemotingConnectException(String addr, Throwable cause) { - super("connect to " + addr + " failed", cause); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingException.java deleted file mode 100644 index f3546a3..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingException extends Exception { - private static final long serialVersionUID = -5690687334570505110L; - - public RemotingException(String message) { - super(message); - } - - public RemotingException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingSendRequestException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingSendRequestException.java deleted file mode 100644 index 6fbf8e2..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingSendRequestException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingSendRequestException extends RemotingException { - private static final long serialVersionUID = 5391285827332471674L; - - public RemotingSendRequestException(String addr) { - this(addr, null); - } - - public RemotingSendRequestException(String addr, Throwable cause) { - super("send request to <" + addr + "> failed", cause); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTimeoutException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTimeoutException.java deleted file mode 100644 index 5f8dc90..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTimeoutException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingTimeoutException extends RemotingException { - - private static final long serialVersionUID = 4106899185095245979L; - - public RemotingTimeoutException(String message) { - super(message); - } - - public RemotingTimeoutException(String addr, long timeoutMillis) { - this(addr, timeoutMillis, null); - } - - public RemotingTimeoutException(String addr, long timeoutMillis, Throwable cause) { - super("wait response on the channel <" + addr + "> timeout, " + timeoutMillis + "(ms)", cause); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTooMuchRequestException.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTooMuchRequestException.java deleted file mode 100644 index fd32cc5..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTooMuchRequestException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 com.pantheon.remoting.exception; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class RemotingTooMuchRequestException extends RemotingException { - private static final long serialVersionUID = 4326919581254519654L; - - public RemotingTooMuchRequestException(String message) { - super(message); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/AsyncNettyRequestProcessor.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/AsyncNettyRequestProcessor.java deleted file mode 100644 index e18f712..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/AsyncNettyRequestProcessor.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.ChannelHandlerContext; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc add async support with {@link RemotingResponseCallback}on {@link NettyRequestProcessor} - **/ -public abstract class AsyncNettyRequestProcessor implements NettyRequestProcessor { - - public void asyncProcessRequest(ChannelHandlerContext ctx, RemotingCommand request, RemotingResponseCallback responseCallback) throws Exception { - RemotingCommand response = processRequest(ctx, request); - responseCallback.callback(response); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/FileRegionEncoder.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/FileRegionEncoder.java deleted file mode 100644 index d7d9344..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/FileRegionEncoder.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.FileRegion; -import io.netty.handler.codec.MessageToByteEncoder; -import io.netty.handler.ssl.SslHandler; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.WritableByteChannel; - -/** - * extends from MessageToByteEncoder - *

- * By default, file region are directly transferred to socket channel which is known as zero copy. In case we need - * to encrypt transmission, data being sent should go through the {@link SslHandler}. This encoder ensures this - * process. - *

- */ -public class FileRegionEncoder extends MessageToByteEncoder { - - /** - * Encode a message into a {@link ByteBuf}. This method will be called for each written message that - * can be handled by this encoder. - * - * @param ctx the {@link ChannelHandlerContext} which this {@link - * MessageToByteEncoder} belongs to - * @param msg the message to encode - * @param out the {@link ByteBuf} into which the encoded message will be written - * @throws Exception is thrown if an error occurs - */ - @Override - protected void encode(ChannelHandlerContext ctx, FileRegion msg, final ByteBuf out) throws Exception { - WritableByteChannel writableByteChannel = new WritableByteChannel() { - @Override - public int write(ByteBuffer src) throws IOException { - out.writeBytes(src); - return out.capacity(); - } - - @Override - public boolean isOpen() { - return true; - } - - @Override - public void close() throws IOException { - } - }; - - long toTransfer = msg.count(); - - while (true) { - long transferred = msg.transfered(); - if (toTransfer - transferred <= 0) { - break; - } - msg.transferTo(writableByteChannel, transferred); - } - } -} \ No newline at end of file diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyClientConfig.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyClientConfig.java deleted file mode 100644 index c0110f8..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyClientConfig.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -public class NettyClientConfig { - /** - * Worker thread number - */ - private int clientWorkerThreads = 4; - private int clientCallbackExecutorThreads = Runtime.getRuntime().availableProcessors(); - private int clientOnewaySemaphoreValue = NettySystemConfig.CLIENT_ONEWAY_SEMAPHORE_VALUE; - private int clientAsyncSemaphoreValue = NettySystemConfig.CLIENT_ASYNC_SEMAPHORE_VALUE; - private int connectTimeoutMillis = 3000; - private long channelNotActiveInterval = 1000 * 60; - - /** - * IdleStateEvent will be triggered when neither read nor write was performed for - * the specified period of this time. Specify {@code 0} to disable - */ - private int clientChannelMaxIdleTimeSeconds = 120; - - private int clientSocketSndBufSize = NettySystemConfig.socketSndbufSize; - private int clientSocketRcvBufSize = NettySystemConfig.socketRcvbufSize; - private boolean clientPooledByteBufAllocatorEnable = false; - private boolean clientCloseSocketIfTimeout = false; - - private boolean useTLS; - - public boolean isClientCloseSocketIfTimeout() { - return clientCloseSocketIfTimeout; - } - - public void setClientCloseSocketIfTimeout(final boolean clientCloseSocketIfTimeout) { - this.clientCloseSocketIfTimeout = clientCloseSocketIfTimeout; - } - - public int getClientWorkerThreads() { - return clientWorkerThreads; - } - - public void setClientWorkerThreads(int clientWorkerThreads) { - this.clientWorkerThreads = clientWorkerThreads; - } - - public int getClientOnewaySemaphoreValue() { - return clientOnewaySemaphoreValue; - } - - public void setClientOnewaySemaphoreValue(int clientOnewaySemaphoreValue) { - this.clientOnewaySemaphoreValue = clientOnewaySemaphoreValue; - } - - public int getConnectTimeoutMillis() { - return connectTimeoutMillis; - } - - public void setConnectTimeoutMillis(int connectTimeoutMillis) { - this.connectTimeoutMillis = connectTimeoutMillis; - } - - public int getClientCallbackExecutorThreads() { - return clientCallbackExecutorThreads; - } - - public void setClientCallbackExecutorThreads(int clientCallbackExecutorThreads) { - this.clientCallbackExecutorThreads = clientCallbackExecutorThreads; - } - - public long getChannelNotActiveInterval() { - return channelNotActiveInterval; - } - - public void setChannelNotActiveInterval(long channelNotActiveInterval) { - this.channelNotActiveInterval = channelNotActiveInterval; - } - - public int getClientAsyncSemaphoreValue() { - return clientAsyncSemaphoreValue; - } - - public void setClientAsyncSemaphoreValue(int clientAsyncSemaphoreValue) { - this.clientAsyncSemaphoreValue = clientAsyncSemaphoreValue; - } - - public int getClientChannelMaxIdleTimeSeconds() { - return clientChannelMaxIdleTimeSeconds; - } - - public void setClientChannelMaxIdleTimeSeconds(int clientChannelMaxIdleTimeSeconds) { - this.clientChannelMaxIdleTimeSeconds = clientChannelMaxIdleTimeSeconds; - } - - public int getClientSocketSndBufSize() { - return clientSocketSndBufSize; - } - - public void setClientSocketSndBufSize(int clientSocketSndBufSize) { - this.clientSocketSndBufSize = clientSocketSndBufSize; - } - - public int getClientSocketRcvBufSize() { - return clientSocketRcvBufSize; - } - - public void setClientSocketRcvBufSize(int clientSocketRcvBufSize) { - this.clientSocketRcvBufSize = clientSocketRcvBufSize; - } - - public boolean isClientPooledByteBufAllocatorEnable() { - return clientPooledByteBufAllocatorEnable; - } - - public void setClientPooledByteBufAllocatorEnable(boolean clientPooledByteBufAllocatorEnable) { - this.clientPooledByteBufAllocatorEnable = clientPooledByteBufAllocatorEnable; - } - - public boolean isUseTLS() { - return useTLS; - } - - public void setUseTLS(boolean useTLS) { - this.useTLS = useTLS; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyDecoder.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyDecoder.java deleted file mode 100644 index d17ccec..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyDecoder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.RemotingUtil; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; - -public class NettyDecoder extends LengthFieldBasedFrameDecoder { - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - private static final int FRAME_MAX_LENGTH = - Integer.parseInt(System.getProperty("com.pantheon.remoting.frameMaxLength", "16777216")); - - public NettyDecoder() { - super(FRAME_MAX_LENGTH, 0, 4, 0, 4); - } - - @Override - public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { - ByteBuf frame = null; - try { - frame = (ByteBuf) super.decode(ctx, in); - if (null == frame) { - return null; - } - //netty‘s bytebuf to standard bytebuffer - ByteBuffer byteBuffer = frame.nioBuffer(); - //bytebuffer data convert to RemotingCommand - return RemotingCommand.decode(byteBuffer); - } catch (Exception e) { - logger.error("decode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e); - RemotingUtil.closeChannel(ctx.channel()); - } finally { - if (null != frame) { - frame.release(); - } - } - - return null; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEncoder.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEncoder.java deleted file mode 100644 index e02b8a9..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEncoder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.RemotingUtil; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; - - -@ChannelHandler.Sharable -public class NettyEncoder extends MessageToByteEncoder { - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - @Override - public void encode(ChannelHandlerContext ctx, RemotingCommand remotingCommand, ByteBuf out) - throws Exception { - try { - //encode header then write to ByteBuf - ByteBuffer header = remotingCommand.encodeHeader(); - out.writeBytes(header); - //body write to ByteBuf - byte[] body = remotingCommand.getBody(); - if (body != null) { - out.writeBytes(body); - } - } catch (Exception e) { - logger.error("encode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e); - if (remotingCommand != null) { - logger.error(remotingCommand.toString()); - } - RemotingUtil.closeChannel(ctx.channel()); - } - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEvent.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEvent.java deleted file mode 100644 index 5eb0c99..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import io.netty.channel.Channel; - -public class NettyEvent { - private final NettyEventType type; - private final String remoteAddr; - private final Channel channel; - - public NettyEvent(NettyEventType type, String remoteAddr, Channel channel) { - this.type = type; - this.remoteAddr = remoteAddr; - this.channel = channel; - } - - public NettyEventType getType() { - return type; - } - - public String getRemoteAddr() { - return remoteAddr; - } - - public Channel getChannel() { - return channel; - } - - @Override - public String toString() { - return "NettyEvent [type=" + type + ", remoteAddr=" + remoteAddr + ", channel=" + channel + "]"; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEventType.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEventType.java deleted file mode 100644 index 89f64cd..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEventType.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -public enum NettyEventType { - CONNECT, - CLOSE, - IDLE, - EXCEPTION -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyLogger.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyLogger.java deleted file mode 100644 index 6d2fca6..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyLogger.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - - -import io.netty.util.internal.logging.InternalLogLevel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicBoolean; - -public class NettyLogger { - - private static AtomicBoolean nettyLoggerSeted = new AtomicBoolean(false); - - private static InternalLogLevel nettyLogLevel = InternalLogLevel.ERROR; - - public static void initNettyLogger() { - if (!nettyLoggerSeted.get()) { - try { - io.netty.util.internal.logging.InternalLoggerFactory.setDefaultFactory(new NettyBridgeLoggerFactory()); - } catch (Throwable e) { - //ignore - } - nettyLoggerSeted.set(true); - } - } - - private static class NettyBridgeLoggerFactory extends io.netty.util.internal.logging.InternalLoggerFactory { - @Override - protected io.netty.util.internal.logging.InternalLogger newInstance(String s) { - return new NettyBridgeLogger(s); - } - } - - private static class NettyBridgeLogger implements io.netty.util.internal.logging.InternalLogger { - - private Logger logger = null; - - public NettyBridgeLogger(String name) { - logger = LoggerFactory.getLogger(name); - } - - @Override - public String name() { - return logger.getName(); - } - - @Override - public boolean isEnabled(InternalLogLevel internalLogLevel) { - return nettyLogLevel.ordinal() <= internalLogLevel.ordinal(); - } - - @Override - public void log(InternalLogLevel internalLogLevel, String s) { - if (internalLogLevel.equals(InternalLogLevel.DEBUG)) { - logger.debug(s); - } - if (internalLogLevel.equals(InternalLogLevel.TRACE)) { - logger.info(s); - } - if (internalLogLevel.equals(InternalLogLevel.INFO)) { - logger.info(s); - } - if (internalLogLevel.equals(InternalLogLevel.WARN)) { - logger.warn(s); - } - if (internalLogLevel.equals(InternalLogLevel.ERROR)) { - logger.error(s); - } - } - - @Override - public void log(InternalLogLevel internalLogLevel, String s, Object o) { - if (internalLogLevel.equals(InternalLogLevel.DEBUG)) { - logger.debug(s, o); - } - if (internalLogLevel.equals(InternalLogLevel.TRACE)) { - logger.info(s, o); - } - if (internalLogLevel.equals(InternalLogLevel.INFO)) { - logger.info(s, o); - } - if (internalLogLevel.equals(InternalLogLevel.WARN)) { - logger.warn(s, o); - } - if (internalLogLevel.equals(InternalLogLevel.ERROR)) { - logger.error(s, o); - } - } - - @Override - public void log(InternalLogLevel internalLogLevel, String s, Object o, Object o1) { - if (internalLogLevel.equals(InternalLogLevel.DEBUG)) { - logger.debug(s, o, o1); - } - if (internalLogLevel.equals(InternalLogLevel.TRACE)) { - logger.info(s, o, o1); - } - if (internalLogLevel.equals(InternalLogLevel.INFO)) { - logger.info(s, o, o1); - } - if (internalLogLevel.equals(InternalLogLevel.WARN)) { - logger.warn(s, o, o1); - } - if (internalLogLevel.equals(InternalLogLevel.ERROR)) { - logger.error(s, o, o1); - } - } - - @Override - public void log(InternalLogLevel internalLogLevel, String s, Object... objects) { - if (internalLogLevel.equals(InternalLogLevel.DEBUG)) { - logger.debug(s, objects); - } - if (internalLogLevel.equals(InternalLogLevel.TRACE)) { - logger.info(s, objects); - } - if (internalLogLevel.equals(InternalLogLevel.INFO)) { - logger.info(s, objects); - } - if (internalLogLevel.equals(InternalLogLevel.WARN)) { - logger.warn(s, objects); - } - if (internalLogLevel.equals(InternalLogLevel.ERROR)) { - logger.error(s, objects); - } - } - - @Override - public void log(InternalLogLevel internalLogLevel, String s, Throwable throwable) { - if (internalLogLevel.equals(InternalLogLevel.DEBUG)) { - logger.debug(s, throwable); - } - if (internalLogLevel.equals(InternalLogLevel.TRACE)) { - logger.info(s, throwable); - } - if (internalLogLevel.equals(InternalLogLevel.INFO)) { - logger.info(s, throwable); - } - if (internalLogLevel.equals(InternalLogLevel.WARN)) { - logger.warn(s, throwable); - } - if (internalLogLevel.equals(InternalLogLevel.ERROR)) { - logger.error(s, throwable); - } - } - - @Override - public boolean isTraceEnabled() { - return isEnabled(InternalLogLevel.TRACE); - } - - @Override - public void trace(String var1) { - logger.info(var1); - } - - @Override - public void trace(String var1, Object var2) { - logger.info(var1, var2); - } - - @Override - public void trace(String var1, Object var2, Object var3) { - logger.info(var1, var2, var3); - } - - @Override - public void trace(String var1, Object... var2) { - logger.info(var1, var2); - } - - @Override - public void trace(String var1, Throwable var2) { - logger.info(var1, var2); - } - - @Override - public boolean isDebugEnabled() { - return isEnabled(InternalLogLevel.DEBUG); - } - - @Override - public void debug(String var1) { - logger.debug(var1); - } - - @Override - public void debug(String var1, Object var2) { - logger.debug(var1, var2); - } - - @Override - public void debug(String var1, Object var2, Object var3) { - logger.debug(var1, var2, var3); - } - - @Override - public void debug(String var1, Object... var2) { - logger.debug(var1, var2); - } - - @Override - public void debug(String var1, Throwable var2) { - logger.debug(var1, var2); - } - - @Override - public boolean isInfoEnabled() { - return isEnabled(InternalLogLevel.INFO); - } - - @Override - public void info(String var1) { - logger.info(var1); - } - - @Override - public void info(String var1, Object var2) { - logger.info(var1, var2); - } - - @Override - public void info(String var1, Object var2, Object var3) { - logger.info(var1, var2, var3); - } - - @Override - public void info(String var1, Object... var2) { - logger.info(var1, var2); - } - - @Override - public void info(String var1, Throwable var2) { - logger.info(var1, var2); - } - - @Override - public boolean isWarnEnabled() { - return isEnabled(InternalLogLevel.WARN); - } - - @Override - public void warn(String var1) { - logger.warn(var1); - } - - @Override - public void warn(String var1, Object var2) { - logger.warn(var1, var2); - } - - @Override - public void warn(String var1, Object... var2) { - logger.warn(var1, var2); - } - - @Override - public void warn(String var1, Object var2, Object var3) { - logger.warn(var1, var2, var3); - } - - @Override - public void warn(String var1, Throwable var2) { - logger.warn(var1, var2); - } - - @Override - public boolean isErrorEnabled() { - return isEnabled(InternalLogLevel.ERROR); - } - - @Override - public void error(String var1) { - logger.error(var1); - } - - @Override - public void error(String var1, Object var2) { - logger.error(var1, var2); - } - - @Override - public void error(String var1, Object var2, Object var3) { - logger.error(var1, var2, var3); - } - - @Override - public void error(String var1, Object... var2) { - logger.error(var1, var2); - } - - @Override - public void error(String var1, Throwable var2) { - logger.error(var1, var2); - } - } - -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingAbstract.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingAbstract.java deleted file mode 100644 index 95477ed..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingAbstract.java +++ /dev/null @@ -1,636 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.ChannelEventListener; -import com.pantheon.remoting.InvokeCallback; -import com.pantheon.remoting.RPCHook; -import com.pantheon.remoting.common.Pair; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.SemaphoreReleaseOnlyOnce; -import com.pantheon.remoting.common.ServiceThread; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.exception.RemotingTooMuchRequestException; -import com.pantheon.remoting.protocol.RemotingCommand; -import com.pantheon.remoting.protocol.RemotingSysResponseCode; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -public abstract class NettyRemotingAbstract { - - /** - * Remoting logger instance. - */ - private static final Logger log = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - /** - * Semaphore to limit maximum number of on-going one-way requests, which protects system memory footprint. - */ - protected final Semaphore semaphoreOneway; - - /** - * Semaphore to limit maximum number of on-going asynchronous requests, which protects system memory footprint. - */ - protected final Semaphore semaphoreAsync; - - /** - * This map caches all on-going requests. - */ - protected final ConcurrentMap responseTable = - new ConcurrentHashMap(256); - - /** - * This container holds all processors per request code, aka, for each incoming request, we may look up the - * responding processor in this map to handle the request. - */ - protected final HashMap> processorTable = - new HashMap>(64); - - /** - * Executor to feed netty events to user defined {@link ChannelEventListener}. - */ - protected final NettyEventExecutor nettyEventExecutor = new NettyEventExecutor(); - - /** - * The default request processor to use in case there is no exact match in {@link #processorTable} per request code. - */ - protected Pair defaultRequestProcessor; - - /** - * SSL context via which to create {@link SslHandler}. - */ - protected volatile SslContext sslContext; - - /** - * custom rpc hooks - */ - protected List rpcHooks = new ArrayList(); - - - static { - NettyLogger.initNettyLogger(); - } - - /** - * Constructor, specifying capacity of one-way and asynchronous semaphores. - * - * @param permitsOneway Number of permits for one-way requests. - * @param permitsAsync Number of permits for asynchronous requests. - */ - public NettyRemotingAbstract(final int permitsOneway, final int permitsAsync) { - this.semaphoreOneway = new Semaphore(permitsOneway, true); - this.semaphoreAsync = new Semaphore(permitsAsync, true); - } - - /** - * Custom channel event listener. - * - * @return custom channel event listener if defined; null otherwise. - */ - public abstract ChannelEventListener getChannelEventListener(); - - /** - * Put a netty event to the executor. - * - * @param event Netty event instance. - */ - public void putNettyEvent(final NettyEvent event) { - this.nettyEventExecutor.putNettyEvent(event); - } - - /** - * Entry of incoming command processing. - * - *

- * Note: - * The incoming remoting command may be - *

    - *
  • An inquiry request from a remote peer component;
  • - *
  • A response to a previous request issued by this very participant.
  • - *
- *

- * - * @param ctx Channel handler context. - * @param msg incoming remoting command. - * @throws Exception if there were any error while processing the incoming command. - */ - public void processMessageReceived(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception { - final RemotingCommand cmd = msg; - if (cmd != null) { - switch (cmd.getType()) { - case REQUEST_COMMAND: - processRequestCommand(ctx, cmd); - break; - case RESPONSE_COMMAND: - processResponseCommand(ctx, cmd); - break; - default: - break; - } - } - } - - protected void doBeforeRpcHooks(String addr, RemotingCommand request) { - if (rpcHooks.size() > 0) { - for (RPCHook rpcHook: rpcHooks) { - rpcHook.doBeforeRequest(addr, request); - } - } - } - - protected void doAfterRpcHooks(String addr, RemotingCommand request, RemotingCommand response) { - if (rpcHooks.size() > 0) { - for (RPCHook rpcHook: rpcHooks) { - rpcHook.doAfterResponse(addr, request, response); - } - } - } - - - /** - * Process incoming request command issued by remote peer. - * - * @param ctx channel handler context. - * @param cmd request command. - */ - public void processRequestCommand(final ChannelHandlerContext ctx, final RemotingCommand cmd) { - final Pair matched = this.processorTable.get(cmd.getCode()); - final Pair pair = null == matched ? this.defaultRequestProcessor : matched; - final int opaque = cmd.getOpaque(); - - if (pair != null) { - Runnable run = new Runnable() { - @Override - public void run() { - try { - doBeforeRpcHooks(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd); - final RemotingResponseCallback callback = new RemotingResponseCallback() { - @Override - public void callback(RemotingCommand response) { - doAfterRpcHooks(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd, response); - if (!cmd.isOnewayRPC()) { - if (response != null) { - response.setOpaque(opaque); - response.markResponseType(); - try { - ctx.writeAndFlush(response); - } catch (Throwable e) { - log.error("process request over, but response failed", e); - log.error(cmd.toString()); - log.error(response.toString()); - } - } else { - } - } - } - }; - if (pair.getObject1() instanceof AsyncNettyRequestProcessor) { - AsyncNettyRequestProcessor processor = (AsyncNettyRequestProcessor)pair.getObject1(); - processor.asyncProcessRequest(ctx, cmd, callback); - } else { - NettyRequestProcessor processor = pair.getObject1(); - RemotingCommand response = processor.processRequest(ctx, cmd); - callback.callback(response); - } - } catch (Throwable e) { - log.error("process request exception", e); - log.error(cmd.toString()); - - if (!cmd.isOnewayRPC()) { - final RemotingCommand response = RemotingCommand.createResponseCommand(RemotingSysResponseCode.SYSTEM_ERROR, - RemotingHelper.exceptionSimpleDesc(e)); - response.setOpaque(opaque); - ctx.writeAndFlush(response); - } - } - } - }; - - if (pair.getObject1().rejectRequest()) { - final RemotingCommand response = RemotingCommand.createResponseCommand(RemotingSysResponseCode.SYSTEM_BUSY, - "[REJECTREQUEST]system busy, start flow control for a while"); - response.setOpaque(opaque); - ctx.writeAndFlush(response); - return; - } - - try { - final RequestTask requestTask = new RequestTask(run, ctx.channel(), cmd); - pair.getObject2().submit(requestTask); - } catch (RejectedExecutionException e) { - if ((System.currentTimeMillis() % 10000) == 0) { - log.warn(RemotingHelper.parseChannelRemoteAddr(ctx.channel()) - + ", too many requests and system thread pool busy, RejectedExecutionException " - + pair.getObject2().toString() - + " request code: " + cmd.getCode()); - } - - if (!cmd.isOnewayRPC()) { - final RemotingCommand response = RemotingCommand.createResponseCommand(RemotingSysResponseCode.SYSTEM_BUSY, - "[OVERLOAD]system busy, start flow control for a while"); - response.setOpaque(opaque); - ctx.writeAndFlush(response); - } - } - } else { - String error = " request type " + cmd.getCode() + " not supported"; - final RemotingCommand response = - RemotingCommand.createResponseCommand(RemotingSysResponseCode.REQUEST_CODE_NOT_SUPPORTED, error); - response.setOpaque(opaque); - ctx.writeAndFlush(response); - log.error(RemotingHelper.parseChannelRemoteAddr(ctx.channel()) + error); - } - } - - /** - * Process response from remote peer to the previous issued requests. - * - * @param ctx channel handler context. - * @param cmd response command instance. - */ - public void processResponseCommand(ChannelHandlerContext ctx, RemotingCommand cmd) { - final int opaque = cmd.getOpaque(); - final ResponseFuture responseFuture = responseTable.get(opaque); - if (responseFuture != null) { - responseFuture.setResponseCommand(cmd); - - responseTable.remove(opaque); - - if (responseFuture.getInvokeCallback() != null) { - executeInvokeCallback(responseFuture); - } else { - responseFuture.putResponse(cmd); - responseFuture.release(); - } - } else { - log.warn("receive response, but not matched any request, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - log.warn(cmd.toString()); - } - } - - - private void executeInvokeCallback(final ResponseFuture responseFuture) { - boolean runInThisThread = false; - ExecutorService executor = this.getCallbackExecutor(); - if (executor != null) { - try { - executor.submit(new Runnable() { - @Override - public void run() { - try { - responseFuture.executeInvokeCallback(); - } catch (Throwable e) { - log.warn("execute callback in executor exception, and callback throw", e); - } finally { - responseFuture.release(); - } - } - }); - } catch (Exception e) { - runInThisThread = true; - log.warn("execute callback in executor exception, maybe executor busy", e); - } - } else { - runInThisThread = true; - } - - if (runInThisThread) { - try { - responseFuture.executeInvokeCallback(); - } catch (Throwable e) { - log.warn("executeInvokeCallback Exception", e); - } finally { - responseFuture.release(); - } - } - } - - - - /** - * Custom RPC hook. - * Just be compatible with the previous version, use getRPCHooks instead. - */ - @Deprecated - protected RPCHook getRPCHook() { - if (rpcHooks.size() > 0) { - return rpcHooks.get(0); - } - return null; - } - - /** - * Custom RPC hooks. - * - * @return RPC hooks if specified; null otherwise. - */ - public List getRPCHooks() { - return rpcHooks; - } - - - /** - * This method specifies thread pool to use while invoking callback methods. - * - * @return Dedicated thread pool instance if specified; or null if the callback is supposed to be executed in the - * netty event-loop thread. - */ - public abstract ExecutorService getCallbackExecutor(); - - /** - *

- * This method is periodically invoked to scan and expire deprecated request. - *

- */ - public void scanResponseTable() { - final List rfList = new LinkedList(); - Iterator> it = this.responseTable.entrySet().iterator(); - while (it.hasNext()) { - Entry next = it.next(); - ResponseFuture rep = next.getValue(); - - if ((rep.getBeginTimestamp() + rep.getTimeoutMillis() + 1000) <= System.currentTimeMillis()) { - rep.release(); - it.remove(); - rfList.add(rep); - log.warn("remove timeout request, " + rep); - } - } - - for (ResponseFuture rf : rfList) { - try { - executeInvokeCallback(rf); - } catch (Throwable e) { - log.warn("scanResponseTable, operationComplete Exception", e); - } - } - } - - public RemotingCommand invokeSyncImpl(final Channel channel, final RemotingCommand request, - final long timeoutMillis) - throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException { - final int opaque = request.getOpaque(); - - try { - final ResponseFuture responseFuture = new ResponseFuture(channel, opaque, timeoutMillis, null, null); - //treat opaque as request id, save to responseTable for later process - this.responseTable.put(opaque, responseFuture); - final SocketAddress addr = channel.remoteAddress(); - channel.writeAndFlush(request).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture f) throws Exception { - if (f.isSuccess()) { - responseFuture.setSendRequestOK(true); - return; - } else { - responseFuture.setSendRequestOK(false); - } - - responseTable.remove(opaque); - responseFuture.setCause(f.cause()); - responseFuture.putResponse(null); - log.warn("send a request command to channel <" + addr + "> failed."); - } - }); - - //use countDownLatch.await(timeoutMillis) wait for result, responseFuture.putResponse will be called by processResponseCommand(ChannelHandlerContext ctx, RemotingCommand cmd) - // from which the countDownLatch.countDown() will be triggered - RemotingCommand responseCommand = responseFuture.waitResponse(timeoutMillis); - if (null == responseCommand) { - if (responseFuture.isSendRequestOK()) { - throw new RemotingTimeoutException(RemotingHelper.parseSocketAddressAddr(addr), timeoutMillis, - responseFuture.getCause()); - } else { - throw new RemotingSendRequestException(RemotingHelper.parseSocketAddressAddr(addr), responseFuture.getCause()); - } - } - - return responseCommand; - } finally { - this.responseTable.remove(opaque); - } - } - - public void invokeAsyncImpl(final Channel channel, final RemotingCommand request, final long timeoutMillis, - final InvokeCallback invokeCallback) - throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { - long beginStartTime = System.currentTimeMillis(); - final int opaque = request.getOpaque(); - //use semaphore for timeout event,semaphoreAsync default value 64 - boolean acquired = this.semaphoreAsync.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); - if (acquired) { - final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreAsync); - long costTime = System.currentTimeMillis() - beginStartTime; - if (timeoutMillis < costTime) { - once.release(); - throw new RemotingTimeoutException("invokeAsyncImpl call timeout"); - } - - final ResponseFuture responseFuture = new ResponseFuture(channel, opaque, timeoutMillis - costTime, invokeCallback, once); - this.responseTable.put(opaque, responseFuture); - try { - channel.writeAndFlush(request).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture f) throws Exception { - if (f.isSuccess()) { - responseFuture.setSendRequestOK(true); - return; - } - requestFail(opaque); - log.warn("send a request command to channel <{}> failed.", RemotingHelper.parseChannelRemoteAddr(channel)); - } - }); - } catch (Exception e) { - responseFuture.release(); - log.warn("send a request command to channel <" + RemotingHelper.parseChannelRemoteAddr(channel) + "> Exception", e); - throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e); - } - } else { - if (timeoutMillis <= 0) { - throw new RemotingTooMuchRequestException("invokeAsyncImpl invoke too fast"); - } else { - String info = - String.format("invokeAsyncImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", - timeoutMillis, - this.semaphoreAsync.getQueueLength(), - this.semaphoreAsync.availablePermits() - ); - log.warn(info); - throw new RemotingTimeoutException(info); - } - } - } - - private void requestFail(final int opaque) { - ResponseFuture responseFuture = responseTable.remove(opaque); - if (responseFuture != null) { - responseFuture.setSendRequestOK(false); - responseFuture.putResponse(null); - try { - executeInvokeCallback(responseFuture); - } catch (Throwable e) { - log.warn("execute callback in requestFail, and callback throw", e); - } finally { - responseFuture.release(); - } - } - } - - /** - * mark the request of the specified channel as fail and to invoke fail callback immediately - * @param channel the channel which is close already - */ - protected void failFast(final Channel channel) { - Iterator> it = responseTable.entrySet().iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getValue().getProcessChannel() == channel) { - Integer opaque = entry.getKey(); - if (opaque != null) { - requestFail(opaque); - } - } - } - } - - /** - * one way message do not process response - * @param channel - * @param request - * @param timeoutMillis - * @throws InterruptedException - * @throws RemotingTooMuchRequestException - * @throws RemotingTimeoutException - * @throws RemotingSendRequestException - */ - public void invokeOnewayImpl(final Channel channel, final RemotingCommand request, final long timeoutMillis) - throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { - request.markOnewayRPC(); - boolean acquired = this.semaphoreOneway.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); - if (acquired) { - //semaphore to process one time message num - final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreOneway); - try { - channel.writeAndFlush(request).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture f) throws Exception { - once.release(); - if (!f.isSuccess()) { - log.warn("send a request command to channel <" + channel.remoteAddress() + "> failed."); - } - } - }); - } catch (Exception e) { - once.release(); - log.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed."); - throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e); - } - } else { - if (timeoutMillis <= 0) { - throw new RemotingTooMuchRequestException("invokeOnewayImpl invoke too fast"); - } else { - String info = String.format( - "invokeOnewayImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", - timeoutMillis, - this.semaphoreOneway.getQueueLength(), - this.semaphoreOneway.availablePermits() - ); - log.warn(info); - throw new RemotingTimeoutException(info); - } - } - } - - /** - * use {@link ChannelEventListener} listen to Netty event({@link NettyEventType}) ,{@link NettyEventExecutor#putNettyEvent(NettyEvent)} is required for triggering event - */ - class NettyEventExecutor extends ServiceThread { - private final LinkedBlockingQueue eventQueue = new LinkedBlockingQueue(); - private final int maxSize = 10000; - - public void putNettyEvent(final NettyEvent event) { - if (this.eventQueue.size() <= maxSize) { - this.eventQueue.add(event); - } else { - log.warn("event queue size[{}] enough, so drop this event {}", this.eventQueue.size(), event.toString()); - } - } - - @Override - public void run() { - log.info(this.getServiceName() + " service started"); - - final ChannelEventListener listener = NettyRemotingAbstract.this.getChannelEventListener(); - - while (!this.isStopped()) { - try { - NettyEvent event = this.eventQueue.poll(3000, TimeUnit.MILLISECONDS); - if (event != null && listener != null) { - switch (event.getType()) { - case IDLE: - listener.onChannelIdle(event.getRemoteAddr(), event.getChannel()); - break; - case CLOSE: - listener.onChannelClose(event.getRemoteAddr(), event.getChannel()); - break; - case CONNECT: - listener.onChannelConnect(event.getRemoteAddr(), event.getChannel()); - break; - case EXCEPTION: - listener.onChannelException(event.getRemoteAddr(), event.getChannel()); - break; - default: - break; - - } - } - } catch (Exception e) { - log.warn(this.getServiceName() + " service has exception. ", e); - } - } - - log.info(this.getServiceName() + " service end"); - } - - @Override - public String getServiceName() { - return NettyEventExecutor.class.getSimpleName(); - } - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingClient.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingClient.java deleted file mode 100644 index 24e03a1..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingClient.java +++ /dev/null @@ -1,750 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.ChannelEventListener; -import com.pantheon.remoting.InvokeCallback; -import com.pantheon.remoting.RPCHook; -import com.pantheon.remoting.RemotingClient; -import com.pantheon.remoting.common.Pair; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.RemotingUtil; -import com.pantheon.remoting.exception.RemotingConnectException; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.exception.RemotingTooMuchRequestException; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.ChannelPromise; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.timeout.IdleState; -import io.netty.handler.timeout.IdleStateEvent; -import io.netty.handler.timeout.IdleStateHandler; -import io.netty.util.concurrent.DefaultEventExecutorGroup; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -import java.io.IOException; -import java.net.SocketAddress; -import java.security.cert.CertificateException; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -public class NettyRemotingClient extends NettyRemotingAbstract implements RemotingClient { - private static final Logger log = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - private static final long LOCK_TIMEOUT_MILLIS = 3000; - - private final NettyClientConfig nettyClientConfig; - private final Bootstrap bootstrap = new Bootstrap(); - private final EventLoopGroup eventLoopGroupWorker; - private final Lock lockChannelTables = new ReentrantLock(); - private final ConcurrentMap channelTables = new ConcurrentHashMap(); - - private final Timer timer = new Timer("ClientHouseKeepingService", true); - - private final AtomicReference> serverAddressList = new AtomicReference>(); - private final AtomicReference serverAddressChoosed = new AtomicReference(); - private final AtomicInteger serverIndex = new AtomicInteger(initValueIndex()); - private final Lock lockServerChannel = new ReentrantLock(); - - private final ExecutorService publicExecutor; - - /** - * Invoke the callback methods in this executor when process response. - */ - private ExecutorService callbackExecutor; - private final ChannelEventListener channelEventListener; - private DefaultEventExecutorGroup defaultEventExecutorGroup; - - public NettyRemotingClient(final NettyClientConfig nettyClientConfig) { - this(nettyClientConfig, null); - } - - public NettyRemotingClient(final NettyClientConfig nettyClientConfig, - final ChannelEventListener channelEventListener) { - super(nettyClientConfig.getClientOnewaySemaphoreValue(), nettyClientConfig.getClientAsyncSemaphoreValue()); - this.nettyClientConfig = nettyClientConfig; - this.channelEventListener = channelEventListener; - - int publicThreadNums = nettyClientConfig.getClientCallbackExecutorThreads(); - if (publicThreadNums <= 0) { - publicThreadNums = 4; - } - - this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "NettyClientPublicExecutor_" + this.threadIndex.incrementAndGet()); - } - }); - - this.eventLoopGroupWorker = new NioEventLoopGroup(1, new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, String.format("NettyClientSelector_%d", this.threadIndex.incrementAndGet())); - } - }); - - if (nettyClientConfig.isUseTLS()) { - try { - sslContext = TlsHelper.buildSslContext(true); - log.info("SSL enabled for client"); - } catch (IOException e) { - log.error("Failed to create SSLContext", e); - } catch (CertificateException e) { - log.error("Failed to create SSLContext", e); - throw new RuntimeException("Failed to create SSLContext", e); - } - } - } - - private static int initValueIndex() { - Random r = new Random(); - - return Math.abs(r.nextInt() % 999) % 999; - } - - /** - * 主要进行netty初始化 - */ - @Override - public void start() { - this.defaultEventExecutorGroup = new DefaultEventExecutorGroup( - nettyClientConfig.getClientWorkerThreads(), - new ThreadFactory() { - - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "NettyClientWorkerThread_" + this.threadIndex.incrementAndGet()); - } - }); - - Bootstrap handler = this.bootstrap.group(this.eventLoopGroupWorker).channel(NioSocketChannel.class) - .option(ChannelOption.TCP_NODELAY, true) - .option(ChannelOption.SO_KEEPALIVE, false) - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyClientConfig.getConnectTimeoutMillis()) //3s - .option(ChannelOption.SO_SNDBUF, nettyClientConfig.getClientSocketSndBufSize()) //65535 - .option(ChannelOption.SO_RCVBUF, nettyClientConfig.getClientSocketRcvBufSize()) //65535 - .handler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - if (nettyClientConfig.isUseTLS()) { - if (null != sslContext) { - pipeline.addFirst(defaultEventExecutorGroup, "sslHandler", sslContext.newHandler(ch.alloc())); - log.info("Prepend SSL handler"); - } else { - log.warn("Connections are insecure as SSLContext is null!"); - } - } - pipeline.addLast( - defaultEventExecutorGroup, - new NettyEncoder(), - new NettyDecoder(), - new IdleStateHandler(0, 0, nettyClientConfig.getClientChannelMaxIdleTimeSeconds()), - new NettyConnectManageHandler(), - new NettyClientHandler()); - } - }); - - this.timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - NettyRemotingClient.this.scanResponseTable(); - } catch (Throwable e) { - log.error("scanResponseTable exception", e); - } - } - }, 1000 * 3, 1000); - - if (this.channelEventListener != null) { - this.nettyEventExecutor.start(); - } - } - - @Override - public void shutdown() { - try { - this.timer.cancel(); - - for (ChannelWrapper cw : this.channelTables.values()) { - this.closeChannel(null, cw.getChannel()); - } - - this.channelTables.clear(); - - this.eventLoopGroupWorker.shutdownGracefully(); - - if (this.nettyEventExecutor != null) { - this.nettyEventExecutor.shutdown(); - } - - if (this.defaultEventExecutorGroup != null) { - this.defaultEventExecutorGroup.shutdownGracefully(); - } - } catch (Exception e) { - log.error("NettyRemotingClient shutdown exception, ", e); - } - - if (this.publicExecutor != null) { - try { - this.publicExecutor.shutdown(); - } catch (Exception e) { - log.error("NettyRemotingServer shutdown exception, ", e); - } - } - } - - public void closeChannel(final String addr, final Channel channel) { - if (null == channel) { - return; - } - - final String addrRemote = null == addr ? RemotingHelper.parseChannelRemoteAddr(channel) : addr; - - try { - if (this.lockChannelTables.tryLock(LOCK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) { - try { - boolean removeItemFromTable = true; - final ChannelWrapper prevCW = this.channelTables.get(addrRemote); - - log.info("closeChannel: begin close the channel[{}] Found: {}", addrRemote, prevCW != null); - - if (null == prevCW) { - log.info("closeChannel: the channel[{}] has been removed from the channel table before", addrRemote); - removeItemFromTable = false; - } else if (prevCW.getChannel() != channel) { - log.info("closeChannel: the channel[{}] has been closed before, and has been created again, nothing to do.", - addrRemote); - removeItemFromTable = false; - } - - if (removeItemFromTable) { - this.channelTables.remove(addrRemote); - log.info("closeChannel: the channel[{}] was removed from channel table", addrRemote); - } - - RemotingUtil.closeChannel(channel); - } catch (Exception e) { - log.error("closeChannel: close the channel exception", e); - } finally { - this.lockChannelTables.unlock(); - } - } else { - log.warn("closeChannel: try to lock channel table, but timeout, {}ms", LOCK_TIMEOUT_MILLIS); - } - } catch (InterruptedException e) { - log.error("closeChannel exception", e); - } - } - - @Override - public void registerRPCHook(RPCHook rpcHook) { - if (rpcHook != null && !rpcHooks.contains(rpcHook)) { - rpcHooks.add(rpcHook); - } - } - - public void closeChannel(final Channel channel) { - if (null == channel) { - return; - } - - try { - if (this.lockChannelTables.tryLock(LOCK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) { - try { - boolean removeItemFromTable = true; - ChannelWrapper prevCW = null; - String addrRemote = null; - //address and channel map - for (Map.Entry entry : channelTables.entrySet()) { - String key = entry.getKey(); - ChannelWrapper prev = entry.getValue(); - if (prev.getChannel() != null) { - if (prev.getChannel() == channel) { - prevCW = prev; - addrRemote = key; - break; - } - } - } - - if (null == prevCW) { - log.info("eventCloseChannel: the channel[{}] has been removed from the channel table before", addrRemote); - removeItemFromTable = false; - } - - if (removeItemFromTable) { - this.channelTables.remove(addrRemote); - log.info("closeChannel: the channel[{}] was removed from channel table", addrRemote); - //call channel.close() - RemotingUtil.closeChannel(channel); - } - } catch (Exception e) { - log.error("closeChannel: close the channel exception", e); - } finally { - this.lockChannelTables.unlock(); - } - } else { - log.warn("closeChannel: try to lock channel table, but timeout, {}ms", LOCK_TIMEOUT_MILLIS); - } - } catch (InterruptedException e) { - log.error("closeChannel exception", e); - } - } - - @Override - public void updateServerAddressList(List addrs) { - List old = this.serverAddressList.get(); - boolean update = false; - - if (!addrs.isEmpty()) { - if (null == old) { - update = true; - } else if (addrs.size() != old.size()) { - update = true; - } else { - for (int i = 0; i < addrs.size() && !update; i++) { - if (!old.contains(addrs.get(i))) { - update = true; - } - } - } - - if (update) { - Collections.shuffle(addrs); - log.info("name server address updated. NEW : {} , OLD: {}", addrs, old); - this.serverAddressList.set(addrs); - - if (!addrs.contains(this.serverAddressChoosed.get())) { - this.serverAddressChoosed.set(null); - } - } - } - } - - /** - * sync message - * - * @param addr - * @param request - * @param timeoutMillis - * @return - * @throws InterruptedException - * @throws RemotingConnectException - * @throws RemotingSendRequestException - * @throws RemotingTimeoutException - */ - @Override - public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis) - throws InterruptedException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException { - // sync message - long beginStartTime = System.currentTimeMillis(); - //use ip address to get netty channel, in which Netty's Bootstrap.connect() is triggered - final Channel channel = this.getAndCreateChannel(addr); - if (channel != null && channel.isActive()) { - try { - //preprocess process - doBeforeRpcHooks(addr, request); - long costTime = System.currentTimeMillis() - beginStartTime; - if (timeoutMillis < costTime) { - throw new RemotingTimeoutException("invokeSync call timeout"); - } - //actual call - RemotingCommand response = this.invokeSyncImpl(channel, request, timeoutMillis - costTime); - //post process - doAfterRpcHooks(RemotingHelper.parseChannelRemoteAddr(channel), request, response); - return response; - } catch (RemotingSendRequestException e) { - log.warn("invokeSync: send request exception, so close the channel[{}]", addr); - this.closeChannel(addr, channel); - throw e; - } catch (RemotingTimeoutException e) { - if (nettyClientConfig.isClientCloseSocketIfTimeout()) { - this.closeChannel(addr, channel); - log.warn("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, addr); - } - log.warn("invokeSync: wait response timeout exception, the channel[{}]", addr); - throw e; - } - } else { - this.closeChannel(addr, channel); - throw new RemotingConnectException(addr); - } - } - - private Channel getAndCreateChannel(final String addr) throws RemotingConnectException, InterruptedException { - if (null == addr) { - return getAndCreateServerChannel(); - } - - ChannelWrapper cw = this.channelTables.get(addr); - if (cw != null && cw.isOK()) { - return cw.getChannel(); - } - - return this.createChannel(addr); - } - - private Channel getAndCreateServerChannel() throws RemotingConnectException, InterruptedException { - String addr = this.serverAddressChoosed.get(); - if (addr != null) { - ChannelWrapper cw = this.channelTables.get(addr); - if (cw != null && cw.isOK()) { - return cw.getChannel(); - } - } - - final List addrList = this.serverAddressList.get(); - if (this.lockServerChannel.tryLock(LOCK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) { - try { - addr = this.serverAddressChoosed.get(); - if (addr != null) { - ChannelWrapper cw = this.channelTables.get(addr); - if (cw != null && cw.isOK()) { - return cw.getChannel(); - } - } - - if (addrList != null && !addrList.isEmpty()) { - for (int i = 0; i < addrList.size(); i++) { - int index = this.serverIndex.incrementAndGet(); - index = Math.abs(index); - index = index % addrList.size(); - String newAddr = addrList.get(index); - - this.serverAddressChoosed.set(newAddr); - Channel channelNew = this.createChannel(newAddr); - if (channelNew != null) { - return channelNew; - } - } - throw new RemotingConnectException(addrList.toString()); - } - } finally { - this.lockServerChannel.unlock(); - } - } else { - log.warn("getAndCreateNameserverChannel: try to lock server, but timeout, {}ms", LOCK_TIMEOUT_MILLIS); - } - - return null; - } - - /** - * create channel and wrap it with ChannelWrapper ,channelTables map save the connection for reusing - * - * @param addr - * @return - * @throws InterruptedException - */ - private Channel createChannel(final String addr) throws InterruptedException { - ChannelWrapper cw = this.channelTables.get(addr); - if (cw != null && cw.isOK()) { - return cw.getChannel(); - } - - if (this.lockChannelTables.tryLock(LOCK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) { - try { - boolean createNewConnection; - cw = this.channelTables.get(addr); - if (cw != null) { - - if (cw.isOK()) { - return cw.getChannel(); - } else if (!cw.getChannelFuture().isDone()) { - createNewConnection = false; - } else { - this.channelTables.remove(addr); - createNewConnection = true; - } - } else { - createNewConnection = true; - } - - if (createNewConnection) { - //async create channel - ChannelFuture channelFuture = this.bootstrap.connect(RemotingHelper.string2SocketAddress(addr)); - log.info("createChannel: begin to connect remote host[{}] asynchronously", addr); - cw = new ChannelWrapper(channelFuture); - this.channelTables.put(addr, cw); - } - } catch (Exception e) { - log.error("createChannel: create channel exception", e); - } finally { - this.lockChannelTables.unlock(); - } - } else { - log.warn("createChannel: try to lock channel table, but timeout, {}ms", LOCK_TIMEOUT_MILLIS); - } - - if (cw != null) { - ChannelFuture channelFuture = cw.getChannelFuture(); - //blocking - if (channelFuture.awaitUninterruptibly(this.nettyClientConfig.getConnectTimeoutMillis())) { - if (cw.isOK()) { - log.info("createChannel: connect remote host[{}] success, {}", addr, channelFuture.toString()); - return cw.getChannel(); - } else { - log.warn("createChannel: connect remote host[" + addr + "] failed, " + channelFuture.toString(), channelFuture.cause()); - } - } else { -// log.warn("createChannel: connect remote host[{}] timeout {}ms, {}", addr, this.nettyClientConfig.getConnectTimeoutMillis(), -// channelFuture.toString()); - } - } - - return null; - } - - /** - * 异步发送消息 - * - * @param addr - * @param request - * @param timeoutMillis - * @param invokeCallback - * @throws InterruptedException - * @throws RemotingConnectException - * @throws RemotingTooMuchRequestException - * @throws RemotingTimeoutException - * @throws RemotingSendRequestException - */ - @Override - public void invokeAsync(String addr, RemotingCommand request, long timeoutMillis, InvokeCallback invokeCallback) - throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException, - RemotingSendRequestException { - long beginStartTime = System.currentTimeMillis(); - final Channel channel = this.getAndCreateChannel(addr); - if (channel != null && channel.isActive()) { - try { - doBeforeRpcHooks(addr, request); - long costTime = System.currentTimeMillis() - beginStartTime; - if (timeoutMillis < costTime) { - throw new RemotingTooMuchRequestException("invokeAsync call timeout"); - } - this.invokeAsyncImpl(channel, request, timeoutMillis - costTime, invokeCallback); - } catch (RemotingSendRequestException e) { - log.warn("invokeAsync: send request exception, so close the channel[{}]", addr); - this.closeChannel(addr, channel); - throw e; - } - } else { - this.closeChannel(addr, channel); - throw new RemotingConnectException(addr); - } - } - - - @Override - public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis) throws InterruptedException, - RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { - final Channel channel = this.getAndCreateChannel(addr); - if (channel != null && channel.isActive()) { - try { - doBeforeRpcHooks(addr, request); - this.invokeOnewayImpl(channel, request, timeoutMillis); - } catch (RemotingSendRequestException e) { - log.warn("invokeOneway: send request exception, so close the channel[{}]", addr); - this.closeChannel(addr, channel); - throw e; - } - } else { - this.closeChannel(addr, channel); - throw new RemotingConnectException(addr); - } - } - - @Override - public void registerProcessor(int requestCode, NettyRequestProcessor processor, ExecutorService executor) { - ExecutorService executorThis = executor; - if (null == executor) { - executorThis = this.publicExecutor; - } - - Pair pair = new Pair(processor, executorThis); - this.processorTable.put(requestCode, pair); - } - - @Override - public boolean isChannelWritable(String addr) { - ChannelWrapper cw = this.channelTables.get(addr); - if (cw != null && cw.isOK()) { - return cw.isWritable(); - } - return true; - } - - @Override - public List getServerAddressList() { - return this.serverAddressList.get(); - } - - @Override - public ChannelEventListener getChannelEventListener() { - return channelEventListener; - } - - @Override - public ExecutorService getCallbackExecutor() { - return callbackExecutor != null ? callbackExecutor : publicExecutor; - } - - @Override - public void setCallbackExecutor(final ExecutorService callbackExecutor) { - this.callbackExecutor = callbackExecutor; - } - - static class ChannelWrapper { - private final ChannelFuture channelFuture; - - public ChannelWrapper(ChannelFuture channelFuture) { - this.channelFuture = channelFuture; - } - - public boolean isOK() { - return this.channelFuture.channel() != null && this.channelFuture.channel().isActive(); - } - - public boolean isWritable() { - return this.channelFuture.channel().isWritable(); - } - - private Channel getChannel() { - return this.channelFuture.channel(); - } - - public ChannelFuture getChannelFuture() { - return channelFuture; - } - } - - class NettyClientHandler extends SimpleChannelInboundHandler { - - @Override - protected void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception { - processMessageReceived(ctx, msg); - } - } - - - /** - * put netty event in a LinkedBlockingQueue and invoke correspondent listener - */ - class NettyConnectManageHandler extends ChannelDuplexHandler { - @Override - public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, - ChannelPromise promise) throws Exception { - final String local = localAddress == null ? "UNKNOWN" : RemotingHelper.parseSocketAddressAddr(localAddress); - final String remote = remoteAddress == null ? "UNKNOWN" : RemotingHelper.parseSocketAddressAddr(remoteAddress); - log.info("NETTY CLIENT PIPELINE: CONNECT {} => {}", local, remote); - - super.connect(ctx, remoteAddress, localAddress, promise); - - if (NettyRemotingClient.this.channelEventListener != null) { - NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CONNECT, remote, ctx.channel())); - } - } - - @Override - public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY CLIENT PIPELINE: DISCONNECT {}", remoteAddress); - closeChannel(ctx.channel()); - super.disconnect(ctx, promise); - - if (NettyRemotingClient.this.channelEventListener != null) { - NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress, ctx.channel())); - } - } - - @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY CLIENT PIPELINE: CLOSE {}", remoteAddress); - closeChannel(ctx.channel()); - super.close(ctx, promise); - NettyRemotingClient.this.failFast(ctx.channel()); - if (NettyRemotingClient.this.channelEventListener != null) { - NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress, ctx.channel())); - } - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt instanceof IdleStateEvent) { - IdleStateEvent event = (IdleStateEvent) evt; - if (event.state().equals(IdleState.ALL_IDLE)) { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.warn("NETTY CLIENT PIPELINE: IDLE exception [{}]", remoteAddress); - closeChannel(ctx.channel()); - if (NettyRemotingClient.this.channelEventListener != null) { - NettyRemotingClient.this - .putNettyEvent(new NettyEvent(NettyEventType.IDLE, remoteAddress, ctx.channel())); - } - } - } - - ctx.fireUserEventTriggered(evt); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.warn("NETTY CLIENT PIPELINE: exceptionCaught {}", remoteAddress); - log.warn("NETTY CLIENT PIPELINE: exceptionCaught exception.", cause); - closeChannel(ctx.channel()); - if (NettyRemotingClient.this.channelEventListener != null) { - NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.EXCEPTION, remoteAddress, ctx.channel())); - } - } - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingServer.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingServer.java deleted file mode 100644 index 9c451a3..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRemotingServer.java +++ /dev/null @@ -1,499 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.ChannelEventListener; -import com.pantheon.remoting.InvokeCallback; -import com.pantheon.remoting.RPCHook; -import com.pantheon.remoting.RemotingServer; -import com.pantheon.remoting.common.Pair; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.RemotingUtil; -import com.pantheon.remoting.common.TlsMode; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.exception.RemotingTooMuchRequestException; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.channel.Channel; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.timeout.IdleState; -import io.netty.handler.timeout.IdleStateEvent; -import io.netty.handler.timeout.IdleStateHandler; -import io.netty.util.concurrent.DefaultEventExecutorGroup; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.security.cert.CertificateException; -import java.util.NoSuchElementException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -public class NettyRemotingServer extends NettyRemotingAbstract implements RemotingServer { - private static final Logger log = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - private final ServerBootstrap serverBootstrap; - private final EventLoopGroup eventLoopGroupSelector; - private final EventLoopGroup eventLoopGroupBoss; - private final NettyServerConfig nettyServerConfig; - - private final ExecutorService publicExecutor; - private final ChannelEventListener channelEventListener; - - private final Timer timer = new Timer("ServerHouseKeepingService", true); - private DefaultEventExecutorGroup defaultEventExecutorGroup; - - - private int port = 0; - - private static final String HANDSHAKE_HANDLER_NAME = "handshakeHandler"; - private static final String TLS_HANDLER_NAME = "sslHandler"; - private static final String FILE_REGION_ENCODER_NAME = "fileRegionEncoder"; - - // sharable handlers - private HandshakeHandler handshakeHandler; - private NettyEncoder encoder; - private NettyConnectManageHandler connectionManageHandler; - private NettyServerHandler serverHandler; - - public NettyRemotingServer(final NettyServerConfig nettyServerConfig) { - this(nettyServerConfig, null); - } - - public NettyRemotingServer(final NettyServerConfig nettyServerConfig, - final ChannelEventListener channelEventListener) { - super(nettyServerConfig.getServerOnewaySemaphoreValue(), nettyServerConfig.getServerAsyncSemaphoreValue()); - this.serverBootstrap = new ServerBootstrap(); - this.nettyServerConfig = nettyServerConfig; - this.channelEventListener = channelEventListener; - - int publicThreadNums = nettyServerConfig.getServerCallbackExecutorThreads(); - if (publicThreadNums <= 0) { - publicThreadNums = 4; - } - - this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "NettyServerPublicExecutor_" + this.threadIndex.incrementAndGet()); - } - }); - - if (useEpoll()) { - this.eventLoopGroupBoss = new EpollEventLoopGroup(1, new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, String.format("NettyEPOLLBoss_%d", this.threadIndex.incrementAndGet())); - } - }); - - this.eventLoopGroupSelector = new EpollEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - private int threadTotal = nettyServerConfig.getServerSelectorThreads(); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, String.format("NettyServerEPOLLSelector_%d_%d", threadTotal, this.threadIndex.incrementAndGet())); - } - }); - } else { - this.eventLoopGroupBoss = new NioEventLoopGroup(1, new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, String.format("NettyNIOBoss_%d", this.threadIndex.incrementAndGet())); - } - }); - this.eventLoopGroupSelector = new NioEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - private int threadTotal = nettyServerConfig.getServerSelectorThreads(); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, String.format("NettyServerNIOSelector_%d_%d", threadTotal, this.threadIndex.incrementAndGet())); - } - }); - } - - loadSslContext(); - } - - public void loadSslContext() { - TlsMode tlsMode = TlsSystemConfig.tlsMode; - log.info("Server is running in TLS {} mode", tlsMode.getName()); - - if (tlsMode != TlsMode.DISABLED) { - try { - sslContext = TlsHelper.buildSslContext(false); - log.info("SSLContext created for server"); - } catch (CertificateException e) { - log.error("Failed to create SSLContext for server", e); - } catch (IOException e) { - log.error("Failed to create SSLContext for server", e); - } - } - } - - private boolean useEpoll() { - return RemotingUtil.isLinuxPlatform() - && nettyServerConfig.isUseEpollNativeSelector() - && Epoll.isAvailable(); - } - - @Override - public void start() { - this.defaultEventExecutorGroup = new DefaultEventExecutorGroup( - nettyServerConfig.getServerWorkerThreads(), - new ThreadFactory() { - - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "NettyServerCodecThread_" + this.threadIndex.incrementAndGet()); - } - }); - - prepareSharableHandlers(); - - ServerBootstrap childHandler = - this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupSelector) - .channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) - .option(ChannelOption.SO_BACKLOG, 1024) - .option(ChannelOption.SO_REUSEADDR, true) - .option(ChannelOption.SO_KEEPALIVE, false) - .childOption(ChannelOption.TCP_NODELAY, true) - .childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize()) - .childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize()) - .localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort())) - .childHandler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ch.pipeline() - .addLast(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, handshakeHandler) - .addLast(defaultEventExecutorGroup, - encoder, - new NettyDecoder(), - new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()), - connectionManageHandler, - serverHandler - ); - } - }); - - if (nettyServerConfig.isServerPooledByteBufAllocatorEnable()) { - childHandler.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); - } - - try { - ChannelFuture sync = this.serverBootstrap.bind().sync(); - InetSocketAddress addr = (InetSocketAddress) sync.channel().localAddress(); - this.port = addr.getPort(); - } catch (InterruptedException e1) { - throw new RuntimeException("this.serverBootstrap.bind().sync() InterruptedException", e1); - } - - if (this.channelEventListener != null) { - this.nettyEventExecutor.start(); - } - - this.timer.scheduleAtFixedRate(new TimerTask() { - - @Override - public void run() { - try { - NettyRemotingServer.this.scanResponseTable(); - } catch (Throwable e) { - log.error("scanResponseTable exception", e); - } - } - }, 1000 * 3, 1000); - } - - @Override - public void shutdown() { - try { - if (this.timer != null) { - this.timer.cancel(); - } - - this.eventLoopGroupBoss.shutdownGracefully(); - - this.eventLoopGroupSelector.shutdownGracefully(); - - if (this.nettyEventExecutor != null) { - this.nettyEventExecutor.shutdown(); - } - - if (this.defaultEventExecutorGroup != null) { - this.defaultEventExecutorGroup.shutdownGracefully(); - } - } catch (Exception e) { - log.error("NettyRemotingServer shutdown exception, ", e); - } - - if (this.publicExecutor != null) { - try { - this.publicExecutor.shutdown(); - } catch (Exception e) { - log.error("NettyRemotingServer shutdown exception, ", e); - } - } - } - - @Override - public void registerRPCHook(RPCHook rpcHook) { - if (rpcHook != null && !rpcHooks.contains(rpcHook)) { - rpcHooks.add(rpcHook); - } - } - - /** - * 添加所有processor到hashmap中去,注意processorTable定义为final类型 - * @param requestCode - * @param processor - * @param executor - */ - @Override - public void registerProcessor(int requestCode, NettyRequestProcessor processor, ExecutorService executor) { - ExecutorService executorThis = executor; - if (null == executor) { - executorThis = this.publicExecutor; - } - - Pair pair = new Pair(processor, executorThis); - this.processorTable.put(requestCode, pair); - } - - @Override - public void registerDefaultProcessor(NettyRequestProcessor processor, ExecutorService executor) { - this.defaultRequestProcessor = new Pair(processor, executor); - } - - @Override - public int localListenPort() { - return this.port; - } - - @Override - public Pair getProcessorPair(int requestCode) { - return processorTable.get(requestCode); - } - - @Override - public RemotingCommand invokeSync(final Channel channel, final RemotingCommand request, final long timeoutMillis) - throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException { - return this.invokeSyncImpl(channel, request, timeoutMillis); - } - - @Override - public void invokeAsync(Channel channel, RemotingCommand request, long timeoutMillis, InvokeCallback invokeCallback) - throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { - this.invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback); - } - - @Override - public void invokeOneway(Channel channel, RemotingCommand request, long timeoutMillis) throws InterruptedException, - RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { - this.invokeOnewayImpl(channel, request, timeoutMillis); - } - - @Override - public ChannelEventListener getChannelEventListener() { - return channelEventListener; - } - - - @Override - public ExecutorService getCallbackExecutor() { - return this.publicExecutor; - } - - private void prepareSharableHandlers() { - handshakeHandler = new HandshakeHandler(TlsSystemConfig.tlsMode); - encoder = new NettyEncoder(); - connectionManageHandler = new NettyConnectManageHandler(); - serverHandler = new NettyServerHandler(); - } - - @ChannelHandler.Sharable - class HandshakeHandler extends SimpleChannelInboundHandler { - - private final TlsMode tlsMode; - - private static final byte HANDSHAKE_MAGIC_CODE = 0x16; - - HandshakeHandler(TlsMode tlsMode) { - this.tlsMode = tlsMode; - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { - - // mark the current position so that we can peek the first byte to determine if the content is starting with - // TLS handshake - - msg.markReaderIndex(); - - byte b = msg.getByte(0); - - if (b == HANDSHAKE_MAGIC_CODE) { - switch (tlsMode) { - case DISABLED: - ctx.close(); - log.warn("Clients intend to establish an SSL connection while this server is running in SSL disabled mode"); - break; - case PERMISSIVE: - case ENFORCING: - if (null != sslContext) { - ctx.pipeline() - .addAfter(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, TLS_HANDLER_NAME, sslContext.newHandler(ctx.channel().alloc())) - .addAfter(defaultEventExecutorGroup, TLS_HANDLER_NAME, FILE_REGION_ENCODER_NAME, new FileRegionEncoder()); - log.info("Handlers prepended to channel pipeline to establish SSL connection"); - } else { - ctx.close(); - log.error("Trying to establish an SSL connection but sslContext is null"); - } - break; - - default: - log.warn("Unknown TLS mode"); - break; - } - } else if (tlsMode == TlsMode.ENFORCING) { - ctx.close(); - log.warn("Clients intend to establish an insecure connection while this server is running in SSL enforcing mode"); - } - - // reset the reader index so that handshake negotiation may proceed as normal. - msg.resetReaderIndex(); - - try { - // Remove this handler - ctx.pipeline().remove(this); - } catch (NoSuchElementException e) { - log.error("Error while removing HandshakeHandler", e); - } - - // Hand over this message to the next . - ctx.fireChannelRead(msg.retain()); - } - } - - @ChannelHandler.Sharable - class NettyServerHandler extends SimpleChannelInboundHandler { - - @Override - protected void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception { - processMessageReceived(ctx, msg); - } - } - - @ChannelHandler.Sharable - class NettyConnectManageHandler extends ChannelDuplexHandler { - @Override - public void channelRegistered(ChannelHandlerContext ctx) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY SERVER PIPELINE: channelRegistered {}", remoteAddress); - super.channelRegistered(ctx); - } - - @Override - public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY SERVER PIPELINE: channelUnregistered, the channel[{}]", remoteAddress); - super.channelUnregistered(ctx); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY SERVER PIPELINE: channelActive, the channel[{}]", remoteAddress); - super.channelActive(ctx); - if (NettyRemotingServer.this.channelEventListener != null) { - NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.CONNECT, remoteAddress, ctx.channel())); - } - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.info("NETTY SERVER PIPELINE: channelInactive, the channel[{}]", remoteAddress); - super.channelInactive(ctx); - - if (NettyRemotingServer.this.channelEventListener != null) { - NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress, ctx.channel())); - } - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt instanceof IdleStateEvent) { - IdleStateEvent event = (IdleStateEvent) evt; - if (event.state().equals(IdleState.ALL_IDLE)) { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.warn("NETTY SERVER PIPELINE: IDLE exception [{}]", remoteAddress); - RemotingUtil.closeChannel(ctx.channel()); - if (NettyRemotingServer.this.channelEventListener != null) { - NettyRemotingServer.this - .putNettyEvent(new NettyEvent(NettyEventType.IDLE, remoteAddress, ctx.channel())); - } - } - } - - ctx.fireUserEventTriggered(evt); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - log.warn("NETTY SERVER PIPELINE: exceptionCaught {}", remoteAddress); - log.warn("NETTY SERVER PIPELINE: exceptionCaught exception.", cause); - - if (NettyRemotingServer.this.channelEventListener != null) { - NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.EXCEPTION, remoteAddress, ctx.channel())); - } - - RemotingUtil.closeChannel(ctx.channel()); - } - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRequestProcessor.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRequestProcessor.java deleted file mode 100644 index f7594a7..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRequestProcessor.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.ChannelHandlerContext; - - -/** - * @author Anthony - * @create 2021/11/17 - * @desc Common remoting command processor - **/ -public interface NettyRequestProcessor { - RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) - throws Exception; - - boolean rejectRequest(); - -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyServerConfig.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyServerConfig.java deleted file mode 100644 index acf0f32..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyServerConfig.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -public class NettyServerConfig implements Cloneable { - private int listenPort = 8888; - private int serverWorkerThreads = 8; - private int serverCallbackExecutorThreads = 0; - private int serverSelectorThreads = 3; - private int serverOnewaySemaphoreValue = 256; - private int serverAsyncSemaphoreValue = 64; - private int serverChannelMaxIdleTimeSeconds = 120; - - private int serverSocketSndBufSize = NettySystemConfig.socketSndbufSize; - private int serverSocketRcvBufSize = NettySystemConfig.socketRcvbufSize; - private boolean serverPooledByteBufAllocatorEnable = true; - - /** - * make make install - * - * - * ../glibc-2.10.1/configure \ --prefix=/usr \ --with-headers=/usr/include \ - * --host=x86_64-linux-gnu \ --build=x86_64-pc-linux-gnu \ --without-gd - */ - private boolean useEpollNativeSelector = false; - - public int getListenPort() { - return listenPort; - } - - public void setListenPort(int listenPort) { - this.listenPort = listenPort; - } - - public int getServerWorkerThreads() { - return serverWorkerThreads; - } - - public void setServerWorkerThreads(int serverWorkerThreads) { - this.serverWorkerThreads = serverWorkerThreads; - } - - public int getServerSelectorThreads() { - return serverSelectorThreads; - } - - public void setServerSelectorThreads(int serverSelectorThreads) { - this.serverSelectorThreads = serverSelectorThreads; - } - - public int getServerOnewaySemaphoreValue() { - return serverOnewaySemaphoreValue; - } - - public void setServerOnewaySemaphoreValue(int serverOnewaySemaphoreValue) { - this.serverOnewaySemaphoreValue = serverOnewaySemaphoreValue; - } - - public int getServerCallbackExecutorThreads() { - return serverCallbackExecutorThreads; - } - - public void setServerCallbackExecutorThreads(int serverCallbackExecutorThreads) { - this.serverCallbackExecutorThreads = serverCallbackExecutorThreads; - } - - public int getServerAsyncSemaphoreValue() { - return serverAsyncSemaphoreValue; - } - - public void setServerAsyncSemaphoreValue(int serverAsyncSemaphoreValue) { - this.serverAsyncSemaphoreValue = serverAsyncSemaphoreValue; - } - - public int getServerChannelMaxIdleTimeSeconds() { - return serverChannelMaxIdleTimeSeconds; - } - - public void setServerChannelMaxIdleTimeSeconds(int serverChannelMaxIdleTimeSeconds) { - this.serverChannelMaxIdleTimeSeconds = serverChannelMaxIdleTimeSeconds; - } - - public int getServerSocketSndBufSize() { - return serverSocketSndBufSize; - } - - public void setServerSocketSndBufSize(int serverSocketSndBufSize) { - this.serverSocketSndBufSize = serverSocketSndBufSize; - } - - public int getServerSocketRcvBufSize() { - return serverSocketRcvBufSize; - } - - public void setServerSocketRcvBufSize(int serverSocketRcvBufSize) { - this.serverSocketRcvBufSize = serverSocketRcvBufSize; - } - - public boolean isServerPooledByteBufAllocatorEnable() { - return serverPooledByteBufAllocatorEnable; - } - - public void setServerPooledByteBufAllocatorEnable(boolean serverPooledByteBufAllocatorEnable) { - this.serverPooledByteBufAllocatorEnable = serverPooledByteBufAllocatorEnable; - } - - public boolean isUseEpollNativeSelector() { - return useEpollNativeSelector; - } - - public void setUseEpollNativeSelector(boolean useEpollNativeSelector) { - this.useEpollNativeSelector = useEpollNativeSelector; - } - - @Override - public Object clone() throws CloneNotSupportedException { - return (NettyServerConfig) super.clone(); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettySystemConfig.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettySystemConfig.java deleted file mode 100644 index 8fdc8ba..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettySystemConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -public class NettySystemConfig { - public static final String COM_PANTHEON_REMOTING_NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE = - "com.pantheon.remoting.nettyPooledByteBufAllocatorEnable"; - public static final String COM_PANTHEON_REMOTING_SOCKET_SNDBUF_SIZE = - "com.pantheon.remoting.socket.sndbuf.size"; - public static final String COM_PANTHEON_REMOTING_SOCKET_RCVBUF_SIZE = - "com.pantheon.remoting.socket.rcvbuf.size"; - public static final String COM_PANTHEON_REMOTING_CLIENT_ASYNC_SEMAPHORE_VALUE = - "com.pantheon.remoting.clientAsyncSemaphoreValue"; - public static final String COM_PANTHEON_REMOTING_CLIENT_ONEWAY_SEMAPHORE_VALUE = - "com.pantheon.remoting.clientOnewaySemaphoreValue"; - - public static final boolean NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE = // - Boolean.parseBoolean(System.getProperty(COM_PANTHEON_REMOTING_NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE, "false")); - public static final int CLIENT_ASYNC_SEMAPHORE_VALUE = // - Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_CLIENT_ASYNC_SEMAPHORE_VALUE, "65535")); - public static final int CLIENT_ONEWAY_SEMAPHORE_VALUE = - Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_CLIENT_ONEWAY_SEMAPHORE_VALUE, "65535")); - public static int socketSndbufSize = - Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_SOCKET_SNDBUF_SIZE, "65535")); - public static int socketRcvbufSize = - Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_SOCKET_RCVBUF_SIZE, "65535")); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RemotingResponseCallback.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RemotingResponseCallback.java deleted file mode 100644 index 08cf29b..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RemotingResponseCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - - -import com.pantheon.remoting.protocol.RemotingCommand; - -public interface RemotingResponseCallback { - void callback(RemotingCommand response); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RequestTask.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RequestTask.java deleted file mode 100644 index cf09207..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RequestTask.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.Channel; - -public class RequestTask implements Runnable { - private final Runnable runnable; - private final long createTimestamp = System.currentTimeMillis(); - private final Channel channel; - private final RemotingCommand request; - private boolean stopRun = false; - - public RequestTask(final Runnable runnable, final Channel channel, final RemotingCommand request) { - this.runnable = runnable; - this.channel = channel; - this.request = request; - } - - @Override - public int hashCode() { - int result = runnable != null ? runnable.hashCode() : 0; - result = 31 * result + (int) (getCreateTimestamp() ^ (getCreateTimestamp() >>> 32)); - result = 31 * result + (channel != null ? channel.hashCode() : 0); - result = 31 * result + (request != null ? request.hashCode() : 0); - result = 31 * result + (isStopRun() ? 1 : 0); - return result; - } - - @Override - public boolean equals(final Object o) { - if (this == o) - return true; - if (!(o instanceof RequestTask)) - return false; - - final RequestTask that = (RequestTask) o; - - if (getCreateTimestamp() != that.getCreateTimestamp()) - return false; - if (isStopRun() != that.isStopRun()) - return false; - if (channel != null ? !channel.equals(that.channel) : that.channel != null) - return false; - return request != null ? request.getOpaque() == that.request.getOpaque() : that.request == null; - - } - - public long getCreateTimestamp() { - return createTimestamp; - } - - public boolean isStopRun() { - return stopRun; - } - - public void setStopRun(final boolean stopRun) { - this.stopRun = stopRun; - } - - @Override - public void run() { - if (!this.stopRun) - this.runnable.run(); - } - - public void returnResponse(int code, String remark) { - final RemotingCommand response = RemotingCommand.createResponseCommand(code, remark); - response.setOpaque(request.getOpaque()); - this.channel.writeAndFlush(response); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/ResponseFuture.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/ResponseFuture.java deleted file mode 100644 index 40d20a8..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/ResponseFuture.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.InvokeCallback; -import com.pantheon.remoting.common.SemaphoreReleaseOnlyOnce; -import com.pantheon.remoting.protocol.RemotingCommand; -import io.netty.channel.Channel; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -public class ResponseFuture { - private final int opaque; - private final Channel processChannel; - private final long timeoutMillis; - //invokeCallback for async message - private final InvokeCallback invokeCallback; - private final long beginTimestamp = System.currentTimeMillis(); - // countDownLatch for implementing wait - private final CountDownLatch countDownLatch = new CountDownLatch(1); - - private final SemaphoreReleaseOnlyOnce once; - private final AtomicBoolean executeCallbackOnlyOnce = new AtomicBoolean(false); - private volatile RemotingCommand responseCommand; - private volatile boolean sendRequestOK = true; - private volatile Throwable cause; - - public ResponseFuture(Channel channel, int opaque, long timeoutMillis, InvokeCallback invokeCallback, - SemaphoreReleaseOnlyOnce once) { - this.opaque = opaque; - this.processChannel = channel; - this.timeoutMillis = timeoutMillis; - this.invokeCallback = invokeCallback; - this.once = once; - } - - public void executeInvokeCallback() { - if (invokeCallback != null) { - if (this.executeCallbackOnlyOnce.compareAndSet(false, true)) { - invokeCallback.operationComplete(this); - } - } - } - - public void release() { - if (this.once != null) { - this.once.release(); - } - } - - public boolean isTimeout() { - long diff = System.currentTimeMillis() - this.beginTimestamp; - return diff > this.timeoutMillis; - } - - public RemotingCommand waitResponse(final long timeoutMillis) throws InterruptedException { - this.countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); - return this.responseCommand; - } - - public void putResponse(final RemotingCommand responseCommand) { - this.responseCommand = responseCommand; - this.countDownLatch.countDown(); - } - - public long getBeginTimestamp() { - return beginTimestamp; - } - - public boolean isSendRequestOK() { - return sendRequestOK; - } - - public void setSendRequestOK(boolean sendRequestOK) { - this.sendRequestOK = sendRequestOK; - } - - public long getTimeoutMillis() { - return timeoutMillis; - } - - public InvokeCallback getInvokeCallback() { - return invokeCallback; - } - - public Throwable getCause() { - return cause; - } - - public void setCause(Throwable cause) { - this.cause = cause; - } - - public RemotingCommand getResponseCommand() { - return responseCommand; - } - - public void setResponseCommand(RemotingCommand responseCommand) { - this.responseCommand = responseCommand; - } - - public int getOpaque() { - return opaque; - } - - public Channel getProcessChannel() { - return processChannel; - } - - @Override - public String toString() { - return "ResponseFuture [responseCommand=" + responseCommand - + ", sendRequestOK=" + sendRequestOK - + ", cause=" + cause - + ", opaque=" + opaque - + ", processChannel=" + processChannel - + ", timeoutMillis=" + timeoutMillis - + ", invokeCallback=" + invokeCallback - + ", beginTimestamp=" + beginTimestamp - + ", countDownLatch=" + countDownLatch + "]"; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsHelper.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsHelper.java deleted file mode 100644 index 10d707a..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsHelper.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.common.RemotingHelper; -import io.netty.handler.ssl.ClientAuth; -import io.netty.handler.ssl.OpenSsl; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.SslProvider; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import io.netty.handler.ssl.util.SelfSignedCertificate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.cert.CertificateException; -import java.util.Properties; - -import static com.pantheon.remoting.netty.TlsSystemConfig.*; - - -public class TlsHelper { - - public interface DecryptionStrategy { - /** - * Decrypt the target encrpted private key file. - * - * @param privateKeyEncryptPath A pathname string - * @param forClient tells whether it's a client-side key file - * @return An input stream for a decrypted key file - * @throws IOException if an I/O error has occurred - */ - InputStream decryptPrivateKey(String privateKeyEncryptPath, boolean forClient) throws IOException; - } - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - - private static DecryptionStrategy decryptionStrategy = new DecryptionStrategy() { - @Override - public InputStream decryptPrivateKey(final String privateKeyEncryptPath, - final boolean forClient) throws IOException { - return new FileInputStream(privateKeyEncryptPath); - } - }; - - - public static void registerDecryptionStrategy(final DecryptionStrategy decryptionStrategy) { - TlsHelper.decryptionStrategy = decryptionStrategy; - } - - public static SslContext buildSslContext(boolean forClient) throws IOException, CertificateException { - File configFile = new File(TlsSystemConfig.tlsConfigFile); - extractTlsConfigFromFile(configFile); - logTheFinalUsedTlsConfig(); - - SslProvider provider; - if (OpenSsl.isAvailable()) { - provider = SslProvider.OPENSSL; - logger.info("Using OpenSSL provider"); - } else { - provider = SslProvider.JDK; - logger.info("Using JDK SSL provider"); - } - - if (forClient) { - if (tlsTestModeEnable) { - return SslContextBuilder - .forClient() - .sslProvider(SslProvider.JDK) - .trustManager(InsecureTrustManagerFactory.INSTANCE) - .build(); - } else { - SslContextBuilder sslContextBuilder = SslContextBuilder.forClient().sslProvider(SslProvider.JDK); - - - if (!tlsClientAuthServer) { - sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE); - } else { - if (!isNullOrEmpty(tlsClientTrustCertPath)) { - sslContextBuilder.trustManager(new File(tlsClientTrustCertPath)); - } - } - - return sslContextBuilder.keyManager( - !isNullOrEmpty(tlsClientCertPath) ? new FileInputStream(tlsClientCertPath) : null, - !isNullOrEmpty(tlsClientKeyPath) ? decryptionStrategy.decryptPrivateKey(tlsClientKeyPath, true) : null, - !isNullOrEmpty(tlsClientKeyPassword) ? tlsClientKeyPassword : null) - .build(); - } - } else { - - if (tlsTestModeEnable) { - SelfSignedCertificate selfSignedCertificate = new SelfSignedCertificate(); - return SslContextBuilder - .forServer(selfSignedCertificate.certificate(), selfSignedCertificate.privateKey()) - .sslProvider(SslProvider.JDK) - .clientAuth(ClientAuth.OPTIONAL) - .build(); - } else { - SslContextBuilder sslContextBuilder = SslContextBuilder.forServer( - !isNullOrEmpty(tlsServerCertPath) ? new FileInputStream(tlsServerCertPath) : null, - !isNullOrEmpty(tlsServerKeyPath) ? decryptionStrategy.decryptPrivateKey(tlsServerKeyPath, false) : null, - !isNullOrEmpty(tlsServerKeyPassword) ? tlsServerKeyPassword : null) - .sslProvider(provider); - - if (!tlsServerAuthClient) { - sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE); - } else { - if (!isNullOrEmpty(tlsServerTrustCertPath)) { - sslContextBuilder.trustManager(new File(tlsServerTrustCertPath)); - } - } - - sslContextBuilder.clientAuth(parseClientAuthMode(tlsServerNeedClientAuth)); - return sslContextBuilder.build(); - } - } - } - - private static void extractTlsConfigFromFile(final File configFile) { - if (!(configFile.exists() && configFile.isFile() && configFile.canRead())) { - logger.info("Tls config file doesn't exist, skip it"); - return; - } - - Properties properties; - properties = new Properties(); - InputStream inputStream = null; - try { - inputStream = new FileInputStream(configFile); - properties.load(inputStream); - } catch (IOException ignore) { - } finally { - if (null != inputStream) { - try { - inputStream.close(); - } catch (IOException ignore) { - } - } - } - - tlsTestModeEnable = Boolean.parseBoolean(properties.getProperty(TLS_TEST_MODE_ENABLE, String.valueOf(tlsTestModeEnable))); - tlsServerNeedClientAuth = properties.getProperty(TLS_SERVER_NEED_CLIENT_AUTH, tlsServerNeedClientAuth); - tlsServerKeyPath = properties.getProperty(TLS_SERVER_KEYPATH, tlsServerKeyPath); - tlsServerKeyPassword = properties.getProperty(TLS_SERVER_KEYPASSWORD, tlsServerKeyPassword); - tlsServerCertPath = properties.getProperty(TLS_SERVER_CERTPATH, tlsServerCertPath); - tlsServerAuthClient = Boolean.parseBoolean(properties.getProperty(TLS_SERVER_AUTHCLIENT, String.valueOf(tlsServerAuthClient))); - tlsServerTrustCertPath = properties.getProperty(TLS_SERVER_TRUSTCERTPATH, tlsServerTrustCertPath); - - tlsClientKeyPath = properties.getProperty(TLS_CLIENT_KEYPATH, tlsClientKeyPath); - tlsClientKeyPassword = properties.getProperty(TLS_CLIENT_KEYPASSWORD, tlsClientKeyPassword); - tlsClientCertPath = properties.getProperty(TLS_CLIENT_CERTPATH, tlsClientCertPath); - tlsClientAuthServer = Boolean.parseBoolean(properties.getProperty(TLS_CLIENT_AUTHSERVER, String.valueOf(tlsClientAuthServer))); - tlsClientTrustCertPath = properties.getProperty(TLS_CLIENT_TRUSTCERTPATH, tlsClientTrustCertPath); - } - - private static void logTheFinalUsedTlsConfig() { - logger.info("Log the final used tls related configuration"); - logger.info("{} = {}", TLS_TEST_MODE_ENABLE, tlsTestModeEnable); - logger.info("{} = {}", TLS_SERVER_NEED_CLIENT_AUTH, tlsServerNeedClientAuth); - logger.info("{} = {}", TLS_SERVER_KEYPATH, tlsServerKeyPath); - logger.info("{} = {}", TLS_SERVER_KEYPASSWORD, tlsServerKeyPassword); - logger.info("{} = {}", TLS_SERVER_CERTPATH, tlsServerCertPath); - logger.info("{} = {}", TLS_SERVER_AUTHCLIENT, tlsServerAuthClient); - logger.info("{} = {}", TLS_SERVER_TRUSTCERTPATH, tlsServerTrustCertPath); - - logger.info("{} = {}", TLS_CLIENT_KEYPATH, tlsClientKeyPath); - logger.info("{} = {}", TLS_CLIENT_KEYPASSWORD, tlsClientKeyPassword); - logger.info("{} = {}", TLS_CLIENT_CERTPATH, tlsClientCertPath); - logger.info("{} = {}", TLS_CLIENT_AUTHSERVER, tlsClientAuthServer); - logger.info("{} = {}", TLS_CLIENT_TRUSTCERTPATH, tlsClientTrustCertPath); - } - - private static ClientAuth parseClientAuthMode(String authMode) { - if (null == authMode || authMode.trim().isEmpty()) { - return ClientAuth.NONE; - } - - for (ClientAuth clientAuth : ClientAuth.values()) { - if (clientAuth.name().equals(authMode.toUpperCase())) { - return clientAuth; - } - } - - return ClientAuth.NONE; - } - - /** - * Determine if a string is {@code null} or {@link String#isEmpty()} returns {@code true}. - */ - private static boolean isNullOrEmpty(String s) { - return s == null || s.isEmpty(); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsSystemConfig.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsSystemConfig.java deleted file mode 100644 index 26444ac..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/netty/TlsSystemConfig.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 com.pantheon.remoting.netty; - -import com.pantheon.remoting.common.TlsMode; -import io.netty.handler.ssl.SslContext; - -public class TlsSystemConfig { - public static final String TLS_SERVER_MODE = "tls.server.mode"; - public static final String TLS_ENABLE = "tls.enable"; - public static final String TLS_CONFIG_FILE = "tls.config.file"; - public static final String TLS_TEST_MODE_ENABLE = "tls.test.mode.enable"; - - public static final String TLS_SERVER_NEED_CLIENT_AUTH = "tls.server.need.client.auth"; - public static final String TLS_SERVER_KEYPATH = "tls.server.keyPath"; - public static final String TLS_SERVER_KEYPASSWORD = "tls.server.keyPassword"; - public static final String TLS_SERVER_CERTPATH = "tls.server.certPath"; - public static final String TLS_SERVER_AUTHCLIENT = "tls.server.authClient"; - public static final String TLS_SERVER_TRUSTCERTPATH = "tls.server.trustCertPath"; - - public static final String TLS_CLIENT_KEYPATH = "tls.client.keyPath"; - public static final String TLS_CLIENT_KEYPASSWORD = "tls.client.keyPassword"; - public static final String TLS_CLIENT_CERTPATH = "tls.client.certPath"; - public static final String TLS_CLIENT_AUTHSERVER = "tls.client.authServer"; - public static final String TLS_CLIENT_TRUSTCERTPATH = "tls.client.trustCertPath"; - - - /** - * To determine whether use SSL in client-side, include SDK client and BrokerOuterAPI - */ - public static boolean tlsEnable = Boolean.parseBoolean(System.getProperty(TLS_ENABLE, "false")); - - /** - * To determine whether use test mode when initialize TLS context - */ - public static boolean tlsTestModeEnable = Boolean.parseBoolean(System.getProperty(TLS_TEST_MODE_ENABLE, "true")); - - /** - * Indicates the state of the {@link javax.net.ssl.SSLEngine} with respect to client authentication. - * This configuration item really only applies when building the server-side {@link SslContext}, - * and can be set to none, require or optional. - */ - public static String tlsServerNeedClientAuth = System.getProperty(TLS_SERVER_NEED_CLIENT_AUTH, "none"); - /** - * The store path of server-side private key - */ - public static String tlsServerKeyPath = System.getProperty(TLS_SERVER_KEYPATH, null); - - /** - * The password of the server-side private key - */ - public static String tlsServerKeyPassword = System.getProperty(TLS_SERVER_KEYPASSWORD, null); - - /** - * The store path of server-side X.509 certificate chain in PEM format - */ - public static String tlsServerCertPath = System.getProperty(TLS_SERVER_CERTPATH, null); - - /** - * To determine whether verify the client endpoint's certificate strictly - */ - public static boolean tlsServerAuthClient = Boolean.parseBoolean(System.getProperty(TLS_SERVER_AUTHCLIENT, "false")); - - /** - * The store path of trusted certificates for verifying the client endpoint's certificate - */ - public static String tlsServerTrustCertPath = System.getProperty(TLS_SERVER_TRUSTCERTPATH, null); - - /** - * The store path of client-side private key - */ - public static String tlsClientKeyPath = System.getProperty(TLS_CLIENT_KEYPATH, null); - - /** - * The password of the client-side private key - */ - public static String tlsClientKeyPassword = System.getProperty(TLS_CLIENT_KEYPASSWORD, null); - - /** - * The store path of client-side X.509 certificate chain in PEM format - */ - public static String tlsClientCertPath = System.getProperty(TLS_CLIENT_CERTPATH, null); - - /** - * To determine whether verify the server endpoint's certificate strictly - */ - public static boolean tlsClientAuthServer = Boolean.parseBoolean(System.getProperty(TLS_CLIENT_AUTHSERVER, "false")); - - /** - * The store path of trusted certificates for verifying the server endpoint's certificate - */ - public static String tlsClientTrustCertPath = System.getProperty(TLS_CLIENT_TRUSTCERTPATH, null); - - /** - * For server, three SSL modes are supported: disabled, permissive and enforcing. - * For client, use {@link TlsSystemConfig#tlsEnable} to determine whether use SSL. - *
    - *
  1. disabled: SSL is not supported; any incoming SSL handshake will be rejected, causing connection closed.
  2. - *
  3. permissive: SSL is optional, aka, server in this mode can serve client connections with or without SSL;
  4. - *
  5. enforcing: SSL is required, aka, non SSL connection will be rejected.
  6. - *
- */ - public static TlsMode tlsMode = TlsMode.parse(System.getProperty(TLS_SERVER_MODE, "permissive")); - - /** - * A config file to store the above TLS related configurations, - * except {@link TlsSystemConfig#tlsMode} and {@link TlsSystemConfig#tlsEnable} - */ - public static String tlsConfigFile = System.getProperty(TLS_CONFIG_FILE, "/etc/pantheon/tls.properties"); -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/LanguageCode.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/LanguageCode.java deleted file mode 100644 index d2d8555..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/LanguageCode.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -public enum LanguageCode { - JAVA((byte) 0); - - private byte code; - - LanguageCode(byte code) { - this.code = code; - } - - public static LanguageCode valueOf(byte code) { - for (LanguageCode languageCode : LanguageCode.values()) { - if (languageCode.getCode() == code) { - return languageCode; - } - } - return null; - } - - public byte getCode() { - return code; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/PantheonSerializable.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/PantheonSerializable.java deleted file mode 100644 index e7ebdc3..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/PantheonSerializable.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -public class PantheonSerializable { - private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); - - public static byte[] pantheonProtocolEncode(RemotingCommand cmd) { - // String remark - byte[] remarkBytes = null; - int remarkLen = 0; - if (cmd.getRemark() != null && cmd.getRemark().length() > 0) { - remarkBytes = cmd.getRemark().getBytes(CHARSET_UTF8); - remarkLen = remarkBytes.length; - } - - // HashMap extFields - byte[] extFieldsBytes = null; - int extLen = 0; - if (cmd.getExtFields() != null && !cmd.getExtFields().isEmpty()) { - extFieldsBytes = mapSerialize(cmd.getExtFields()); - extLen = extFieldsBytes.length; - } - - int totalLen = calTotalLen(remarkLen, extLen); - - ByteBuffer headerBuffer = ByteBuffer.allocate(totalLen); - // int code(~32767) - headerBuffer.putShort((short) cmd.getCode()); - // LanguageCode language - headerBuffer.put(cmd.getLanguage().getCode()); - // int version(~32767) - headerBuffer.putShort((short) cmd.getVersion()); - // int opaque - headerBuffer.putInt(cmd.getOpaque()); - // int flag - headerBuffer.putInt(cmd.getFlag()); - // String remark - if (remarkBytes != null) { - headerBuffer.putInt(remarkBytes.length); - headerBuffer.put(remarkBytes); - } else { - headerBuffer.putInt(0); - } - // HashMap extFields; - if (extFieldsBytes != null) { - headerBuffer.putInt(extFieldsBytes.length); - headerBuffer.put(extFieldsBytes); - } else { - headerBuffer.putInt(0); - } - - return headerBuffer.array(); - } - - public static byte[] mapSerialize(HashMap map) { - // keySize+key+valSize+val - if (null == map || map.isEmpty()) - return null; - - int totalLength = 0; - int kvLength; - Iterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - if (entry.getKey() != null && entry.getValue() != null) { - kvLength = - // keySize + Key - 2 + entry.getKey().getBytes(CHARSET_UTF8).length - // valSize + val - + 4 + entry.getValue().getBytes(CHARSET_UTF8).length; - totalLength += kvLength; - } - } - - ByteBuffer content = ByteBuffer.allocate(totalLength); - byte[] key; - byte[] val; - it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - if (entry.getKey() != null && entry.getValue() != null) { - key = entry.getKey().getBytes(CHARSET_UTF8); - val = entry.getValue().getBytes(CHARSET_UTF8); - - content.putShort((short) key.length); - content.put(key); - - content.putInt(val.length); - content.put(val); - } - } - - return content.array(); - } - - private static int calTotalLen(int remark, int ext) { - // int code(~32767) - int length = 2 - // LanguageCode language - + 1 - // int version(~32767) - + 2 - // int opaque - + 4 - // int flag - + 4 - // String remark - + 4 + remark - // HashMap extFields - + 4 + ext; - - return length; - } - - public static RemotingCommand pantheonProtocolDecode(final byte[] headerArray) { - RemotingCommand cmd = new RemotingCommand(); - ByteBuffer headerBuffer = ByteBuffer.wrap(headerArray); - // int code(~32767) - cmd.setCode(headerBuffer.getShort()); - // LanguageCode language - cmd.setLanguage(LanguageCode.valueOf(headerBuffer.get())); - // int version(~32767) - cmd.setVersion(headerBuffer.getShort()); - // int opaque - cmd.setOpaque(headerBuffer.getInt()); - // int flag - cmd.setFlag(headerBuffer.getInt()); - // String remark - int remarkLength = headerBuffer.getInt(); - if (remarkLength > 0) { - byte[] remarkContent = new byte[remarkLength]; - headerBuffer.get(remarkContent); - cmd.setRemark(new String(remarkContent, CHARSET_UTF8)); - } - - // HashMap extFields - int extFieldsLength = headerBuffer.getInt(); - if (extFieldsLength > 0) { - byte[] extFieldsBytes = new byte[extFieldsLength]; - headerBuffer.get(extFieldsBytes); - cmd.setExtFields(mapDeserialize(extFieldsBytes)); - } - return cmd; - } - - public static HashMap mapDeserialize(byte[] bytes) { - if (bytes == null || bytes.length <= 0) - return null; - - HashMap map = new HashMap(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); - - short keySize; - byte[] keyContent; - int valSize; - byte[] valContent; - while (byteBuffer.hasRemaining()) { - keySize = byteBuffer.getShort(); - keyContent = new byte[keySize]; - byteBuffer.get(keyContent); - - valSize = byteBuffer.getInt(); - valContent = new byte[valSize]; - byteBuffer.get(valContent); - - map.put(new String(keyContent, CHARSET_UTF8), new String(valContent, CHARSET_UTF8)); - } - return map; - } - - public static boolean isBlank(String str) { - int strLen; - if (str == null || (strLen = str.length()) == 0) { - return true; - } - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return false; - } - } - return true; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommand.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommand.java deleted file mode 100644 index 12a6ae0..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommand.java +++ /dev/null @@ -1,544 +0,0 @@ -package com.pantheon.remoting.protocol; - -import com.alibaba.fastjson.annotation.JSONField; -import com.pantheon.remoting.CommandCustomHeader; -import com.pantheon.remoting.annotation.CFNotNull; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.exception.RemotingCommandException; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc Netty message wrapper for request and response command which include encode and decode process - * protocol :
- * 1,4 bytes total length - * 2,4 bytes head length - * 3,header data - * 4,body data - **/ -public class RemotingCommand { - private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); - - public static final String SERIALIZE_TYPE_PROPERTY = "pantheon.serialize.type"; - public static final String SERIALIZE_TYPE_ENV = "PANTHEON_SERIALIZE_TYPE"; - public static final String REMOTING_VERSION_KEY = "pantheon.remoting.version"; - private static final int RPC_TYPE = 0; // 0, REQUEST_COMMAND - private static final int RPC_ONEWAY = 1; // 0, RPC - private static final Map, Field[]> CLASS_HASH_MAP = - new HashMap, Field[]>(); - private static final Map CANONICAL_NAME_CACHE = new HashMap(); - private static final Map NULLABLE_FIELD_CACHE = new HashMap(); - private static final String STRING_CANONICAL_NAME = String.class.getCanonicalName(); - private static final String DOUBLE_CANONICAL_NAME_1 = Double.class.getCanonicalName(); - private static final String DOUBLE_CANONICAL_NAME_2 = double.class.getCanonicalName(); - private static final String INTEGER_CANONICAL_NAME_1 = Integer.class.getCanonicalName(); - private static final String INTEGER_CANONICAL_NAME_2 = int.class.getCanonicalName(); - private static final String LONG_CANONICAL_NAME_1 = Long.class.getCanonicalName(); - private static final String LONG_CANONICAL_NAME_2 = long.class.getCanonicalName(); - private static final String BOOLEAN_CANONICAL_NAME_1 = Boolean.class.getCanonicalName(); - private static final String BOOLEAN_CANONICAL_NAME_2 = boolean.class.getCanonicalName(); - private static volatile int configVersion = -1; - private static AtomicInteger requestId = new AtomicInteger(0); - - private static SerializeType serializeTypeConfigInThisServer = SerializeType.JSON; - - static { - final String protocol = System.getProperty(SERIALIZE_TYPE_PROPERTY, System.getenv(SERIALIZE_TYPE_ENV)); - if (!isBlank(protocol)) { - try { - serializeTypeConfigInThisServer = SerializeType.valueOf(protocol); - } catch (IllegalArgumentException e) { - throw new RuntimeException("parser specified protocol error. protocol=" + protocol, e); - } - } - } - - private int code; - private LanguageCode language = LanguageCode.JAVA; - private int version = 0; - private int opaque = requestId.getAndIncrement(); - private int flag = 0; - private String remark; - private HashMap extFields; - private transient CommandCustomHeader customHeader; - - private SerializeType serializeTypeCurrentRPC = serializeTypeConfigInThisServer; - - private transient byte[] body; - - protected RemotingCommand() { - } - - public static RemotingCommand createRequestCommand(int code, CommandCustomHeader customHeader) { - RemotingCommand cmd = new RemotingCommand(); - cmd.setCode(code); - cmd.customHeader = customHeader; - setCmdVersion(cmd); - return cmd; - } - - private static void setCmdVersion(RemotingCommand cmd) { - if (configVersion >= 0) { - cmd.setVersion(configVersion); - } else { - String v = System.getProperty(REMOTING_VERSION_KEY); - if (v != null) { - int value = Integer.parseInt(v); - cmd.setVersion(value); - configVersion = value; - } - } - } - - public static RemotingCommand createResponseCommand(Class classHeader) { - return createResponseCommand(RemotingSysResponseCode.SYSTEM_ERROR, "not set any response code", classHeader); - } - - public static RemotingCommand createResponseCommand(int code, String remark, - Class classHeader) { - RemotingCommand cmd = new RemotingCommand(); - cmd.markResponseType(); - cmd.setCode(code); - cmd.setRemark(remark); - setCmdVersion(cmd); - - if (classHeader != null) { - try { - CommandCustomHeader objectHeader = classHeader.newInstance(); - cmd.customHeader = objectHeader; - } catch (InstantiationException e) { - return null; - } catch (IllegalAccessException e) { - return null; - } - } - - return cmd; - } - - public static RemotingCommand createResponseCommand(int code, String remark) { - return createResponseCommand(code, remark, null); - } - - public static RemotingCommand decode(final byte[] array) { - ByteBuffer byteBuffer = ByteBuffer.wrap(array); - return decode(byteBuffer); - } - - public static RemotingCommand decode(final ByteBuffer byteBuffer) { - //1 load header data to 'byte[] headerData' - int length = byteBuffer.limit(); - int oriHeaderLen = byteBuffer.getInt(); - int headerLength = getHeaderLength(oriHeaderLen); - - byte[] headerData = new byte[headerLength]; - byteBuffer.get(headerData); - //2 decode header depends on protocol(Json or PANTHEON) - RemotingCommand cmd = headerDecode(headerData, getProtocolType(oriHeaderLen)); - - //3 decode body - int bodyLength = length - 4 - headerLength; - byte[] bodyData = null; - if (bodyLength > 0) { - bodyData = new byte[bodyLength]; - byteBuffer.get(bodyData); - } - cmd.body = bodyData; - - return cmd; - } - - public static int getHeaderLength(int length) { - return length & 0xFFFFFF; - } - - private static RemotingCommand headerDecode(byte[] headerData, SerializeType type) { - switch (type) { - case JSON: - RemotingCommand resultJson = RemotingSerializable.decode(headerData, RemotingCommand.class); - resultJson.setSerializeTypeCurrentRPC(type); - return resultJson; - case PANTHEON: - RemotingCommand resultPantheon = PantheonSerializable.pantheonProtocolDecode(headerData); - resultPantheon.setSerializeTypeCurrentRPC(type); - return resultPantheon; - default: - break; - } - - return null; - } - - public static SerializeType getProtocolType(int source) { - return SerializeType.valueOf((byte) ((source >> 24) & 0xFF)); - } - - public static int createNewRequestId() { - return requestId.getAndIncrement(); - } - - public static SerializeType getSerializeTypeConfigInThisServer() { - return serializeTypeConfigInThisServer; - } - - private static boolean isBlank(String str) { - int strLen; - if (str == null || (strLen = str.length()) == 0) { - return true; - } - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return false; - } - } - return true; - } - - public static byte[] markProtocolType(int source, SerializeType type) { - byte[] result = new byte[4]; - - result[0] = type.getCode(); - result[1] = (byte) ((source >> 16) & 0xFF); - result[2] = (byte) ((source >> 8) & 0xFF); - result[3] = (byte) (source & 0xFF); - return result; - } - - public void markResponseType() { - int bits = 1 << RPC_TYPE; - this.flag |= bits; - } - - public CommandCustomHeader readCustomHeader() { - return customHeader; - } - - public void writeCustomHeader(CommandCustomHeader customHeader) { - this.customHeader = customHeader; - } - - public CommandCustomHeader decodeCommandCustomHeader( - Class classHeader) throws RemotingCommandException { - CommandCustomHeader objectHeader; - try { - objectHeader = classHeader.newInstance(); - } catch (InstantiationException e) { - return null; - } catch (IllegalAccessException e) { - return null; - } - - if (this.extFields != null) { - - Field[] fields = getClazzFields(classHeader); - for (Field field : fields) { - if (!Modifier.isStatic(field.getModifiers())) { - String fieldName = field.getName(); - if (!fieldName.startsWith("this")) { - try { - String value = this.extFields.get(fieldName); - if (null == value) { - //解析字段是否为空逻辑处理 - if (!isFieldNullable(field)) { - throw new RemotingCommandException("the custom field <" + fieldName + "> is null"); - } - continue; - } - - field.setAccessible(true); - String type = getCanonicalName(field.getType()); - Object valueParsed; - - if (type.equals(STRING_CANONICAL_NAME)) { - valueParsed = value; - } else if (type.equals(INTEGER_CANONICAL_NAME_1) || type.equals(INTEGER_CANONICAL_NAME_2)) { - valueParsed = Integer.parseInt(value); - } else if (type.equals(LONG_CANONICAL_NAME_1) || type.equals(LONG_CANONICAL_NAME_2)) { - valueParsed = Long.parseLong(value); - } else if (type.equals(BOOLEAN_CANONICAL_NAME_1) || type.equals(BOOLEAN_CANONICAL_NAME_2)) { - valueParsed = Boolean.parseBoolean(value); - } else if (type.equals(DOUBLE_CANONICAL_NAME_1) || type.equals(DOUBLE_CANONICAL_NAME_2)) { - valueParsed = Double.parseDouble(value); - } else { - throw new RemotingCommandException("the custom field <" + fieldName + "> type is not supported"); - } - - field.set(objectHeader, valueParsed); - - } catch (Throwable e) { - logger.error("Failed field [{}] decoding", fieldName, e); - } - } - } - } - - objectHeader.checkFields(); - } - - return objectHeader; - } - - private Field[] getClazzFields(Class classHeader) { - Field[] field = CLASS_HASH_MAP.get(classHeader); - - if (field == null) { - field = classHeader.getDeclaredFields(); - synchronized (CLASS_HASH_MAP) { - CLASS_HASH_MAP.put(classHeader, field); - } - } - return field; - } - - private boolean isFieldNullable(Field field) { - if (!NULLABLE_FIELD_CACHE.containsKey(field)) { - Annotation annotation = field.getAnnotation(CFNotNull.class); - synchronized (NULLABLE_FIELD_CACHE) { - NULLABLE_FIELD_CACHE.put(field, annotation == null); - } - } - return NULLABLE_FIELD_CACHE.get(field); - } - - private String getCanonicalName(Class clazz) { - String name = CANONICAL_NAME_CACHE.get(clazz); - - if (name == null) { - name = clazz.getCanonicalName(); - synchronized (CANONICAL_NAME_CACHE) { - CANONICAL_NAME_CACHE.put(clazz, name); - } - } - return name; - } - - - public ByteBuffer encode() { - // 1> header length size - int length = 4; - - // 2> header data length - byte[] headerData = this.headerEncode(); - length += headerData.length; - - // 3> body data length - if (this.body != null) { - length += body.length; - } - - ByteBuffer result = ByteBuffer.allocate(4 + length); - - // length - result.putInt(length); - - // header length - result.put(markProtocolType(headerData.length, serializeTypeCurrentRPC)); - - // header data - result.put(headerData); - - // body data; - if (this.body != null) { - result.put(this.body); - } - - result.flip(); - - return result; - } - - private byte[] headerEncode() { - this.makeCustomHeaderToNet(); - if (SerializeType.PANTHEON == serializeTypeCurrentRPC) { - return PantheonSerializable.pantheonProtocolEncode(this); - } else { - return RemotingSerializable.encode(this); - } - } - - public void makeCustomHeaderToNet() { - if (this.customHeader != null) { - Field[] fields = getClazzFields(customHeader.getClass()); - if (null == this.extFields) { - this.extFields = new HashMap(); - } - - for (Field field : fields) { - if (!Modifier.isStatic(field.getModifiers())) { - String name = field.getName(); - if (!name.startsWith("this")) { - Object value = null; - try { - field.setAccessible(true); - value = field.get(this.customHeader); - } catch (Exception e) { - logger.error("Failed to access field [{}]", name, e); - } - - if (value != null) { - this.extFields.put(name, value.toString()); - } - } - } - } - } - } - - public ByteBuffer encodeHeader() { - return encodeHeader(this.body != null ? this.body.length : 0); - } - - public ByteBuffer encodeHeader(final int bodyLength) { - // 1> header length size - int length = 4; - - // 2> header data length - byte[] headerData; - headerData = this.headerEncode(); - - length += headerData.length; - - // 3> body data length - length += bodyLength; - - ByteBuffer result = ByteBuffer.allocate(4 + length - bodyLength); - - // length - result.putInt(length); - - // header length - result.put(markProtocolType(headerData.length, serializeTypeCurrentRPC)); - - // header data - result.put(headerData); - - result.flip(); - - return result; - } - - public void markOnewayRPC() { - int bits = 1 << RPC_ONEWAY; - this.flag |= bits; - } - - @JSONField(serialize = false) - public boolean isOnewayRPC() { - int bits = 1 << RPC_ONEWAY; - return (this.flag & bits) == bits; - } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - @JSONField(serialize = false) - public RemotingCommandType getType() { - if (this.isResponseType()) { - return RemotingCommandType.RESPONSE_COMMAND; - } - - return RemotingCommandType.REQUEST_COMMAND; - } - - @JSONField(serialize = false) - public boolean isResponseType() { - int bits = 1 << RPC_TYPE; - return (this.flag & bits) == bits; - } - - public LanguageCode getLanguage() { - return language; - } - - public void setLanguage(LanguageCode language) { - this.language = language; - } - - public int getVersion() { - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public int getOpaque() { - return opaque; - } - - public void setOpaque(int opaque) { - this.opaque = opaque; - } - - public int getFlag() { - return flag; - } - - public void setFlag(int flag) { - this.flag = flag; - } - - public String getRemark() { - return remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } - - public byte[] getBody() { - return body; - } - - public void setBody(byte[] body) { - this.body = body; - } - - public HashMap getExtFields() { - return extFields; - } - - public void setExtFields(HashMap extFields) { - this.extFields = extFields; - } - - public void addExtField(String key, String value) { - if (null == extFields) { - extFields = new HashMap(); - } - extFields.put(key, value); - } - - @Override - public String toString() { - return "RemotingCommand [code=" + code + ", language=" + language + ", version=" + version + ", opaque=" + opaque + ", flag(B)=" - + Integer.toBinaryString(flag) + ", remark=" + remark + ", extFields=" + extFields + ", serializeTypeCurrentRPC=" - + serializeTypeCurrentRPC + "]"; - } - - public SerializeType getSerializeTypeCurrentRPC() { - return serializeTypeCurrentRPC; - } - - public void setSerializeTypeCurrentRPC(SerializeType serializeTypeCurrentRPC) { - this.serializeTypeCurrentRPC = serializeTypeCurrentRPC; - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommandType.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommandType.java deleted file mode 100644 index 4267589..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommandType.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -public enum RemotingCommandType { - REQUEST_COMMAND, - RESPONSE_COMMAND; -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSerializable.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSerializable.java deleted file mode 100644 index 38fc155..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSerializable.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -import com.alibaba.fastjson.JSON; - -import java.nio.charset.Charset; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc fastjson to serialize and deserialize data - **/ -public abstract class RemotingSerializable { - private final static Charset CHARSET_UTF8 = Charset.forName("UTF-8"); - - public static byte[] encode(final Object obj) { - final String json = toJson(obj, false); - if (json != null) { - return json.getBytes(CHARSET_UTF8); - } - return null; - } - - public static String toJson(final Object obj, boolean prettyFormat) { - return JSON.toJSONString(obj, prettyFormat); - } - - public static T decode(final byte[] data, Class classOfT) { - final String json = new String(data, CHARSET_UTF8); - return fromJson(json, classOfT); - } - - public static T fromJson(String json, Class classOfT) { - return JSON.parseObject(json, classOfT); - } - - public byte[] encode() { - final String json = this.toJson(); - if (json != null) { - return json.getBytes(CHARSET_UTF8); - } - return null; - } - - public String toJson() { - return toJson(false); - } - - public String toJson(final boolean prettyFormat) { - return toJson(this, prettyFormat); - } -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSysResponseCode.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSysResponseCode.java deleted file mode 100644 index 23a91aa..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSysResponseCode.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -public class RemotingSysResponseCode { - - public static final int SUCCESS = 0; - - public static final int SYSTEM_ERROR = 1; - - public static final int SYSTEM_BUSY = 2; - - public static final int REQUEST_CODE_NOT_SUPPORTED = 3; - -} diff --git a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/SerializeType.java b/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/SerializeType.java deleted file mode 100644 index a4a1f96..0000000 --- a/pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/SerializeType.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 com.pantheon.remoting.protocol; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc support JSON and our own (PANTHEON) serialization protocol - **/ -public enum SerializeType { - JSON((byte) 0), - PANTHEON((byte) 1); - - private byte code; - - SerializeType(byte code) { - this.code = code; - } - - public static SerializeType valueOf(byte code) { - for (SerializeType serializeType : SerializeType.values()) { - if (serializeType.getCode() == code) { - return serializeType; - } - } - return null; - } - - public byte getCode() { - return code; - } -} diff --git a/pantheon-remoting/src/main/resources/log4j.properties b/pantheon-remoting/src/main/resources/log4j.properties deleted file mode 100644 index 5648e40..0000000 --- a/pantheon-remoting/src/main/resources/log4j.properties +++ /dev/null @@ -1,33 +0,0 @@ -log4j.rootLogger=DEBUG, CONSOLE - -# local : debug log to console -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.Threshold=DEBUG -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - -# test: log to file -log4j.appender.TRACEFILE=org.apache.log4j.FileAppender -log4j.appender.TRACEFILE.Threshold=DEBUG -log4j.appender.TRACEFILE.File=/usr/local/pantheon/logs/pantheon.trace -log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n - -# prod: log to pantheon.log and pantheon.error -log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender -log4j.appender.ROLLINGFILE.Threshold=INFO -log4j.appender.ROLLINGFILE.File=/usr/local/pantheon/logs/pantheon.log -log4j.appender.ROLLINGFILE.MaxFileSize=10MB -log4j.appender.ROLLINGFILE.MaxBackupIndex=10 -log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - -log4j.appender.ERRORFILE=org.apache.log4j.RollingFileAppender -log4j.appender.ERRORFILE.Threshold=WARN -log4j.appender.ERRORFILE.File=/usr/local/pantheon/logs/pantheon.error -log4j.appender.ERRORFILE.MaxFileSize=10MB -log4j.appender.ERRORFILE.MaxBackupIndex=10 -log4j.appender.ERRORFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.ERRORFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - - diff --git a/pantheon-server/README.md b/pantheon-server/README.md deleted file mode 100644 index a64a5b2..0000000 --- a/pantheon-server/README.md +++ /dev/null @@ -1 +0,0 @@ -pantheon server \ No newline at end of file diff --git a/pantheon-server/pom.xml b/pantheon-server/pom.xml deleted file mode 100644 index b15d3fb..0000000 --- a/pantheon-server/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - pantheon-server - jar - pantheon-server ${project.version} - - - 8 - 8 - - - - - javax.jms - jms - 1.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - log4j - log4j - 1.2.17 - - - com.alibaba - fastjson - 1.2.71 - - - io.netty - netty-all - 4.0.42.Final - - - com.netflix.archaius - archaius-core - 0.7.6 - - - commons-configuration - commons-configuration - 1.8 - - - com.google.guava - guava - 19.0 - - - javax.ws.rs - jsr311-api - 1.1.1 - - - - ${project.groupId} - pantheon-remoting - 1.0-SNAPSHOT - - - ${project.groupId} - pantheon-common - 1.0-SNAPSHOT - - - ${project.groupId} - pantheon-client - 1.0-SNAPSHOT - - - com.pantheon - pantheon-client - 1.0-SNAPSHOT - compile - - - \ No newline at end of file diff --git a/pantheon-server/src/main/java/com/pantheon/server/ServerBootstrap.java b/pantheon-server/src/main/java/com/pantheon/server/ServerBootstrap.java deleted file mode 100644 index 5dd6a85..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/ServerBootstrap.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.pantheon.server; - -import com.netflix.config.ConfigurationManager; -import com.pantheon.common.ShutdownHookThread; -import com.pantheon.common.lifecycle.Lifecycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.Callable; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc - **/ -public class ServerBootstrap { - private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); - private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - private static final String TEST = "test"; - - - public static void main(String[] args) { - logger.info("ServerBootstrap initializing......"); - - initPantheonEnvironment(); - startServerNode(); - } - - private static ServerNode startServerNode() { - ServerNode serverNode =ServerNode.getInstance(); - serverNode.start(); - if (!serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) { - serverNode.stop(); - System.exit(-3); - } - Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(logger, (Callable) () -> { - serverNode.stop(); - return null; - })); - return serverNode; - } - - public static void shutdown(final ServerNode serverNode) { - serverNode.stop(); - } - - - /** - * Users can override to initialize the environment themselves. - */ - protected static void initPantheonEnvironment() { - String environment = ConfigurationManager.getConfigInstance().getString(PANTHEON_ENVIRONMENT); - if (environment == null) { - //default test environment - ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); - logger.info(PANTHEON_ENVIRONMENT + " value is not set, defaulting to test"); - } - logger.info("Setting the Pantheon configuration withe environment " + environment); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/ServerNode.java b/pantheon-server/src/main/java/com/pantheon/server/ServerNode.java deleted file mode 100644 index c87dda6..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/ServerNode.java +++ /dev/null @@ -1,297 +0,0 @@ -package com.pantheon.server; - -import com.pantheon.common.ServerNodeRole; -import com.pantheon.common.ThreadFactoryImpl; -import com.pantheon.common.lifecycle.AbstractLifecycleComponent; -import com.pantheon.common.protocol.RequestCode; -import com.pantheon.common.protocol.header.GetConsumerRunningInfoRequestHeader; -import com.pantheon.remoting.RemotingServer; -import com.pantheon.remoting.exception.RemotingCommandException; -import com.pantheon.remoting.netty.NettyRemotingServer; -import com.pantheon.remoting.netty.NettyServerConfig; -import com.pantheon.remoting.protocol.RemotingCommand; -import com.pantheon.server.client.ClientHousekeepingService; -import com.pantheon.server.client.ConsumerInfoManager; -import com.pantheon.server.client.ServerToClient; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.config.PantheonServerConfig; -import com.pantheon.server.network.ServerMessageReceiver; -import com.pantheon.server.network.ServerNetworkManager; -import com.pantheon.server.node.*; -import com.pantheon.server.processor.ClientManageProcessor; -import com.pantheon.server.processor.ServerNodeProcessor; -import com.pantheon.server.slot.SlotManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.concurrent.*; - -/** - * @author Anthony - * @create 2021/11/18 - * @desc - * 1 todo building slots mechanism and treat it as something like topic in RocketMq - * 2 todo server side push services clients' register - * 3 todo heartbeat check and heartbeat past due - * 4 todo rebuild master election mechanism reference from ElasticSearch - **/ -public class ServerNode extends AbstractLifecycleComponent { - private final ThreadPoolExecutor heartbeatExecutor; - private final ThreadPoolExecutor serviceManageExecutor; - private final ServerToClient serverToClient; - private final ConsumerInfoManager consumerInfoManager; - private final ClientHousekeepingService clientHousekeepingService; - private NettyServerConfig nettyServerConfig; - private PantheonServerConfig serverConfig; - private RemotingServer remotingServer; - private ExecutorService remotingExecutor; - private ClientManageProcessor clientManageProcessor; - private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl( - "ServerControllerScheduledThread")); - private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); - - private volatile static ServerNodeRole serverNodeRole = ServerNodeRole.COMMON_NODE; - - private ServerNode() { - this.nettyServerConfig = new NettyServerConfig(); - this.serverConfig = CachedPantheonServerConfig.getInstance(); - this.serverToClient = new ServerToClient(this); - this.consumerInfoManager = new ConsumerInfoManager(this); - this.clientHousekeepingService = new ClientHousekeepingService(this); - this.heartbeatExecutor = new ThreadPoolExecutor( - 1, - 1, - 1000 * 60, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(5000), - new ThreadFactoryImpl("InstanceHeartbeatThread_", true)); - - this.serviceManageExecutor = new ThreadPoolExecutor( - 1, - 1, - 1000 * 60, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(5000), - new ThreadFactoryImpl("ServiceManageThread_", true)); - } - - private static class Singleton { - static ServerNode instance = new ServerNode(); - } - - public static ServerNode getInstance() { - return ServerNode.Singleton.instance; - } - - private void startNettyClientServer() { - nettyServerConfig.setListenPort(serverConfig.getNodeClientTcpPort()); - remotingServer = new NettyRemotingServer(nettyServerConfig, this.clientHousekeepingService); - this.remotingExecutor = - Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_")); - ServerNodeProcessor defaultProcessor = new ServerNodeProcessor(this); - remotingServer.registerDefaultProcessor(defaultProcessor, remotingExecutor); - //use threadpool to process management event - clientManageProcessor = new ClientManageProcessor(this); - remotingServer.registerProcessor(RequestCode.SERVICE_HEART_BEAT, clientManageProcessor, heartbeatExecutor); - remotingServer.registerProcessor(RequestCode.GET_ALL_APP, clientManageProcessor, heartbeatExecutor); - remotingServer.registerProcessor(RequestCode.GET_DELTA_APP, clientManageProcessor, heartbeatExecutor); - remotingServer.registerProcessor(RequestCode.SERVICE_UNREGISTER, clientManageProcessor, heartbeatExecutor); - remotingServer.registerProcessor(RequestCode.SERVICE_REGISTRY, clientManageProcessor, heartbeatExecutor); - - remotingServer.start(); - logger.info("server with id :{}, listen to client connection on tcp port :{}", serverConfig.getNodeId(), serverConfig.getNodeClientTcpPort()); - } - - private boolean manageServerNetwork(Boolean isControllerCandidate) { - //listener for other servers' connection - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.startServerConnectionListener(); - - // controller candidate - if (isControllerCandidate) { - // connect before candidates (not all) avoid of nodes' duplicate connection - if (!serverNetworkManager.connectBeforeControllerCandidateServers()) { - ServerNode.this.stop(); - return false; - } - //wait for other nodes' connection - serverNetworkManager.waitAllControllerCandidatesConnected(); - serverNetworkManager.waitAllServerNodeConnected(); - } - // common node will connect to all controller node - else { - serverNetworkManager.connectAllControllerCandidates(); - } - // message receiver to receive messages from servers - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - serverMessageReceiver.start(); - return true; - } - - private boolean controllerCandidateInit(ServerNodeRole serverNodeRole) { - // controller candidate elect controller with votes - ControllerCandidate controllerCandidate = ControllerCandidate.getInstance(); - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - //controller exists - if (remoteServerNodeManager.hasController()) { - RemoteServerNode controller = remoteServerNodeManager.getController(); - // ask controller to sync slots data - controllerCandidate.requestSlotsData(controller.getNodeId()); - controllerCandidate.waitForSlotsAllocation(); - controllerCandidate.waitForSlotsReplicaAllocation(); - controllerCandidate.waitReplicaNodeIds(); - } else { - serverNodeRole = controllerCandidate.electController(); - logger.info("after election, the role of this server node:" + (serverNodeRole == ServerNodeRole.CONTROLLER_NODE ? "Controller" : "Controller candidate")); - - if (serverNodeRole == ServerNodeRole.CONTROLLER_NODE) { - //controller determine slots allocation - Controller controller = Controller.getInstance(); - controller.allocateSlots(); - controller.initControllerNode(); - controller.broadcastControllerId(); - } else if (serverNodeRole == ServerNodeRole.CONTROLLER_CANDIDATE_NODE) { - //controller candidate wait for slots allocation - controllerCandidate.waitForSlotsAllocation(); - controllerCandidate.waitForSlotsReplicaAllocation(); - controllerCandidate.waitReplicaNodeIds(); - } - } - setServerRole(serverNodeRole); - return true; - } - - private void startScheduledTask() { - this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - try { - ServerNode.this.getConsumerRunningInfo(); - } catch (Exception e) { - logger.error("ScheduledTask getConsumerRunningInfo exception", e); - } - } - }, 5000, serverConfig.getHeartBeatCheckInterval(), TimeUnit.MILLISECONDS); - //heartbeat check with connected instances,remove expired ones -// this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { -// -// @Override -// public void run() { -// try { -// ServerNode.this.heartBeatCheck(); -// } catch (Exception e) { -// logger.error("ScheduledTask heartBeatCheck exception", e); -// } -// } -// }, 5000, serverConfig.getHeartBeatCheckInterval(), TimeUnit.MILLISECONDS); - - } - - private void getConsumerRunningInfo() throws RemotingCommandException { - if (clientManageProcessor != null) { - final GetConsumerRunningInfoRequestHeader requestHeader = new GetConsumerRunningInfoRequestHeader(); - RemotingCommand request = - RemotingCommand.createRequestCommand(RequestCode.GET_CONSUMER_RUNNING_INFO, - requestHeader); - //todo just for test - clientManageProcessor.callConsumer(RequestCode.GET_CONSUMER_RUNNING_INFO, request); - } - - } - - - //todo heartbeat check and cache evict when timeout - private void heartBeatCheck() { - - } - - - public PantheonServerConfig getServerConfig() { - return serverConfig; - } - - public NettyServerConfig getNettyServerConfig() { - return nettyServerConfig; - } - - -// public static boolean isRunning() { -// return getServiceState() == ServiceState.RUNNING; -// } - - public static boolean isController() { - return getServerNodeRole() == ServerNodeRole.CONTROLLER_NODE; - } - - public static ServerNodeRole setServerRole(ServerNodeRole serverNodeRole) { - ServerNode.serverNodeRole = serverNodeRole; - return ServerNode.serverNodeRole; - } - - public static ServerNodeRole getServerNodeRole() { - return serverNodeRole; - } - - @Override - protected void doStart() { - ServerNodeRole serverNodeRole = ServerNodeRole.COMMON_NODE; - - this.startScheduledTask(); - - Boolean isControllerCandidate = serverConfig.isControllerCandidate(); - - manageServerNetwork(isControllerCandidate); - if (isControllerCandidate) { - controllerCandidateInit(serverNodeRole); - } - - //master node (not controller) wait for slots data - if (!isController()) { - SlotManager slotManager = SlotManager.getInstance(); - slotManager.initSlots(null); - slotManager.initSlotsReplicas(null, false); - slotManager.initReplicaNodeId(null); - ControllerNode.setNodeId(ServerMessageReceiver.getInstance().takeControllerNodeId()); - } - - startNettyClientServer(); - - //save connection between client and server - if (this.clientHousekeepingService != null) { - this.clientHousekeepingService.start(); - } - } - - @Override - protected void doStop() { - if (remotingServer != null) { - this.remotingServer.shutdown(); - } - if (remotingExecutor != null) { - this.remotingExecutor.shutdown(); - } - if (clientHousekeepingService != null) { - this.clientHousekeepingService.shutdown(); - } - logger.info("the server controller shutdown OK"); - } - - @Override - protected void doClose() throws IOException { - - } - - public RemotingServer getRemotingServer() { - return remotingServer; - } - - public ServerToClient getServerToClient() { - return serverToClient; - } - - public ConsumerInfoManager getConsumerInfoManager() { - return consumerInfoManager; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/client/ClientChannelInfo.java b/pantheon-server/src/main/java/com/pantheon/server/client/ClientChannelInfo.java deleted file mode 100644 index 3e4b01b..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/client/ClientChannelInfo.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 com.pantheon.server.client; - -import com.pantheon.remoting.protocol.LanguageCode; -import io.netty.channel.Channel; - -/** - * 对于每一个客户端,会根据clientID和连接对象Channel关联到一个ClientChannelInfo,用于标识该客户端实例。 - */ -public class ClientChannelInfo { - private final Channel channel; - private final String clientId; - private final LanguageCode language; - private final int version; - private volatile long lastUpdateTimestamp = System.currentTimeMillis(); - - public ClientChannelInfo(Channel channel) { - this(channel, null, null, 0); - } - - public ClientChannelInfo(Channel channel, String clientId, LanguageCode language, int version) { - this.channel = channel; - this.clientId = clientId; - this.language = language; - this.version = version; - } - - public Channel getChannel() { - return channel; - } - - public String getClientId() { - return clientId; - } - - public LanguageCode getLanguage() { - return language; - } - - public int getVersion() { - return version; - } - - public long getLastUpdateTimestamp() { - return lastUpdateTimestamp; - } - - public void setLastUpdateTimestamp(long lastUpdateTimestamp) { - this.lastUpdateTimestamp = lastUpdateTimestamp; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((channel == null) ? 0 : channel.hashCode()); - result = prime * result + ((clientId == null) ? 0 : clientId.hashCode()); - result = prime * result + ((language == null) ? 0 : language.hashCode()); - result = prime * result + (int) (lastUpdateTimestamp ^ (lastUpdateTimestamp >>> 32)); - result = prime * result + version; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ClientChannelInfo other = (ClientChannelInfo) obj; - if (channel == null) { - if (other.channel != null) - return false; - } else if (this.channel != other.channel) { - return false; - } - - return true; - } - - @Override - public String toString() { - return "ClientChannelInfo [channel=" + channel + ", clientId=" + clientId + ", language=" + language - + ", version=" + version + ", lastUpdateTimestamp=" + lastUpdateTimestamp + "]"; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/client/ClientHousekeepingService.java b/pantheon-server/src/main/java/com/pantheon/server/client/ClientHousekeepingService.java deleted file mode 100644 index 8ad2a95..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/client/ClientHousekeepingService.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.pantheon.server.client; - -import com.pantheon.common.ThreadFactoryImpl; -import com.pantheon.remoting.ChannelEventListener; -import com.pantheon.server.ServerNode; -import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -public class ClientHousekeepingService implements ChannelEventListener { - private static final Logger log = LoggerFactory.getLogger(ClientHousekeepingService.class); - - private final ServerNode serverNode; - - private ScheduledExecutorService scheduledExecutorService = Executors - .newSingleThreadScheduledExecutor(new ThreadFactoryImpl("ClientHousekeepingScheduledThread")); - - public ClientHousekeepingService(final ServerNode serverNode) { - this.serverNode = serverNode; - } - - public void start() { - - this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - try { - ClientHousekeepingService.this.scanExceptionChannel(); - } catch (Throwable e) { - log.error("Error occurred when scan not active client channels.", e); - } - } - }, 1000 * 10, 1000 * 10, TimeUnit.MILLISECONDS); - } - - private void scanExceptionChannel() { - this.serverNode.getConsumerInfoManager().scanNotActiveChannel(); - } - - public void shutdown() { - this.scheduledExecutorService.shutdown(); - } - - @Override - public void onChannelConnect(String remoteAddr, Channel channel) { - - } - - @Override - public void onChannelClose(String remoteAddr, Channel channel) { - this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); - } - - @Override - public void onChannelException(String remoteAddr, Channel channel) { - this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); - } - - @Override - public void onChannelIdle(String remoteAddr, Channel channel) { - this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/client/ConsumerInfoManager.java b/pantheon-server/src/main/java/com/pantheon/server/client/ConsumerInfoManager.java deleted file mode 100644 index 347ba04..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/client/ConsumerInfoManager.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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 com.pantheon.server.client; - -import com.pantheon.common.protocol.heartBeat.SubscriptionData; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.common.RemotingUtil; -import com.pantheon.server.ServerNode; -import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -public class ConsumerInfoManager { - private static final long CHANNEL_EXPIRED_TIMEOUT = 1000 * 120; - private static final Logger log = LoggerFactory.getLogger(ConsumerInfoManager.class); - private final ConcurrentMap subscriptionTable = - new ConcurrentHashMap(); - //bind channel with clientId - private final ConcurrentMap channelInfoTable = - new ConcurrentHashMap(16); - private final ServerNode serverNode; - private volatile long lastUpdateTimestamp = System.currentTimeMillis(); - - public ConsumerInfoManager(ServerNode serverNode) { - this.serverNode=serverNode; - } - - public ClientChannelInfo findChannel(final String clientId) { - Iterator> it = this.channelInfoTable.entrySet().iterator(); - while (it.hasNext()) { - Entry next = it.next(); - if (next.getValue().getClientId().equals(clientId)) { - return next.getValue(); - } - } - - return null; - } - - public String findClientId(final Channel channel) { - Iterator> it = this.channelInfoTable.entrySet().iterator(); - while (it.hasNext()) { - Entry next = it.next(); - if (next.getKey().equals(channel)) { - ClientChannelInfo value = next.getValue(); - return value.getClientId(); - } - } - - return null; - } - - - public void scanNotActiveChannel() { - Iterator> itChannel = channelInfoTable.entrySet().iterator(); - while (itChannel.hasNext()) { - Entry nextChannel = itChannel.next(); - ClientChannelInfo clientChannelInfo = nextChannel.getValue(); - long diff = System.currentTimeMillis() - clientChannelInfo.getLastUpdateTimestamp(); - if (diff > CHANNEL_EXPIRED_TIMEOUT) { - log.warn( - "SCAN: remove expired channel from ConsumerManager consumerTable. channel={}, consumerGroup={}", - RemotingHelper.parseChannelRemoteAddr(clientChannelInfo.getChannel())); - RemotingUtil.closeChannel(clientChannelInfo.getChannel()); - itChannel.remove(); - } - } - - if (channelInfoTable.isEmpty()) { - log.warn( - "SCAN: remove expired channel from ConsumerManager consumerTable, all clear" - ); - } - } - - - public ConcurrentMap getSubscriptionTable() { - return subscriptionTable; - } - - public ConcurrentMap getChannelInfoTable() { - return channelInfoTable; - } - - public List getAllChannel() { - List result = new ArrayList<>(); - - result.addAll(this.channelInfoTable.keySet()); - - return result; - } - - public List getAllClientId() { - List result = new ArrayList<>(); - - Iterator> it = this.channelInfoTable.entrySet().iterator(); - - while (it.hasNext()) { - Entry entry = it.next(); - ClientChannelInfo clientChannelInfo = entry.getValue(); - result.add(clientChannelInfo.getClientId()); - } - - return result; - } - - public void unregisterChannel(final ClientChannelInfo clientChannelInfo) { - ClientChannelInfo old = this.channelInfoTable.remove(clientChannelInfo.getChannel()); - if (old != null) { - log.info("unregister a consumer from consumerInfo {}", old.toString()); - } - } - - public boolean doChannelCloseEvent(final String remoteAddr, final Channel channel) { - final ClientChannelInfo info = this.channelInfoTable.remove(channel); - if (info != null) { - log.warn( - "NETTY EVENT: remove not active channel[{}] fromchannelInfoTable", - info.toString()); - return true; - } - - return false; - } - - public boolean updateChannel(final ClientChannelInfo infoNew) { - boolean updated = false; - - - ClientChannelInfo infoOld = this.channelInfoTable.get(infoNew.getChannel()); - if (null == infoOld) { - ClientChannelInfo prev = this.channelInfoTable.put(infoNew.getChannel(), infoNew); - if (null == prev) { - log.info("new consumer connected, channel: {}", infoNew.toString()); - updated = true; - } - - infoOld = infoNew; - } else { - if (!infoOld.getClientId().equals(infoNew.getClientId())) { - log.error("[BUG] consumer channel exist in server, but clientId not equal.OLD: {} NEW: {} ", - infoOld.toString(), - infoNew.toString()); - this.channelInfoTable.put(infoNew.getChannel(), infoNew); - } - } - - this.lastUpdateTimestamp = System.currentTimeMillis(); - infoOld.setLastUpdateTimestamp(this.lastUpdateTimestamp); - - return updated; - } - - - public boolean registerConsumer(final ClientChannelInfo clientChannelInfo, - final Set subList) { - - boolean r1 = - updateChannel(clientChannelInfo); - boolean r2 = updateSubscription(subList); - - return r1 || r2; - } - - public boolean updateSubscription(final Set subList) { - boolean updated = false; - - for (SubscriptionData sub : subList) { - SubscriptionData old = this.subscriptionTable.get(sub.getSlotNum()); - if (old == null) { - SubscriptionData prev = this.subscriptionTable.putIfAbsent(sub.getSlotNum(), sub); - if (null == prev) { - updated = true; - log.info("subscription changed, add new topic, {}", - sub.toString()); - } - } - } - - Iterator> it = this.subscriptionTable.entrySet().iterator(); - while (it.hasNext()) { - Entry next = it.next(); - Integer oldSlot = next.getKey(); - - boolean exist = false; - for (SubscriptionData sub : subList) { - if (sub.getSlotNum().equals(oldSlot)) { - exist = true; - break; - } - } - - if (!exist) { - log.warn("subscription changed, remove slot {} {}", - oldSlot, - next.getValue().toString() - ); - - it.remove(); - updated = true; - } - } - - this.lastUpdateTimestamp = System.currentTimeMillis(); - - return updated; - } - - public Set getSubscribeTopics() { - return subscriptionTable.keySet(); - } - - public SubscriptionData findSubscriptionData(final String topic) { - return this.subscriptionTable.get(topic); - } - - public long getLastUpdateTimestamp() { - return lastUpdateTimestamp; - } - - public void setLastUpdateTimestamp(long lastUpdateTimestamp) { - this.lastUpdateTimestamp = lastUpdateTimestamp; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/client/ServerToClient.java b/pantheon-server/src/main/java/com/pantheon/server/client/ServerToClient.java deleted file mode 100644 index b8b9a01..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/client/ServerToClient.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.pantheon.server.client; - -import com.pantheon.remoting.RemotingServer; -import com.pantheon.remoting.exception.RemotingSendRequestException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.protocol.RemotingCommand; -import com.pantheon.server.ServerNode; -import io.netty.channel.Channel; - -/** - * @author Anthony - * @create 2021/12/13 - * @desc server to client communication - */ -public class ServerToClient { - private ServerNode serverNode; - private RemotingServer remotingServer; - - public ServerToClient(ServerNode serverNode) { - this.serverNode=serverNode; - } - - public RemotingCommand callClient(final Channel channel, - final RemotingCommand request - ) throws RemotingSendRequestException, RemotingTimeoutException, InterruptedException { - if(serverNode!=null&&remotingServer==null){ - remotingServer=serverNode.getRemotingServer(); - } - if(remotingServer!=null){ - return this.remotingServer.invokeSync(channel, request, 10000); - } - return null; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/config/ArchaiusPantheonServerConfig.java b/pantheon-server/src/main/java/com/pantheon/server/config/ArchaiusPantheonServerConfig.java deleted file mode 100644 index 41f1a0b..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/config/ArchaiusPantheonServerConfig.java +++ /dev/null @@ -1,338 +0,0 @@ -package com.pantheon.server.config; - -import com.pantheon.common.ObjectUtils; -import com.pantheon.server.ServerBootstrap; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc A default implementation of Pantheon Server configuration as required by {@link PantheonServerConfig}. - *

- * The information required for configuring pantheon server is provided in a - * configuration file.The configuration file is searched for in the classpath - * with the name specified by the property pantheon.server.props and with - * the suffix .properties. If the property is not specified, - * pantheon-server.properties is assumed as the default.The properties - * that are looked up uses the namespace passed on to this class. - *

- * - *

- * If the pantheon.environment property is specified, additionally - * pantheon-server-.properties is loaded in addition - * to pantheon-server.properties. - *

- *

- **/ -public class ArchaiusPantheonServerConfig implements PantheonServerConfig { - private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); - private static final String TEST = "test"; - private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - private static final DynamicPropertyFactory configInstance = com.netflix.config.DynamicPropertyFactory - .getInstance(); - private static final DynamicStringProperty PANTHEON_PROPS_FILE = DynamicPropertyFactory - .getInstance().getStringProperty("pantheon.server.props", - "pantheon-server"); - protected String namespace = "pantheon."; - - - final String CONFIG_KEY_NODE_ID = namespace + "nodeId"; - final String CONFIG_KEY_NODE_IP = namespace + "nodeIp"; - final String CONFIG_KEY_INTERN_TCP_PORT = namespace + "nodeInternTcpPort"; - final String CONFIG_KEY_NODE_CLIENT_HTTP_PORT = namespace + "nodeClientHttpPort"; - final String CONFIG_KEY_CLIENT_TCP_PORT = namespace + "nodeClientTcpPort"; - final String CONFIG_KEY_CONTROLLER_CANDIDATE = namespace + "isControllerCandidate"; - final String CONFIG_KEY_DATA_DIR = namespace + "dataDir"; - final String CONFIG_KEY_CLUSTER_NODE_COUNT = namespace + "clusterNodeCount"; - final String CONFIG_KEY_CONTROLLER_CANDIDATE_SERVERS = namespace + "controllerCandidateServers"; - final String CONFIG_KEY_HEART_CHECK_INTERVAL = namespace + "heartbeatCheckInterval"; - final String CONFIG_KEY_HEART_TIMEOUT_PERIOD = namespace + "heartbeatTimeoutPeriod"; - - - public static final Integer DEFAULT_HEARTBEAT_CHECK_INTERVAL = 3; - public static final Integer DEFAULT_HEARTBEAT_TIMEOUT_PERIOD = 5; - - - - public ArchaiusPantheonServerConfig() { - initConfig(); - validateConfig(); - } - - public ArchaiusPantheonServerConfig(String namespace) { - this.namespace = namespace; - initConfig(); - validateConfig(); - } - - private void initConfig() { - String env = ConfigurationManager.getConfigInstance().getString( - PANTHEON_ENVIRONMENT, TEST); - ConfigurationManager.getConfigInstance().setProperty( - ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env); - String propsFile = PANTHEON_PROPS_FILE.get(); - try { - //load PANTHEON_PROPS_FILE after application.properties - ConfigurationManager - .loadCascadedPropertiesFromResources(propsFile); - } catch (IOException e) { - logger.warn( - "Cannot find the properties specified : {}. This may be okay if there are other environment " - + "specific properties or the configuration is installed with a different mechanism.", - propsFile); - } - } - - public void validateConfig() { - validateNodeId(getNodeId()); - validateNodeIp(getNodeIp()); - validateNodeInternTcpPort(getNodeInternTcpPort()); - validateNodeClientHttpPort(getNodeClientHttpPort()); - validateNodeClientTcpPort(getNodeClientTcpPort()); - validateIsControllerCandidate(isControllerCandidate()); - validateClusterNodeCount(getClusterNodeCount()); - validateDataDir(getDataDir()); - validateControllerCandidateServers(getControllerCandidateServers()); - } - - /** - * 校验节点id参数 - * - * @param nodeId - * @return - */ - private boolean validateNodeId(Integer nodeId) { - if (ObjectUtils.isEmpty(nodeId)) { - throw new IllegalArgumentException("node.id cannot be empty!!!"); - } - return true; - } - - - /** - * validate ip address - * - * @param nodeIp - * @return - * @throws IllegalArgumentException - */ - private Boolean validateNodeIp(String nodeIp) throws IllegalArgumentException { - if (StringUtils.isEmpty(nodeIp)) { - throw new IllegalArgumentException("node.ip cannot be empty!!!"); - } - - final String regex = "(\\d+\\.\\d+\\.\\d+\\.\\d+)"; - Boolean isMatch = Pattern.matches(regex, nodeIp); - if (!isMatch) { - throw new IllegalArgumentException("node.ip format is incorrect!!!"); - } - - return true; - } - - /** - * validate the tcp port to communicate with intern - * - * @return - */ - private boolean validateNodeInternTcpPort(Integer nodeInternTcpPort) { - if (ObjectUtils.isEmpty(nodeInternTcpPort)) { - throw new IllegalArgumentException("node.intern.tcp.port cannot be empty!!!"); - } - - return true; - } - - /** - * validate the port to communicate with client - * - * @return - */ - private boolean validateNodeClientHttpPort(Integer nodeClientHttpPort) { - if (ObjectUtils.isEmpty(nodeClientHttpPort)) { - throw new IllegalArgumentException("node.client.http.port cannot be empty!!!"); - } - - return true; - } - - /** - * validate the tcp port to communicate with client - * - * @return - */ - private boolean validateNodeClientTcpPort(Integer nodeClientTcpPort) { - if (ObjectUtils.isEmpty(nodeClientTcpPort)) { - throw new IllegalArgumentException("node.client.tcp.port cannot be empty!!!"); - } - - return true; - } - - /** - * whether controller candidate - * - * @param isControllerCandidate - * @return - */ - private boolean validateIsControllerCandidate(Boolean isControllerCandidate) { - if (ObjectUtils.isEmpty(isControllerCandidate)) { - throw new IllegalArgumentException("is.controller.candidate cannot be empty !!!"); - } - return true; - } - - - /** - * validate the cluster node count, for controller node,cluster node count cannot be empty - * - * @param clusterNodesCount - * @return - */ - private boolean validateClusterNodeCount(Integer clusterNodesCount) { - if (isControllerCandidate() && ObjectUtils.isEmpty(clusterNodesCount)) { - throw new IllegalArgumentException("for controller node,clusterNodeCount cannot be empty!!!"); - } - - return true; - } - - /** - * validate data directory for saving - * - * @param dataDir - * @return - */ - private Boolean validateDataDir(String dataDir) { - if (StringUtils.isEmpty(dataDir)) { - throw new IllegalArgumentException("data.dir cannot be empty......"); - } - return true; - } - - - private Boolean validateControllerCandidateServers(String controllerCandidateServers) throws IllegalArgumentException { - if (StringUtils.isEmpty(controllerCandidateServers)) { - throw new IllegalArgumentException("controller.candidate.servers cannot be empty!!!"); - } - - String[] controllerCandidateServersSplited = controllerCandidateServers.split(","); - - final String regex = "(\\d+\\.\\d+\\.\\d+\\.\\d+):(\\d+)"; - - for (String controllerCandidateServer : controllerCandidateServersSplited) { - Boolean isMatch = Pattern.matches(regex, controllerCandidateServer); - if (!isMatch) { - throw new IllegalArgumentException("controller.candidate.servers format is incorrect!!!"); - } - } - - return true; - } - - @Override - public String getDataDir() { - String dataDir = configInstance.getStringProperty(CONFIG_KEY_DATA_DIR, "/").get(); - if (null != dataDir) { - return dataDir.trim(); - } else { - return null; - } - } - - - @Override - public Integer getNodeId() { - return configInstance.getIntProperty( - CONFIG_KEY_NODE_ID, 0).get(); - } - - @Override - public Integer getHeartBeatCheckInterval() { - return configInstance.getIntProperty( - CONFIG_KEY_HEART_CHECK_INTERVAL, DEFAULT_HEARTBEAT_CHECK_INTERVAL).get(); - } - - public Integer getHeartbeatTimeoutPeriod() { - return configInstance.getIntProperty( - CONFIG_KEY_HEART_TIMEOUT_PERIOD, DEFAULT_HEARTBEAT_TIMEOUT_PERIOD).get(); - } - - - @Override - public String getNodeIp() { - String nodeIp = configInstance.getStringProperty(CONFIG_KEY_NODE_IP, null).get(); - if (null != nodeIp) { - return nodeIp.trim(); - } else { - return null; - } - } - - @Override - public Integer getNodeInternTcpPort() { - return configInstance.getIntProperty( - CONFIG_KEY_INTERN_TCP_PORT, 0).get(); - } - - @Override - public Integer getNodeClientTcpPort() { - return configInstance.getIntProperty( - CONFIG_KEY_CLIENT_TCP_PORT, 0).get(); - } - - @Override - public Boolean isControllerCandidate() { - return configInstance.getBooleanProperty(CONFIG_KEY_CONTROLLER_CANDIDATE, false).get(); - } - - @Override - public Integer getClusterNodeCount() { - return configInstance.getIntProperty( - CONFIG_KEY_CLUSTER_NODE_COUNT, 0).get(); - } - - @Override - public Integer getNodeClientHttpPort() { - return configInstance.getIntProperty( - CONFIG_KEY_NODE_CLIENT_HTTP_PORT, 0).get(); - } - - @Override - public String getControllerCandidateServers() { - return configInstance.getStringProperty(CONFIG_KEY_CONTROLLER_CANDIDATE_SERVERS, null).get(); - } - - @Override - public long getResponseCacheAutoExpirationInSeconds() { - return 180; - } - - @Override - public long getResponseCacheUpdateIntervalMs() { - return 30; - } - - @Override - public long getRetentionTimeInMSInDeltaQueue() { - return 180; - } - - @Override - public long getDeltaRetentionTimerIntervalInMs() { - return 30; - } -} - - diff --git a/pantheon-server/src/main/java/com/pantheon/server/config/CachedPantheonServerConfig.java b/pantheon-server/src/main/java/com/pantheon/server/config/CachedPantheonServerConfig.java deleted file mode 100644 index 40d486c..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/config/CachedPantheonServerConfig.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.pantheon.server.config; - -import com.pantheon.common.ObjectUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Anthony - * @create 2021/11/20 - * @desc - */ -public class CachedPantheonServerConfig extends ArchaiusPantheonServerConfig { - - private String dataDir; - private Boolean isControllerCandidate; - private Integer nodeId; - private String nodeIp; - private Integer nodeInternTcpPort; - private Integer nodeClientHttpPort; - private Integer clusterNodeCount; - private Integer heartBeatCheckInterval; - private Integer nodeClientTcpPort; - private String controllerCandidateServers; - - private static class Singleton { - static CachedPantheonServerConfig instance = new CachedPantheonServerConfig(); - } - - public static CachedPantheonServerConfig getInstance() { - return CachedPantheonServerConfig.Singleton.instance; - } - - private CachedPantheonServerConfig() { - super(); - } - - - @Override - public String getDataDir() { - if (ObjectUtils.isEmpty(dataDir)) { - dataDir = super.getDataDir(); - } - return dataDir; - } - - @Override - public Boolean isControllerCandidate() { - if (ObjectUtils.isEmpty(isControllerCandidate)) { - isControllerCandidate = super.isControllerCandidate(); - } - return isControllerCandidate; - } - - @Override - public Integer getNodeId() { - if (ObjectUtils.isEmpty(nodeId)) { - nodeId = super.getNodeId(); - } - return nodeId; - } - - @Override - public String getNodeIp() { - if (ObjectUtils.isEmpty(nodeIp)) { - nodeIp = super.getNodeIp(); - } - return nodeIp; - } - - @Override - public Integer getNodeInternTcpPort() { - if (ObjectUtils.isEmpty(nodeInternTcpPort)) { - nodeInternTcpPort = super.getNodeInternTcpPort(); - } - return nodeInternTcpPort; - } - - @Override - public Integer getNodeClientHttpPort() { - if (ObjectUtils.isEmpty(nodeClientHttpPort)) { - nodeClientHttpPort = super.getNodeClientHttpPort(); - } - return nodeClientHttpPort; - } - - @Override - public Integer getNodeClientTcpPort() { - if (ObjectUtils.isEmpty(nodeClientTcpPort)) { - nodeClientTcpPort = super.getNodeClientTcpPort(); - } - return nodeClientTcpPort; - } - - @Override - public Integer getClusterNodeCount() { - if (ObjectUtils.isEmpty(clusterNodeCount)) { - clusterNodeCount = super.getClusterNodeCount(); - } - return clusterNodeCount; - } - - @Override - public String getControllerCandidateServers() { - if (ObjectUtils.isEmpty(controllerCandidateServers)) { - controllerCandidateServers = super.getControllerCandidateServers(); - } - return controllerCandidateServers; - } - - @Override - public Integer getHeartBeatCheckInterval() { - if (ObjectUtils.isEmpty(heartBeatCheckInterval)) { - heartBeatCheckInterval = super.getHeartBeatCheckInterval(); - } - return heartBeatCheckInterval; - } - - /** - * get 'before candidates' avoid of nodes' duplicate connection - * - * @return - */ - public List getBeforeControllerCandidateServers() { - List beforeControllerCandidateServers = new ArrayList(); - - - String nodeIp = getNodeIp(); - Integer nodeInternTcpPort = getNodeInternTcpPort(); - - String controllerCandidateServers = getControllerCandidateServers(); - String[] controllerCandidateServersSplited = controllerCandidateServers.split(","); - - for (String controllerCandidateServer : controllerCandidateServersSplited) { - String[] controllerCandidateServerSplited = controllerCandidateServer.split(":"); - String controllerCandidateIp = controllerCandidateServerSplited[0]; - Integer controllerCandidateInternTcpPort = Integer.valueOf(controllerCandidateServerSplited[1]); - - if (!controllerCandidateIp.equals(nodeIp) || - !controllerCandidateInternTcpPort.equals(nodeInternTcpPort)) { - beforeControllerCandidateServers.add(controllerCandidateServer); - } else if (controllerCandidateIp.equals(nodeIp) && - controllerCandidateInternTcpPort.equals(nodeInternTcpPort)) { - break; - } - } - - return beforeControllerCandidateServers; - } - - public List getOtherControllerCandidateServers() { - List otherControllerCandidateServers = new ArrayList(); - - String nodeIp = getNodeIp(); - Integer nodeInternTcpPort = getNodeInternTcpPort(); - - String controllerCandidateServers = getControllerCandidateServers(); - String[] controllerCandidateServersSplited = controllerCandidateServers.split(","); - - for (String controllerCandidateServer : controllerCandidateServersSplited) { - String[] controllerCandidateServerSplited = controllerCandidateServer.split(":"); - String controllerCandidateIp = controllerCandidateServerSplited[0]; - Integer controllerCandidateInternTcpPort = Integer.valueOf(controllerCandidateServerSplited[1]); - - if (!controllerCandidateIp.equals(nodeIp) || - !controllerCandidateInternTcpPort.equals(nodeInternTcpPort)) { - otherControllerCandidateServers.add(controllerCandidateServer); - } - } - - return otherControllerCandidateServers; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/config/PantheonServerConfig.java b/pantheon-server/src/main/java/com/pantheon/server/config/PantheonServerConfig.java deleted file mode 100644 index bce154d..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/config/PantheonServerConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.pantheon.server.config; - -/** - * @author Anthony - * @create 2021/11/17 - * @desc Configuration information required by the Pantheon Server to operate. - **/ -public interface PantheonServerConfig { - String getDataDir(); - - Boolean isControllerCandidate(); - - Integer getNodeId(); - - String getNodeIp(); - - Integer getNodeInternTcpPort(); - - Integer getNodeClientHttpPort(); - - Integer getNodeClientTcpPort(); - - Integer getClusterNodeCount(); - - String getControllerCandidateServers(); - - Integer getHeartBeatCheckInterval(); - - long getResponseCacheAutoExpirationInSeconds(); - - long getResponseCacheUpdateIntervalMs(); - - long getRetentionTimeInMSInDeltaQueue(); - - long getDeltaRetentionTimerIntervalInMs(); -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/lease/Lease.java b/pantheon-server/src/main/java/com/pantheon/server/lease/Lease.java deleted file mode 100644 index cbbd6f1..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/lease/Lease.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.pantheon.server.lease; - - -import com.pantheon.client.appinfo.InstanceInfo; - -/** - * Describes a time-based availability of a {@link T}. - * - * If a lease elapses without renewals, it will eventually expire consequently - * marking the associated {@link T} for immediate eviction - this is similar to - * an explicit cancellation except that there is no communication between the - * {@link T} and {@link LeaseManager}. - * - * @author Karthik Ranganathan, Greg Kim - */ -public class Lease { - - enum Action { - Register, Cancel, Renew - }; - - public static final int DEFAULT_DURATION_IN_SECS = 90; - - private T holder; - private long evictionTimestamp; - private long registrationTimestamp; - private long serviceUpTimestamp; - // Make it volatile so that the expiration task would see this quicker - private volatile long lastUpdateTimestamp; - private long duration; - - public Lease(T r, int durationInSecs) { - holder = r; - registrationTimestamp = System.currentTimeMillis(); - lastUpdateTimestamp = registrationTimestamp; - duration = (durationInSecs * 1000); - - } - - /** - * Renew the lease, use renewal duration if it was specified by the - * associated {@link T} during registration, otherwise default duration is - * {@link #DEFAULT_DURATION_IN_SECS}. - */ - public void renew() { - lastUpdateTimestamp = System.currentTimeMillis() + duration; - - } - - /** - * Cancels the lease by updating the eviction time. - */ - public void cancel() { - if (evictionTimestamp <= 0) { - evictionTimestamp = System.currentTimeMillis(); - } - } - - /** - * Mark the service as up. This will only take affect the first time called, - * subsequent calls will be ignored. - */ - public void serviceUp() { - if (serviceUpTimestamp == 0) { - serviceUpTimestamp = System.currentTimeMillis(); - } - } - - /** - * Set the leases service UP timestamp. - */ - public void setServiceUpTimestamp(long serviceUpTimestamp) { - this.serviceUpTimestamp = serviceUpTimestamp; - } - - /** - * Checks if the lease of a given {@link InstanceInfo} has expired or not. - */ - public boolean isExpired() { - return isExpired(0l); - } - - /** - * Checks if the lease of a given {@link InstanceInfo} has expired or not. - * - * Note that due to renew() doing the 'wrong" thing and setting lastUpdateTimestamp to +duration more than - * what it should be, the expiry will actually be 2 * duration. This is a minor bug and should only affect - * instances that ungracefully shutdown. Due to possible wide ranging impact to existing usage, this will - * not be fixed. - * - * @param additionalLeaseMs any additional lease time to add to the lease evaluation in ms. - */ - public boolean isExpired(long additionalLeaseMs) { - return (evictionTimestamp > 0 || System.currentTimeMillis() > (lastUpdateTimestamp + duration + additionalLeaseMs)); - } - - /** - * Gets the milliseconds since epoch when the lease was registered. - * - * @return the milliseconds since epoch when the lease was registered. - */ - public long getRegistrationTimestamp() { - return registrationTimestamp; - } - - /** - * Gets the milliseconds since epoch when the lease was last renewed. - * Note that the value returned here is actually not the last lease renewal time but the renewal + duration. - * - * @return the milliseconds since epoch when the lease was last renewed. - */ - public long getLastRenewalTimestamp() { - return lastUpdateTimestamp; - } - - /** - * Gets the milliseconds since epoch when the lease was evicted. - * - * @return the milliseconds since epoch when the lease was evicted. - */ - public long getEvictionTimestamp() { - return evictionTimestamp; - } - - /** - * Gets the milliseconds since epoch when the service for the lease was marked as up. - * - * @return the milliseconds since epoch when the service for the lease was marked as up. - */ - public long getServiceUpTimestamp() { - return serviceUpTimestamp; - } - - /** - * Returns the holder of the lease. - */ - public T getHolder() { - return holder; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/lease/LeaseManager.java b/pantheon-server/src/main/java/com/pantheon/server/lease/LeaseManager.java deleted file mode 100644 index d710531..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/lease/LeaseManager.java +++ /dev/null @@ -1,54 +0,0 @@ - -package com.pantheon.server.lease; - - -/** - * This class is responsible for creating/renewing and evicting a lease - * for a particular instance. - * - *

- * Leases determine what instances receive traffic. When there is no renewal - * request from the client, the lease gets expired and the instances are evicted - * out of {@link com.pantheon.server.registry.InstanceRegistry}. This is key to instances receiving traffic - * or not. - *

- */ -public interface LeaseManager { - - /** - * Assign a new {@link Lease} to the passed in {@link T}. - * - * @param r - * - T to register - * @param leaseDuration - * - whether this is a replicated entry from another pantheon node. - */ - void register(T r, int leaseDuration); - - /** - * Cancel the {@link Lease} associated with the passed in appName - * and id. - * - * @param appName - * - unique id of the application. - * @param id - * - unique id within appName. - * @return true, if the operation was successful, false otherwise. - */ - boolean cancel(String appName, String id); - - /** - * Renew the {@link Lease} associated with the passed in appName - * and id. - * - * @param id - unique id within appName - * - whether this is a replicated entry from another ds node - * @return whether the operation of successful - */ - boolean renew(String appName, String id); - - /** - * Evict {@link T}s with expired {@link Lease}(s). - */ - void evict(); -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/network/IOThreadRunningSignal.java b/pantheon-server/src/main/java/com/pantheon/server/network/IOThreadRunningSignal.java deleted file mode 100644 index 9472d4f..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/network/IOThreadRunningSignal.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.pantheon.server.network; - -/** - * io thread running signal - */ -public class IOThreadRunningSignal { - - private volatile Boolean isRunning; - - public IOThreadRunningSignal(Boolean isRunning) { - this.isRunning = isRunning; - } - - public Boolean isRunning() { - return isRunning; - } - - public void setIsRunning(Boolean isRunning) { - this.isRunning = isRunning; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/network/ServerMessageReceiver.java b/pantheon-server/src/main/java/com/pantheon/server/network/ServerMessageReceiver.java deleted file mode 100644 index 9c9053a..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/network/ServerMessageReceiver.java +++ /dev/null @@ -1,307 +0,0 @@ -package com.pantheon.server.network; - -import com.alibaba.fastjson.JSONObject; -import com.pantheon.common.MessageType; -import com.pantheon.common.lifecycle.Lifecycle; -import com.pantheon.common.entity.Request; -import com.pantheon.server.ServerNode; -import com.pantheon.server.node.Controller; -import com.pantheon.server.node.ControllerVote; -import com.pantheon.server.slot.SlotManager; -import com.pantheon.server.slot.registry.ServiceInstance; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingQueue; - - -public class ServerMessageReceiver extends Thread { - - static final Logger LOGGER = LoggerFactory.getLogger(ServerMessageReceiver.class); - - - private ServerMessageReceiver() { - - } - - static class Singleton { - static ServerMessageReceiver instance = new ServerMessageReceiver(); - } - - public static ServerMessageReceiver getInstance() { - return Singleton.instance; - } - - private LinkedBlockingQueue voteReceiveQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue>> slotsAllocationReceiveQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue>> slotsReplicaAllocationReceiveQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue> replicaNodeIdsQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue> nodeSlotsQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue> nodeSlotsReplicasQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue replicaNodeIdQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue controllerNodeIdQueue = - new LinkedBlockingQueue<>(); - private LinkedBlockingQueue replicaRequestQueue = - new LinkedBlockingQueue<>(); - - - @Override - public void run() { - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - ServerNode serverNode = ServerNode.getInstance(); - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED)||serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) { - try { - ByteBuffer message = serverNetworkManager.takeMessage(); - int messageType = message.getInt(); - - if (messageType == MessageType.VOTE) { - ControllerVote vote = new ControllerVote(message); - voteReceiveQueue.put(vote); - LOGGER.info("receive controller vote: " + vote); - } else if (messageType == MessageType.SLOTS_ALLOCATION) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - String slotsAllocationJSON = new String(bytes); - ConcurrentHashMap> slotsAllocation = JSONObject.parseObject( - slotsAllocationJSON, ConcurrentHashMap.class); - slotsAllocationReceiveQueue.put(slotsAllocation); - - LOGGER.info("receive slots allocation : " + slotsAllocation); - } else if (messageType == MessageType.NODE_SLOTS) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - String slotsListJSON = new String(bytes); - List slotsList = JSONObject.parseObject(slotsListJSON, ArrayList.class); - nodeSlotsQueue.put(slotsList); - - LOGGER.info("receive slots scope: " + slotsList); - } else if (messageType == MessageType.UPDATE_NODE_SLOTS) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - String slotsListJSON = new String(bytes); - List slotsList = JSONObject.parseObject(slotsListJSON, ArrayList.class); - - SlotManager slotManager = SlotManager.getInstance(); - slotManager.initSlots(slotsList); - } else if (messageType == MessageType.SLOTS_REPLICA_ALLOCATION) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - String slotsReplicaAllocationJson = new String(bytes); - ConcurrentHashMap> slotsReplicaAllocation = JSONObject.parseObject( - slotsReplicaAllocationJson, ConcurrentHashMap.class); - slotsReplicaAllocationReceiveQueue.put(slotsReplicaAllocation); - - LOGGER.info("receive slots replica allocation : " + slotsReplicaAllocation); - } else if (messageType == MessageType.NODE_SLOTS_REPLICAS) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - List slotsReplicas = JSONObject.parseObject(new String(bytes), List.class); - nodeSlotsReplicasQueue.put(slotsReplicas); - - LOGGER.info("receive current node's slots replica: " + slotsReplicas); - } else if (messageType == MessageType.REPLICA_NODE_ID) { - Integer replicaNodeId = message.getInt(); - replicaNodeIdQueue.put(replicaNodeId); - LOGGER.info("receive replica node id: " + replicaNodeId); - } else if (messageType == MessageType.REFRESH_REPLICA_NODE_ID) { - Integer newReplicaNodeId = message.getInt(); - SlotManager slotManager = SlotManager.getInstance(); - slotManager.refreshReplicaNodeId(newReplicaNodeId); - } else if (messageType == MessageType.REPLICA_REGISTER) { - //todo replica register info - Integer messageFlag = message.getInt(); - Integer messageBodyLength = message.getInt(); - Integer requestType = message.getInt(); - -// RegisterRequest registerRequest = -// RegisterRequest.deserialize(message); -// -// replicaRequestQueue.put(registerRequest); -// -// LOGGER.info("receive register request to replica: " + registerRequest); - } else if (messageType == MessageType.REPLICA_HEARTBEAT) { - //todo replica heartbeat request -// Integer messageFlag = message.getInt(); -// Integer messageBodyLength = message.getInt(); -// Integer requestType = message.getInt(); - -// HeartbeatRequest heartbeatRequest = -// HeartbeatRequest.deserialize(message); -// -// replicaRequestQueue.put(heartbeatRequest); - -// LOGGER.info("receive heartbeat request to replica: " + heartbeatRequest); - } else if (messageType == MessageType.REPLICA_NODE_IDS) { - int remaining = message.remaining(); - byte[] bytes = new byte[remaining]; - message.get(bytes); - - ConcurrentHashMap replicaNodeIds = JSONObject.parseObject( - new String(bytes), ConcurrentHashMap.class); - replicaNodeIdsQueue.put(replicaNodeIds); - - LOGGER.info("receive replica node ids: " + replicaNodeIds); - } else if (messageType == MessageType.CONTROLLER_NODE_ID) { - Integer controllerNodeId = message.getInt(); - controllerNodeIdQueue.put(controllerNodeId); - LOGGER.info("receive controller node id: " + controllerNodeId); - } else if (messageType == MessageType.CHANGE_REPLICA_TO_SLOTS) { - //todo build mechanism of change replica to slots -// int remaining = message.remaining(); -// byte[] bytes = new byte[remaining]; -// message.get(bytes); -// -// List slots = JSONObject.parseObject(new String(bytes), ArrayList.class); -// SlotManager slotManager = SlotManager.getInstance(); -// slotManager.changeReplicaToSlots(slots); - } else if (messageType == MessageType.REFRESH_REPLICA_SLOTS) { - //todo refresh replica slots -// int remaining = message.remaining(); -// byte[] bytes = new byte[remaining]; -// message.get(bytes); -// -// List replicaSlots = JSONObject.parseObject(new String(bytes), ArrayList.class); -// SlotManager slotManager = SlotManager.getInstance(); -// slotManager.refreshReplicaSlots(replicaSlots); - } else if (messageType == MessageType.REQUEST_SLOTS_DATA) { - // take all of metadata from controller and sync to this node - Integer candidateNodeId = message.getInt(); - Controller controller = Controller.getInstance(); - controller.syncSlotsAllocation(candidateNodeId); - controller.syncSlotsReplicaAllocation(candidateNodeId); - controller.syncReplicaNodeIds(candidateNodeId); - } else if (messageType == MessageType.TRANSFER_SLOTS) { - //todo transfer slots when fail - Integer targetNodeId = message.getInt(); - - Integer bytesLength = message.getInt(); - byte[] bytes = new byte[bytesLength]; - message.get(bytes); - String slots = new String(bytes); - - SlotManager slotManager = SlotManager.getInstance(); - slotManager.transferSlots(targetNodeId, slots); - } else if (messageType == MessageType.UPDATE_SLOTS) { - //todo update slots when others make a transfer -// Integer slotNo = message.getInt(); -// -// int remaining = message.remaining(); -// byte[] bytes = new byte[remaining]; -// message.get(bytes); -// List serviceInstances = JSONObject.parseObject( -// new String(bytes), ArrayList.class); -// -// SlotManager slotManager = SlotManager.getInstance(); -// slotManager.updateSlotData(slotNo, serviceInstances); - } - } catch (Exception e) { - LOGGER.error("receive message error......", e); - } - } - } - - - public ControllerVote takeVote() { - try { - return voteReceiveQueue.take(); - } catch (Exception e) { - LOGGER.error("take vote message error......", e); - return null; - } - } - - - public ConcurrentHashMap> takeSlotsAllocation() { - try { - return slotsAllocationReceiveQueue.take(); - } catch (Exception e) { - LOGGER.error("take slots allocation message error......", e); - return null; - } - } - - public ConcurrentHashMap> takeSlotsReplicaAllocation() { - try { - return slotsReplicaAllocationReceiveQueue.take(); - } catch (Exception e) { - LOGGER.error("take slots allocation message error......", e); - return null; - } - } - - public List takeNodeSlots() { - try { - return nodeSlotsQueue.take(); - } catch (Exception e) { - LOGGER.error("take node slots message error......", e); - return null; - } - } - - public List takeNodeSlotsReplicas() { - try { - return nodeSlotsReplicasQueue.take(); - } catch (Exception e) { - LOGGER.error("take node slots message error......", e); - return null; - } - } - - public Integer takeReplicaNodeId() { - try { - return replicaNodeIdQueue.take(); - } catch (Exception e) { - LOGGER.error("take node slots message error......", e); - return null; - } - } - - public Request takeReplicaRequest() { - try { - return replicaRequestQueue.take(); - } catch (Exception e) { - LOGGER.error("get replica request failed!!!", e); - return null; - } - } - - public ConcurrentHashMap takeReplicaNodeIds() { - try { - return replicaNodeIdsQueue.take(); - } catch (Exception e) { - LOGGER.error("get replica node id failed!!!", e); - return null; - } - } - - public Integer takeControllerNodeId() { - try { - return controllerNodeIdQueue.take(); - } catch (Exception e) { - LOGGER.error("get controller node id failed!!!", e); - return null; - } - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/network/ServerNetworkManager.java b/pantheon-server/src/main/java/com/pantheon/server/network/ServerNetworkManager.java deleted file mode 100644 index 5548240..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/network/ServerNetworkManager.java +++ /dev/null @@ -1,564 +0,0 @@ -package com.pantheon.server.network; - -import com.pantheon.common.MessageType; -import com.pantheon.common.ThreadFactoryImpl; -import com.pantheon.common.lifecycle.Lifecycle; -import com.pantheon.server.ServerNode; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.node.RemoteServerNode; -import com.pantheon.server.node.RemoteServerNodeManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -/** - * 集群内部的master节点之间进行网络通信的管理组件 - *

- * 1、跟其他的master节点建立网络连接,避免出现重复的连接 - * 2、在底层基于队列和线程,帮助我们发送请求给其他的机器节点 - * 3、同上,需要接受其他节点发送过来的请求,交给我们来进行业务逻辑上的处理 - */ -public class ServerNetworkManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServerNetworkManager.class); - - /** - * default retry connect times - */ - private static final int DEFAULT_CONNECT_RETRIES = 3; - /** - * default connect timeout - */ - private static final int CONNECT_TIMEOUT = 5000; - /** - * interval for retrying connect with master - */ - private static final long RETRY_CONNECT_MASTER_NODE_INTERVAL = 1 * 60 * 1000; - /** - * interval for checking all other nodes connection - */ - private static final long CHECK_ALL_OTHER_NODES_CONNECT_INTERVAL = 10 * 1000; - /** - * interval for waiting all other master nodes connection - */ - private static final Long ALL_MASTER_NODE_CONNECT_CHECK_INTERVAL = 100L; - - private ServerNetworkManager() { - ScheduledThreadPoolExecutor scheduledExecutorService = new ScheduledThreadPoolExecutor(2, - new ThreadFactoryImpl("RetryConnectMasterNodeThread") - ); - scheduledExecutorService.scheduleAtFixedRate(new RetryConnectMasterNodeThread(), 10, RETRY_CONNECT_MASTER_NODE_INTERVAL, TimeUnit.MILLISECONDS); - } - - static class Singleton { - static ServerNetworkManager instance = new ServerNetworkManager(); - } - - public static ServerNetworkManager getInstance() { - return Singleton.instance; - } - - /** - * nodes waiting for retrying - */ - private CopyOnWriteArrayList retryConnectMasterNodes = - new CopyOnWriteArrayList(); - /** - * connection with other master nodes - */ - private ConcurrentHashMap remoteNodeSockets = - new ConcurrentHashMap(); - /** - * read & write thread is running or not - */ - private ConcurrentHashMap ioThreadRunningSignals = - new ConcurrentHashMap<>(); - /** - * send messages queue - */ - private ConcurrentHashMap> sendQueues = - new ConcurrentHashMap>(); - /** - * receive messages queue - */ - private LinkedBlockingQueue receiveQueue = - new LinkedBlockingQueue(); - - /** - * connect server listener - */ - public void startServerConnectionListener() { - new ServerConnectionListener().start(); - } - - /** - * connect to all controller candidate servers - * - * @return - */ - public Boolean connectAllControllerCandidates() { - String controllerCandidateServers = CachedPantheonServerConfig.getInstance().getControllerCandidateServers(); - String[] controllerCandidateServersSplited = controllerCandidateServers.split(","); - - for (String controllerCandidateServer : controllerCandidateServersSplited) { - if (!connectServerNode(controllerCandidateServer)) { - continue; - } - } - - return true; - } - - /** - * connect before candidates avoid of nodes' duplicate connection - * - * @return - */ - public Boolean connectBeforeControllerCandidateServers() { - - List beforeControllerCandidateServers = - CachedPantheonServerConfig.getInstance().getBeforeControllerCandidateServers(); - if (beforeControllerCandidateServers.size() == 0) { - return true; - } - - for (String beforeControllerCandidateServer : beforeControllerCandidateServers) { - if (!connectServerNode(beforeControllerCandidateServer)) { - continue; - } - } - - return true; - } - - /** - * connect server node - * - * @param serverNodeStr - * @return - */ - public Boolean connectServerNode(String serverNodeStr) { - boolean fatal = false; - - String[] serverNodeSplited = serverNodeStr.split(":"); - String ip = serverNodeSplited[0]; - int port = Integer.valueOf(serverNodeSplited[1]); - - InetSocketAddress endpoint = new InetSocketAddress(ip, port); - - int retries = 0; - ServerNode serverNode = ServerNode.getInstance(); - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) && - retries <= DEFAULT_CONNECT_RETRIES) { - try { - Socket socket = new Socket(); - socket.setTcpNoDelay(true); - socket.setSoTimeout(0); - socket.connect(endpoint, CONNECT_TIMEOUT); - - if (!sendSelfInformation(socket)) { - fatal = true; - break; - } - RemoteServerNode remoteServerNode = readRemoteNodeInformation(socket); - if (remoteServerNode == null) { - fatal = true; - break; - } - - startServerIOThreads(remoteServerNode.getNodeId(), socket); - this.remoteNodeSockets.put(remoteServerNode.getNodeId(), socket); - RemoteServerNodeManager.getInstance().addRemoteServerNode(remoteServerNode); - - LOGGER.info("complete the connection with server node:" + remoteServerNode + "......"); - - if (ServerNode.isController()) { -// AutoRebalanceManager autoRebalanceManager = AutoRebalanceManager.getInstance(); -// autoRebalanceManager.rebalance(remoteServerNode.getNodeId()); - } - - return true; - } catch (IOException e) { - LOGGER.error("exception when connecting with (" + endpoint + ") !!!"); - e.printStackTrace(); - retries++; - if (retries <= DEFAULT_CONNECT_RETRIES) { - LOGGER.error("round :" + retries + " retry connect with server node: (" + endpoint + ")......"); - } - } - } - - // fatal error - if (fatal) { - serverNode.stop(); - return false; - } - - // add to retry connect master list - if (!retryConnectMasterNodes.contains(serverNodeStr)) { - retryConnectMasterNodes.add(serverNodeStr); - LOGGER.error("connect to server node (" + serverNodeStr + ") fail, add to retry connect master list......"); - } - - return false; - } - - - public boolean sendSelfInformation(Socket socket) { - - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - Boolean isControllerCandidate = CachedPantheonServerConfig.getInstance().isControllerCandidate(); - String ip = CachedPantheonServerConfig.getInstance().getNodeIp(); - Integer clientTcpPort = CachedPantheonServerConfig.getInstance().getNodeClientTcpPort(); - - DataOutputStream outputStream = null; - try { - outputStream = new DataOutputStream(socket.getOutputStream()); - outputStream.writeInt(nodeId); - outputStream.writeBoolean(isControllerCandidate); - outputStream.writeInt(ip.length()); - outputStream.write(ip.getBytes()); - outputStream.writeInt(clientTcpPort); - outputStream.writeBoolean(ServerNode.isController()); - outputStream.flush(); - } catch (IOException e) { - LOGGER.error("exception occurs when connect with server node!!!", e); - - try { - socket.close(); - } catch (IOException ex) { - LOGGER.error("close socket with exception!!!", ex); - } - - return false; - } - - return true; - } - - /** - * blocking read information from other nodes - * - * @param socket - * @return - */ - public RemoteServerNode readRemoteNodeInformation(Socket socket) { - try { - DataInputStream inputStream = new DataInputStream(socket.getInputStream()); - - Integer remoteNodeId = inputStream.readInt(); - Boolean isControllerCandidate = inputStream.readBoolean(); - - Integer ipLength = inputStream.readInt(); - byte[] ipBytes = new byte[ipLength]; - inputStream.read(ipBytes); - String ip = new String(ipBytes); - - Integer clientPort = inputStream.readInt(); - boolean isController = inputStream.readBoolean(); - - RemoteServerNode remoteServerNode = new RemoteServerNode( - remoteNodeId, - isControllerCandidate, - ip, - clientPort, - isController - ); - - return remoteServerNode; - } catch (IOException e) { - LOGGER.error("read information from other server node exception!!!", e); - - try { - socket.close(); - } catch (IOException ex) { - LOGGER.error("Socket close exception!!!", ex); - } - } - return null; - } - - /** - * background write and read thread after connecting - * - * @param socket - */ - public void startServerIOThreads(Integer remoteNodeId, Socket socket) { - // init send message queue - LinkedBlockingQueue sendQueue = - new LinkedBlockingQueue(); - sendQueues.put(remoteNodeId, sendQueue); - - IOThreadRunningSignal ioThreadRunningSignal = new IOThreadRunningSignal(true); - ioThreadRunningSignals.put(remoteNodeId, ioThreadRunningSignal); - - new ServerWriteIOThread(remoteNodeId, socket, sendQueue, ioThreadRunningSignal).start(); - new ServerReadIOThread(remoteNodeId, socket, receiveQueue, this, ioThreadRunningSignal).start(); - } - - public void shutdownIOThread(Integer remoteNodeId) { - ioThreadRunningSignals.get(remoteNodeId).setIsRunning(false); - ioThreadRunningSignals.remove(remoteNodeId); - sendQueues.remove(remoteNodeId); - } - - - public void remoteRemoteNodeSocket(Integer remoteNodeId) { - remoteNodeSockets.remove(remoteNodeId); - } - - - /** - * when {@link CachedPantheonServerConfig#getClusterNodeCount()} in config equals - * {@link RemoteServerNodeManager#getRemoteServerNodes()}, all servers connected!!! - */ - public void waitAllServerNodeConnected() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - - Integer clusterNodeCount = CachedPantheonServerConfig.getInstance().getClusterNodeCount(); - - Boolean allServerNodeConnected = false; - - LOGGER.info("waiting connection with all of {} servers......", clusterNodeCount); - - while (!allServerNodeConnected) { - try { - Thread.sleep(ALL_MASTER_NODE_CONNECT_CHECK_INTERVAL); - } catch (InterruptedException e) { - LOGGER.error("InterruptedException!!!", e); - } - if (clusterNodeCount == remoteServerNodeManager.getRemoteServerNodes().size() + 1) { - allServerNodeConnected = true; - } - } - - LOGGER.info("all servers node connected!!!!"); - } - - /** - * when {@link CachedPantheonServerConfig#getOtherControllerCandidateServers()} in config equals - * {@link RemoteServerNodeManager#getOtherControllerCandidates()}, all controller candidate connected!!! - */ - public void waitAllControllerCandidatesConnected() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - - - List otherControllerCandidateServers = CachedPantheonServerConfig.getInstance().getOtherControllerCandidateServers(); - - LOGGER.info("waiting connection with controller candidates: " + otherControllerCandidateServers + "......"); - ServerNode serverNode = ServerNode.getInstance(); - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED)) { - boolean allControllerCandidatesConnected = false; - - List connectedControllerCandidates = - remoteServerNodeManager.getOtherControllerCandidates(); - if (connectedControllerCandidates.size() == otherControllerCandidateServers.size()) { - allControllerCandidatesConnected = true; - } - - if (allControllerCandidatesConnected) { - LOGGER.info(" all controller candidate connected!!!"); - break; - } - - try { - Thread.sleep(CHECK_ALL_OTHER_NODES_CONNECT_INTERVAL); - } catch (InterruptedException e) { - LOGGER.error("InterruptedException!!!", e); - } - } - } - - /** - * send message to other nodes - * - * @param remoteNodeId - * @param message - * @return - */ - public Boolean sendMessage(Integer remoteNodeId, ByteBuffer message) { - try { - LinkedBlockingQueue sendQueue = sendQueues.get(remoteNodeId); - if (sendQueue != null) { - sendQueue.put(message); - } - } catch (InterruptedException e) { - LOGGER.error("put message into send queue error, remoteNodeId=" + remoteNodeId, e); - return false; - } - return true; - } - - /** - * blocking take - * - * @return - */ - public ByteBuffer takeMessage() { - try { - return receiveQueue.take(); - } catch (Exception e) { - LOGGER.error("take message from receive queue error......", e); - } - return null; - } - - /** - * retry connection with master node - */ - class RetryConnectMasterNodeThread implements Runnable { - - private final Logger LOGGER = LoggerFactory.getLogger(RetryConnectMasterNodeThread.class); - - @Override - public void run() { - ServerNode serverNode = ServerNode.getInstance(); - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) || serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) { - - List retryConnectSuccessMasterNodes = new ArrayList(); - - for (String retryConnectMasterNode : retryConnectMasterNodes) { - LOGGER.error("scheduled retry connect master node: " + retryConnectMasterNode + "......."); - if (connectServerNode(retryConnectMasterNode)) { - retryConnectSuccessMasterNodes.add(retryConnectMasterNode); - } - } - - //remove from retry list after success - for (String retryConnectSuccessMasterNode : retryConnectSuccessMasterNodes) { - retryConnectMasterNodes.remove(retryConnectSuccessMasterNode); - } - } - } - } - - /** - * server connection listener - */ - class ServerConnectionListener extends Thread { - - private final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionListener.class); - - /** - * default retry times - */ - public static final int DEFAULT_RETRIES = 3; - - - private ServerSocket serverSocket; - /** - * retried times - */ - private int retries = 0; - - - @Override - public void run() { - - - boolean fatal = false; - - ServerNode serverNode = ServerNode.getInstance(); - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) - && retries <= DEFAULT_RETRIES) { - try { - // connect using intern tcp port - int port = CachedPantheonServerConfig.getInstance().getNodeInternTcpPort(); - InetSocketAddress endpoint = new InetSocketAddress(port); - this.serverSocket = new ServerSocket(); - this.serverSocket.setReuseAddress(true); - this.serverSocket.bind(endpoint); - - LOGGER.info("server connection thread bind to: " + port + ",waiting for connection......"); - - while (serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) - || serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) { - // BIO - Socket socket = this.serverSocket.accept(); - socket.setTcpNoDelay(true); - socket.setSoTimeout(0); - - RemoteServerNode remoteServerNode = readRemoteNodeInformation(socket); - if (remoteServerNode == null) { - fatal = true; - break; - } - startServerIOThreads(remoteServerNode.getNodeId(), socket); - ServerNetworkManager.this.remoteNodeSockets.put(remoteServerNode.getNodeId(), socket); - RemoteServerNodeManager.getInstance().addRemoteServerNode(remoteServerNode); - - // send self information - if (!sendSelfInformation(socket)) { - fatal = true; - break; - } - - if (ServerNode.isController()) { -// AutoRebalanceManager autoRebalanceManager = AutoRebalanceManager.getInstance(); -// autoRebalanceManager.rebalance(remoteServerNode.getNodeId()); - } - - LOGGER.info("connected with server node:" + remoteServerNode + ", IO thread started......"); - } - } catch (IOException e) { - LOGGER.error("IOException when monitor connecting!!!", e); - - this.retries++; - if (this.retries <= DEFAULT_RETRIES) { - LOGGER.error("retry times:" + retries + "for monitoring connecting......"); - } - } finally { - // close ServerSocket - try { - this.serverSocket.close(); - } catch (IOException ex) { - LOGGER.error("IOException when close socket!!!", ex); - } - } - - if (fatal) { - break; - } - } - - serverNode.stop(); - - LOGGER.error("unable to monitor other servers' connection!!!"); - } - - } - - - public void clearConnection(Integer remoteNodeId) { - LOGGER.info("broker connection with【" + remoteNodeId + "】,cleaning......"); - - remoteNodeSockets.remove(remoteNodeId); - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - remoteServerNodeManager.removeServerNode(remoteNodeId); - - IOThreadRunningSignal ioThreadRunningSignal = - ioThreadRunningSignals.get(remoteNodeId); - ioThreadRunningSignal.setIsRunning(false); - - ByteBuffer terminateBuffer = ByteBuffer.allocate(4); - terminateBuffer.putInt(MessageType.TERMINATE); - sendQueues.get(remoteNodeId).offer(terminateBuffer); - - sendQueues.remove(remoteNodeId); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/network/ServerReadIOThread.java b/pantheon-server/src/main/java/com/pantheon/server/network/ServerReadIOThread.java deleted file mode 100644 index 04d5e4e..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/network/ServerReadIOThread.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.pantheon.server.network; - -import com.pantheon.common.lifecycle.Lifecycle; -import com.pantheon.server.ServerNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.IOException; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.concurrent.LinkedBlockingQueue; - - -public class ServerReadIOThread extends Thread { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServerReadIOThread.class); - - /** - * remote node id - */ - private Integer remoteNodeId; - /** - * master connections - */ - private Socket socket; - /** - * inputStream with master nodes - */ - private DataInputStream inputStream; - /** - * receive queue - */ - private LinkedBlockingQueue receiveQueue; - /** - * server network manager - */ - private ServerNetworkManager serverNetworkManager; - /** - * thread is running or not - */ - private IOThreadRunningSignal ioThreadRunningSignal; - - - public ServerReadIOThread( - Integer remoteNodeId, - Socket socket, - LinkedBlockingQueue receiveQueue, - ServerNetworkManager serverNetworkManager, - IOThreadRunningSignal ioThreadRunningSignal) { - this.remoteNodeId = remoteNodeId; - this.socket = socket; - try { - this.inputStream = new DataInputStream(socket.getInputStream()); - this.receiveQueue = receiveQueue; - } catch (IOException e) { - LOGGER.error("get input stream from socket error......", e); - } - this.serverNetworkManager = serverNetworkManager; - this.ioThreadRunningSignal = ioThreadRunningSignal; - } - - - @Override - public void run() { - ServerNode serverNode = ServerNode.getInstance(); - while ((serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) - || serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) && ioThreadRunningSignal.isRunning()) { - try { - // blocking read from DataInputStream - int messageLength = inputStream.readInt(); - byte[] messageBytes = new byte[messageLength]; - inputStream.readFully(messageBytes, 0, messageLength); - - // bytes to ByteBuffer - ByteBuffer message = ByteBuffer.wrap(messageBytes); - - receiveQueue.put(message); - } catch (EOFException e) { - LOGGER.error("connection broker with 【" + remoteNodeId + "】......", e); - serverNetworkManager.clearConnection(remoteNodeId); -// HighAvailabilityManager highAvailabilityManager = HighAvailabilityManager.getInstance(); -// highAvailabilityManager.handleDisconnectedException(remoteNodeId); - } catch (IOException e) { - LOGGER.error("IOException when connection with node id: 【" + remoteNodeId + "】......", e); - serverNode.stop(); - } catch (InterruptedException e) { - LOGGER.error("InterruptedException when connection with node id: 【" + remoteNodeId + "】......", e); - serverNode.stop(); - } - } - - LOGGER.info("read connection with【" + remoteNodeId + "】will finish......"); - if (serverNode.lifecycleState().equals(Lifecycle.State.STOPPED)) { - LOGGER.error("read connection with【" + remoteNodeId + "】collapsed......"); - } - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/network/ServerWriteIOThread.java b/pantheon-server/src/main/java/com/pantheon/server/network/ServerWriteIOThread.java deleted file mode 100644 index 37be63b..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/network/ServerWriteIOThread.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.pantheon.server.network; - -import com.pantheon.common.lifecycle.Lifecycle; -import com.pantheon.server.ServerNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.concurrent.LinkedBlockingQueue; - - -public class ServerWriteIOThread extends Thread { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServerWriteIOThread.class); - - public static final Integer TERMINATE_MESSAGE_CAPACITY = 4; - - /** - * remote node id - */ - private Integer remoteNodeId; - /** - * master connections - */ - private Socket socket; - /** - * outputStream for remote node - */ - private DataOutputStream outputStream; - /** - * send queue - */ - private LinkedBlockingQueue sendQueue; - /** - * thread is running - */ - private IOThreadRunningSignal ioThreadRunningSignal; - - public ServerWriteIOThread( - Integer remoteNodeId, - Socket socket, - LinkedBlockingQueue sendQueue, - IOThreadRunningSignal ioThreadRunningSignal) { - this.remoteNodeId = remoteNodeId; - this.socket = socket; - try { - this.outputStream = new DataOutputStream(socket.getOutputStream()); - } catch (IOException e) { - LOGGER.error("get data output stream from socket error......", e); - } - this.sendQueue = sendQueue; - this.ioThreadRunningSignal = ioThreadRunningSignal; - } - - - @Override - public void run() { - ServerNode serverNode = ServerNode.getInstance(); - while ((serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) - || serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) && ioThreadRunningSignal.isRunning()) { - try { - // blocking take message - ByteBuffer message = sendQueue.take(); - - // receive terminate message - if (message.capacity() == TERMINATE_MESSAGE_CAPACITY) { - continue; - } - outputStream.writeInt(message.capacity()); - outputStream.write(message.array()); - outputStream.flush(); - } catch (InterruptedException e) { - LOGGER.error("get message from send queue error......", e); - serverNode.stop(); - } catch (IOException e) { - LOGGER.error("send message to remote node error: " + socket.getRemoteSocketAddress()); - serverNode.stop(); - } - } - - LOGGER.info("write connection with【" + remoteNodeId + "】will finish......"); - if (serverNode.lifecycleState().equals(Lifecycle.State.STOPPED)) { - LOGGER.error("write connection with【" + remoteNodeId + "】collapsed......"); - } - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/Controller.java b/pantheon-server/src/main/java/com/pantheon/server/node/Controller.java deleted file mode 100644 index eddaad4..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/Controller.java +++ /dev/null @@ -1,535 +0,0 @@ -package com.pantheon.server.node; - -import com.alibaba.fastjson.JSONObject; -import com.pantheon.common.MessageType; -import com.pantheon.server.ServerNode; -import com.pantheon.server.config.ArchaiusPantheonServerConfig; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.network.ServerNetworkManager; -import com.pantheon.server.persist.FilePersistUtils; -import com.pantheon.server.slot.SlotManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - - -/** - * Controller node - */ -public class Controller { - - private static final Logger LOGGER = LoggerFactory.getLogger(Controller.class); - - /** - * default total slots count - */ - private static final int SLOTS_COUNT = 16384; - /** - * file name of slots allocation - */ - private static final String SLOTS_ALLOCATION_FILENAME = "slots_allocation"; - /** - * file name of the replica of slots allocation - */ - private static final String SLOTS_REPLICA_ALLOCATION_FILENAME = "slots_replica_allocation"; - private static final String REPLICA_NODE_IDS_FILENAME = "replica_node_ids"; - /** - * file name of node slots - */ - private static final String NODE_SLOTS_FILENAME = "node_slots"; - private static final String NODE_SLOTS_REPLICAS_FILENAME = "node_slots_replicas"; - - private Controller() { - - } - - static class Singleton { - static Controller instance = new Controller(); - } - - public static Controller getInstance() { - return Singleton.instance; - } - - /** - * slots allocation - */ - private ConcurrentHashMap/*multi slots scope*/> slotsAllocation = - new ConcurrentHashMap>(); - /** - * replica of slots allocation - */ - private ConcurrentHashMap/*multi slots replica scope*/> slotsReplicaAllocation = - new ConcurrentHashMap<>(); - /** - * nodeId and location of my replica - */ - private ConcurrentHashMap replicaNodeIds = - new ConcurrentHashMap<>(); - private long startTimestamp = new Date().getTime(); - - /** - * allocate all slots to master node - */ - public void allocateSlots() { - //after the slots' allocation, save it to memory and disk, - executeSlotsAllocation(); - - executeSlotsReplicaAllocation(); - - ServerNode serverNode = ServerNode.getInstance(); - if (!persistSlotsAllocation()) { - serverNode.stop(); - return; - } - if (!persistSlotsReplicaAllocation()) { - serverNode.stop(); - return; - } - if (!persistReplicaNodeIds()) { - serverNode.stop(); - return; - } - - // sync to other node - syncSlotsAllocation(); - syncSlotsReplicaAllocation(); - syncReplicaNodeIds(); - - initSlots(); - initSlotsReplicas(); - initReplicaNodeId(); - - //controller is responsible for sending node slots to other candidates and other master nodes - sendNodeSlots(); - - //these nodes will init and persist slots' scope and slots scopes replica - broadcastNodeSlotsReplicas(); - broadcastReplicaNodeId(); - } - - /** - * controller node initialization - */ - public void initControllerNode() { - ControllerNode.setNodeId(CachedPantheonServerConfig.getInstance().getNodeId()); - } - - /** - * controller node's replica slots initialization - */ - private void initReplicaNodeId() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - Integer replicaNodeId = replicaNodeIds.get(nodeId); - SlotManager slotManager = SlotManager.getInstance(); - slotManager.initReplicaNodeId(replicaNodeId); - } - - /** - * calculate slots allocation with {@link #SLOTS_COUNT} and master node count - */ - private void executeSlotsAllocation() { - // current node id - ArchaiusPantheonServerConfig config = CachedPantheonServerConfig.getInstance(); - Integer myNodeId = config.getNodeId(); - - //get master node count - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List remoteMasterNodes = - remoteServerNodeManager.getRemoteServerNodes(); - int totalMasterNodeCount = remoteMasterNodes.size() + 1; - // allocate slots per node - int slotsPerMasterNode = SLOTS_COUNT / totalMasterNodeCount; - int remainSlotsCount = SLOTS_COUNT - slotsPerMasterNode * totalMasterNodeCount; - - Integer nextStartSlot = 1; - Integer nextEndSlot = nextStartSlot - 1 + slotsPerMasterNode; - - - for (RemoteServerNode remoteMasterNode : remoteMasterNodes) { - List slotsList = new ArrayList(); - slotsList.add(nextStartSlot + "," + nextEndSlot); - slotsAllocation.put(remoteMasterNode.getNodeId(), slotsList); - nextStartSlot = nextEndSlot + 1; - nextEndSlot = nextStartSlot - 1 + slotsPerMasterNode; - } - - List slotsList = new ArrayList(); - slotsList.add(nextStartSlot + "," + (nextEndSlot + remainSlotsCount)); - slotsAllocation.put(myNodeId, slotsList); - - LOGGER.info("after election, allocate slots complete:" + slotsAllocation); - } - - /** - * get node id of all nodes and then allocate slots replica - */ - private void executeSlotsReplicaAllocation() { - // get node id of all nodes - List nodeIds = new ArrayList(); - - Integer myNodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - nodeIds.add(myNodeId); - - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List remoteMasterNodes = - remoteServerNodeManager.getRemoteServerNodes(); - for (RemoteServerNode remoteServerNode : remoteMasterNodes) { - nodeIds.add(remoteServerNode.getNodeId()); - } - - // allocate slots replica with a random server node - Random random = new Random(); - - for (Map.Entry> nodeSlots : slotsAllocation.entrySet()) { - Integer nodeId = nodeSlots.getKey(); - List slotsList = nodeSlots.getValue(); - - Integer replicaNodeId = null; - boolean hasDecidedReplicaNode = false; - - while (!hasDecidedReplicaNode) { - replicaNodeId = nodeIds.get(random.nextInt(nodeIds.size())); - if (!replicaNodeId.equals(nodeId)) { - hasDecidedReplicaNode = true; - } - } - - List slotsReplicas = slotsReplicaAllocation.get(replicaNodeId); - - if (slotsReplicas == null) { - slotsReplicas = new ArrayList(); - slotsReplicaAllocation.put(replicaNodeId, slotsReplicas); - } - slotsReplicas.addAll(slotsList); - - replicaNodeIds.put(nodeId, replicaNodeId); - } - - LOGGER.info("after election, allocate slots replica complete:" + slotsReplicaAllocation); - } - - - private Boolean persistSlotsAllocation() { - String slotsAllocationJSON = JSONObject.toJSONString(slotsAllocation); - byte[] slotsAllocationByteArray = slotsAllocationJSON.getBytes(); - return FilePersistUtils.persist(slotsAllocationByteArray, SLOTS_ALLOCATION_FILENAME); - } - - private Boolean persistSlotsReplicaAllocation() { - String slotsReplicaAllocationJSON = JSONObject.toJSONString(slotsReplicaAllocation); - byte[] slotsReplicaAllocationByteArray = slotsReplicaAllocationJSON.getBytes(); - return FilePersistUtils.persist(slotsReplicaAllocationByteArray, SLOTS_REPLICA_ALLOCATION_FILENAME); - } - - private Boolean persistReplicaNodeIds() { - byte[] bytes = JSONObject.toJSONString(replicaNodeIds).getBytes(); - return FilePersistUtils.persist(bytes, REPLICA_NODE_IDS_FILENAME); - } - - /** - * persist node slots into disk - * - * @return - */ - private Boolean persistNodeSlots() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - List slotsList = slotsAllocation.get(nodeId); - byte[] bytes = JSONObject.toJSONString(slotsList).getBytes(); - return FilePersistUtils.persist(bytes, NODE_SLOTS_FILENAME); - } - - /** - * persist node slots replica into disk - * - * @return - */ - private Boolean persistNodeSlotsReplicas() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - List slotsReplicas = slotsReplicaAllocation.get(nodeId); - byte[] bytes = JSONObject.toJSONString(slotsReplicas).getBytes(); - return FilePersistUtils.persist(bytes, NODE_SLOTS_REPLICAS_FILENAME); - } - - /** - * sync slots allocation to other controller candidates - */ - public void syncSlotsAllocation() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List otherControllerCandidates = - remoteServerNodeManager.getOtherControllerCandidates(); - - byte[] slotsAllocationByteArray = JSONObject - .toJSONString(slotsAllocation).getBytes(); - - ByteBuffer slotsAllocationByteBuffer = - ByteBuffer.allocate(4 + slotsAllocationByteArray.length); - slotsAllocationByteBuffer.putInt(MessageType.SLOTS_ALLOCATION); - slotsAllocationByteBuffer.put(slotsAllocationByteArray); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode controllerCandidate : otherControllerCandidates) { - serverNetworkManager.sendMessage(controllerCandidate.getNodeId(), slotsAllocationByteBuffer); - } - - LOGGER.info("after slots allocation, sync slots allocation data to other node already......"); - } - - public void syncSlotsReplicaAllocation() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List otherControllerCandidates = - remoteServerNodeManager.getOtherControllerCandidates(); - - byte[] bytes = JSONObject.toJSONString(replicaNodeIds).getBytes(); - - ByteBuffer byteBuffer = ByteBuffer.allocate(4 + bytes.length); - byteBuffer.putInt(MessageType.REPLICA_NODE_IDS); - byteBuffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode controllerCandidate : otherControllerCandidates) { - serverNetworkManager.sendMessage(controllerCandidate.getNodeId(), byteBuffer); - } - - LOGGER.info("after slots allocation, sync slots replica node id data to other node already......"); - } - - public void syncReplicaNodeIds() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List otherControllerCandidates = - remoteServerNodeManager.getOtherControllerCandidates(); - - byte[] bytes = JSONObject.toJSONString(slotsReplicaAllocation).getBytes(); - - ByteBuffer byteBuffer = ByteBuffer.allocate(4 + bytes.length); - byteBuffer.putInt(MessageType.SLOTS_REPLICA_ALLOCATION); - byteBuffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode controllerCandidate : otherControllerCandidates) { - serverNetworkManager.sendMessage(controllerCandidate.getNodeId(), byteBuffer); - } - - LOGGER.info("after slots allocation, sync slots replica allocation data to other node already......"); - } - - public void syncSlotsAllocation(Integer candidateNodeId) { - byte[] bytes = JSONObject - .toJSONString(slotsAllocation).getBytes(); - - ByteBuffer buffer = - ByteBuffer.allocate(4 + bytes.length); - buffer.putInt(MessageType.SLOTS_ALLOCATION); - buffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(candidateNodeId, buffer); - } - - public void syncSlotsReplicaAllocation(Integer candidateNodeId) { - byte[] bytes = JSONObject.toJSONString(replicaNodeIds).getBytes(); - - ByteBuffer byteBuffer = ByteBuffer.allocate(4 + bytes.length); - byteBuffer.putInt(MessageType.REPLICA_NODE_IDS); - byteBuffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(candidateNodeId, byteBuffer); - } - - public void syncReplicaNodeIds(Integer candidateNodeId) { - byte[] bytes = JSONObject.toJSONString(slotsReplicaAllocation).getBytes(); - - ByteBuffer byteBuffer = ByteBuffer.allocate(4 + bytes.length); - byteBuffer.putInt(MessageType.SLOTS_REPLICA_ALLOCATION); - byteBuffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(candidateNodeId, byteBuffer); - } - - - private void initSlots() { - SlotManager slotManager = SlotManager.getInstance(); - - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - List slotsList = slotsAllocation.get(nodeId); - slotManager.initSlots(slotsList); - } - - private void initSlotsReplicas() { - SlotManager slotManager = SlotManager.getInstance(); - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - List slotsReplicas = slotsReplicaAllocation.get(nodeId); - slotManager.initSlotsReplicas(slotsReplicas, true); - } - - - private void sendNodeSlots() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List nodes = - remoteServerNodeManager.getRemoteServerNodes(); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode node : nodes) { - List slotsList = slotsAllocation.get(node.getNodeId()); - - byte[] bytes = JSONObject.toJSONString(slotsList).getBytes(); - ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length); - buffer.putInt(MessageType.NODE_SLOTS); - buffer.put(bytes); - - serverNetworkManager.sendMessage(node.getNodeId(), buffer); - } - - LOGGER.info("broadcast slots allocation to other node successfully......"); - } - - public void sendNodeSlots(Integer nodeId) { - List slotsList = slotsAllocation.get(nodeId); - - byte[] bytes = JSONObject.toJSONString(slotsList).getBytes(); - ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length); - buffer.putInt(MessageType.UPDATE_NODE_SLOTS); - buffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(nodeId, buffer); - } - - private void broadcastNodeSlotsReplicas() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List nodes = remoteServerNodeManager.getRemoteServerNodes(); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode node : nodes) { - List slotsReplicas = slotsReplicaAllocation.get(node.getNodeId()); - if (slotsReplicas == null || slotsReplicas.size() == 0) { - slotsReplicas = new ArrayList(); - } - - byte[] bytes = JSONObject.toJSONString(slotsReplicas).getBytes(); - ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length); - buffer.putInt(MessageType.NODE_SLOTS_REPLICAS); - buffer.put(bytes); - - serverNetworkManager.sendMessage(node.getNodeId(), buffer); - } - - LOGGER.info("broadcast node slots replica to other node successfully......"); - } - - private void broadcastReplicaNodeId() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List nodes = - remoteServerNodeManager.getRemoteServerNodes(); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode node : nodes) { - Integer replicaNodeId = replicaNodeIds.get(node.getNodeId()); - - ByteBuffer buffer = ByteBuffer.allocate(4 + 4); - buffer.putInt(MessageType.REPLICA_NODE_ID); - buffer.putInt(replicaNodeId); - - serverNetworkManager.sendMessage(node.getNodeId(), buffer); - } - - LOGGER.info("broadcast replica node id to other node successfully......"); - } - - public void broadcastReplicaNodeId(Integer nodeId) { - Integer replicaNodeId = replicaNodeIds.get(nodeId); - - ByteBuffer buffer = ByteBuffer.allocate(4 + 4); - buffer.putInt(MessageType.UPDATE_REPLICA_NODE_ID); - buffer.putInt(replicaNodeId); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(nodeId, buffer); - } - - public void transferSlots(Integer sourceNodeId, Integer targetNodeId, String slots) { - byte[] bytes = slots.getBytes(); - - ByteBuffer buffer = ByteBuffer.allocate(4 + 4 + 4 + bytes.length); - buffer.putInt(MessageType.TRANSFER_SLOTS); - buffer.putInt(targetNodeId); - buffer.putInt(bytes.length); - buffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(sourceNodeId, buffer); - } - - public void broadcastControllerId() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List nodes = - remoteServerNodeManager.getRemoteServerNodes(); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - for (RemoteServerNode node : nodes) { - ByteBuffer buffer = ByteBuffer.allocate(4 + 4); - buffer.putInt(MessageType.CONTROLLER_NODE_ID); - buffer.putInt(nodeId); - serverNetworkManager.sendMessage(node.getNodeId(), buffer); - } - - LOGGER.info("broadcast controller id successfully......"); - } - - public Map> getSlotsAllocation() { - return slotsAllocation; - } - - public void setSlotsAllocation(ConcurrentHashMap> slotsAllocation) { - this.slotsAllocation = slotsAllocation; - } - - public ConcurrentHashMap> getSlotsReplicaAllocation() { - return slotsReplicaAllocation; - } - - public void setSlotsReplicaAllocation(ConcurrentHashMap> slotsReplicaAllocation) { - this.slotsReplicaAllocation = slotsReplicaAllocation; - } - - public ConcurrentHashMap getReplicaNodeIds() { - return replicaNodeIds; - } - - public void setReplicaNodeIds(ConcurrentHashMap replicaNodeIds) { - this.replicaNodeIds = replicaNodeIds; - } - - /** - * get server node list - * - * @return - */ - public List getServerAddresses() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - String ip = CachedPantheonServerConfig.getInstance().getNodeIp(); - Integer clientTcpPort = CachedPantheonServerConfig.getInstance().getNodeClientTcpPort(); - - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List servers = remoteServerNodeManager.getRemoteServerNodes(); - List serverAddresses = new ArrayList(); - - for (RemoteServerNode server : servers) { - serverAddresses.add(server.getNodeId() + ":" + server.getIp() + ":" + server.getClientPort()); - } - serverAddresses.add(nodeId + ":" + ip + ":" + clientTcpPort); - - return serverAddresses; - } - - public long getStartTimestamp() { - return startTimestamp; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerCandidate.java b/pantheon-server/src/main/java/com/pantheon/server/node/ControllerCandidate.java deleted file mode 100644 index 9cd0b4d..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerCandidate.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.pantheon.server.node; - -import com.alibaba.fastjson.JSONObject; -import com.pantheon.common.MessageType; -import com.pantheon.common.ServerNodeRole; -import com.pantheon.common.lifecycle.Lifecycle; -import com.pantheon.server.ServerNode; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.network.ServerMessageReceiver; -import com.pantheon.server.network.ServerNetworkManager; -import com.pantheon.server.persist.FilePersistUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Controller candidate node - */ -public class ControllerCandidate { - - private static final Logger LOGGER = LoggerFactory.getLogger(ControllerCandidate.class); - - /** - * filename of slot allocation - */ - private static final String SLOTS_ALLOCATION_FILENAME = "slot_allocation"; - private static final String SLOTS_REPLICA_ALLOCATION_FILENAME = "slot_replica_allocation"; - private static final String REPLICA_NODE_IDS_FILENAME = "replica_node_ids"; - /** - * expiration time of waiting all other master node to connect - */ - private static final Long ALL_MASTER_NODE_CONNECT_CHECK_INTERVAL = 100L; - - private ControllerCandidate() { - - } - - static class Singleton { - static ControllerCandidate instance = new ControllerCandidate(); - } - - public static ControllerCandidate getInstance() { - return Singleton.instance; - } - - private int voteRound = 1; - //current vote - private ControllerVote currentVote; - private ConcurrentHashMap> slotsAllocation; - private ConcurrentHashMap> slotsReplicaAllocation; - private ConcurrentHashMap replicaNodeIds; - - /** - * elect controller within controller candidate - * - * @return - */ - public ServerNodeRole electController() { - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - - //get all other controller candidate - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - List otherControllerCandidates = - remoteServerNodeManager.getOtherControllerCandidates(); - LOGGER.info("other controller candidates : " + otherControllerCandidates); - - // first round election - this.voteRound = 1; - this.currentVote = new ControllerVote(nodeId, nodeId, voteRound); - Integer controllerNodeId = startNextRoundVote(otherControllerCandidates); - //first round failed to elect controller - while (controllerNodeId == null) { - controllerNodeId = startNextRoundVote(otherControllerCandidates); - } - - // controller found!! - if (nodeId.equals(controllerNodeId)) { - return ServerNodeRole.CONTROLLER_NODE; - } else { - return ServerNodeRole.CONTROLLER_CANDIDATE_NODE; - } - } - - /** - * 开启下一轮投票 - */ - private Integer startNextRoundVote( - List otherControllerCandidates) { - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - - LOGGER.info("start round: " + voteRound + " votes......"); - - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - - // quorum num calc, if controller is 3,quorum = 3 / 2 + 1 = 2 - int candidateCount = (1 + otherControllerCandidates.size()); - int quorum = candidateCount / 2 + 1; - - - List votes = new ArrayList(); - votes.add(currentVote); - - // initial vote to self - ByteBuffer voteMessage = currentVote.getMessageByteBuffer(); - for (RemoteServerNode remoteNode : otherControllerCandidates) { - Integer remoteNodeId = remoteNode.getNodeId(); - serverNetworkManager.sendMessage(remoteNodeId, voteMessage); - LOGGER.info("send controller votes to : " + remoteNode); - } - - // waiting for others' votes - ServerNode serverNode = ServerNode.getInstance(); - while ((serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) - || serverNode.lifecycleState().equals(Lifecycle.State.STARTED))) { - ControllerVote receivedVote = serverMessageReceiver.takeVote(); - - if (receivedVote.getVoterNodeId() == null) { - continue; - } - - votes.add(receivedVote); - LOGGER.info("received vote : " + receivedVote); - - // votes num > quorum leads to controller judge - if (votes.size() >= quorum) { - Integer judgedControllerNodeId = - getControllerFromVotes(votes, quorum); - - // controller found after judgement - if (judgedControllerNodeId != null) { - if (votes.size() == candidateCount) { - LOGGER.info(" Controller Selected : " + judgedControllerNodeId + ", with all votes......"); - return judgedControllerNodeId; - } - LOGGER.info("Controller Selected: " + judgedControllerNodeId + ", with not all votes......"); - } else { - LOGGER.info("Not yet affirm who is the Controller: " + votes); - } - } - - if (votes.size() == candidateCount) { - //fail round: after all votes received ,but have not affirmed controller - //start next round with a better controller node(the biggest one in all candidates) - voteRound++; - Integer betterControllerNodeId = getBetterControllerNodeId(votes); - this.currentVote = new ControllerVote(nodeId, betterControllerNodeId, voteRound); - - LOGGER.info("fail round, create a better vote: " + currentVote); - - return null; - } - } - - return null; - } - - /** - * get controller node id from current votes - * - * @param votes - * @return - */ - private Integer getControllerFromVotes(List votes, int quorum) { - // <1, 1>, <2, 1>, <3, 2> - Map voteCountMap = new HashMap(); - - for (ControllerVote vote : votes) { - Integer controllerNodeId = vote.getControllerNodeId(); - - Integer count = voteCountMap.get(controllerNodeId); - if (count == null) { - count = 0; - } - - voteCountMap.put(controllerNodeId, ++count); - } - - for (Map.Entry voteCountEntry : voteCountMap.entrySet()) { - if (voteCountEntry.getValue() >= quorum) { - return voteCountEntry.getKey(); - } - } - - return null; - } - - /** - * get least controller id - * - * @param votes - * @return - */ - private Integer getBetterControllerNodeId(List votes) { - Integer betterControllerNodeId = 0; - - for (ControllerVote vote : votes) { - Integer controllerNodeId = vote.getControllerNodeId(); - if (controllerNodeId > betterControllerNodeId) { - betterControllerNodeId = controllerNodeId; - } - } - - return betterControllerNodeId; - } - - - public void waitForSlotsAllocation() { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - this.slotsAllocation = serverMessageReceiver.takeSlotsAllocation(); - String slotsAllocationJSON = JSONObject.toJSONString(slotsAllocation); - byte[] slotsAllocationByteArray = slotsAllocationJSON.getBytes(); - FilePersistUtils.persist(slotsAllocationByteArray, SLOTS_ALLOCATION_FILENAME); - } - - public Map> getSlotsAllocation() { - return slotsAllocation; - } - - public ConcurrentHashMap> getSlotsReplicaAllocation() { - return slotsReplicaAllocation; - } - - public ConcurrentHashMap getReplicaNodeIds() { - return replicaNodeIds; - } - - public List getServerAddresses() { - RemoteServerNodeManager remoteServerNodeManager = RemoteServerNodeManager.getInstance(); - - Integer nodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - String ip = CachedPantheonServerConfig.getInstance().getNodeIp(); - Integer clientTcpPort = CachedPantheonServerConfig.getInstance().getNodeClientTcpPort(); - - List servers = remoteServerNodeManager.getRemoteServerNodes(); - List serverAddresses = new ArrayList(); - - for (RemoteServerNode server : servers) { - serverAddresses.add(server.getNodeId() + ":" + server.getIp() + ":" + server.getClientPort()); - } - serverAddresses.add(nodeId + ":" + ip + ":" + clientTcpPort); - - return serverAddresses; - } - - public void waitForSlotsReplicaAllocation() { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - this.slotsReplicaAllocation = serverMessageReceiver.takeSlotsReplicaAllocation(); - String slotsReplicaAllocationJSON = JSONObject.toJSONString(slotsReplicaAllocation); - byte[] slotsReplicaAllocationByteArray = slotsReplicaAllocationJSON.getBytes(); - FilePersistUtils.persist(slotsReplicaAllocationByteArray, SLOTS_REPLICA_ALLOCATION_FILENAME); - } - - public void waitReplicaNodeIds() { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - this.replicaNodeIds = serverMessageReceiver.takeReplicaNodeIds(); - byte[] bytes = JSONObject.toJSONString(replicaNodeIds).getBytes(); - FilePersistUtils.persist(bytes, REPLICA_NODE_IDS_FILENAME); - } - - /** - * request slots data - */ - public void requestSlotsData(Integer controllerNodeId) { - Integer myNodeId = CachedPantheonServerConfig.getInstance().getNodeId(); - - ByteBuffer buffer = ByteBuffer.allocate(4 + 4); - buffer.putInt(MessageType.REQUEST_SLOTS_DATA); - buffer.putInt(myNodeId); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(controllerNodeId, buffer); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerNode.java b/pantheon-server/src/main/java/com/pantheon/server/node/ControllerNode.java deleted file mode 100644 index 06476a7..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerNode.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.pantheon.server.node; - -public class ControllerNode { - - private Integer nodeId; - - private ControllerNode() { - - } - - static class Singleton { - static ControllerNode instance = new ControllerNode(); - } - - public static ControllerNode getInstance() { - return Singleton.instance; - } - - public Integer getNodeId() { - return nodeId; - } - - public static void setNodeId(Integer nodeId) { - getInstance().nodeId = nodeId; - } - - public static Boolean isControllerNode(Integer nodeId) { - return getInstance().nodeId.equals(nodeId); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerVote.java b/pantheon-server/src/main/java/com/pantheon/server/node/ControllerVote.java deleted file mode 100644 index fb89e36..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/ControllerVote.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.pantheon.server.node; - - -import com.pantheon.common.MessageType; - -import java.nio.ByteBuffer; - - -public class ControllerVote { - - /** - * voter's id - */ - private Integer voterNodeId; - /** - * vote which controller - */ - private Integer controllerNodeId; - /** - * vote round - */ - private Integer voteRound; - - public ControllerVote(Integer voterNodeId, Integer controllerNodeId, Integer voteRound) { - this.voterNodeId = voterNodeId; - this.controllerNodeId = controllerNodeId; - this.voteRound = voteRound; - } - - public ControllerVote(ByteBuffer message) { - this.voterNodeId = message.getInt(); - this.controllerNodeId = message.getInt(); - this.voteRound = message.getInt(); - } - - public Integer getVoterNodeId() { - return voterNodeId; - } - - public void setVoterNodeId(Integer voterNodeId) { - this.voterNodeId = voterNodeId; - } - - public Integer getControllerNodeId() { - return controllerNodeId; - } - - public void setControllerNodeId(Integer controllerNodeId) { - this.controllerNodeId = controllerNodeId; - } - - public Integer getVoteRound() { - return voteRound; - } - - public void setVoteRound(Integer voteRound) { - this.voteRound = voteRound; - } - - public ByteBuffer getMessageByteBuffer() { - byte[] bytes = new byte[16]; - ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); - byteBuffer.clear(); - - byteBuffer.putInt(MessageType.VOTE); - byteBuffer.putInt(voterNodeId); - byteBuffer.putInt(controllerNodeId); - byteBuffer.putInt(voteRound); - - return byteBuffer; - } - - @Override - public String toString() { - return "Vote{" + - "voterNodeId=" + voterNodeId + - ", controllerNodeId=" + controllerNodeId + - ", voteRound=" + voteRound + - '}'; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNode.java b/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNode.java deleted file mode 100644 index e470787..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNode.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.pantheon.server.node; - -public class RemoteServerNode { - - /** - * remote server's node id - */ - private Integer nodeId; - /** - * whether a controller candidate - */ - private Boolean isControllerCandidate; - /** - * whether a controller - */ - private Boolean isController = false; - /** - * remote server's node ip - */ - private String ip; - /** - * remote server's port for client connection - */ - private Integer clientPort; - - public RemoteServerNode(Integer nodeId, - Boolean isControllerCandidate, - String ip, - Integer clientPort, - Boolean isContorller) { - this.nodeId = nodeId; - this.isControllerCandidate = isControllerCandidate; - this.ip = ip; - this.clientPort = clientPort; - this.isController = isController(); - } - - public Integer getNodeId() { - return nodeId; - } - - public void setNodeId(Integer nodeId) { - this.nodeId = nodeId; - } - - public Boolean isControllerCandidate() { - return isControllerCandidate; - } - - public void setControllerCandidate(Boolean controllerCandidate) { - isControllerCandidate = controllerCandidate; - } - - public Boolean isController() { - return isController; - } - - public void setController(Boolean controller) { - isController = controller; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Integer getClientPort() { - return clientPort; - } - - public void setClientPort(Integer clientPort) { - this.clientPort = clientPort; - } - - @Override - public String toString() { - return "RemoteMasterNode{" + - "nodeId=" + nodeId + - ", isControllerCandidate=" + isControllerCandidate + - ", ip='" + ip + '\'' + - ", clientPort=" + clientPort + - '}'; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNodeManager.java b/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNodeManager.java deleted file mode 100644 index 55ce058..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNodeManager.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.pantheon.server.node; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -/** - * save remote servers connecting with current node - */ -public class RemoteServerNodeManager { - - private RemoteServerNodeManager() { - - } - - static class Singleton { - static RemoteServerNodeManager instance = new RemoteServerNodeManager(); - } - - public static RemoteServerNodeManager getInstance() { - return Singleton.instance; - } - - /** - * save remote server nodes - */ - private ConcurrentHashMap remoteServerNodes = - new ConcurrentHashMap(); - - - public void addRemoteServerNode(RemoteServerNode remoteServerNode) { - remoteServerNodes.put(remoteServerNode.getNodeId(), remoteServerNode); - } - - /** - * get all other controller candidates - * @return - */ - public List getOtherControllerCandidates() { - List otherControllerCandidates = new ArrayList(); - - for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { - if(remoteServerNode.isControllerCandidate()) { - otherControllerCandidates.add(remoteServerNode); - } - } - - return otherControllerCandidates; - } - - /** - * get all other master nodes - * @return - */ - public List getRemoteServerNodes() { - return new ArrayList<>(remoteServerNodes.values()); - } - - /** - * remove server node in memory - * @param remoteNodeId - */ - public void removeServerNode(Integer remoteNodeId) { - remoteServerNodes.remove(remoteNodeId); - } - - public RemoteServerNode getRemoteServerNode(Integer remoteNodeId) { - return remoteServerNodes.get(remoteNodeId); - } - - public boolean hasController() { - for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { - if(remoteServerNode.isController()) { - return true; - } - } - return false; - } - - public RemoteServerNode getController() { - for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { - if(remoteServerNode.isController()) { - return remoteServerNode; - } - } - return null; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/persist/FilePersistUtils.java b/pantheon-server/src/main/java/com/pantheon/server/persist/FilePersistUtils.java deleted file mode 100644 index d1f0b53..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/persist/FilePersistUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.pantheon.server.persist; - -import com.pantheon.server.config.ArchaiusPantheonServerConfig; -import com.pantheon.server.config.CachedPantheonServerConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.util.zip.Adler32; -import java.util.zip.Checksum; - -public class FilePersistUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(FilePersistUtils.class); - - - /** - * save to disk - * @param bytes - * @param filename - * @return - */ - public static Boolean persist(byte[] bytes, String filename) { - try { - // get data saving directory - File dataDir = new File(CachedPantheonServerConfig.getInstance().getDataDir()); - if(!dataDir.exists()) { - dataDir.mkdirs(); - } - - File file = new File(dataDir, filename); - FileOutputStream fileOutputStream = new FileOutputStream(file); - BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); - DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); - - //checksum for data in disk - Checksum checksum = new Adler32(); - checksum.update(bytes, 0, bytes.length); - long checksumValue = checksum.getValue(); - dataOutputStream.writeLong(checksumValue); - dataOutputStream.writeInt(bytes.length); - dataOutputStream.write(bytes); - //flush to fileOutputStream - bufferedOutputStream.flush(); - // flush to os cache - fileOutputStream.flush(); - // flush to disk - fileOutputStream.getChannel().force(false); - } catch(Exception e) { - LOGGER.error("persist file error......", e); - return false; - } - return true; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/processor/ClientManageProcessor.java b/pantheon-server/src/main/java/com/pantheon/server/processor/ClientManageProcessor.java deleted file mode 100644 index 493993d..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/processor/ClientManageProcessor.java +++ /dev/null @@ -1,422 +0,0 @@ -package com.pantheon.server.processor; - - -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.common.ObjectUtils; -import com.pantheon.common.protocol.RequestCode; -import com.pantheon.common.protocol.ResponseCode; -import com.pantheon.common.protocol.header.GetConsumerRunningInfoRequestHeader; -import com.pantheon.common.protocol.heartBeat.HeartBeat; -import com.pantheon.common.protocol.heartBeat.ServiceUnregister; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.exception.RemotingCommandException; -import com.pantheon.remoting.exception.RemotingTimeoutException; -import com.pantheon.remoting.netty.AsyncNettyRequestProcessor; -import com.pantheon.remoting.netty.NettyRequestProcessor; -import com.pantheon.remoting.protocol.RemotingCommand; -import com.pantheon.server.ServerNode; -import com.pantheon.server.client.ClientChannelInfo; -import com.pantheon.server.registry.*; -import com.pantheon.server.slot.SlotManager; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.ws.rs.core.Response; -import java.util.List; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc process the connection between client and server - **/ -public class ClientManageProcessor extends AsyncNettyRequestProcessor implements NettyRequestProcessor { - private static final Logger logger = LoggerFactory.getLogger(ClientManageProcessor.class); - private final RouteInstanceToSlotRegistry routeInstanceToSlotRegistry; - private final ServerNode serverNode; - - - public ClientManageProcessor(ServerNode serverNode) { - this.routeInstanceToSlotRegistry = RouteInstanceToSlotRegistry.getInstance(); - this.serverNode = serverNode; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { - switch (request.getCode()) { - case RequestCode.SERVICE_REGISTRY: - return this.serviceRegistry(ctx, request); - case RequestCode.SERVICE_HEART_BEAT: - return this.heartBeat(ctx, request); - case RequestCode.GET_ALL_APP: - return this.getApplications(ctx, request); - case RequestCode.GET_DELTA_APP: - return this.getDeltaApplications(ctx, request); - //todo case only load some apps - case RequestCode.SERVICE_UNREGISTER: - return this.serviceUnregister(ctx, request); - -// case RequestCode.GET_CONSUMER_RUNNING_INFO: -// return this.getConsumerInfo(ctx, request); - default: - break; - } - return null; - } - - private RemotingCommand getConsumerInfo(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException { - final GetConsumerRunningInfoRequestHeader requestHeader = - (GetConsumerRunningInfoRequestHeader) request.decodeCommandCustomHeader(GetConsumerRunningInfoRequestHeader.class); - - return this.callConsumer(RequestCode.GET_CONSUMER_RUNNING_INFO, request, requestHeader.getClientId()); - } - - private RemotingCommand getApplications(ChannelHandlerContext ctx, RemotingCommand request) { - String clientId = this.serverNode.getConsumerInfoManager().findClientId(ctx.channel()); - SlotManager slotManager = SlotManager.getInstance(); - - RemotingCommand response = RemotingCommand.createResponseCommand(null); - logger.info("getApplications request from : {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); -// response.setBody(instanceRegistry.getApplicationsData()); - response.setOpaque(request.getOpaque()); - return response; - } - - private RemotingCommand getDeltaApplications(ChannelHandlerContext ctx, RemotingCommand request) { - RemotingCommand response = RemotingCommand.createResponseCommand(null); - logger.info("getDeltaApplications request from : {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); -// response.setBody(instanceRegistry.getApplicationsDeltaData()); - response.setOpaque(request.getOpaque()); - return response; - } - - private RemotingCommand serviceUnregister(ChannelHandlerContext ctx, RemotingCommand request) { - RemotingCommand response = RemotingCommand.createResponseCommand(null); - ServiceUnregister serviceUnregister = ServiceUnregister.decode(request.getBody(), ServiceUnregister.class); - logger.info("receive serviceUnregister from: {} / {}", serviceUnregister.getServiceName(), serviceUnregister.getInstanceId()); - cancelLease(serviceUnregister.getServiceName(), serviceUnregister.getInstanceId()); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - return response; - } - - private RemotingCommand heartBeat(ChannelHandlerContext ctx, RemotingCommand request) { - RemotingCommand response = RemotingCommand.createResponseCommand(null); - HeartBeat heartBeat = HeartBeat.decode(request.getBody(), HeartBeat.class); - - ClientChannelInfo clientChannelInfo = new ClientChannelInfo( - ctx.channel(), - heartBeat.getInstanceId(), - request.getLanguage(), - request.getVersion() - ); - - - logger.debug("receive heartBeat from: {} / {}", heartBeat.getServiceName(), heartBeat.getInstanceId()); - String renewError = routeInstanceToSlotRegistry.renew(heartBeat.getServiceName(), heartBeat.getInstanceId()); - if (renewError == null) { - response.setCode(ResponseCode.SUCCESS); - } else { - response.setRemark(renewError); - response.setCode(ResponseCode.SYSTEM_ERROR); - } - response.setRemark(null); - response.setOpaque(request.getOpaque()); - - this.serverNode.getConsumerInfoManager().registerConsumer(clientChannelInfo, heartBeat.getSubscriptionDataSet()); - return response; - } - - private RemotingCommand serviceRegistry(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException { - RemotingCommand response = RemotingCommand.createResponseCommand(null); - InstanceInfo instanceInfo = InstanceInfo.decode(request.getBody(), InstanceInfo.class); - logger.debug("serviceRegistry called by {},receive instanceInfo: {} ", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), instanceInfo.toString()); - if (ObjectUtils.isEmpty(instanceInfo)) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - } else { - register(instanceInfo.getAppName(), instanceInfo); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - } - return response; - } - - - /** - * Get requests returns the information about the instance's - * {@link InstanceInfo}. - * - * @return response containing information about the the instance's - * {@link InstanceInfo}. - */ - public InstanceInfo getInstanceInfo(final String appName, final String id) { - InstanceInfo appInfo = routeInstanceToSlotRegistry - .getInstanceByAppAndId(appName, id); - return appInfo; - } - - /** - * A request for renewing lease from a client instance. - * - * @param overriddenStatus overridden status if any. - * @param status the {@link InstanceInfo.InstanceStatus} of the instance. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return response indicating whether the operation was a success or - * failure. - */ - public Response renewLease( - String id, - String appName, - String overriddenStatus, - String status, - String lastDirtyTimestamp) { - String renewError = routeInstanceToSlotRegistry.renew(appName, id); - - // Not found in the registry, immediately ask for a register - if (renewError != null) { - logger.warn("Not Found (Renew): {} - {}", appName, id); - return null; - } - // Check if we need to sync based on dirty time stamp, the client - // instance might have changed some value - Response response = null; - if (lastDirtyTimestamp != null) { - response = this.validateDirtyTimestamp(appName, id, Long.valueOf(lastDirtyTimestamp)); - // Store the overridden status since the validation found out the node that replicates wins - if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode() - && (overriddenStatus != null) - && !(InstanceInfo.InstanceStatus.UNKNOWN.name().equals(overriddenStatus))) { - routeInstanceToSlotRegistry.storeOverriddenStatusIfRequired(appName, id, InstanceInfo.InstanceStatus.valueOf(overriddenStatus)); - } - } else { - response = Response.ok().build(); - } - logger.debug("Found (Renew): {} - {}; reply status={}" + appName, id, response.getStatus()); - return response; - } - - - /** - * Registers information about a particular instance for an - * {@link Application}. - * - * @param info {@link InstanceInfo} information of the instance. - */ - public Boolean register(String appName, InstanceInfo info) { - logger.debug("Registering instance with instanceId {} ", info.getId()); - // validate that the instanceinfo contains all the necessary required fields - if (ObjectUtils.isEmpty(info.getId())) { - throw new IllegalArgumentException("Missing instanceId"); - } else if (ObjectUtils.isEmpty(info.getHostName())) { - throw new IllegalArgumentException("Missing hostname"); - } else if (ObjectUtils.isEmpty(info.getIPAddr())) { - throw new IllegalArgumentException("Missing ip address"); - } else if (ObjectUtils.isEmpty(info.getAppName())) { - throw new IllegalArgumentException("Missing appName"); - } else if (!appName.equals(info.getAppName())) { - throw new IllegalArgumentException("Mismatched appName, expecting " + appName + " but was " + info.getAppName()); - } else if (ObjectUtils.isEmpty(info.getSlotNum())) { - throw new IllegalArgumentException("Missing slotNum"); - } - - routeInstanceToSlotRegistry.register(info); - return true; - } - - - /** - * Handles {@link InstanceInfo.InstanceStatus} updates. - * - *

- * The status updates are normally done for administrative purposes to - * change the instance status between {@link InstanceInfo.InstanceStatus#UP} and - * {@link InstanceInfo.InstanceStatus#OUT_OF_SERVICE} to select or remove instances for - * receiving traffic. - *

- * - * @param newStatus the new status of the instance. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return response indicating whether the operation was a success or - * failure. - */ - public Response statusUpdate(String appName, String id, - String newStatus, String lastDirtyTimestamp) { - try { - if (routeInstanceToSlotRegistry.getInstanceByAppAndId(appName, id) == null) { - logger.warn("Instance not found: {}/{}", appName, id); - return Response.status(Response.Status.NOT_FOUND).build(); - } - boolean isSuccess = routeInstanceToSlotRegistry.statusUpdate(appName, id, - InstanceInfo.InstanceStatus.valueOf(newStatus), lastDirtyTimestamp); - - if (isSuccess) { - logger.info("Status updated: " + appName + " - " + id - + " - " + newStatus); - return Response.ok().build(); - } else { - logger.warn("Unable to update status: " + appName + " - " - + id + " - " + newStatus); - return Response.serverError().build(); - } - } catch (Throwable e) { - logger.error("Error updating instance {} for status {}", id, - newStatus); - return Response.serverError().build(); - } - } - - /** - * Removes status override for an instance, set with - * {@link #statusUpdate(String, String, String, String)}. - * - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return response indicating whether the operation was a success or - * failure. - */ - public Response deleteStatusUpdate(String appName, String id, - String newStatusValue, - String lastDirtyTimestamp) { - try { - if (routeInstanceToSlotRegistry.getInstanceByAppAndId(appName, id) == null) { - logger.warn("Instance not found: {}/{}", appName, id); - return Response.status(Response.Status.NOT_FOUND).build(); - } - - InstanceInfo.InstanceStatus newStatus = newStatusValue == null ? InstanceInfo.InstanceStatus.UNKNOWN : InstanceInfo.InstanceStatus.valueOf(newStatusValue); - boolean isSuccess = routeInstanceToSlotRegistry.deleteStatusOverride(appName, id, - newStatus, lastDirtyTimestamp); - - if (isSuccess) { - logger.info("Status override removed: " + appName + " - " + id); - return Response.ok().build(); - } else { - logger.warn("Unable to remove status override: " + appName + " - " + id); - return Response.serverError().build(); - } - } catch (Throwable e) { - logger.error("Error removing instance's {} status override", id); - return Response.serverError().build(); - } - } - - - /** - * Handles cancellation of leases for this particular instance. - * - * @return response indicating whether the operation was a success or - * failure. - */ - public Boolean cancelLease(String appName, String id) { - boolean isSuccess = routeInstanceToSlotRegistry.cancel(appName, id); - - if (isSuccess) { - logger.debug("Found (Cancel): " + appName + " - " + id); - return true; - } else { - logger.info("Not Found (Cancel): " + appName + " - " + id); - return false; - } - } - - - private Response validateDirtyTimestamp(String appName, String id, Long lastDirtyTimestamp) { - InstanceInfo appInfo = routeInstanceToSlotRegistry.getInstanceByAppAndId(appName, id); - if (appInfo != null) { - if ((lastDirtyTimestamp != null) && (!lastDirtyTimestamp.equals(appInfo.getLastDirtyTimestamp()))) { - Object[] args = {id, appInfo.getLastDirtyTimestamp(), lastDirtyTimestamp}; - - if (lastDirtyTimestamp > appInfo.getLastDirtyTimestamp()) { - logger.debug( - "Time to sync, since the last dirty timestamp differs -" - + " ReplicationInstance id : {},Registry : {} Incoming: {} ", - args); - return Response.status(Response.Status.NOT_FOUND).build(); - } else if (appInfo.getLastDirtyTimestamp() > lastDirtyTimestamp) { - return Response.ok().build(); - } - } - - } - return Response.ok().build(); - } - - - @Override - public boolean rejectRequest() { - return false; - } - - public RemotingCommand callConsumer( - final int requestCode, - final RemotingCommand request, - final String clientId) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - ClientChannelInfo clientChannelInfo = this.serverNode.getConsumerInfoManager().findChannel(clientId); - - if (null == clientChannelInfo) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark(String.format("The Consumer <%s> not online", clientId)); - return response; - } - - try { - RemotingCommand newRequest = RemotingCommand.createRequestCommand(requestCode, null); - newRequest.setExtFields(request.getExtFields()); - newRequest.setBody(request.getBody()); - - return this.serverNode.getServerToClient().callClient(clientChannelInfo.getChannel(), newRequest); - } catch (RemotingTimeoutException e) { - response.setCode(ResponseCode.CONSUME_MSG_TIMEOUT); - response - .setRemark(String.format("consumer <%s> Timeout: %s", clientId, RemotingHelper.exceptionSimpleDesc(e))); - return response; - } catch (Exception e) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark( - String.format("invoke consumer <%s> Exception: %s", clientId, RemotingHelper.exceptionSimpleDesc(e))); - return response; - } - } - - public void callConsumer( - final int requestCode, - final RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - List allChannel = this.serverNode.getConsumerInfoManager().getAllChannel(); - for (Channel channel : allChannel) { - try { - final GetConsumerRunningInfoRequestHeader requestHeader = - (GetConsumerRunningInfoRequestHeader) request.decodeCommandCustomHeader(GetConsumerRunningInfoRequestHeader.class); - requestHeader.setClientId(this.serverNode.getConsumerInfoManager().findClientId(channel)); - RemotingCommand newRequest = RemotingCommand.createRequestCommand(requestCode, requestHeader); - newRequest.setExtFields(request.getExtFields()); - newRequest.setBody(request.getBody()); - - RemotingCommand remotingCommand = this.serverNode.getServerToClient().callClient(channel, newRequest); - if (remotingCommand != null) { -// logger.info("getConsumerRunningInfo response from client: " + remotingCommand.getRemark()); - } - } catch (RemotingTimeoutException e) { - response.setCode(ResponseCode.CONSUME_MSG_TIMEOUT); - response - .setRemark(String.format("consumer <%s> Timeout: %s", channel, RemotingHelper.exceptionSimpleDesc(e))); - } catch (Exception e) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark( - String.format("invoke consumer <%s> Exception: %s", channel, RemotingHelper.exceptionSimpleDesc(e))); - } - } - } - - -} \ No newline at end of file diff --git a/pantheon-server/src/main/java/com/pantheon/server/processor/ServerNodeProcessor.java b/pantheon-server/src/main/java/com/pantheon/server/processor/ServerNodeProcessor.java deleted file mode 100644 index beb9e40..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/processor/ServerNodeProcessor.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.pantheon.server.processor; - - -import com.alibaba.fastjson.JSON; -import com.pantheon.common.ServerNodeRole; -import com.pantheon.common.protocol.RequestCode; -import com.pantheon.common.protocol.ResponseCode; -import com.pantheon.common.protocol.header.*; -import com.pantheon.remoting.common.RemotingHelper; -import com.pantheon.remoting.exception.RemotingCommandException; -import com.pantheon.remoting.netty.AsyncNettyRequestProcessor; -import com.pantheon.remoting.netty.NettyRequestProcessor; -import com.pantheon.remoting.protocol.RemotingCommand; -import com.pantheon.server.ServerNode; -import com.pantheon.server.node.Controller; -import com.pantheon.server.node.ControllerCandidate; -import io.netty.channel.ChannelHandlerContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** - * @author Anthony - * @create 2021/11/19 - * @desc process the connection between client and server - **/ -public class ServerNodeProcessor extends AsyncNettyRequestProcessor implements NettyRequestProcessor { - private static final Logger logger = LoggerFactory.getLogger(ServerNodeProcessor.class); - private final ServerNode serverNode; - - public ServerNodeProcessor(final ServerNode serverNode) { - this.serverNode = serverNode; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { - switch (request.getCode()) { - case RequestCode.GET_SERVER_NODE_ID: - return this.getServerNodeId(ctx, request); - case RequestCode.GET_SLOTS_ALLOCATION: - return this.getSlotsAllocation(ctx, request); - case RequestCode.GET_SERVER_ADDRESSES: - return this.getServerAddresses(ctx, request); - default: - break; - } - return null; - } - - - @Override - public boolean rejectRequest() { - return false; - } - - - private synchronized RemotingCommand getServerNodeId(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(GetServerNodeIdResponseHeader.class); - final GetServerNodeIdRequestHeader requestHeader = - (GetServerNodeIdRequestHeader) request.decodeCommandCustomHeader(GetServerNodeIdRequestHeader.class); - logger.info("getServerNodeId called by {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - final GetServerNodeIdResponseHeader responseHeader = (GetServerNodeIdResponseHeader) response.readCustomHeader(); - responseHeader.setServerNodeId(serverNode.getServerConfig().getNodeId()); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - return response; - } - - private synchronized RemotingCommand getSlotsAllocation(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(GetSlotsResponseHeader.class); - final GetSlotsRequestHeader requestHeader = - (GetSlotsRequestHeader) request.decodeCommandCustomHeader(GetSlotsRequestHeader.class); - logger.info("getSlotsAllocation called by {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - final GetSlotsResponseHeader responseHeader = (GetSlotsResponseHeader) response.readCustomHeader(); - if (ServerNode.getServerNodeRole() == ServerNodeRole.CONTROLLER_CANDIDATE_NODE) { - responseHeader.setSlotsAllocation(JSON.toJSONString(ControllerCandidate.getInstance().getSlotsAllocation())); - } else if (ServerNode.getServerNodeRole() == ServerNodeRole.CONTROLLER_NODE) { - responseHeader.setSlotsAllocation(JSON.toJSONString(Controller.getInstance().getSlotsAllocation())); - } - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - return response; - } - - private synchronized RemotingCommand getServerAddresses(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - List serverAddresses = null; - final RemotingCommand response = RemotingCommand.createResponseCommand(GetServerAddressResponseHeader.class); - final GetServerAddressRequestHeader requestHeader = - (GetServerAddressRequestHeader) request.decodeCommandCustomHeader(GetServerAddressRequestHeader.class); - logger.info("getServerAddresses called by {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - final GetServerAddressResponseHeader responseHeader = (GetServerAddressResponseHeader) response.readCustomHeader(); - if (ServerNode.getServerNodeRole() == ServerNodeRole.CONTROLLER_CANDIDATE_NODE) { - ControllerCandidate controllerCandidate = ControllerCandidate.getInstance(); - serverAddresses = controllerCandidate.getServerAddresses(); - responseHeader.setServerAddresses(JSON.toJSONString(serverAddresses)); - } else if (ServerNode.getServerNodeRole() == ServerNodeRole.CONTROLLER_NODE) { - Controller controller = Controller.getInstance(); - serverAddresses = controller.getServerAddresses(); - responseHeader.setServerAddresses(JSON.toJSONString(serverAddresses)); - } - - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - response.setOpaque(request.getOpaque()); - return response; - } - -} \ No newline at end of file diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistry.java b/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistry.java deleted file mode 100644 index cb2d371..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistry.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.pantheon.server.registry; - -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.config.PantheonServerConfig; -import com.pantheon.server.lease.LeaseManager; - - -/** - * @author Anthony - * @create 2021/11/28 - * @desc the class that load and update data from Server Side cache - */ -public interface InstanceRegistry { - - void register(final InstanceInfo info); - - /** - * Registers a new instance with a given duration. - * - * @see LeaseManager#register(java.lang.Object, int) - */ - void register(InstanceInfo registrant, int leaseDuration); - - - /** - * Get the registry information about all {@link Applications}. - */ - Applications getApplications(); - - - /** - * Get the registry information about the delta changes. The deltas are - * cached for a window specified by - * {@link PantheonServerConfig#getRetentionTimeInMSInDeltaQueue()}. Subsequent - * requests for delta information may return the same information and client - * must make sure this does not adversely affect them. - * - * @return all application deltas. - */ - Applications getApplicationDeltas(); - - InstanceInfo getInstanceByAppAndId(String appName, String id); - - /** - * Marks the given instance of the given app name as renewed - * - * @see LeaseManager#renew(java.lang.String, java.lang.String) - * @return error response when failed - */ - String renew(String appName, String id); - - /** - * Updates the status of an instance. Normally happens to put an instance - * between {@link InstanceInfo.InstanceStatus#OUT_OF_SERVICE} and - * {@link InstanceInfo.InstanceStatus#UP} to put the instance in and out of traffic. - * - * @param appName the application name of the instance. - * @param id the unique identifier of the instance. - * @param newStatus the new {@link InstanceInfo.InstanceStatus}. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return true if the status was successfully updated, false otherwise. - */ - boolean statusUpdate(String appName, String id, - InstanceInfo.InstanceStatus newStatus, String lastDirtyTimestamp); - - void storeOverriddenStatusIfRequired(String appName, String id, InstanceInfo.InstanceStatus overriddenStatus); - - /** - * Removes status override for a give instance. - * - * @param appName the application name of the instance. - * @param id the unique identifier of the instance. - * @param newStatus the new {@link InstanceInfo.InstanceStatus}. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return true if the status was successfully updated, false otherwise. - */ - boolean deleteStatusOverride(String appName, String id, - InstanceInfo.InstanceStatus newStatus, - String lastDirtyTimestamp); - - /** - * Cancels the registration of an instance. - * - *

- * This is normally invoked by a client when it shuts down informing the - * server to remove the instance from traffic. - *

- * - * @param appName the application name of the application. - * @param id the unique identifier of the instance. - * @return true if the instance was removed from the {@link InstanceRegistryImpl} successfully, false otherwise. - */ - boolean cancel(String appName, String id); - - Application getApplication(String appName); - - - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistryImpl.java b/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistryImpl.java deleted file mode 100644 index 937aed1..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/InstanceRegistryImpl.java +++ /dev/null @@ -1,567 +0,0 @@ -package com.pantheon.server.registry; - -import com.google.common.cache.CacheBuilder; -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.appinfo.LeaseInfo; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.config.PantheonServerConfig; -import com.pantheon.server.lease.Lease; -import com.pantheon.server.lease.LeaseManager; -import com.pantheon.server.rule.DownOrStartingRule; -import com.pantheon.server.rule.FirstMatchWinsCompositeRule; -import com.pantheon.server.rule.InstanceStatusOverrideRule; -import com.pantheon.server.slot.Slot; -import com.pantheon.server.slot.SlotManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * @author Anthony - * @create 2021/11/28 - * @desc the class that load and update data from Server Side cache - */ -public class InstanceRegistryImpl implements InstanceRegistry { - private static final Logger logger = LoggerFactory.getLogger(InstanceRegistryImpl.class); - private final ConcurrentHashMap>> registry - = new ConcurrentHashMap>>(); - - private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); - private final Lock read = readWriteLock.readLock(); - private final Lock write = readWriteLock.writeLock(); - protected final Object lock = new Object(); - protected final ConcurrentMap overriddenInstanceStatusMap = CacheBuilder - .newBuilder().initialCapacity(500) - .expireAfterAccess(1, TimeUnit.HOURS) - .build().asMap(); -// private final SlotManager slotManager; - // delta queue - private ConcurrentLinkedQueue recentlyChangedQueue = new ConcurrentLinkedQueue(); - protected volatile ResponseCache responseCache; - CachedPantheonServerConfig serverConfig; - private Timer deltaRetentionTimer = new Timer("Pantheon-DeltaRetentionTimer", true); - - public InstanceRegistryImpl() { - this.serverConfig = CachedPantheonServerConfig.getInstance(); - responseCache = new ResponseCacheImpl(serverConfig, this); - this.deltaRetentionTimer.schedule(getDeltaRetentionTask(), - serverConfig.getDeltaRetentionTimerIntervalInMs(), - serverConfig.getDeltaRetentionTimerIntervalInMs()); - } - - public void register(final InstanceInfo info) { - int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS; - if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) { - leaseDuration = info.getLeaseInfo().getDurationInSecs(); - } - this.register(info, leaseDuration); - } - - /** - * Registers a new instance with a given duration. - * - * @see LeaseManager#register(java.lang.Object, int) - */ - public void register(InstanceInfo registrant, int leaseDuration) { - try { - read.lock(); - Map> gMap = registry.get(registrant.getAppName()); - if (gMap == null) { - //build new map - final ConcurrentHashMap> gNewMap = new ConcurrentHashMap>(); - gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap); - if (gMap == null) { - gMap = gNewMap; - } - } - Lease existingLease = gMap.get(registrant.getId()); - // Retain the last dirty timestamp without overwriting it, if there is already a lease - if (existingLease != null && (existingLease.getHolder() != null)) { - Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp(); - Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp(); - logger.debug("Existing lease found (existing={}, provided={}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp); - - // this is a > instead of a >= because if the timestamps are equal, we still take the remote transmitted - // InstanceInfo instead of the server local copy. - if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) { - logger.warn("There is an existing lease and the existing lease's dirty timestamp {} is greater" + - " than the one that is being registered {}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp); - logger.warn("Using the existing instanceInfo instead of the new instanceInfo as the registrant"); - registrant = existingLease.getHolder(); - } - } else { - logger.debug("No previous lease information found; it is new registration"); - } - Lease lease = new Lease(registrant, leaseDuration); - if (existingLease != null) { - lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp()); - } - gMap.put(registrant.getId(), lease); - -// // This is where the initial state transfer of overridden status happens - if (!InstanceInfo.InstanceStatus.UNKNOWN.equals(registrant.getOverriddenStatus())) { - logger.debug("Found overridden status {} for instance {}. Checking to see if needs to be add to the " - + "overrides", registrant.getOverriddenStatus(), registrant.getId()); - if (!overriddenInstanceStatusMap.containsKey(registrant.getId())) { - logger.info("Not found overridden id {} and hence adding it", registrant.getId()); - overriddenInstanceStatusMap.put(registrant.getId(), registrant.getOverriddenStatus()); - } - } - InstanceInfo.InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId()); - if (overriddenStatusFromMap != null) { - logger.info("Storing overridden status {} from map", overriddenStatusFromMap); - registrant.setOverriddenStatus(overriddenStatusFromMap); - } - - // Set the status based on the overridden status rules - InstanceInfo.InstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease); - registrant.setStatusWithoutDirty(overriddenInstanceStatus); - - // If the lease is registered with UP status, set lease service up timestamp - if (InstanceInfo.InstanceStatus.UP.equals(registrant.getStatus())) { - lease.serviceUp(); - } - registrant.setActionType(InstanceInfo.ActionType.ADDED); - recentlyChangedQueue.add(new RecentlyChangedItem(lease)); - registrant.setLastUpdatedTimestamp(); - //todo one instance bind to one slot - responseCache.invalidate(registrant.getAppName()); - - logger.info("Registered instance {} with status {}", - registrant.getAppName() + "/" + registrant.getId(), registrant.getStatus()); - } finally { - read.unlock(); - } - } - - public InstanceInfo.InstanceStatus getOverriddenInstanceStatus(InstanceInfo r, - Lease existingLease) { - InstanceStatusOverrideRule rule = new FirstMatchWinsCompositeRule(new DownOrStartingRule(), - new OverrideExistsRule(overriddenInstanceStatusMap), new LeaseExistsRule()); - logger.debug("Processing override status using rule: {}", rule); - return rule.apply(r, existingLease).status(); - } - - - /** - * Get the registry information about all {@link Applications}. - */ - public Applications getApplications() { - - Applications apps = new Applications(); - for (Map.Entry>> entry : registry.entrySet()) { - Application app = null; - - if (entry.getValue() != null) { - for (Map.Entry> stringLeaseEntry : entry.getValue().entrySet()) { - Lease lease = stringLeaseEntry.getValue(); - if (app == null) { - app = new Application(lease.getHolder().getAppName()); - } - app.addInstance(decorateInstanceInfo(lease)); - } - } - if (app != null) { - apps.addApplication(app); - } - } - apps.setAppsHashCode(apps.getReconcileHashCode()); - return apps; - } - - private InstanceInfo decorateInstanceInfo(Lease lease) { - InstanceInfo info = lease.getHolder(); - - // client app settings - int renewalInterval = LeaseInfo.DEFAULT_LEASE_RENEWAL_INTERVAL; - int leaseDuration = LeaseInfo.DEFAULT_LEASE_DURATION; - - - if (info.getLeaseInfo() != null) { - renewalInterval = info.getLeaseInfo().getRenewalIntervalInSecs(); - leaseDuration = info.getLeaseInfo().getDurationInSecs(); - } - - info.setLeaseInfo(LeaseInfo.Builder.newBuilder() - .setRegistrationTimestamp(lease.getRegistrationTimestamp()) - .setRenewalTimestamp(lease.getLastRenewalTimestamp()) - .setServiceUpTimestamp(lease.getServiceUpTimestamp()) - .setRenewalIntervalInSecs(renewalInterval) - .setDurationInSecs(leaseDuration) - .setEvictionTimestamp(lease.getEvictionTimestamp()).build()); - - return info; - } - - /** - * Get the registry information about the delta changes. The deltas are - * cached for a window specified by - * {@link PantheonServerConfig#getRetentionTimeInMSInDeltaQueue()}. Subsequent - * requests for delta information may return the same information and client - * must make sure this does not adversely affect them. - * - * @return all application deltas. - */ - public Applications getApplicationDeltas() { - - Applications apps = new Applications(); - Map applicationInstancesMap = new HashMap(); - try { - write.lock(); - Iterator iter = this.recentlyChangedQueue.iterator(); - logger.debug("The number of elements in the delta queue is :" + this.recentlyChangedQueue.size()); - while (iter.hasNext()) { - Lease lease = iter.next().getLeaseInfo(); - InstanceInfo instanceInfo = lease.getHolder(); - Object[] args = {instanceInfo.getId(), - instanceInfo.getStatus().name(), - instanceInfo.getActionType().name()}; - logger.debug("The instance id %s is found with status %s and actiontype %s", args); - Application app = applicationInstancesMap.get(instanceInfo.getAppName()); - if (app == null) { - app = new Application(instanceInfo.getAppName()); - applicationInstancesMap.put(instanceInfo.getAppName(), app); - apps.addApplication(app); - } - app.addInstance(decorateInstanceInfo(lease)); - } - - - Applications allApps = getApplications(); - apps.setAppsHashCode(allApps.getReconcileHashCode()); - return apps; - } finally { - write.unlock(); - } - } - - public InstanceInfo getInstanceByAppAndId(String appName, String id) { - Map> leaseMap = registry.get(appName); - Lease lease = null; - if (leaseMap != null) { - lease = leaseMap.get(id); - } - if (lease != null - && (!lease.isExpired())) { - return decorateInstanceInfo(lease); - } - return null; - } - - /** - * Marks the given instance of the given app name as renewed, and also marks whether it originated from - * replication. - * - * @return error response when failed - * @see LeaseManager#renew(java.lang.String, java.lang.String) - */ - public String renew(String appName, String id) { - String errorResponse = null; - Map> gMap = registry.get(appName); - Lease leaseToRenew = null; - if (gMap != null) { - leaseToRenew = gMap.get(id); - } - if (leaseToRenew == null) { - errorResponse = String.format("Registry: lease doesn't exist, registering resource: {} - {}", appName, id); - logger.warn(errorResponse); - return errorResponse; - } else { - InstanceInfo instanceInfo = leaseToRenew.getHolder(); - if (instanceInfo != null) { - - InstanceInfo.InstanceStatus overriddenInstanceStatus = this.getOverriddenInstanceStatus( - instanceInfo, leaseToRenew); - if (overriddenInstanceStatus == InstanceInfo.InstanceStatus.UNKNOWN) { - errorResponse = String.format("Instance status UNKNOWN possibly due to deleted override for instance {}" - + "; re-register required", instanceInfo.getId()); - logger.warn(errorResponse); - return errorResponse; - } - if (!instanceInfo.getStatus().equals(overriddenInstanceStatus)) { - Object[] args = { - instanceInfo.getStatus().name(), - instanceInfo.getOverriddenStatus().name(), - instanceInfo.getId() - }; - logger.info( - "The instance status {} is different from overridden instance status {} for instance {}. " - + "Hence setting the status to overridden status", args); - instanceInfo.setStatusWithoutDirty(overriddenInstanceStatus); - } - } - leaseToRenew.renew(); - return null; - } - } - - /** - * Updates the status of an instance. Normally happens to put an instance - * between {@link InstanceInfo.InstanceStatus#OUT_OF_SERVICE} and - * {@link InstanceInfo.InstanceStatus#UP} to put the instance in and out of traffic. - * - * @param appName the application name of the instance. - * @param id the unique identifier of the instance. - * @param newStatus the new {@link InstanceInfo.InstanceStatus}. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return true if the status was successfully updated, false otherwise. - */ - public boolean statusUpdate(String appName, String id, - InstanceInfo.InstanceStatus newStatus, String lastDirtyTimestamp) { - try { - read.lock(); - Map> gMap = registry.get(appName); - Lease lease = null; - if (gMap != null) { - lease = gMap.get(id); - } - if (lease == null) { - return false; - } else { - lease.renew(); - InstanceInfo info = lease.getHolder(); - // Lease is always created with its instance info object. - // This log statement is provided as a safeguard, in case this invariant is violated. - if (info == null) { - logger.error("Found Lease without a holder for instance id {}", id); - } - if ((info != null) && !(info.getStatus().equals(newStatus))) { - // Mark service as UP if needed - if (InstanceInfo.InstanceStatus.UP.equals(newStatus)) { - lease.serviceUp(); - } - // This is NAC overriden status - overriddenInstanceStatusMap.put(id, newStatus); - // Set it for transfer of overridden status to replica on - // replica start up - info.setOverriddenStatus(newStatus); - long replicaDirtyTimestamp = 0; - info.setStatusWithoutDirty(newStatus); - if (lastDirtyTimestamp != null) { - replicaDirtyTimestamp = Long.valueOf(lastDirtyTimestamp); - } - // If the replication's dirty timestamp is more than the existing one, just update - // it to the replica's. - if (replicaDirtyTimestamp > info.getLastDirtyTimestamp()) { - info.setLastDirtyTimestamp(replicaDirtyTimestamp); - } - info.setActionType(InstanceInfo.ActionType.MODIFIED); - recentlyChangedQueue.add(new RecentlyChangedItem(lease)); - info.setLastUpdatedTimestamp(); - responseCache.invalidate(appName); - - } - return true; - } - } finally { - read.unlock(); - } - } - - public void storeOverriddenStatusIfRequired(String appName, String id, InstanceInfo.InstanceStatus overriddenStatus) { - InstanceInfo.InstanceStatus instanceStatus = overriddenInstanceStatusMap.get(id); - if ((instanceStatus == null) || (!overriddenStatus.equals(instanceStatus))) { - // We might not have the overridden status if the server got - // restarted -this will help us maintain the overridden state - // from the replica - logger.info("Adding overridden status for instance id {} and the value is {}", - id, overriddenStatus.name()); - overriddenInstanceStatusMap.put(id, overriddenStatus); - InstanceInfo instanceInfo = this.getInstanceByAppAndId(appName, id); - instanceInfo.setOverriddenStatus(overriddenStatus); - logger.info("Set the overridden status for instance (appname:{}} and the value is {} ", - appName + ",id:" + id, overriddenStatus.name()); - } - } - - /** - * Removes status override for a give instance. - * - * @param appName the application name of the instance. - * @param id the unique identifier of the instance. - * @param newStatus the new {@link InstanceInfo.InstanceStatus}. - * @param lastDirtyTimestamp last timestamp when this instance information was updated. - * @return true if the status was successfully updated, false otherwise. - */ - public boolean deleteStatusOverride(String appName, String id, - InstanceInfo.InstanceStatus newStatus, - String lastDirtyTimestamp) { - try { - read.lock(); - Map> gMap = registry.get(appName); - Lease lease = null; - if (gMap != null) { - lease = gMap.get(id); - } - if (lease == null) { - return false; - } else { - lease.renew(); - InstanceInfo info = lease.getHolder(); - - // Lease is always created with its instance info object. - // This log statement is provided as a safeguard, in case this invariant is violated. - if (info == null) { - logger.error("Found Lease without a holder for instance id {}", id); - } - - InstanceInfo.InstanceStatus currentOverride = overriddenInstanceStatusMap.remove(id); - if (currentOverride != null && info != null) { - info.setOverriddenStatus(InstanceInfo.InstanceStatus.UNKNOWN); - info.setStatusWithoutDirty(newStatus); - long replicaDirtyTimestamp = 0; - if (lastDirtyTimestamp != null) { - replicaDirtyTimestamp = Long.valueOf(lastDirtyTimestamp); - } - // If the replication's dirty timestamp is more than the existing one, just update - // it to the replica's. - if (replicaDirtyTimestamp > info.getLastDirtyTimestamp()) { - info.setLastDirtyTimestamp(replicaDirtyTimestamp); - } - info.setActionType(InstanceInfo.ActionType.MODIFIED); - recentlyChangedQueue.add(new RecentlyChangedItem(lease)); - info.setLastUpdatedTimestamp(); - responseCache.invalidate(appName); - } - return true; - } - } finally { - read.unlock(); - } - } - - /** - * Cancels the registration of an instance. - * - *

- * This is normally invoked by a client when it shuts down informing the - * server to remove the instance from traffic. - *

- * - * @param appName the application name of the application. - * @param id the unique identifier of the instance. - * @return true if the instance was removed from the {@link InstanceRegistryImpl} successfully, false otherwise. - */ - public boolean cancel(String appName, String id) { - try { - read.lock(); - Map> gMap = registry.get(appName); - Lease leaseToCancel = null; - if (gMap != null) { - leaseToCancel = gMap.remove(id); - } - InstanceInfo.InstanceStatus instanceStatus = overriddenInstanceStatusMap.remove(id); - if (instanceStatus != null) { - logger.debug("Removed instance id {} from the overridden map which has value {}", id, instanceStatus.name()); - } - if (leaseToCancel == null) { - logger.warn("Registry: cancel failed because Lease is not registered for: {}/{}", appName, id); - return false; - } else { - leaseToCancel.cancel(); - InstanceInfo instanceInfo = leaseToCancel.getHolder(); - if (instanceInfo != null) { - instanceInfo.setActionType(InstanceInfo.ActionType.DELETED); - recentlyChangedQueue.add(new RecentlyChangedItem(leaseToCancel)); - instanceInfo.setLastUpdatedTimestamp(); - } - responseCache.invalidate(appName); - logger.info("Cancelled instance {}/{} ", appName, id); - return true; - } - } finally { - read.unlock(); - } - } - - public Application getApplication(String appName) { - Application app = null; - - Map> leaseMap = registry.get(appName); - - if (leaseMap != null && leaseMap.size() > 0) { - for (Map.Entry> entry : leaseMap.entrySet()) { - if (app == null) { - app = new Application(appName); - } - app.addInstance(decorateInstanceInfo(entry.getValue())); - } - } - return app; - } - - private static final class RecentlyChangedItem { - private long lastUpdateTime; - private Lease leaseInfo; - - public RecentlyChangedItem(Lease lease) { - this.leaseInfo = lease; - lastUpdateTime = System.currentTimeMillis(); - } - - public long getLastUpdateTime() { - return this.lastUpdateTime; - } - - public Lease getLeaseInfo() { - return this.leaseInfo; - } - } - - /** - * remove data from recentlyChangedQueue - */ - private TimerTask getDeltaRetentionTask() { - return new TimerTask() { - - @Override - public void run() { - Iterator it = recentlyChangedQueue.iterator(); - while (it.hasNext()) { - if (it.next().getLastUpdateTime() < - //default 180s - System.currentTimeMillis() - serverConfig.getRetentionTimeInMSInDeltaQueue()) { - it.remove(); - } else { - break; - } - } - } - }; - } - - /** - * get applications info from cache - * - * @return - */ - public byte[] getApplicationsData() { - Key cacheKey = new Key( - ResponseCacheImpl.ALL_APPS, - Key.ACCEPT.COMPACT - ); - return responseCache.getGZIP(cacheKey); - } - - /** - * get applications delta info from cache - * - * @return - */ - public byte[] getApplicationsDeltaData() { - Key cacheKey = new Key( - ResponseCacheImpl.ALL_APPS_DELTA, - Key.ACCEPT.COMPACT - ); - return responseCache.getGZIP(cacheKey); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/Key.java b/pantheon-server/src/main/java/com/pantheon/server/registry/Key.java deleted file mode 100644 index 911fc1e..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/Key.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.pantheon.server.registry; - -/** - * @author Anthony - * @create 2021/11/30 - * @desc - */ -public class Key { - private final String entityName; - private final String hashKey; - private final ACCEPT accept; - - public enum ACCEPT { - FULL, COMPACT - } - - - public Key(String entityName,ACCEPT accept) { - this.entityName = entityName; - this.accept =accept; - hashKey = this.entityName+this.accept; - } - - public String getName() { - return entityName; - } - - public String getHashKey() { - return hashKey; - } - - - @Override - public int hashCode() { - String hashKey = getHashKey(); - return hashKey.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (other instanceof Key) { - return getHashKey().equals(((Key) other).getHashKey()); - } else { - return false; - } - } - - - public String toStringCompact() { - StringBuilder sb = new StringBuilder(); - sb.append("{name=").append(entityName).append(", accept=").append(accept).append('}'); - return sb.toString(); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/LeaseExistsRule.java b/pantheon-server/src/main/java/com/pantheon/server/registry/LeaseExistsRule.java deleted file mode 100644 index 3cf65e4..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/LeaseExistsRule.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.pantheon.server.registry; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; -import com.pantheon.server.rule.InstanceStatusOverrideRule; -import com.pantheon.server.rule.StatusOverrideResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This rule matches if we have an existing lease for the instance that is UP or OUT_OF_SERVICE. - */ -public class LeaseExistsRule implements InstanceStatusOverrideRule { - - private static final Logger logger = LoggerFactory.getLogger(LeaseExistsRule.class); - - @Override - public StatusOverrideResult apply(InstanceInfo instanceInfo, - Lease existingLease) { - InstanceInfo.InstanceStatus existingStatus = null; - if (existingLease != null) { - existingStatus = existingLease.getHolder().getStatus(); - } - // Allow server to have its way when the status is UP or OUT_OF_SERVICE - if ((existingStatus != null) - && (InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(existingStatus) - || InstanceInfo.InstanceStatus.UP.equals(existingStatus))) { - logger.debug("There is already an existing lease with status {} for instance {}", - existingLease.getHolder().getStatus().name(), - existingLease.getHolder().getId()); - return StatusOverrideResult.matchingStatus(existingLease.getHolder().getStatus()); - } - return StatusOverrideResult.NO_MATCH; - } - - @Override - public String toString() { - return LeaseExistsRule.class.getName(); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/OverrideExistsRule.java b/pantheon-server/src/main/java/com/pantheon/server/registry/OverrideExistsRule.java deleted file mode 100644 index 2a2c654..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/OverrideExistsRule.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.pantheon.server.registry; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; -import com.pantheon.server.rule.InstanceStatusOverrideRule; -import com.pantheon.server.rule.StatusOverrideResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; - -/** - * This rule checks to see if we have overrides for an instance and if we do then we return those. - * - */ -public class OverrideExistsRule implements InstanceStatusOverrideRule { - - private static final Logger logger = LoggerFactory.getLogger(OverrideExistsRule.class); - - private Map statusOverrides; - - public OverrideExistsRule(Map statusOverrides) { - this.statusOverrides = statusOverrides; - } - - @Override - public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease existingLease) { - InstanceInfo.InstanceStatus overridden = statusOverrides.get(instanceInfo.getId()); - // If there are instance specific overrides, then they win - if (overridden != null) { - logger.debug("The instance specific override for instance {} and the value is {}", - instanceInfo.getId(), overridden.name()); - return StatusOverrideResult.matchingStatus(overridden); - } - return StatusOverrideResult.NO_MATCH; - } - - @Override - public String toString() { - return OverrideExistsRule.class.getName(); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCache.java b/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCache.java deleted file mode 100644 index b6a76e0..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCache.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.pantheon.server.registry; - -import java.util.concurrent.atomic.AtomicLong; - -/** - * @author Anthony - * @create 2021/11/30 - * @desc - */ -public interface ResponseCache { - - void invalidate(String appName); - - AtomicLong getVersionDelta(); - - - /** - * Get the cached information about applications. - * - *

- * - * @param key the key for which the cached information needs to be obtained. - * @return payload which contains information about the applications. - */ - String get(Key key); - - /** - * Get the compressed information about the applications. - * - * @param key the key for which the compressed cached information needs to be obtained. - * @return compressed payload which contains information about the applications. - */ - byte[] getGZIP(Key key); -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCacheImpl.java b/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCacheImpl.java deleted file mode 100644 index 3d54e4f..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCacheImpl.java +++ /dev/null @@ -1,263 +0,0 @@ -package com.pantheon.server.registry; - -import com.alibaba.fastjson.JSON; -import com.google.common.cache.*; -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.server.config.CachedPantheonServerConfig; -import com.pantheon.server.config.PantheonServerConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Date; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.zip.GZIPOutputStream; - -/** - * @author Anthony - * @create 2021/11/30 - * @desc The class that is responsible for caching registry information that will be - * queried by the clients. - * - *

- * The cache is maintained in compressed and non-compressed form for three - * categories of requests - all applications, delta changes and for individual - * applications. The compressed form is probably the most efficient in terms of - * network traffic especially when querying all applications. - */ -public class ResponseCacheImpl implements ResponseCache { - private final PantheonServerConfig serverConfig; - private final InstanceRegistryImpl instanceRegistryImpl; - private static final Logger logger = LoggerFactory.getLogger(ResponseCacheImpl.class); - - public static final String ALL_APPS = "ALL_APPS"; - public static final String ALL_APPS_DELTA = "ALL_APPS_DELTA"; - private static final String EMPTY_PAYLOAD = ""; - private final AtomicLong versionDelta = new AtomicLong(0); - //map实现readOnlyCacheMap - private final ConcurrentMap readOnlyCacheMap = new ConcurrentHashMap(); - //guava缓存 - private final LoadingCache readWriteCacheMap; - private final java.util.Timer timer = new java.util.Timer("Pantheon-CacheFillTimer", true); - - - public ResponseCacheImpl(CachedPantheonServerConfig serverConfig, InstanceRegistryImpl instanceRegistryImpl) { - this.serverConfig = serverConfig; - this.instanceRegistryImpl = instanceRegistryImpl; - //default 30 - long responseCacheUpdateIntervalMs = serverConfig.getResponseCacheUpdateIntervalMs(); - this.readWriteCacheMap = - CacheBuilder.newBuilder().initialCapacity(1000) - //default 180s - .expireAfterWrite(serverConfig.getResponseCacheAutoExpirationInSeconds(), TimeUnit.SECONDS) - .removalListener(new RemovalListener() { - @Override - public void onRemoval(RemovalNotification notification) { - Key removedKey = notification.getKey(); - } - }) -//If the cached information is not available it is generated on the first -//request. After the first request, the information is then updated periodically by a background thread. - .build(new CacheLoader() { - @Override - public Value load(Key key) throws Exception { - Value value = generatePayload(key); - return value; - } - }); - - timer.schedule(getCacheUpdateTask(), - new Date(((System.currentTimeMillis() / responseCacheUpdateIntervalMs) * responseCacheUpdateIntervalMs) - + responseCacheUpdateIntervalMs), - responseCacheUpdateIntervalMs); - } - - private Value generatePayload(Key key) { - String payload; - if (ALL_APPS.equals(key.getName())) { - payload = getPayLoad(instanceRegistryImpl.getApplications()); - } else if (ALL_APPS_DELTA.equals(key.getName())) { - versionDelta.incrementAndGet(); - payload = getPayLoad(instanceRegistryImpl.getApplicationDeltas()); - } else { - payload = getPayLoad(instanceRegistryImpl.getApplication(key.getName())); - } - return new Value(payload); - } - - private String getPayLoad(Applications applications) { - return JSON.toJSONString(applications); - } - - - /** - * Generate pay load with both JSON and XML formats for a given application. - */ - private String getPayLoad(Application app) { - if (app == null) { - return EMPTY_PAYLOAD; - } - return JSON.toJSONString(app); - } - - /** - * Invalidate the cache of a particular application. - * - * @param appName the application name of the application. - */ - @Override - public void invalidate(String appName) { - invalidate( - new Key(ALL_APPS, Key.ACCEPT.FULL), - new Key(ALL_APPS, Key.ACCEPT.COMPACT), - new Key(ALL_APPS_DELTA, Key.ACCEPT.FULL), - new Key(ALL_APPS_DELTA, Key.ACCEPT.COMPACT) - ); - } - - /** - * Invalidate the cache information given the list of keys. - * - * @param keys the list of keys for which the cache information needs to be invalidated. - */ - public void invalidate(Key... keys) { - for (Key key : keys) { - logger.debug("Invalidating the response cache key : {} {} ", - "Application", key.getName()); - - readWriteCacheMap.invalidate(key); - } - } - - /** - * Gets the version number of the cached data. - * - * @return teh version number of the cached data. - */ - @Override - public AtomicLong getVersionDelta() { - return versionDelta; - } - - @Override - public String get(Key key) { - Value payload = getValue(key); - if (payload == null || payload.getPayload().equals(EMPTY_PAYLOAD)) { - return null; - } else { - return payload.getPayload(); - } - } - - /** - * Get the payload in both compressed and uncompressed form. - */ - Value getValue(final Key key) { - Value payload = null; - try { - //first cache - final Value currentPayload = readOnlyCacheMap.get(key); - if (currentPayload != null) { - payload = currentPayload; - } else { - //secondary cache - payload = readWriteCacheMap.get(key); - readOnlyCacheMap.put(key, payload); - } - } catch (Throwable t) { - logger.error("Cannot get value for key :" + key, t); - } - return payload; - } - - @Override - public byte[] getGZIP(Key key) { - Value payload = getValue(key); - logger.info("send all apps info info: {}, with size:{} " ,payload.getPayload(),payload.getGzipped().length); - if (payload == null || payload.getPayload().equals(EMPTY_PAYLOAD)) { - return null; - } else { - return payload.getGzipped(); - } - } - - - /** - * transfer cache data from readWriteCacheMap to readOnlyCacheMap - */ - private TimerTask getCacheUpdateTask() { - return new TimerTask() { - @Override - public void run() { -// logger.debug("Updating the client cache from response cache"); - for (Key key : readOnlyCacheMap.keySet()) { -// if (logger.isDebugEnabled()) { -// logger.debug("Updating the client cache from response cache for key : {}", key.getName()); -// } - try { - Value cacheValue = readWriteCacheMap.get(key); - Value currentCacheValue = readOnlyCacheMap.get(key); - if (cacheValue != currentCacheValue) { - readOnlyCacheMap.put(key, cacheValue); - } - } catch (Throwable th) { - logger.error("Error while updating the client cache from response cache", th); - } - } - } - }; - } - - - /** - * The class that stores payload in both compressed and uncompressed form. - */ - public class Value { - private final String payload; - private byte[] gzipped; - - public Value(String payload) { - this.payload = payload; - if (!EMPTY_PAYLOAD.equals(payload)) { - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - GZIPOutputStream out = new GZIPOutputStream(bos); - byte[] rawBytes = payload.getBytes(); - out.write(rawBytes); - // Finish creation of gzip file - out.finish(); - out.close(); - bos.close(); - gzipped = bos.toByteArray(); - } catch (IOException e) { - gzipped = null; - } - } else { - gzipped = null; - } - } - - public String getPayload() { - return payload; - } - - public byte[] getGzipped() { - return gzipped; - } - } - - /** - * Get the number of items in the response cache. - * - * @return int value representing the number of items in response cache. - */ - public int getCurrentSize() { - return readWriteCacheMap.asMap().size(); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/registry/RouteInstanceToSlotRegistry.java b/pantheon-server/src/main/java/com/pantheon/server/registry/RouteInstanceToSlotRegistry.java deleted file mode 100644 index 8873888..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/registry/RouteInstanceToSlotRegistry.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.pantheon.server.registry; - -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.slot.Slot; -import com.pantheon.server.slot.SlotManager; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Anthony - * @create 2021/12/13 - * @desc service route to corresponding slot , - * Slot mechanism is reference from Redis, in which the client instance will be route to a slot after name hash - * and there are {@link SlotManager#SLOT_COUNT} slot count - * - **/ -public class RouteInstanceToSlotRegistry implements InstanceRegistry { - public final SlotManager slotManager; - public final ConcurrentHashMap instanceRouteMap = new ConcurrentHashMap<>(); - public final ConcurrentHashMap slotServicesMap = new ConcurrentHashMap<>(); - - private static RouteInstanceToSlotRegistry instance = new RouteInstanceToSlotRegistry(); - - private RouteInstanceToSlotRegistry() { - slotManager = SlotManager.getInstance(); - } - - public static RouteInstanceToSlotRegistry getInstance() { - return instance; - } - @Override - public void register(InstanceInfo info) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(info.getAppName()); - instanceRegistry.register(info); - } - - public synchronized InstanceRegistryImpl getSpecificInstanceRegistry(String instanceName) { - InstanceRegistryImpl instanceRegistry = instanceRouteMap.get(instanceName); - if (instanceRegistry == null) { - Slot slot = slotManager.getSlot(instanceName); - slotServicesMap.put(slot.getSlotNo(),instanceName); - instanceRouteMap.put(instanceName, new InstanceRegistryImpl()); - } - return instanceRegistry; - } - - @Override - public void register(InstanceInfo info, int leaseDuration) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(info.getAppName()); - instanceRegistry.register(info, leaseDuration); - } - - @Override - public Applications getApplications() { - return null; - } - - @Override - public Applications getApplicationDeltas() { - return null; - } - - @Override - public InstanceInfo getInstanceByAppAndId(String appName, String id) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.getInstanceByAppAndId(appName,id); - } - - @Override - public String renew(String appName, String id) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.renew(appName,id); - } - - @Override - public boolean statusUpdate(String appName, String id, InstanceInfo.InstanceStatus newStatus, String lastDirtyTimestamp) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.statusUpdate(appName, id, newStatus, lastDirtyTimestamp); - } - - @Override - public void storeOverriddenStatusIfRequired(String appName, String id, InstanceInfo.InstanceStatus overriddenStatus) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - instanceRegistry.storeOverriddenStatusIfRequired(appName, id, overriddenStatus); - } - - @Override - public boolean deleteStatusOverride(String appName, String id, InstanceInfo.InstanceStatus newStatus, String lastDirtyTimestamp) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.deleteStatusOverride(appName, id, newStatus, lastDirtyTimestamp); - } - - @Override - public boolean cancel(String appName, String id) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.cancel(appName, id); - } - - @Override - public Application getApplication(String appName) { - InstanceRegistryImpl instanceRegistry = getSpecificInstanceRegistry(appName); - return instanceRegistry.getApplication(appName); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/rule/AlwaysMatchInstanceStatusRule.java b/pantheon-server/src/main/java/com/pantheon/server/rule/AlwaysMatchInstanceStatusRule.java deleted file mode 100644 index 89d84d0..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/rule/AlwaysMatchInstanceStatusRule.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.pantheon.server.rule; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This rule matches always and returns the current status of the instance. - * - */ -public class AlwaysMatchInstanceStatusRule implements InstanceStatusOverrideRule { - private static final Logger logger = LoggerFactory.getLogger(AlwaysMatchInstanceStatusRule.class); - - @Override - public StatusOverrideResult apply(InstanceInfo instanceInfo, - Lease existingLease) { - logger.debug("Returning the default instance status {} for instance {}", instanceInfo.getStatus(), - instanceInfo.getId()); - return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); - } - - @Override - public String toString() { - return AlwaysMatchInstanceStatusRule.class.getName(); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/rule/DownOrStartingRule.java b/pantheon-server/src/main/java/com/pantheon/server/rule/DownOrStartingRule.java deleted file mode 100644 index 9255ab6..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/rule/DownOrStartingRule.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.pantheon.server.rule; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This rule matches if the instance is DOWN or STARTING. - * - */ -public class DownOrStartingRule implements InstanceStatusOverrideRule { - private static final Logger logger = LoggerFactory.getLogger(DownOrStartingRule.class); - - @Override - public StatusOverrideResult apply(InstanceInfo instanceInfo, - Lease existingLease) { - if ((!InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())) - && (!InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(instanceInfo.getStatus()))) { - logger.debug("Trusting the instance status {} for instance {}", - instanceInfo.getStatus(), instanceInfo.getId()); - return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); - } - return StatusOverrideResult.NO_MATCH; - } - - @Override - public String toString() { - return DownOrStartingRule.class.getName(); - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/rule/FirstMatchWinsCompositeRule.java b/pantheon-server/src/main/java/com/pantheon/server/rule/FirstMatchWinsCompositeRule.java deleted file mode 100644 index 036e8e3..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/rule/FirstMatchWinsCompositeRule.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.pantheon.server.rule; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; - -import java.util.ArrayList; -import java.util.List; - -/** - * This rule takes an ordered list of rules and returns the result of the first match or the - * result of the {@link AlwaysMatchInstanceStatusRule}. - * - */ -public class FirstMatchWinsCompositeRule implements InstanceStatusOverrideRule { - - private final InstanceStatusOverrideRule[] rules; - private final InstanceStatusOverrideRule defaultRule; - private final String compositeRuleName; - - public FirstMatchWinsCompositeRule(InstanceStatusOverrideRule... rules) { - this.rules = rules; - this.defaultRule = new AlwaysMatchInstanceStatusRule(); - // Let's build up and "cache" the rule name to be used by toString(); - List ruleNames = new ArrayList<>(rules.length+1); - for (int i = 0; i < rules.length; ++i) { - ruleNames.add(rules[i].toString()); - } - ruleNames.add(defaultRule.toString()); - compositeRuleName = ruleNames.toString(); - } - - @Override - public StatusOverrideResult apply(InstanceInfo instanceInfo, - Lease existingLease) { - for (int i = 0; i < this.rules.length; ++i) { - StatusOverrideResult result = this.rules[i].apply(instanceInfo, existingLease); - if (result.matches()) { - return result; - } - } - return defaultRule.apply(instanceInfo, existingLease); - } - - @Override - public String toString() { - return this.compositeRuleName; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/rule/InstanceStatusOverrideRule.java b/pantheon-server/src/main/java/com/pantheon/server/rule/InstanceStatusOverrideRule.java deleted file mode 100644 index c3f66d1..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/rule/InstanceStatusOverrideRule.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.pantheon.server.rule; - - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.server.lease.Lease; -import com.pantheon.server.registry.InstanceRegistryImpl; - -/** - * A single rule that if matched it returns an instance status. - * The idea is to use an ordered list of such rules and pick the first result that matches. - * - * It is designed to be used by - * {@link InstanceRegistryImpl#getOverriddenInstanceStatus(InstanceInfo, Lease)} - * - */ -public interface InstanceStatusOverrideRule { - - /** - * Match this rule. - * - * @param instanceInfo The instance info whose status we care about. - * @param existingLease Does the instance have an existing lease already? If so let's consider that. - * @return A result with whether we matched and what we propose the status to be overriden to. - */ - StatusOverrideResult apply(final InstanceInfo instanceInfo, - final Lease existingLease); - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/rule/StatusOverrideResult.java b/pantheon-server/src/main/java/com/pantheon/server/rule/StatusOverrideResult.java deleted file mode 100644 index 07084e1..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/rule/StatusOverrideResult.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.pantheon.server.rule; - - -import com.pantheon.client.appinfo.InstanceInfo; - -/** - * Container for a result computed by an {@link InstanceStatusOverrideRule}. - * - */ -public class StatusOverrideResult { - - public static StatusOverrideResult NO_MATCH = new StatusOverrideResult(false, null); - - public static StatusOverrideResult matchingStatus(InstanceInfo.InstanceStatus status) { - return new StatusOverrideResult(true, status); - } - - // Does the rule match? - private final boolean matches; - - // The status computed by the rule. - private final InstanceInfo.InstanceStatus status; - - private StatusOverrideResult(boolean matches, InstanceInfo.InstanceStatus status) { - this.matches = matches; - this.status = status; - } - - public boolean matches() { - return matches; - } - - public InstanceInfo.InstanceStatus status() { - return status; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/Slot.java b/pantheon-server/src/main/java/com/pantheon/server/slot/Slot.java deleted file mode 100644 index 63dfe4b..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/Slot.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.pantheon.server.slot; - - -import com.pantheon.server.registry.InstanceRegistryImpl; -import com.pantheon.server.slot.registry.ServiceInstance; -import com.pantheon.server.slot.registry.ServiceRegistry; - -import java.util.List; - -/** - * Slot play a role of routing and partitioning services data - */ -public class Slot { - - /** - * slot num - */ - private Integer slotNo; - - private InstanceRegistryImpl instanceRegistry; - - - public Slot(Integer slotNo) { - this.slotNo = slotNo; - } - - - - public Slot(Integer slotNo,InstanceRegistryImpl instanceRegistry) { - this.slotNo = slotNo; - this.instanceRegistry =instanceRegistry; - } - - public void setInstanceRegistry(InstanceRegistryImpl instanceRegistry) { - this.instanceRegistry = instanceRegistry; - } - - public void setSlotNo(Integer slotNo) { - this.slotNo = slotNo; - } - - public InstanceRegistryImpl getInstanceRegistry() { - return instanceRegistry; - } - - public Integer getSlotNo() { - return slotNo; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/SlotManager.java b/pantheon-server/src/main/java/com/pantheon/server/slot/SlotManager.java deleted file mode 100644 index 0e631f1..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/SlotManager.java +++ /dev/null @@ -1,253 +0,0 @@ -package com.pantheon.server.slot; - -import com.alibaba.fastjson.JSONObject; -import com.pantheon.common.MessageType; -import com.pantheon.server.network.ServerMessageReceiver; -import com.pantheon.server.network.ServerNetworkManager; -import com.pantheon.server.persist.FilePersistUtils; -import com.pantheon.server.slot.registry.ServiceInstance; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * slot data manage - * todo build with new register mechanism - * - */ -public class SlotManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(SlotManager.class); - - /** - * file name for node slots - */ - public static final String NODE_SLOTS_FILENAME = "node_slots"; - /** - * file name for node replica - */ - public static final String NODE_SLOTS_REPLICAS_FILENAME = "node_slots_replicas"; - public static final Integer SLOT_COUNT = 16384; - - private SlotManager() { - - } - - static class Singleton { - static SlotManager instance = new SlotManager(); - } - - public static SlotManager getInstance() { - return Singleton.instance; - } - - /** - * slots in current node - */ - private Slots slots = new Slots(); - /** - * slots replica in current node - */ - private Map slotsReplicas = new ConcurrentHashMap<>(); - - - /** - * if slotsList is empty will blocking in this method - * @param slotsList - */ - public void initSlots(List slotsList) { - if (slotsList == null) { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - slotsList = serverMessageReceiver.takeNodeSlots(); - } - - for (String slotScope : slotsList) { - slots.init(slotScope); - } - FilePersistUtils.persist(JSONObject.toJSONString(slotsList).getBytes(), NODE_SLOTS_FILENAME); - - LOGGER.info("initialization of current node slots allocation finish......"); - } - - - /** - * if slotScopes is empty and a controller candidate will blocking in this method - * @param slotScopes - * @param isController - */ - public void initSlotsReplicas(List slotScopes, boolean isController) { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - if (slotScopes == null && !isController) { - slotScopes = serverMessageReceiver.takeNodeSlotsReplicas(); - } else if (slotScopes == null && isController) { - return; - } - - for (String slotScope : slotScopes) { - SlotsReplica slotsReplica = new SlotsReplica(); - slotsReplica.init(slotScope); - slotsReplicas.put(slotScope, slotsReplica); - } - - byte[] bytes = JSONObject.toJSONString(slotScopes).getBytes(); - FilePersistUtils.persist(bytes, NODE_SLOTS_REPLICAS_FILENAME); - LOGGER.info("initialization of current node slots replica allocation finish......"); - } - - /** - * if replicaNodeId is empty , will blocking in this method - */ - public void initReplicaNodeId(Integer replicaNodeId) { - ServerMessageReceiver serverMessageReceiver = ServerMessageReceiver.getInstance(); - if(replicaNodeId == null) { - replicaNodeId = serverMessageReceiver.takeReplicaNodeId(); - } - slots.setReplicaNodeId(replicaNodeId); - LOGGER.info("init replica node id complete:" + replicaNodeId); - } - - public void refreshReplicaNodeId(Integer newReplicaNodeId) { - LOGGER.info("副本节点id进行刷新,老节点id:" + slots.getReplicaNodeId() + ",新节点id:" + newReplicaNodeId); - slots.setReplicaNodeId(newReplicaNodeId); - } - - /** - * get slot - * - * @param serviceName - * @return - */ - public Slot getSlot(String serviceName) { - return slots.getSlot(routeSlot(serviceName)); - } - - /** - * get slot replica - * - * @param serviceName - * @return - */ - public Slot getSlotReplica(String serviceName) { - Integer slotNo = routeSlot(serviceName); - - SlotsReplica slotsReplica = null; - - for (String slotScope : slotsReplicas.keySet()) { - Integer startSlot = Integer.valueOf(slotScope.split(",")[0]); - Integer endSlot = Integer.valueOf(slotScope.split(",")[1]); - - if (slotNo >= startSlot && slotNo <= endSlot) { - slotsReplica = slotsReplicas.get(slotScope); - break; - } - } - - return slotsReplica.getSlot(slotNo); - } - - /** - * slots replica regularize to slots - * - * @param replicaSlotsList - */ - public void changeReplicaToSlots(List replicaSlotsList) { - // 把这些slots从当前节点管理的副本槽位里拿出来 - // 把拿出来的副本slots都转移到正式的槽位数据集合里去 - for (String replicaSlots : replicaSlotsList) { - SlotsReplica slotsReplica = slotsReplicas.get(replicaSlots); - ConcurrentHashMap _slots = slotsReplica.getSlots(); - for (Integer slotNo : _slots.keySet()) { - Slot slot = _slots.get(slotNo); - slots.putSlot(slotNo, slot); - } - } - - for (String replicaSlots : replicaSlotsList) { - slotsReplicas.remove(replicaSlots); - } - - LOGGER.info("slots replica (" + replicaSlotsList + ")regularized......"); - } - - /** - * refresh replica slots - * - * @param replicaSlotsList - */ - public void refreshReplicaSlots(List replicaSlotsList) { - LOGGER.info("refresh replica slots ,old ones :" + slotsReplicas.keySet() + ",new ones :" + replicaSlotsList); - - for (String replicaSlots : replicaSlotsList) { - if (!slotsReplicas.containsKey(replicaSlots)) { - SlotsReplica slotsReplica = new SlotsReplica(); - slotsReplica.init(replicaSlots); - slotsReplicas.put(replicaSlots, slotsReplica); - } - } - - byte[] bytes = JSONObject.toJSONString(replicaSlotsList).getBytes(); - FilePersistUtils.persist(bytes, NODE_SLOTS_REPLICAS_FILENAME); - } - - /** - * transfer slots - * - * @param targetNodeId - * @param slots - */ - public void transferSlots(Integer targetNodeId, String slots) { - String[] slotsSplited = slots.split(","); - Integer startSlotNo = Integer.valueOf(slotsSplited[0]); - Integer endSlotNo = Integer.valueOf(slotsSplited[1]); - - for (int slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) { - Slot slot = this.slots.getSlot(slotNo); -// if (slot.isEmpty()) { -// continue; -// } - -// byte[] bytes = slot.getSlotData(); - byte[] bytes=new byte[10]; - ByteBuffer buffer = ByteBuffer.allocate(4 + 4 + bytes.length); - buffer.putInt(MessageType.UPDATE_SLOTS); - buffer.putInt(slotNo); - buffer.put(bytes); - - ServerNetworkManager serverNetworkManager = ServerNetworkManager.getInstance(); - serverNetworkManager.sendMessage(targetNodeId, buffer); - - this.slots.removeSlot(slotNo); - } - } - - /** - * 将服务路由到slot - * - * @param serviceName - * @return - */ - private Integer routeSlot(String serviceName) { - int hashCode = serviceName.hashCode() & Integer.MAX_VALUE; - Integer slot = hashCode % SLOT_COUNT; - - if (slot == 0) { - slot = slot + 1; - } - - return slot; - } - - public Integer getReplicaNodeId() { - return slots.getReplicaNodeId(); - } - - public void updateSlotData(Integer slotNo, List serviceInstances) { - Slot slot = this.slots.getSlot(slotNo); -// slot.updateSlotData(serviceInstances); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/Slots.java b/pantheon-server/src/main/java/com/pantheon/server/slot/Slots.java deleted file mode 100644 index ec26763..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/Slots.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.pantheon.server.slot; - - -import com.pantheon.server.slot.registry.ServiceRegistry; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * slots in current node - */ -public class Slots { - - /** - * slots in memory - */ - private ConcurrentHashMap slots = - new ConcurrentHashMap<>(); - /** - * corresponding replica slots id - */ - private Integer replicaNodeId; - - /** - * slots initialization - * - * @param slotScope - */ - public void init(String slotScope) { - String[] slotScopeSplited = slotScope.split(","); - Integer startSlotNo = Integer.valueOf(slotScopeSplited[0]); - Integer endSlotNo = Integer.valueOf(slotScopeSplited[1]); - -// ServiceRegistry serviceRegistry = new ServiceRegistry(false); - //todo put map when use - for (Integer slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) { - slots.put(slotNo, new Slot(slotNo)); - } - } - - public void putSlot(Integer slotNo, Slot slot) { - slots.put(slotNo, slot); - } - - /** - * corresponding replica slots id - * - * @param replicaNodeId - */ - public void setReplicaNodeId(Integer replicaNodeId) { - this.replicaNodeId = replicaNodeId; - } - - public Slot getSlot(Integer slotNo) { - return slots.get(slotNo); - } - - public void removeSlot(Integer slotNo) { - slots.remove(slotNo); - } - - public Integer getReplicaNodeId() { - return replicaNodeId; - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/SlotsReplica.java b/pantheon-server/src/main/java/com/pantheon/server/slot/SlotsReplica.java deleted file mode 100644 index 15cf409..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/SlotsReplica.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.pantheon.server.slot; - -import com.pantheon.server.slot.registry.ServiceRegistry; - -import java.util.concurrent.ConcurrentHashMap; - - -/** - * slots replica - * - * 1 todo build with new register mechanism - * 2 todo load specific instances not all - */ -public class SlotsReplica { - - private ConcurrentHashMap slots = - new ConcurrentHashMap<>(); - - public void init(String slotScope) { - String[] slotScopeSplited = slotScope.split(","); - Integer startSlotNo = Integer.valueOf(slotScopeSplited[0]); - Integer endSlotNo = Integer.valueOf(slotScopeSplited[1]); - for(Integer slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) { - slots.put(slotNo, new Slot(slotNo)); - } - } - - public Slot getSlot(Integer slotNo) { - return slots.get(slotNo); - } - - public ConcurrentHashMap getSlots() { - return slots; - } -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceChangedListener.java b/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceChangedListener.java deleted file mode 100644 index 7af19b8..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceChangedListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.pantheon.server.slot.registry; - - -import java.util.ArrayList; -import java.util.List; - -/** - * when service changed, get notified in {@link ServiceChangedListener#onChange(String, List)} - */ -public class ServiceChangedListener { - - /** - * identifier for client connection - */ - private String clientConnectionId; - - public ServiceChangedListener(String clientConnectionId) { - this.clientConnectionId = clientConnectionId; - } - - /** - * notify this method when service changed - * - * @param serviceInstances - */ - public void onChange(String serviceName, List serviceInstances) { - List serviceInstanceAddresses = new ArrayList(); - for (ServiceInstance serviceInstance : serviceInstances) { - serviceInstanceAddresses.add(serviceInstance.getAddress()); - } - -// build and send a request of service changed to client connection -// Request request = new ServiceChangedRequest.Builder() -// .serviceName(serviceName) -// .serviceInstanceAddresses(serviceInstanceAddresses) -// .build(); - -// ClientMessageQueues clientRequestQueues = ClientMessageQueues.getInstance(); -// clientRequestQueues.offerMessage(clientConnectionId, request); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceInstance.java b/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceInstance.java deleted file mode 100644 index 8f33c3f..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceInstance.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.pantheon.server.slot.registry; - -import java.util.Objects; - - -public class ServiceInstance { - - private String serviceName; - private String serviceInstanceIp; - private Integer serviceInstancePort; - private volatile Long latestHeartbeatTime; - - public ServiceInstance(String serviceName, String serviceInstanceIp, Integer serviceInstancePort) { - this.serviceName = serviceName; - this.serviceInstanceIp = serviceInstanceIp; - this.serviceInstancePort = serviceInstancePort; - } - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getServiceInstanceIp() { - return serviceInstanceIp; - } - - public void setServiceInstanceIp(String serviceInstanceIp) { - this.serviceInstanceIp = serviceInstanceIp; - } - - public Integer getServiceInstancePort() { - return serviceInstancePort; - } - - public void setServiceInstancePort(Integer serviceInstancePort) { - this.serviceInstancePort = serviceInstancePort; - } - - public String getServiceInstanceId() { - return serviceName + "_" + serviceInstanceIp + "_" + serviceInstancePort; - } - - public Long getLatestHeartbeatTime() { - return latestHeartbeatTime; - } - - public void setLatestHeartbeatTime(Long latestHeartbeatTime) { - this.latestHeartbeatTime = latestHeartbeatTime; - } - - public String getAddress() { - return serviceName + "," + serviceInstanceIp + "," + serviceInstancePort; - } - - @Override - public String toString() { - return "ServiceInstance{" + - "serviceName='" + serviceName + '\'' + - ", serviceInstanceIp='" + serviceInstanceIp + '\'' + - ", serviceInstancePort=" + serviceInstancePort + - '}'; - } - - public static String getServiceInstanceId(String serviceName, - String serviceInstanceIp, - Integer serviceInstancePort) { - return serviceName + "_" + serviceInstanceIp + "_" + serviceInstancePort; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ServiceInstance that = (ServiceInstance) o; - return serviceName.equals(that.serviceName) && - serviceInstanceIp.equals(that.serviceInstanceIp) && - serviceInstancePort.equals(that.serviceInstancePort); - } - - @Override - public int hashCode() { - return Objects.hash(serviceName, serviceInstanceIp, serviceInstancePort); - } - -} diff --git a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceRegistry.java b/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceRegistry.java deleted file mode 100644 index d39f190..0000000 --- a/pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceRegistry.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.pantheon.server.slot.registry; - -import com.alibaba.fastjson.JSONObject; -import com.pantheon.server.config.ArchaiusPantheonServerConfig; -import com.pantheon.server.config.CachedPantheonServerConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - - -public class ServiceRegistry { - - boolean isReplica; - - public ServiceRegistry(boolean isReplica) { - this.isReplica = isReplica; - new HeartbeatCheckThread().start(); - } - - /** - * cache service registry - */ - private ConcurrentHashMap> serviceRegistryData = - new ConcurrentHashMap<>(); - private ConcurrentHashMap serviceInstanceData = - new ConcurrentHashMap<>(); - private ConcurrentHashMap> serviceChangedListenerData = - new ConcurrentHashMap<>(); - - public void updateData(List serviceInstances) { - for (ServiceInstance serviceInstance : serviceInstances) { - String serviceName = serviceInstance.getServiceName(); - - if (serviceRegistryData.get(serviceName) == null) { - serviceRegistryData.put(serviceName, new ArrayList()); - } - serviceRegistryData.get(serviceName).add(serviceInstance); - - serviceInstanceData.put(serviceInstance.getServiceInstanceId(), serviceInstance); - } - } - - public boolean isEmpty() { - return serviceRegistryData.isEmpty(); - } - - public byte[] getData() { - List allServiceInstances = new ArrayList(); - for (List serviceInstances : serviceRegistryData.values()) { - allServiceInstances.addAll(serviceInstances); - } - return JSONObject.toJSONString(allServiceInstances).getBytes(); - } - - /** - * register service instance - * - * @param serviceInstance - */ - public void register(ServiceInstance serviceInstance) { - // add this instance into registry - List serviceInstances = serviceRegistryData.get( - serviceInstance.getServiceName()); - if (serviceInstances == null) { - synchronized (this) { - if (serviceInstances == null) { - serviceInstances = new CopyOnWriteArrayList<>(); - serviceRegistryData.put(serviceInstance.getServiceName(), serviceInstances); - } - } - } - serviceInstances.add(serviceInstance); - - serviceInstanceData.put(serviceInstance.getServiceInstanceId(), - serviceInstance); - - // notify service changed - - if (!isReplica) { - List serviceChangedListeners = - serviceChangedListenerData.get(serviceInstance.getServiceName()); - - if (serviceChangedListeners == null) { - synchronized (this) { - if (serviceChangedListeners == null) { - serviceChangedListeners = new CopyOnWriteArrayList<>(); - serviceChangedListenerData.put(serviceInstance.getServiceName(), serviceChangedListeners); - } - } - } - - for (ServiceChangedListener serviceChangedListener : serviceChangedListeners) { - serviceChangedListener.onChange(serviceInstance.getServiceName(), - serviceRegistryData.get(serviceInstance.getServiceName())); - } - } - } - - /** - * service instance heartbeat - * - * @param serviceName - * @param serviceInstanceIp - * @param serviceInstancePort - */ - public void heartbeat(String serviceName, - String serviceInstanceIp, - Integer serviceInstancePort) { - String serviceInstanceId = ServiceInstance.getServiceInstanceId( - serviceName, serviceInstanceIp, serviceInstancePort - ); - ServiceInstance serviceInstance = serviceInstanceData.get(serviceInstanceId); - - if (serviceInstance == null) { - synchronized (this) { - if (serviceInstance == null) { - serviceInstance = new ServiceInstance( - serviceName, serviceInstanceIp, serviceInstancePort); - serviceInstanceData.put(serviceInstanceId, serviceInstance); - - List serviceInstances = serviceRegistryData.get(serviceName); - if (serviceInstances == null) { - serviceRegistryData.put(serviceName, new CopyOnWriteArrayList<>()); - } - serviceInstances.add(serviceInstance); - } - } - } - - serviceInstance.setLatestHeartbeatTime(new Date().getTime()); - System.out.println("receive heart beat from " + serviceInstanceId + "......"); - } - - /** - * service registry/subscription - * - * @param serviceName - * @return - */ - public List subscribe(String clientConnectionId, String serviceName) { - List serviceChangedListeners = - serviceChangedListenerData.get(serviceName); - - if (serviceChangedListeners == null) { - synchronized (this) { - if (serviceChangedListeners == null) { - serviceChangedListeners = new CopyOnWriteArrayList<>(); - serviceChangedListenerData.put(serviceName, serviceChangedListeners); - } - } - } - - serviceChangedListeners.add(new ServiceChangedListener(clientConnectionId)); - - return serviceRegistryData.get(serviceName); - } - - /** - * heartbeat check - */ - class HeartbeatCheckThread extends Thread { - - private final Logger LOGGER = LoggerFactory.getLogger(HeartbeatCheckThread.class); - - @Override - public void run() { - ArchaiusPantheonServerConfig config = CachedPantheonServerConfig.getInstance(); - - Integer heartbeatCheckInterval = config.getHeartBeatCheckInterval(); - Integer heartbeatTimeoutPeriod = config.getHeartbeatTimeoutPeriod(); - - while (true) { - long now = new Date().getTime(); - - List removeServiceInstanceIds = new ArrayList(); - Set changedServiceNames = new HashSet(); - - for (ServiceInstance serviceInstance : serviceInstanceData.values()) { - if (now - serviceInstance.getLatestHeartbeatTime() > heartbeatTimeoutPeriod * 1000L) { - List serviceInstances = - serviceRegistryData.get(serviceInstance.getServiceName()); - serviceInstances.remove(serviceInstance); - removeServiceInstanceIds.add(serviceInstance.getServiceInstanceId()); - LOGGER.info("service instance {} get removed after 5s without heartbeat" ,serviceInstance); - - changedServiceNames.add(serviceInstance.getServiceName()); - } - } - - for (String serviceInstanceId : removeServiceInstanceIds) { - serviceInstanceData.remove(serviceInstanceId); - } - - // notify service changed - if (!isReplica) { - for (String serviceName : changedServiceNames) { - List serviceChangedListeners = - serviceChangedListenerData.get(serviceName); - for (ServiceChangedListener serviceChangedListener : serviceChangedListeners) { - serviceChangedListener.onChange(serviceName, serviceRegistryData.get(serviceName)); - } - } - } - - removeServiceInstanceIds.clear(); - changedServiceNames.clear(); - - try { - Thread.sleep(heartbeatCheckInterval * 1000L); - } catch (InterruptedException e) { - LOGGER.error("heartbeat check with InterruptedException !!!", e); - } - } - } - } - -} diff --git a/pantheon-server/src/main/resources/application.properties b/pantheon-server/src/main/resources/application.properties deleted file mode 100644 index 83d75bd..0000000 --- a/pantheon-server/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -pantheon.environment=dev -pantheon.dataDir="/usr/local/1" \ No newline at end of file diff --git a/pantheon-server/src/main/resources/log4j.properties b/pantheon-server/src/main/resources/log4j.properties deleted file mode 100644 index 5648e40..0000000 --- a/pantheon-server/src/main/resources/log4j.properties +++ /dev/null @@ -1,33 +0,0 @@ -log4j.rootLogger=DEBUG, CONSOLE - -# local : debug log to console -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.Threshold=DEBUG -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - -# test: log to file -log4j.appender.TRACEFILE=org.apache.log4j.FileAppender -log4j.appender.TRACEFILE.Threshold=DEBUG -log4j.appender.TRACEFILE.File=/usr/local/pantheon/logs/pantheon.trace -log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n - -# prod: log to pantheon.log and pantheon.error -log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender -log4j.appender.ROLLINGFILE.Threshold=INFO -log4j.appender.ROLLINGFILE.File=/usr/local/pantheon/logs/pantheon.log -log4j.appender.ROLLINGFILE.MaxFileSize=10MB -log4j.appender.ROLLINGFILE.MaxBackupIndex=10 -log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - -log4j.appender.ERRORFILE=org.apache.log4j.RollingFileAppender -log4j.appender.ERRORFILE.Threshold=WARN -log4j.appender.ERRORFILE.File=/usr/local/pantheon/logs/pantheon.error -log4j.appender.ERRORFILE.MaxFileSize=10MB -log4j.appender.ERRORFILE.MaxBackupIndex=10 -log4j.appender.ERRORFILE.layout=org.apache.log4j.PatternLayout -log4j.appender.ERRORFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n - - diff --git a/pantheon-server/src/main/resources/pantheon-server-test1.properties b/pantheon-server/src/main/resources/pantheon-server-test1.properties deleted file mode 100644 index 45b99b3..0000000 --- a/pantheon-server/src/main/resources/pantheon-server-test1.properties +++ /dev/null @@ -1,22 +0,0 @@ -# node id -pantheon.nodeId=111 -# node ip -pantheon.nodeIp= 127.0.0.1 -# intern tcp port -pantheon.nodeInternTcpPort=9971 -# client http port -pantheon.nodeClientHttpPort=9981 -# client tcp port -pantheon.nodeClientTcpPort=9961 -# whether a controller candidate -pantheon.isControllerCandidate=true -# dir to save data -pantheon.dataDir= /Users/anthony/iCloud Drive (Archive)/Desktop/my company/openSource/pantheon/pantheon-server/target/node1 -# all servers count -pantheon.clusterNodeCount=2 -# all controller candidate -pantheon.controllerCandidateServers=127.0.0.1:9971,127.0.0.1:9972 -# heartbeat check interval -pantheon.heartbeatCheckInterval=3 -# heart beat timeout -pantheon.heartbeatTimeoutPeriod=5 diff --git a/pantheon-server/src/main/resources/pantheon-server-test2.properties b/pantheon-server/src/main/resources/pantheon-server-test2.properties deleted file mode 100644 index f9e8e24..0000000 --- a/pantheon-server/src/main/resources/pantheon-server-test2.properties +++ /dev/null @@ -1,22 +0,0 @@ -# node id -pantheon.nodeId=222 -# node ip -pantheon.nodeIp= 127.0.0.1 -# intern tcp port -pantheon.nodeInternTcpPort=9972 -# client http port -pantheon.nodeClientHttpPort=9982 -# client tcp port -pantheon.nodeClientTcpPort=9962 -# whether a controller candidate -pantheon.isControllerCandidate=true -# dir to save data -pantheon.dataDir= /Users/anthony/iCloud Drive (Archive)/Desktop/my company/openSource/pantheon/pantheon-server/target/node2 -# all servers count -pantheon.clusterNodeCount=2 -# all controller candidate -pantheon.controllerCandidateServers=127.0.0.1:9971,127.0.0.1:9972 -# heartbeat check interval -pantheon.heartbeatCheckInterval=3 -# heart beat timeout -pantheon.heartbeatTimeoutPeriod=5 \ No newline at end of file diff --git a/pantheon-server/src/main/resources/pantheon-server.properties b/pantheon-server/src/main/resources/pantheon-server.properties deleted file mode 100644 index 88f321b..0000000 --- a/pantheon-server/src/main/resources/pantheon-server.properties +++ /dev/null @@ -1,12 +0,0 @@ -pantheon.environment=dev -pantheon.nodeId=1 -pantheon.nodeIp= 127.0.0.1 -pantheon.nodeInternTcpPort=9971 -pantheon.nodeClientHttpPort=9981 -pantheon.nodeClientTcpPort=9991 -pantheon.isControllerCandidate=true -pantheon.dataDir= /usr/local/node1 -pantheon.clusterNodeCount=2 -pantheon.controllerCandidateServers=127.0.0.1:9991,127.0.0.1:9992 -pantheon.heartbeatCheckInterval=3 -pantheon.heartbeatTimeoutPeriod=5 \ No newline at end of file diff --git a/pantheon-spring-cloud-gateway-support/pom.xml b/pantheon-spring-cloud-gateway-support/pom.xml deleted file mode 100644 index 5d7212b..0000000 --- a/pantheon-spring-cloud-gateway-support/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-spring-cloud-gateway-support - - - 13 - 13 - - - \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client-new/README.md b/pantheon-spring-cloud-netflix-client-new/README.md deleted file mode 100644 index 74b2d05..0000000 --- a/pantheon-spring-cloud-netflix-client-new/README.md +++ /dev/null @@ -1 +0,0 @@ -Reference from spring-cloud-netflix-eureka-client-3.0.4.RELEASE.jar \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client-new/pom.xml b/pantheon-spring-cloud-netflix-client-new/pom.xml deleted file mode 100644 index 388b40e..0000000 --- a/pantheon-spring-cloud-netflix-client-new/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-spring-cloud-netflix-client-v3.4 - - - 13 - 13 - - - - - - ${project.groupId} - pantheon-client - 1.0-SNAPSHOT - - - org.springframework.boot - spring-boot-configuration-processor - 2.4.10 - compile - true - - - org.springframework.boot - spring-boot-starter-actuator - 2.4.10 - compile - true - - - org.springframework.boot - spring-boot-starter-webflux - 2.4.10 - compile - true - - - org.springframework.cloud - spring-cloud-config-client - 3.0.5 - compile - true - - - org.springframework.cloud - spring-cloud-config-server - 3.0.5 - compile - true - - - org.springframework.cloud - spring-cloud-loadbalancer - 3.0.4 - compile - true - - - javax.inject - javax.inject - 1 - compile - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - 2.4.10 - compile - true - - - \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client/README.md b/pantheon-spring-cloud-netflix-client/README.md deleted file mode 100644 index b524fa8..0000000 --- a/pantheon-spring-cloud-netflix-client/README.md +++ /dev/null @@ -1 +0,0 @@ -Reference from spring-cloud-netflix-eureka-client-1.4.5.RELEASE.jar \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client/pom.xml b/pantheon-spring-cloud-netflix-client/pom.xml deleted file mode 100644 index ed4c74b..0000000 --- a/pantheon-spring-cloud-netflix-client/pom.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-spring-cloud-netflix-client - - - 8 - 8 - - - - - org.springframework.cloud - spring-cloud-commons - 1.3.4.RELEASE - - - org.springframework.cloud - spring-cloud-netflix-core - 1.4.5.RELEASE - - - org.springframework.cloud - spring-cloud-context - 1.3.4.RELEASE - - - org.springframework.boot - spring-boot-actuator - 1.5.14.RELEASE - - - ${project.groupId} - pantheon-client - 1.0-SNAPSHOT - - - org.springframework.cloud - spring-cloud-config-client - 1.4.4.RELEASE - - - com.netflix.ribbon - ribbon - 2.2.5 - - - com.netflix.ribbon - ribbon-core - 2.2.5 - - - com.netflix.ribbon - ribbon-loadbalancer - 2.2.5 - - - com.netflix.ribbon - ribbon-httpclient - 2.2.5 - - - javax.inject - javax.inject - 1 - - - com.google.guava - guava - 19.0 - compile - - - \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/AutoServiceRegistration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/AutoServiceRegistration.java deleted file mode 100644 index 02febc4..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/AutoServiceRegistration.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.pantheon.netflix.client; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public interface AutoServiceRegistration { -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/EnablePantheonClient.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/EnablePantheonClient.java deleted file mode 100644 index 703899b..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/EnablePantheonClient.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.pantheon.netflix.client; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Anthony - * @create 2021/12/14 - * @desc All it does is turn on discovery and let the autoconfiguration - * find the pantheon classes if they are available - **/ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -public @interface EnablePantheonClient { -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/HealthCheckHandler.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/HealthCheckHandler.java deleted file mode 100644 index e88800f..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/HealthCheckHandler.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.appinfo.InstanceInfo; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public interface HealthCheckHandler { - InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus var1); -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/InstanceInfoFactory.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/InstanceInfoFactory.java deleted file mode 100644 index afe643f..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/InstanceInfoFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.appinfo.LeaseInfo; -import com.pantheon.client.config.PantheonInstanceConfig; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Map; - -/** - * @author Anthony - * @create 2021/12/16 - * @desc - **/ -public class InstanceInfoFactory { - - private static final Log log = LogFactory.getLog(InstanceInfoFactory.class); - - public InstanceInfo create(PantheonInstanceConfig config) { - LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder() - .setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds()) - .setDurationInSecs(config.getLeaseExpirationDurationInSeconds()); - - // Builder the instance information to be registered with pantheon - // server - InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - - - builder.setAppName(config.getServiceName()) - .setInstanceId(config.getInstanceId()) - .setIPAddr(config.getInstanceIpAddress()).setHostName(config.getInstanceHostName()) - .setPort(config.getInstancePort()); - - InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.STARTING; - if (log.isInfoEnabled()) { - log.info("Setting initial instance status as: " + initialStatus); - } - builder.setStatus(initialStatus); - - // Add any user-specific metadata information - for (Map.Entry mapEntry : config.getMetadataMap().entrySet()) { - String key = mapEntry.getKey(); - String value = mapEntry.getValue(); - builder.add(key, value); - } - - InstanceInfo instanceInfo = builder.build(); - instanceInfo.setLeaseInfo(leaseInfoBuilder.build()); - return instanceInfo; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonClientAutoConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonClientAutoConfiguration.java deleted file mode 100644 index 7a777d3..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonClientAutoConfiguration.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.pantheon.netflix.client; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public class PantheonClientAutoConfiguration { -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClient.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClient.java deleted file mode 100644 index b1e70aa..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClient.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.config.PantheonInstanceConfig; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * @author Anthony - * @create 2021/12/14 - * @desc - **/ -public class PantheonDiscoveryClient implements DiscoveryClient { - public static final String DESCRIPTION = "Pantheon Discovery Client"; - private final PantheonInstanceConfig config; - - private final DiscoveryClientNode pantheonClient; - - public PantheonDiscoveryClient(PantheonInstanceConfig config, DiscoveryClientNode pantheonClient) { - this.config = config; - this.pantheonClient = pantheonClient; - } - - @Override - public String description() { - return DESCRIPTION; - } - - @Override - public ServiceInstance getLocalServiceInstance() { - return new ServiceInstance() { - @Override - public String getServiceId() { - return PantheonDiscoveryClient.this.config.getServiceName(); - } - - @Override - public String getHost() { - return PantheonDiscoveryClient.this.config.getInstanceHostName(); - } - - @Override - public int getPort() { - return PantheonDiscoveryClient.this.config.getInstancePort(); - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return PantheonDiscoveryClient.this.config.getMetadataMap(); - } - }; - } - - @Override - public List getInstances(String serviceId) { - List infos = this.pantheonClient.getInstance(serviceId); - List instances = new ArrayList<>(); - for (InstanceInfo info : infos) { - instances.add(new PantheonServiceInstance(info)); - } - return instances; - } - - public static class PantheonServiceInstance implements ServiceInstance { - private InstanceInfo instance; - - public PantheonServiceInstance(InstanceInfo instance) { - this.instance = instance; - } - - public InstanceInfo getInstanceInfo() { - return instance; - } - - @Override - public String getServiceId() { - return this.instance.getAppName(); - } - - @Override - public String getHost() { - return this.instance.getHostName(); - } - - @Override - public int getPort() { - if (isSecure()) { - return this.instance.getSecurePort(); - } - return this.instance.getPort(); - } - - @Override - public boolean isSecure() { - // assume if secure is enabled, that is the default - return false; - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return this.instance.getMetadata(); - } - } - - @Override - public List getServices() { - Applications applications = this.pantheonClient.getApplications(); - if (applications == null) { - return Collections.emptyList(); - } - List registered = applications.getRegisteredApplications(); - List names = new ArrayList<>(); - for (Application app : registered) { - if (app.getInstances().isEmpty()) { - continue; - } - names.add(app.getName().toLowerCase()); - - } - return names; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClientConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClientConfiguration.java deleted file mode 100644 index 93adb9d..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonDiscoveryClientConfiguration.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.netflix.client.serviceregistry.PantheonAutoServiceRegistration; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.health.HealthAggregator; -import org.springframework.boot.actuate.health.OrderedHealthAggregator; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -@Configuration -@EnableConfigurationProperties -@ConditionalOnClass({PantheonInstanceConfig.class}) -@ConditionalOnProperty( - value = {"pantheon.client.enabled"}, - matchIfMissing = true -) -public class PantheonDiscoveryClientConfiguration { - public PantheonDiscoveryClientConfiguration() { - } - - @Bean - public PantheonDiscoveryClientConfiguration.Marker pantheonDiscoverClientMarker() { - return new PantheonDiscoveryClientConfiguration.Marker(); - } - - @Configuration - @ConditionalOnProperty( - value = {"pantheon.client.healthcheck.enabled"}, - matchIfMissing = false - ) - protected static class PantheonHealthCheckHandlerConfiguration { - @Autowired( - required = false - ) - private HealthAggregator healthAggregator = new OrderedHealthAggregator(); - - protected PantheonHealthCheckHandlerConfiguration() { - } - - @Bean - @ConditionalOnMissingBean({HealthCheckHandler.class}) - public PantheonHealthCheckHandler pantheonHealthCheckHandler() { - return new PantheonHealthCheckHandler(this.healthAggregator); - } - } - - @Configuration - @ConditionalOnClass({RefreshScopeRefreshedEvent.class}) - protected static class PantheonClientConfigurationRefresher { - @Autowired( - required = false - ) - private DiscoveryClientNode pantheonClient; - @Autowired( - required = false - ) - private PantheonAutoServiceRegistration autoRegistration; - - protected PantheonClientConfigurationRefresher() { - } - - @EventListener({RefreshScopeRefreshedEvent.class}) - public void onApplicationEvent(RefreshScopeRefreshedEvent event) { - if (this.pantheonClient != null) { - this.pantheonClient.getApplications(); - } - - if (this.autoRegistration != null) { - this.autoRegistration.stop(); - this.autoRegistration.start(); - } - - } - } - - class Marker { - Marker() { - } - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthCheckHandler.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthCheckHandler.java deleted file mode 100644 index 8d29d2e..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthCheckHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.appinfo.InstanceInfo; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.actuate.health.CompositeHealthIndicator; -import org.springframework.boot.actuate.health.HealthAggregator; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthIndicator; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.util.Assert; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public class PantheonHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean { - private static final Map STATUS_MAPPING = new HashMap() { - { - this.put(Status.UNKNOWN, InstanceInfo.InstanceStatus.UNKNOWN); - this.put(Status.OUT_OF_SERVICE, InstanceInfo.InstanceStatus.OUT_OF_SERVICE); - this.put(Status.DOWN, InstanceInfo.InstanceStatus.DOWN); - this.put(Status.UP, InstanceInfo.InstanceStatus.UP); - } - }; - private final CompositeHealthIndicator healthIndicator; - private ApplicationContext applicationContext; - - public PantheonHealthCheckHandler(HealthAggregator healthAggregator) { - Assert.notNull(healthAggregator, "HealthAggregator must not be null"); - this.healthIndicator = new CompositeHealthIndicator(healthAggregator); - } - - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - public void afterPropertiesSet() throws Exception { - Map healthIndicators = this.applicationContext.getBeansOfType(HealthIndicator.class); - Iterator var2 = healthIndicators.entrySet().iterator(); - - while(true) { - while(var2.hasNext()) { - Map.Entry entry = (Map.Entry)var2.next(); - if (entry.getValue() instanceof DiscoveryCompositeHealthIndicator) { - DiscoveryCompositeHealthIndicator indicator = (DiscoveryCompositeHealthIndicator)entry.getValue(); - Iterator var5 = indicator.getHealthIndicators().iterator(); - - while(var5.hasNext()) { - DiscoveryCompositeHealthIndicator.Holder holder = (DiscoveryCompositeHealthIndicator.Holder)var5.next(); - if (!(holder.getDelegate() instanceof PantheonHealthIndicator)) { - this.healthIndicator.addHealthIndicator(holder.getDelegate().getName(), holder); - } - } - } else { - this.healthIndicator.addHealthIndicator((String)entry.getKey(), (HealthIndicator)entry.getValue()); - } - } - - return; - } - } - - public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus instanceStatus) { - return this.getHealthStatus(); - } - - protected InstanceInfo.InstanceStatus getHealthStatus() { - Status status = this.healthIndicator.health().getStatus(); - return this.mapToInstanceStatus(status); - } - - protected InstanceInfo.InstanceStatus mapToInstanceStatus(Status status) { - return !STATUS_MAPPING.containsKey(status) ? InstanceInfo.InstanceStatus.UNKNOWN : (InstanceInfo.InstanceStatus)STATUS_MAPPING.get(status); - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthIndicator.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthIndicator.java deleted file mode 100644 index ef7df09..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonHealthIndicator.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.pantheon.netflix.client; - -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.appinfo.Application; -import com.pantheon.client.appinfo.Applications; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.client.discovery.DiscoveryClient; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * @author Anthony - * @create 2021/12/16 - * @desc - **/ -public class PantheonHealthIndicator implements DiscoveryHealthIndicator { - - private final DiscoveryClientNode pantheonClient; - - private final PantheonInstanceConfig instanceConfig; - - public PantheonHealthIndicator(DiscoveryClientNode pantheonClient, PantheonInstanceConfig instanceConfig) { - this.pantheonClient = pantheonClient; - this.instanceConfig = instanceConfig; - } - - @Override - public String getName() { - return "pantheon"; - } - - @Override - public Health health() { - Health.Builder builder = Health.unknown(); - Status status = getStatus(builder); - return builder.status(status).withDetail("applications", getApplications()) - .build(); - } - - private Status getStatus(Health.Builder builder) { - Status status = new Status( - this.pantheonClient.getInstanceRemoteStatus().toString(), - "Remote status from Pantheon server"); - - if (pantheonClient instanceof DiscoveryClientNode && instanceConfig.shouldFetchRegistry()) { - DiscoveryClientNode discoveryClient = (DiscoveryClientNode) pantheonClient; - long lastFetch = discoveryClient.getLastSuccessfulRegistryFetchTimePeriod(); - - if (lastFetch < 0) { - status = new Status("UP", - "Pantheon discovery client has not yet successfully connected to a Pantheon server"); - } - else if (lastFetch > instanceConfig.getRegistryFetchIntervalSeconds() * 2000) { - status = new Status("UP", - "Pantheon discovery client is reporting failures to connect to a Pantheon server"); - builder.withDetail("renewalPeriod", - instanceConfig.getLeaseRenewalIntervalInSeconds()); - builder.withDetail("failCount", - lastFetch / instanceConfig.getRegistryFetchIntervalSeconds()); - } - } - - return status; - } - - private Map getApplications() { - Applications applications = this.pantheonClient.getApplications(); - if (applications == null) { - return Collections.emptyMap(); - } - Map result = new HashMap<>(); - for (Application application : applications.getRegisteredApplications()) { - result.put(application.getName(), application.getInstances().size()); - } - return result; - } - -} \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceAutoConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceAutoConfiguration.java deleted file mode 100644 index 32b595a..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceAutoConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.pantheon.netflix.client.config; - -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.netflix.client.PantheonDiscoveryClientConfiguration; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.ConfigurableApplicationContext; - -import javax.annotation.PostConstruct; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -@ConditionalOnBean({PantheonDiscoveryClientConfiguration.class}) -@ConditionalOnProperty( - value = {"spring.cloud.config.discovery.enabled"}, - matchIfMissing = false -) -public class PantheonDiscoveryClientConfigServiceAutoConfiguration { - @Autowired - private ConfigurableApplicationContext context; - - public PantheonDiscoveryClientConfigServiceAutoConfiguration() { - } - - @PostConstruct - public void init() { - if (this.context.getParent() != null && this.context.getBeanNamesForType(DiscoveryClientNode.class).length > 0 && this.context.getParent().getBeanNamesForType(DiscoveryClientNode.class).length > 0) { - ((DiscoveryClientNode)this.context.getParent().getBean(DiscoveryClientNode.class)).shutdown(); - } - - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceBootstrapConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceBootstrapConfiguration.java deleted file mode 100644 index 6bb0bef..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceBootstrapConfiguration.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.pantheon.netflix.client.config; - -import com.pantheon.netflix.client.PantheonClientAutoConfiguration; -import com.pantheon.netflix.client.PantheonDiscoveryClientConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -@ConditionalOnClass({ConfigServicePropertySourceLocator.class}) -@ConditionalOnProperty( - value = {"spring.cloud.config.discovery.enabled"}, - matchIfMissing = false -) -@Configuration -@Import({PantheonDiscoveryClientConfiguration.class, PantheonClientAutoConfiguration.class}) -public class PantheonDiscoveryClientConfigServiceBootstrapConfiguration { - public PantheonDiscoveryClientConfigServiceBootstrapConfiguration() { - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DefaultNIWSServerListFilter.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DefaultNIWSServerListFilter.java deleted file mode 100644 index 755e016..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DefaultNIWSServerListFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAffinityServerListFilter; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc The Default NIWS Filter - deals with filtering out servers based on the Zone affinity and other related properties - **/ -public class DefaultNIWSServerListFilter extends ZoneAffinityServerListFilter { - public DefaultNIWSServerListFilter() { - } -} \ No newline at end of file diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledNIWSServerList.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledNIWSServerList.java deleted file mode 100644 index 09c0b81..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledNIWSServerList.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.config.ConfigurationManager; -import com.netflix.loadbalancer.AbstractServerList; -import com.netflix.loadbalancer.DynamicServerListLoadBalancer; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.client.discovery.DiscoveryClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Provider; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc The server list class that fetches the server information from Pantheon client. - * ServerList is used by {@link DynamicServerListLoadBalancer} to get server list dynamically. - **/ -public class DiscoveryEnabledNIWSServerList extends AbstractServerList { - private static final Logger logger = LoggerFactory.getLogger(DiscoveryEnabledNIWSServerList.class); - String clientName; - String vipAddresses; - boolean isSecure; - boolean prioritizeVipAddressBasedServers; - String datacenter; - String targetRegion; - int overridePort; - boolean shouldUseOverridePort; - boolean shouldUseIpAddr; - private final Provider pantheonClientProvider; - - public DiscoveryEnabledNIWSServerList(String vipAddresses, Provider pantheonClientProvider) { - this(createClientConfig(vipAddresses), pantheonClientProvider); - } - - public DiscoveryEnabledNIWSServerList(IClientConfig clientConfig, Provider pantheonClientProvider) { - this.isSecure = false; - this.prioritizeVipAddressBasedServers = true; - this.overridePort = 7001; - this.shouldUseOverridePort = false; - this.shouldUseIpAddr = false; - this.pantheonClientProvider = pantheonClientProvider; - this.initWithNiwsConfig(clientConfig); - } - - public void initWithNiwsConfig(IClientConfig clientConfig) { - this.clientName = clientConfig.getClientName(); - this.vipAddresses = clientConfig.resolveDeploymentContextbasedVipAddresses(); - if (this.vipAddresses == null && ConfigurationManager.getConfigInstance().getBoolean("DiscoveryEnabledNIWSServerList.failFastOnNullVip", true)) { - throw new NullPointerException("VIP address for client " + this.clientName + " is null"); - } else { - this.isSecure = Boolean.parseBoolean("" + clientConfig.getProperty(CommonClientConfigKey.IsSecure, "false")); - this.prioritizeVipAddressBasedServers = Boolean.parseBoolean("" + clientConfig.getProperty(CommonClientConfigKey.PrioritizeVipAddressBasedServers, this.prioritizeVipAddressBasedServers)); - this.datacenter = ConfigurationManager.getDeploymentContext().getDeploymentDatacenter(); - this.targetRegion = (String) clientConfig.getProperty(CommonClientConfigKey.TargetRegion); - this.shouldUseIpAddr = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.UseIPAddrForServer, DefaultClientConfigImpl.DEFAULT_USEIPADDRESS_FOR_SERVER); - if (clientConfig.getPropertyAsBoolean(CommonClientConfigKey.ForceClientPortConfiguration, false)) { - if (this.isSecure) { - if (clientConfig.containsProperty(CommonClientConfigKey.SecurePort)) { - this.overridePort = clientConfig.getPropertyAsInteger(CommonClientConfigKey.SecurePort, 7001); - this.shouldUseOverridePort = true; - } else { - logger.warn(this.clientName + " set to force client port but no secure port is set, so ignoring"); - } - } else if (clientConfig.containsProperty(CommonClientConfigKey.Port)) { - this.overridePort = clientConfig.getPropertyAsInteger(CommonClientConfigKey.Port, 7001); - this.shouldUseOverridePort = true; - } else { - logger.warn(this.clientName + " set to force client port but no port is set, so ignoring"); - } - } - - } - } - - public List getInitialListOfServers() { - return this.obtainServersViaDiscovery(); - } - - public List getUpdatedListOfServers() { - return this.obtainServersViaDiscovery(); - } - - private List obtainServersViaDiscovery() { - List serverList = new ArrayList(); - if (this.pantheonClientProvider != null && this.pantheonClientProvider.get() != null) { - DiscoveryClient pantheonClient = (DiscoveryClient) this.pantheonClientProvider.get(); - if (this.vipAddresses != null) { - String[] var3 = this.vipAddresses.split(","); - int var4 = var3.length; - - for (int var5 = 0; var5 < var4; ++var5) { - String vipAddress = var3[var5]; - List listOfInstanceInfo = pantheonClient.getInstance(vipAddress); - Iterator var8 = listOfInstanceInfo.iterator(); - - while (var8.hasNext()) { - InstanceInfo ii = (InstanceInfo) var8.next(); - if (ii.getStatus().equals(InstanceInfo.InstanceStatus.UP)) { - if (this.shouldUseOverridePort) { - if (logger.isDebugEnabled()) { - logger.debug("Overriding port on client name: " + this.clientName + " to " + this.overridePort); - } - - InstanceInfo copy = new InstanceInfo(ii); - ii = (new InstanceInfo.Builder(copy)).setPort(this.overridePort).build(); - } - - DiscoveryEnabledServer des = new DiscoveryEnabledServer(ii, this.isSecure, this.shouldUseIpAddr); - des.setZone("default"); - serverList.add(des); - } - } - - if (serverList.size() > 0 && this.prioritizeVipAddressBasedServers) { - break; - } - } - } - - return serverList; - } else { - logger.warn("PantheonClient has not been initialized yet, returning an empty list"); - return new ArrayList(); - } - } - - public String getVipAddresses() { - return this.vipAddresses; - } - - public void setVipAddresses(String vipAddresses) { - this.vipAddresses = vipAddresses; - } - - public String toString() { - StringBuilder sb = new StringBuilder("DiscoveryEnabledNIWSServerList:"); - sb.append("; clientName:").append(this.clientName); - sb.append("; Effective vipAddresses:").append(this.vipAddresses); - sb.append("; isSecure:").append(this.isSecure); - sb.append("; datacenter:").append(this.datacenter); - return sb.toString(); - } - - private static IClientConfig createClientConfig(String vipAddresses) { - IClientConfig clientConfig = DefaultClientConfigImpl.getClientConfigWithDefaultValues(); - clientConfig.set(IClientConfigKey.Keys.DeploymentContextBasedVipAddresses, vipAddresses); - return clientConfig; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledServer.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledServer.java deleted file mode 100644 index 69fc505..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledServer.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.netflix.loadbalancer.Server; -import com.pantheon.client.appinfo.InstanceInfo; -import com.sun.xml.internal.ws.wsdl.writer.document.PortType; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc Servers that were obtained via Discovery and hence contain meta data in the form of InstanceInfo - **/ -@SuppressWarnings({"EQ_DOESNT_OVERRIDE_EQUALS"}) -public class DiscoveryEnabledServer extends Server { - private final InstanceInfo instanceInfo; - private final MetaInfo serviceInfo; - - public DiscoveryEnabledServer(InstanceInfo instanceInfo, boolean useSecurePort) { - this(instanceInfo, useSecurePort, false); - } - - public DiscoveryEnabledServer(final InstanceInfo instanceInfo, boolean useSecurePort, boolean useIpAddr) { - super(useIpAddr ? instanceInfo.getIPAddr() : instanceInfo.getHostName(), instanceInfo.getPort()); - if (useSecurePort) { - super.setPort(instanceInfo.getSecurePort()); - } - - this.instanceInfo = instanceInfo; - this.serviceInfo = new MetaInfo() { - public String getAppName() { - return instanceInfo.getAppName(); - } - - public String getServerGroup() { - return instanceInfo.getAppGroupName(); - } - - public String getServiceIdForDiscovery() { - return instanceInfo.getInstanceId(); - } - - public String getInstanceId() { - return instanceInfo.getId(); - } - }; - } - - public InstanceInfo getInstanceInfo() { - return this.instanceInfo; - } - - public MetaInfo getMetaInfo() { - return this.serviceInfo; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/LegacyPantheonClientProvider.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/LegacyPantheonClientProvider.java deleted file mode 100644 index 5d12b7f..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/LegacyPantheonClientProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.pantheon.client.ClientManager; -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.config.DefaultInstanceConfig; -import com.pantheon.client.discovery.DiscoveryClient; - -import javax.inject.Provider; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc - **/ -class LegacyPantheonClientProvider implements Provider { - private volatile DiscoveryClientNode pantheonClient; - - LegacyPantheonClientProvider() { - } - - public synchronized DiscoveryClient get() { - if (this.pantheonClient == null) { - this.pantheonClient = ClientManager.getInstance().getOrCreateClientNode(); - } - - return this.pantheonClient; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/NIWSDiscoveryPing.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/NIWSDiscoveryPing.java deleted file mode 100644 index 8e1f8c2..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/NIWSDiscoveryPing.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractLoadBalancerPing; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.Server; -import com.pantheon.client.appinfo.InstanceInfo; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc "Ping" Discovery Client i.e. we dont do a real "ping". We just assume that the server is up if Discovery Client says so - **/ -public class NIWSDiscoveryPing extends AbstractLoadBalancerPing { - BaseLoadBalancer lb = null; - - public NIWSDiscoveryPing() { - } - - public BaseLoadBalancer getLb() { - return this.lb; - } - - public void setLb(BaseLoadBalancer lb) { - this.lb = lb; - } - - public boolean isAlive(Server server) { - boolean isAlive = true; - if (server != null && server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer dServer = (DiscoveryEnabledServer)server; - InstanceInfo instanceInfo = dServer.getInstanceInfo(); - if (instanceInfo != null) { - InstanceInfo.InstanceStatus status = instanceInfo.getStatus(); - if (status != null) { - // InstanceStatus.UP means alive in ribbon and pantheon discovery - isAlive = status.equals(InstanceInfo.InstanceStatus.UP); - } - } - } - - return isAlive; - } - - public void initWithNiwsConfig(IClientConfig clientConfig) { - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/PantheonNotificationServerListUpdater.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/PantheonNotificationServerListUpdater.java deleted file mode 100644 index 854b325..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/PantheonNotificationServerListUpdater.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.pantheon.netflix.client.loadbalancer; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.netflix.config.DynamicIntProperty; -import com.netflix.loadbalancer.ServerListUpdater; - -import com.pantheon.client.CacheRefreshedEvent; -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.PantheonEvent; -import com.pantheon.client.PantheonEventListener; -import com.pantheon.client.discovery.DiscoveryClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Provider; -import java.util.Date; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc A server list updater for the {@link com.netflix.loadbalancer.DynamicServerListLoadBalancer} that - * utilizes pantheon's event listener to trigger LB cache updates. - *

- * Note that when a cache refreshed notification is received, the actual update on the serverList is - * done on a separate scheduler as the notification is delivered on an pantheonclient thread. - **/ -public class PantheonNotificationServerListUpdater implements ServerListUpdater { - private static final Logger logger = LoggerFactory.getLogger(PantheonNotificationServerListUpdater.class); - final AtomicBoolean updateQueued; - private final AtomicBoolean isActive; - private final AtomicLong lastUpdated; - private final Provider pantheonClientProvider; - private final ExecutorService refreshExecutor; - private volatile PantheonEventListener updateListener; - private volatile DiscoveryClientNode pantheonClient; - - public static ExecutorService getDefaultRefreshExecutor() { - return PantheonNotificationServerListUpdater.LazyHolder.SINGLETON.defaultServerListUpdateExecutor; - } - - public PantheonNotificationServerListUpdater() { - this(new LegacyPantheonClientProvider()); - } - - public PantheonNotificationServerListUpdater(Provider pantheonClientProvider) { - this(pantheonClientProvider, getDefaultRefreshExecutor()); - } - - public PantheonNotificationServerListUpdater(Provider pantheonClientProvider, ExecutorService refreshExecutor) { - this.updateQueued = new AtomicBoolean(false); - this.isActive = new AtomicBoolean(false); - this.lastUpdated = new AtomicLong(System.currentTimeMillis()); - this.pantheonClientProvider = pantheonClientProvider; - this.refreshExecutor = refreshExecutor; - } - - public synchronized void start(final UpdateAction updateAction) { - if (this.isActive.compareAndSet(false, true)) { - this.updateListener = new PantheonEventListener() { - public void onEvent(PantheonEvent event) { - if (event instanceof CacheRefreshedEvent) { - if (!PantheonNotificationServerListUpdater.this.updateQueued.compareAndSet(false, true)) { - PantheonNotificationServerListUpdater.logger.info("an update action is already queued, returning as no-op"); - return; - } - - if (!PantheonNotificationServerListUpdater.this.refreshExecutor.isShutdown()) { - try { - PantheonNotificationServerListUpdater.this.refreshExecutor.submit(new Runnable() { - public void run() { - try { - updateAction.doUpdate(); - PantheonNotificationServerListUpdater.this.lastUpdated.set(System.currentTimeMillis()); - } catch (Exception var5) { - PantheonNotificationServerListUpdater.logger.warn("Failed to update serverList", var5); - } finally { - PantheonNotificationServerListUpdater.this.updateQueued.set(false); - } - - } - }); - } catch (Exception var3) { - PantheonNotificationServerListUpdater.logger.warn("Error submitting update task to executor, skipping one round of updates", var3); - PantheonNotificationServerListUpdater.this.updateQueued.set(false); - } - } else { - PantheonNotificationServerListUpdater.logger.debug("stopping PantheonNotificationServerListUpdater, as refreshExecutor has been shut down"); - PantheonNotificationServerListUpdater.this.stop(); - } - } - - } - }; - if (this.pantheonClient == null) { - this.pantheonClient = (DiscoveryClientNode) this.pantheonClientProvider.get(); - } - - if (this.pantheonClient == null) { - logger.error("Failed to register an updateListener to pantheon client, pantheon client is null"); - throw new IllegalStateException("Failed to start the updater, unable to register the update listener due to pantheon client being null."); - } - - this.pantheonClient.registerEventListener(this.updateListener); - } else { - logger.info("Update listener already registered, no-op"); - } - - } - - public synchronized void stop() { - if (this.isActive.compareAndSet(true, false)) { - if (this.pantheonClient != null) { - this.pantheonClient.unregisterEventListener(this.updateListener); - } - } else { - logger.info("Not currently active, no-op"); - } - - } - - public String getLastUpdate() { - return (new Date(this.lastUpdated.get())).toString(); - } - - public long getDurationSinceLastUpdateMs() { - return System.currentTimeMillis() - this.lastUpdated.get(); - } - - public int getNumberMissedCycles() { - return 0; - } - - public int getCoreThreads() { - return this.isActive.get() && this.refreshExecutor != null && this.refreshExecutor instanceof ThreadPoolExecutor ? ((ThreadPoolExecutor) this.refreshExecutor).getCorePoolSize() : 0; - } - - private static class LazyHolder { - private static final String CORE_THREAD = "PantheonNotificationServerListUpdater.ThreadPoolSize"; - private static final String QUEUE_SIZE = "PantheonNotificationServerListUpdater.queueSize"; - private static final PantheonNotificationServerListUpdater.LazyHolder SINGLETON = new PantheonNotificationServerListUpdater.LazyHolder(); - private final DynamicIntProperty poolSizeProp = new DynamicIntProperty("PantheonNotificationServerListUpdater.ThreadPoolSize", 2); - private final DynamicIntProperty queueSizeProp = new DynamicIntProperty("PantheonNotificationServerListUpdater.queueSize", 1000); - private final ThreadPoolExecutor defaultServerListUpdateExecutor; - private final Thread shutdownThread; - - private LazyHolder() { - int corePoolSize = this.getCorePoolSize(); - this.defaultServerListUpdateExecutor = new ThreadPoolExecutor(corePoolSize, corePoolSize * 5, 0L, TimeUnit.NANOSECONDS, - new ArrayBlockingQueue(this.queueSizeProp.get()), (new ThreadFactoryBuilder()).setNameFormat("PantheonNotificationServerListUpdater-%d").setDaemon(true).build()); - this.poolSizeProp.addCallback(new Runnable() { - public void run() { - int corePoolSize = PantheonNotificationServerListUpdater.LazyHolder.this.getCorePoolSize(); - PantheonNotificationServerListUpdater.LazyHolder.this.defaultServerListUpdateExecutor.setCorePoolSize(corePoolSize); - PantheonNotificationServerListUpdater.LazyHolder.this.defaultServerListUpdateExecutor.setMaximumPoolSize(corePoolSize * 5); - } - }); - this.shutdownThread = new Thread(new Runnable() { - public void run() { - PantheonNotificationServerListUpdater.logger.info("Shutting down the Executor for PantheonNotificationServerListUpdater"); - - try { - PantheonNotificationServerListUpdater.LazyHolder.this.defaultServerListUpdateExecutor.shutdown(); - Runtime.getRuntime().removeShutdownHook(PantheonNotificationServerListUpdater.LazyHolder.this.shutdownThread); - } catch (Exception var2) { - } - - } - }); - Runtime.getRuntime().addShutdownHook(this.shutdownThread); - } - - private int getCorePoolSize() { - int propSize = this.poolSizeProp.get(); - return propSize > 0 ? propSize : 2; - } - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServer.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServer.java deleted file mode 100644 index c4918f2..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServer.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import com.netflix.loadbalancer.Server; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc - **/ -class DomainExtractingServer extends DiscoveryEnabledServer { - private String id; - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, boolean useIpAddr, boolean approximateZoneFromHostname) { - super(server.getInstanceInfo(), useSecurePort, useIpAddr); - if (server.getInstanceInfo().getMetadata().containsKey("zone")) { - this.setZone((String)server.getInstanceInfo().getMetadata().get("zone")); - } else if (approximateZoneFromHostname) { - this.setZone(ZoneUtils.extractApproximateZone(server.getHost())); - } else { - this.setZone(server.getZone()); - } - - this.setId(this.extractId(server)); - this.setAlive(server.isAlive()); - this.setReadyToServe(server.isReadyToServe()); - } - - private String extractId(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer enabled = (DiscoveryEnabledServer)server; - InstanceInfo instance = enabled.getInstanceInfo(); - if (instance.getMetadata().containsKey("instanceId")) { - return instance.getHostName() + ":" + (String)instance.getMetadata().get("instanceId"); - } - } - - return super.getId(); - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServerList.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServerList.java deleted file mode 100644 index 1ca6f04..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServerList.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ServerList; -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledNIWSServerList; -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc {@link #getInitialListOfServers()} and {@link #getUpdatedListOfServers()} use {@link DiscoveryEnabledNIWSServerList} to load server list dynamically - **/ -public class DomainExtractingServerList implements ServerList { - private ServerList list; - private IClientConfig clientConfig; - private boolean approximateZoneFromHostname; - - public DomainExtractingServerList(ServerList list, IClientConfig clientConfig, boolean approximateZoneFromHostname) { - this.list = list; - this.clientConfig = clientConfig; - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - public List getInitialListOfServers() { - List servers = this.setZones(this.list.getInitialListOfServers()); - return servers; - } - - public List getUpdatedListOfServers() { - List servers = this.setZones(this.list.getUpdatedListOfServers()); - return servers; - } - - private List setZones(List servers) { - List result = new ArrayList(); - boolean isSecure = this.clientConfig.getPropertyAsBoolean(CommonClientConfigKey.IsSecure, Boolean.TRUE); - boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE); - Iterator var5 = servers.iterator(); - - while (var5.hasNext()) { - DiscoveryEnabledServer server = (DiscoveryEnabledServer) var5.next(); - result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr, this.approximateZoneFromHostname)); - } - - return result; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonRibbonClientConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonRibbonClientConfiguration.java deleted file mode 100644 index 3f23eea..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonRibbonClientConfiguration.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.ServerList; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.client.discovery.DiscoveryClient; -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledNIWSServerList; -import com.pantheon.netflix.client.loadbalancer.NIWSDiscoveryPing; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.netflix.ribbon.PropertiesFactory; -import org.springframework.cloud.netflix.ribbon.RibbonUtils; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -import javax.annotation.PostConstruct; -import javax.inject.Provider; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc Preprocessor that configures defaults for pantheon-discovered ribbon clients. - * Such as: @zone, NIWSServerListClassName, DeploymentContextBasedVipAddresses, NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more - **/ -@Configuration -public class PantheonRibbonClientConfiguration { - private static final Log log = LogFactory.getLog(PantheonRibbonClientConfiguration.class); - @Value("${ribbon.pantheon.approximateZoneFromHostname:false}") - private boolean approximateZoneFromHostname = false; - @Value("${ribbon.client.name}") - private String serviceId = "client"; - - @Autowired( - required = false - ) - private PantheonInstanceConfig pantheonConfig; - @Autowired - private PropertiesFactory propertiesFactory; - - public PantheonRibbonClientConfiguration() { - } - - public PantheonRibbonClientConfiguration( PantheonInstanceConfig pantheonConfig, String serviceId,boolean approximateZoneFromHostname) { - this.serviceId = serviceId; - this.pantheonConfig = pantheonConfig; - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - @Bean - @ConditionalOnMissingBean - public IPing ribbonPing(IClientConfig config) { - if (this.propertiesFactory.isSet(IPing.class, this.serviceId)) { - return (IPing)this.propertiesFactory.get(IPing.class, config, this.serviceId); - } else { - NIWSDiscoveryPing ping = new NIWSDiscoveryPing(); - ping.initWithNiwsConfig(config); - return ping; - } - } - - @Bean - @ConditionalOnMissingBean - public ServerList ribbonServerList(IClientConfig config, Provider pantheonClientProvider) { - if (this.propertiesFactory.isSet(ServerList.class, this.serviceId)) { - return (ServerList)this.propertiesFactory.get(ServerList.class, config, this.serviceId); - } else { - DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(config, pantheonClientProvider); - DomainExtractingServerList serverList = new DomainExtractingServerList(discoveryServerList, config, this.approximateZoneFromHostname); - return serverList; - } - } - - @Bean - public ServerIntrospector serverIntrospector() { - return new PantheonServerIntrospector(); - } - - @PostConstruct - public void preprocess() { - String zone = ConfigurationManager.getDeploymentContext().getValue(DeploymentContext.ContextKey.zone); - if (this.pantheonConfig != null && StringUtils.isEmpty(zone)) { - String availabilityZone; - if (this.approximateZoneFromHostname && this.pantheonConfig != null) { - availabilityZone = ZoneUtils.extractApproximateZone(this.pantheonConfig.getInstanceHostName()); - log.debug("Setting Zone To " + availabilityZone); - ConfigurationManager.getDeploymentContext().setValue(DeploymentContext.ContextKey.zone, availabilityZone); - } else { - availabilityZone = this.pantheonConfig == null ? null : (String)this.pantheonConfig.getMetadataMap().get("zone"); - if (availabilityZone == null) { -// String[] zones = this.pantheonConfig.getAvailabilityZones(this.pantheonConfig.getRegion()); -// availabilityZone = zones != null && zones.length > 0 ? zones[0] : null; - } - - if (availabilityZone != null) { - ConfigurationManager.getDeploymentContext().setValue(DeploymentContext.ContextKey.zone, availabilityZone); - } - } - } - - RibbonUtils.setRibbonProperty(this.serviceId, CommonClientConfigKey.DeploymentContextBasedVipAddresses.key(), this.serviceId); - RibbonUtils.setRibbonProperty(this.serviceId, CommonClientConfigKey.EnableZoneAffinity.key(), "true"); - } -} - diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonServerIntrospector.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonServerIntrospector.java deleted file mode 100644 index 7c821fd..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonServerIntrospector.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import com.netflix.loadbalancer.Server; -import com.pantheon.client.appinfo.InstanceInfo; -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; -import com.sun.xml.internal.ws.wsdl.writer.document.PortType; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; - -import java.util.Map; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc - **/ -public class PantheonServerIntrospector extends DefaultServerIntrospector { - public PantheonServerIntrospector() { - } - - public boolean isSecure(Server server) { - if (server instanceof DiscoveryEnabledServer) { - return false; -// DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer)server; -// return discoveryServer.getInstanceInfo().isPortEnabled( InstanceInfo.PortType.SECURE); - } else { - return super.isSecure(server); - } - } - - public Map getMetadata(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; - return discoveryServer.getInstanceInfo().getMetadata(); - } else { - return super.getMetadata(server); - } - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/RibbonPantheonAutoConfiguration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/RibbonPantheonAutoConfiguration.java deleted file mode 100644 index 983183c..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/RibbonPantheonAutoConfiguration.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledNIWSServerList; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc Spring configuration for configuring Ribbon defaults to be Pantheon based if Pantheon client is enabled - **/ -@Configuration -@EnableConfigurationProperties -@RibbonPantheonAutoConfiguration.ConditionalOnRibbonAndPantheonEnabled -@AutoConfigureAfter({RibbonAutoConfiguration.class}) -@RibbonClients( - defaultConfiguration = {PantheonRibbonClientConfiguration.class} -) -public class RibbonPantheonAutoConfiguration { - public RibbonPantheonAutoConfiguration() { - } - - private static class OnRibbonAndPantheonEnabledCondition extends AllNestedConditions { - public OnRibbonAndPantheonEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty( - value = {"pantheon.client.enabled"}, - matchIfMissing = true - ) - static class OnPantheonClientEnabled { - OnPantheonClientEnabled() { - } - } - - @ConditionalOnBean({DiscoveryClient.class}) - static class PantheonBeans { - PantheonBeans() { - } - } - - @ConditionalOnClass({DiscoveryEnabledNIWSServerList.class}) - @ConditionalOnBean({SpringClientFactory.class}) - @ConditionalOnProperty( - value = {"ribbon.pantheon.enabled"}, - matchIfMissing = true - ) - static class Defaults { - Defaults() { - } - } - } - - @Target({ElementType.TYPE, ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional({RibbonPantheonAutoConfiguration.OnRibbonAndPantheonEnabledCondition.class}) - @interface ConditionalOnRibbonAndPantheonEnabled { - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/ZoneUtils.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/ZoneUtils.java deleted file mode 100644 index 5e63d55..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/ZoneUtils.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.pantheon.netflix.client.ribbon; - -import org.springframework.util.StringUtils; - -/** - * @author Anthony - * @create 2021/12/20 - * @desc - **/ -public class ZoneUtils { - public ZoneUtils() { - } - - public static String extractApproximateZone(String host) { - String[] split = StringUtils.split(host, "."); - return split == null ? host : split[1]; - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonAutoServiceRegistration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonAutoServiceRegistration.java deleted file mode 100644 index 6e29177..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonAutoServiceRegistration.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.pantheon.netflix.client.serviceregistry; - -import com.pantheon.netflix.client.AutoServiceRegistration; -import com.pantheon.netflix.client.PantheonDiscoveryClientConfiguration; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.SmartLifecycle; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.EventListener; -import org.springframework.core.Ordered; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc called by auto configuration class {@link PantheonDiscoveryClientConfiguration} - **/ -public class PantheonAutoServiceRegistration implements AutoServiceRegistration, SmartLifecycle, Ordered { - private static final Log log = LogFactory.getLog(PantheonAutoServiceRegistration.class); - private AtomicBoolean running = new AtomicBoolean(false); - private int order = 0; - private AtomicInteger port = new AtomicInteger(0); - private ApplicationContext context; - private PantheonServiceRegistry serviceRegistry; - private PantheonRegistration registration; - - public PantheonAutoServiceRegistration(ApplicationContext context, PantheonServiceRegistry serviceRegistry, PantheonRegistration registration) { - this.context = context; - this.serviceRegistry = serviceRegistry; - this.registration = registration; - } - - public void start() { - if (this.port.get() != 0) { - if (this.registration.getNonSecurePort() == 0) { - this.registration.setNonSecurePort(this.port.get()); - } - } - - if (!this.running.get() && this.registration.getNonSecurePort() > 0) { - this.serviceRegistry.register(this.registration); - this.context.publishEvent(new InstanceRegisteredEvent(this, this.registration.getInstanceConfig())); - this.running.set(true); - } - - } - - public void stop() { - this.serviceRegistry.deregister(this.registration); - this.running.set(false); - } - - public boolean isRunning() { - return this.running.get(); - } - - public int getPhase() { - return 0; - } - - public boolean isAutoStartup() { - return true; - } - - public void stop(Runnable callback) { - this.stop(); - callback.run(); - } - - public int getOrder() { - return this.order; - } - - @EventListener({EmbeddedServletContainerInitializedEvent.class}) - public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) { - int localPort = event.getEmbeddedServletContainer().getPort(); - if (this.port.get() == 0) { - log.info("Updating port to " + localPort); - this.port.compareAndSet(0, localPort); - this.start(); - } - - } - - @EventListener({ContextClosedEvent.class}) - public void onApplicationEvent(ContextClosedEvent event) { - if (event.getApplicationContext() == this.context) { - this.stop(); - } - - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonRegistration.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonRegistration.java deleted file mode 100644 index 46bde7b..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonRegistration.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.pantheon.netflix.client.serviceregistry; - -import com.pantheon.client.DiscoveryClientNode; -import com.pantheon.client.config.PantheonInstanceConfig; -import com.pantheon.netflix.client.HealthCheckHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.util.Assert; - -import java.net.URI; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public class PantheonRegistration implements Registration { - private static final Log log = LogFactory.getLog(PantheonRegistration.class); - private final DiscoveryClientNode pantheonClient; - private final AtomicReference cloudPantheonClient; - private final PantheonInstanceConfig instanceConfig; - private HealthCheckHandler healthCheckHandler; - - private PantheonRegistration(PantheonInstanceConfig instanceConfig, DiscoveryClientNode pantheonClient, HealthCheckHandler healthCheckHandler) { - this.cloudPantheonClient = new AtomicReference(); - this.pantheonClient = pantheonClient; - this.instanceConfig = instanceConfig; - this.healthCheckHandler = healthCheckHandler; - } - - public static PantheonRegistration.Builder builder(PantheonInstanceConfig instanceConfig) { - return new PantheonRegistration.Builder(instanceConfig); - } - - public String getServiceId() { - return this.instanceConfig.getServiceName(); - } - - public String getHost() { - return this.instanceConfig.getInstanceHostName(); - } - - public int getPort() { - return this.instanceConfig.getInstancePort(); - } - - public boolean isSecure() { - return false; - } - - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - public Map getMetadata() { - return this.instanceConfig.getMetadataMap(); - } - - public DiscoveryClientNode getPantheonClient() { - if (this.cloudPantheonClient.get() == null) { - try { - this.cloudPantheonClient.compareAndSet(null,pantheonClient); - } catch (Exception var2) { - log.error("error getting PantheonClient", var2); - } - } - - return (DiscoveryClientNode) this.cloudPantheonClient.get(); - } - -// protected T getTargetObject(Object proxy, Class targetClass) throws Exception { -// return AopUtils.isJdkDynamicProxy(proxy) ? ((Advised)proxy).getTargetSource().getTarget() : proxy; -// } - - public PantheonInstanceConfig getInstanceConfig() { - return this.instanceConfig; - } - - public HealthCheckHandler getHealthCheckHandler() { - return this.healthCheckHandler; - } - - public void setHealthCheckHandler(HealthCheckHandler healthCheckHandler) { - this.healthCheckHandler = healthCheckHandler; - } - - public void setNonSecurePort(int port) { - this.instanceConfig.setInstancePort(port); - } - - public int getNonSecurePort() { - return this.instanceConfig.getInstancePort(); - } - - - public static class Builder { - private final PantheonInstanceConfig instanceConfig; - private DiscoveryClientNode pantheonClient; - private HealthCheckHandler healthCheckHandler; - private PantheonInstanceConfig clientConfig; - private ApplicationEventPublisher publisher; - - Builder(PantheonInstanceConfig instanceConfig) { - this.instanceConfig = instanceConfig; - } - - - public PantheonRegistration.Builder with(DiscoveryClientNode pantheonClient) { - this.pantheonClient = pantheonClient; - return this; - } - - public PantheonRegistration.Builder with(HealthCheckHandler healthCheckHandler) { - this.healthCheckHandler = healthCheckHandler; - return this; - } - - public PantheonRegistration.Builder with(PantheonInstanceConfig clientConfig, ApplicationEventPublisher publisher) { - this.clientConfig = clientConfig; - this.publisher = publisher; - return this; - } - - public PantheonRegistration build() { - Assert.notNull(this.instanceConfig, "instanceConfig may not be null"); - - if (this.pantheonClient == null) { - Assert.notNull(this.clientConfig, "if pantheonClient is null, clientConfig may not be null"); - Assert.notNull(this.publisher, "if pantheonClient is null, ApplicationEventPublisher may not be null"); - this.pantheonClient = new DiscoveryClientNode(this.clientConfig); - } - - return new PantheonRegistration(this.instanceConfig, this.pantheonClient, this.healthCheckHandler); - } - } -} diff --git a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonServiceRegistry.java b/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonServiceRegistry.java deleted file mode 100644 index 37cd764..0000000 --- a/pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonServiceRegistry.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.pantheon.netflix.client.serviceregistry; - -import com.pantheon.client.appinfo.InstanceInfo; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; - -import java.util.HashMap; - -/** - * @author Anthony - * @create 2021/12/17 - * @desc - **/ -public class PantheonServiceRegistry implements ServiceRegistry { - private static final Log log = LogFactory.getLog(PantheonServiceRegistry.class); - - public PantheonServiceRegistry() { - } - - public void register(PantheonRegistration reg) { - this.maybeInitializeClient(reg); - if (log.isInfoEnabled()) { -// log.info("Registering application " + reg.getInstanceConfig().getServiceName() + " with pantheon with status " + reg.getInstanceConfig().getInitialStatus()); - } - -//todo reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus()); - if (reg.getHealthCheckHandler() != null) { -//todo reg.getEurekaClient().registerHealthCheck(reg.getHealthCheckHandler()); - } - - } - - private void maybeInitializeClient(PantheonRegistration reg) { -// reg.getApplicationInfoManager().getInfo(); - reg.getPantheonClient().getApplications(); - } - - public void deregister(PantheonRegistration reg) { -// if (reg.getApplicationInfoManager().getInfo() != null) { -// if (log.isInfoEnabled()) { -// log.info("Unregistering application " + reg.getInstanceConfig().getAppname() + " with eureka with status DOWN"); -// } -// -// reg.getApplicationInfoManager().setInstanceStatus(InstanceStatus.DOWN); -// } - - } - - public void setStatus(PantheonRegistration registration, String status) { -// InstanceInfo info = registration.getApplicationInfoManager().getInfo(); - if ("CANCEL_OVERRIDE".equalsIgnoreCase(status)) { -// registration.getEurekaClient().cancelOverrideStatus(info); - } else { - InstanceInfo.InstanceStatus newStatus = InstanceInfo.InstanceStatus.toEnum(status); -// registration.getEurekaClient().setStatus(newStatus, info); - } - } - - public Object getStatus(PantheonRegistration registration) { - HashMap status = new HashMap(); -// InstanceInfo info = registration.getApplicationInfoManager().getInfo(); - InstanceInfo info=new InstanceInfo(); - status.put("status", info.getStatus().toString()); - status.put("overriddenStatus", info.getOverriddenStatus().toString()); - return status; - } - - public void close() { - } -} diff --git a/pantheon-spring-cloud-netflix-server/pom.xml b/pantheon-spring-cloud-netflix-server/pom.xml deleted file mode 100644 index 3f5a574..0000000 --- a/pantheon-spring-cloud-netflix-server/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-spring-cloud-netflix-server - - - 8 - 8 - - - - - org.springframework.cloud - spring-cloud-commons - 1.3.4.RELEASE - - - \ No newline at end of file diff --git a/pantheon-zuul-support/pom.xml b/pantheon-zuul-support/pom.xml deleted file mode 100644 index ded7228..0000000 --- a/pantheon-zuul-support/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - pantheon - com.pantheon - 1.0-SNAPSHOT - - 4.0.0 - - pantheon-zuul-support - - - 13 - 13 - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 95064cc..0000000 --- a/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - 4.0.0 - - com.pantheon - pantheon - pom - 1.0-SNAPSHOT - - pantheon-server - pantheon-client - pantheon-common - pantheon-remoting - pantheon-spring-cloud-netflix-client - pantheon-spring-cloud-netflix-server - pantheon-dubbo-support - pantheon-zuul-support - pantheon-spring-cloud-gateway-support - - - - - 8 - 8 - - - - repository.jboss.org-public - JBoss.org Maven repository - https://repository.jboss.org/nexus/content/groups/public - - - - - javax.jms - jms - 1.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - log4j - log4j - 1.2.17 - - - com.alibaba - fastjson - 1.2.71 - - - io.netty - netty-all - 4.0.42.Final - - - com.netflix.archaius - archaius-core - 0.7.6 - - - commons-configuration - commons-configuration - 1.8 - - - - \ No newline at end of file