├── .gitignore ├── README.md ├── pantheon-client ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── pantheon │ │ └── client │ │ ├── CacheRefreshedEvent.java │ │ ├── ClientBootStrap.java │ │ ├── ClientManager.java │ │ ├── DiscoveryClientNode.java │ │ ├── PantheonEvent.java │ │ ├── PantheonEventListener.java │ │ ├── RebalanceService.java │ │ ├── StatusChangeEvent.java │ │ ├── appinfo │ │ ├── Application.java │ │ ├── Applications.java │ │ ├── InstanceInfo.java │ │ └── LeaseInfo.java │ │ ├── config │ │ ├── AbstractInstanceConfig.java │ │ ├── DefaultInstanceConfig.java │ │ └── PantheonInstanceConfig.java │ │ ├── discovery │ │ └── DiscoveryClient.java │ │ ├── transport │ │ ├── ClientAPIImpl.java │ │ ├── ClientRemotingProcessor.java │ │ ├── HeartBeatSender.java │ │ └── Server.java │ │ └── utils │ │ ├── Archaius1Utils.java │ │ └── Pair.java │ └── resources │ ├── pantheon-client-instance1.properties │ ├── pantheon-client-instance2.properties │ └── pantheon-client.properties ├── pantheon-common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── pantheon │ └── common │ ├── CountDownLatch2.java │ ├── MessageType.java │ ├── ObjectUtils.java │ ├── PantheonVersion.java │ ├── ServerNodeRole.java │ ├── ServiceState.java │ ├── ServiceThread.java │ ├── ShutdownHookThread.java │ ├── ThreadFactoryImpl.java │ ├── entity │ ├── Message.java │ └── Request.java │ ├── exception │ └── InitException.java │ ├── lifecycle │ ├── AbstractLifecycleComponent.java │ ├── Lifecycle.java │ ├── LifecycleComponent.java │ ├── LifecycleListener.java │ └── Releasable.java │ └── protocol │ ├── RemotingSysResponseCode.java │ ├── RequestCode.java │ ├── ResponseCode.java │ ├── header │ ├── FetchServerAddressRequestHeader.java │ ├── FetchServerAddressResponseHeader.java │ ├── GetConsumerRunningInfoRequestHeader.java │ ├── GetServerAddressRequestHeader.java │ ├── GetServerAddressResponseHeader.java │ ├── GetServerNodeIdRequestHeader.java │ ├── GetServerNodeIdResponseHeader.java │ ├── GetSlotsRequestHeader.java │ └── GetSlotsResponseHeader.java │ └── heartBeat │ ├── HeartBeat.java │ ├── ServiceUnregister.java │ └── SubscriptionData.java ├── pantheon-dubbo-support └── pom.xml ├── pantheon-remoting ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── pantheon │ │ └── remoting │ │ ├── ChannelEventListener.java │ │ ├── CommandCustomHeader.java │ │ ├── InvokeCallback.java │ │ ├── RPCHook.java │ │ ├── RemotingClient.java │ │ ├── RemotingServer.java │ │ ├── RemotingService.java │ │ ├── annotation │ │ ├── CFNotNull.java │ │ └── CFNullable.java │ │ ├── common │ │ ├── Pair.java │ │ ├── RemotingHelper.java │ │ ├── RemotingUtil.java │ │ ├── SemaphoreReleaseOnlyOnce.java │ │ ├── ServiceThread.java │ │ └── TlsMode.java │ │ ├── exception │ │ ├── RemotingCommandException.java │ │ ├── RemotingConnectException.java │ │ ├── RemotingException.java │ │ ├── RemotingSendRequestException.java │ │ ├── RemotingTimeoutException.java │ │ └── RemotingTooMuchRequestException.java │ │ ├── netty │ │ ├── AsyncNettyRequestProcessor.java │ │ ├── FileRegionEncoder.java │ │ ├── NettyClientConfig.java │ │ ├── NettyDecoder.java │ │ ├── NettyEncoder.java │ │ ├── NettyEvent.java │ │ ├── NettyEventType.java │ │ ├── NettyLogger.java │ │ ├── NettyRemotingAbstract.java │ │ ├── NettyRemotingClient.java │ │ ├── NettyRemotingServer.java │ │ ├── NettyRequestProcessor.java │ │ ├── NettyServerConfig.java │ │ ├── NettySystemConfig.java │ │ ├── RemotingResponseCallback.java │ │ ├── RequestTask.java │ │ ├── ResponseFuture.java │ │ ├── TlsHelper.java │ │ └── TlsSystemConfig.java │ │ └── protocol │ │ ├── LanguageCode.java │ │ ├── PantheonSerializable.java │ │ ├── RemotingCommand.java │ │ ├── RemotingCommandType.java │ │ ├── RemotingSerializable.java │ │ ├── RemotingSysResponseCode.java │ │ └── SerializeType.java │ └── resources │ └── log4j.properties ├── pantheon-server ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── pantheon │ │ └── server │ │ ├── ServerBootstrap.java │ │ ├── ServerNode.java │ │ ├── client │ │ ├── ClientChannelInfo.java │ │ ├── ClientHousekeepingService.java │ │ ├── ConsumerInfoManager.java │ │ └── ServerToClient.java │ │ ├── config │ │ ├── ArchaiusPantheonServerConfig.java │ │ ├── CachedPantheonServerConfig.java │ │ └── PantheonServerConfig.java │ │ ├── lease │ │ ├── Lease.java │ │ └── LeaseManager.java │ │ ├── network │ │ ├── IOThreadRunningSignal.java │ │ ├── ServerMessageReceiver.java │ │ ├── ServerNetworkManager.java │ │ ├── ServerReadIOThread.java │ │ └── ServerWriteIOThread.java │ │ ├── node │ │ ├── Controller.java │ │ ├── ControllerCandidate.java │ │ ├── ControllerNode.java │ │ ├── ControllerVote.java │ │ ├── RemoteServerNode.java │ │ └── RemoteServerNodeManager.java │ │ ├── persist │ │ └── FilePersistUtils.java │ │ ├── processor │ │ ├── ClientManageProcessor.java │ │ └── ServerNodeProcessor.java │ │ ├── registry │ │ ├── InstanceRegistry.java │ │ ├── InstanceRegistryImpl.java │ │ ├── Key.java │ │ ├── LeaseExistsRule.java │ │ ├── OverrideExistsRule.java │ │ ├── ResponseCache.java │ │ ├── ResponseCacheImpl.java │ │ └── RouteInstanceToSlotRegistry.java │ │ ├── rule │ │ ├── AlwaysMatchInstanceStatusRule.java │ │ ├── DownOrStartingRule.java │ │ ├── FirstMatchWinsCompositeRule.java │ │ ├── InstanceStatusOverrideRule.java │ │ └── StatusOverrideResult.java │ │ └── slot │ │ ├── Slot.java │ │ ├── SlotManager.java │ │ ├── Slots.java │ │ ├── SlotsReplica.java │ │ └── registry │ │ ├── ServiceChangedListener.java │ │ ├── ServiceInstance.java │ │ └── ServiceRegistry.java │ └── resources │ ├── application.properties │ ├── log4j.properties │ ├── pantheon-server-test1.properties │ ├── pantheon-server-test2.properties │ └── pantheon-server.properties ├── pantheon-spring-cloud-gateway-support └── pom.xml ├── pantheon-spring-cloud-netflix-client-new ├── README.md └── pom.xml ├── pantheon-spring-cloud-netflix-client ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── pantheon │ └── netflix │ └── client │ ├── AutoServiceRegistration.java │ ├── EnablePantheonClient.java │ ├── HealthCheckHandler.java │ ├── InstanceInfoFactory.java │ ├── PantheonClientAutoConfiguration.java │ ├── PantheonDiscoveryClient.java │ ├── PantheonDiscoveryClientConfiguration.java │ ├── PantheonHealthCheckHandler.java │ ├── PantheonHealthIndicator.java │ ├── config │ ├── PantheonDiscoveryClientConfigServiceAutoConfiguration.java │ └── PantheonDiscoveryClientConfigServiceBootstrapConfiguration.java │ ├── loadbalancer │ ├── DefaultNIWSServerListFilter.java │ ├── DiscoveryEnabledNIWSServerList.java │ ├── DiscoveryEnabledServer.java │ ├── LegacyPantheonClientProvider.java │ ├── NIWSDiscoveryPing.java │ └── PantheonNotificationServerListUpdater.java │ ├── ribbon │ ├── DomainExtractingServer.java │ ├── DomainExtractingServerList.java │ ├── PantheonRibbonClientConfiguration.java │ ├── PantheonServerIntrospector.java │ ├── RibbonPantheonAutoConfiguration.java │ └── ZoneUtils.java │ └── serviceregistry │ ├── PantheonAutoServiceRegistration.java │ ├── PantheonRegistration.java │ └── PantheonServiceRegistry.java ├── pantheon-spring-cloud-netflix-server └── pom.xml ├── pantheon-zuul-support └── pom.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | 27 | # OS generated files # 28 | ###################### 29 | .DS_Store* 30 | ehthumbs.db 31 | Icon? 32 | Thumbs.db 33 | 34 | # Editor Files # 35 | ################ 36 | *~ 37 | *.swp 38 | 39 | # Gradle Files # 40 | ################ 41 | .gradle 42 | .m2 43 | 44 | # Build output directies 45 | /target 46 | */target 47 | /build 48 | */build 49 | /bin 50 | */bin 51 | classes 52 | 53 | # 54 | # # IntelliJ specific files/directories 55 | 56 | # IntelliJ specific files/directories 57 | out 58 | .idea 59 | *.ipr 60 | *.iws 61 | *.iml 62 | atlassian-ide-plugin.xml 63 | 64 | # Eclipse specific files/directories 65 | .classpath 66 | .project 67 | .settings 68 | .metadata 69 | 70 | # NetBeans specific files/directories 71 | .nbattrs 72 | 73 | # publishing secrets 74 | secrets/signing-key 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pantheon 2 | Pantheon is inspired by Eureka and Nacos, aiming to build a better Service Registry Center 3 | 4 | Numerous terrific code snippets and architecture ideas from RocketMq, Zookeeper, ElasticSearch, Redis,Eureka,Nacos, Dubbo...... 5 | are introduced into this project. -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/CacheRefreshedEvent.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/12/20 6 | * @desc 7 | **/ 8 | public class CacheRefreshedEvent implements PantheonEvent { 9 | public CacheRefreshedEvent() { 10 | } 11 | 12 | public String toString() { 13 | return "CacheRefreshedEvent[timestamp=" + System.currentTimeMillis()+ "]"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/ClientBootStrap.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | import com.pantheon.client.config.DefaultInstanceConfig; 4 | import com.pantheon.common.ShutdownHookThread; 5 | import com.pantheon.common.lifecycle.Lifecycle; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.concurrent.Callable; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/11/17 14 | * @desc 15 | **/ 16 | public class ClientBootStrap { 17 | private static final Logger logger = LoggerFactory.getLogger(ClientBootStrap.class); 18 | 19 | public static void main(String[] args) { 20 | logger.info("InstanceBootStrap initializing......"); 21 | DiscoveryClientNode discoveryClientNode = ClientManager.getInstance().getOrCreateClientNode(DefaultInstanceConfig.getInstance()); 22 | 23 | discoveryClientNode.start(); 24 | if (!discoveryClientNode.lifecycleState().equals(Lifecycle.State.STARTED)) { 25 | discoveryClientNode.stop(); 26 | System.exit(-3); 27 | } 28 | Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(logger, (Callable) () -> { 29 | discoveryClientNode.stop(); 30 | return null; 31 | })); 32 | } 33 | 34 | public static void shutdown(final DiscoveryClientNode discoveryClientNode) { 35 | discoveryClientNode.stop(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/ClientManager.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | import com.pantheon.client.config.DefaultInstanceConfig; 4 | import com.pantheon.remoting.netty.NettyClientConfig; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.concurrent.ConcurrentHashMap; 9 | import java.util.concurrent.ConcurrentMap; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/12/5 14 | * @desc singleton to manage all clients 15 | */ 16 | public class ClientManager { 17 | private static final Logger logger = LoggerFactory.getLogger(ClientManager.class); 18 | 19 | private ConcurrentMap factoryTable = 20 | new ConcurrentHashMap<>(); 21 | private NettyClientConfig nettyClientConfig; 22 | 23 | private static ClientManager instance = new ClientManager(); 24 | private DefaultInstanceConfig instanceConfig; 25 | 26 | private ClientManager() { 27 | 28 | } 29 | 30 | public static ClientManager getInstance() { 31 | return instance; 32 | } 33 | 34 | public DiscoveryClientNode getOrCreateClientNode() { 35 | this.instanceConfig = DefaultInstanceConfig.getInstance(); 36 | nettyClientConfig = new NettyClientConfig(); 37 | 38 | String clientId = getInstance().buildClientId(); 39 | DiscoveryClientNode instance = this.factoryTable.get(clientId); 40 | if (null == instance) { 41 | instance = new DiscoveryClientNode(nettyClientConfig, instanceConfig, clientId); 42 | DiscoveryClientNode prev = this.factoryTable.putIfAbsent(clientId, instance); 43 | if (prev != null) { 44 | instance = prev; 45 | logger.warn("Returned Previous ClientNode for clientId:[{}]", clientId); 46 | } else { 47 | logger.info("Created new ClientNode for clientId:[{}]", clientId); 48 | } 49 | } 50 | 51 | return instance; 52 | 53 | } 54 | 55 | 56 | public DiscoveryClientNode getOrCreateClientNode(DefaultInstanceConfig instanceConfig) { 57 | this.instanceConfig = instanceConfig; 58 | nettyClientConfig = new NettyClientConfig(); 59 | 60 | String clientId = getInstance().buildClientId(); 61 | DiscoveryClientNode instance = this.factoryTable.get(clientId); 62 | if (null == instance) { 63 | instance = new DiscoveryClientNode(nettyClientConfig, instanceConfig, clientId); 64 | DiscoveryClientNode prev = this.factoryTable.putIfAbsent(clientId, instance); 65 | if (prev != null) { 66 | instance = prev; 67 | logger.warn("Returned Previous ClientNode for clientId:[{}]", clientId); 68 | } else { 69 | logger.info("Created new ClientNode for clientId:[{}]", clientId); 70 | } 71 | } 72 | 73 | return instance; 74 | 75 | } 76 | 77 | public String buildClientId() { 78 | StringBuilder sb = new StringBuilder(); 79 | sb.append(instanceConfig.getInstanceIpAddress()); 80 | 81 | sb.append(":"); 82 | sb.append(instanceConfig.getServiceName()); 83 | sb.append(":"); 84 | sb.append(instanceConfig.getInstancePort()); 85 | 86 | return sb.toString(); 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/PantheonEvent.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | /** 4 | * Marker interface for Pantheon events 5 | * 6 | * @see {@link PantheonEventListener} 7 | */ 8 | public interface PantheonEvent { 9 | } 10 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/PantheonEventListener.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | /** 4 | * Listener for receiving {@link DiscoveryClientNode} events such as {@link StatusChangeEvent}. Register 5 | * a listener by calling {@link DiscoveryClientNode#registerEventListener(PantheonEventListener)} 6 | */ 7 | public interface PantheonEventListener { 8 | /** 9 | * Notification of an event within the {@link DiscoveryClientNode}. 10 | * 11 | * {@link PantheonEventListener#onEvent} is called from the context of an internal pantheon thread 12 | * and must therefore return as quickly as possible without blocking. 13 | * 14 | * @param event 15 | */ 16 | public void onEvent(PantheonEvent event); 17 | } 18 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/RebalanceService.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/27 6 | * @desc todo Rebalance service 7 | */ 8 | public class RebalanceService { 9 | } 10 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/StatusChangeEvent.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client; 2 | 3 | import com.pantheon.client.appinfo.InstanceInfo; 4 | 5 | /** 6 | * Event containing the latest instance status information. This event 7 | * is sent to the {@link com.netflix.eventbus.spi.EventBus} by {@link DiscoveryClientNode ) whenever 8 | * a status change is identified from the remote Pantheon server response. 9 | */ 10 | public class StatusChangeEvent implements PantheonEvent{ 11 | // System time when the event happened 12 | private final long timestamp; 13 | private final InstanceInfo.InstanceStatus current; 14 | private final InstanceInfo.InstanceStatus previous; 15 | 16 | public StatusChangeEvent(InstanceInfo.InstanceStatus previous, InstanceInfo.InstanceStatus current) { 17 | this.timestamp = System.currentTimeMillis(); 18 | this.current = current; 19 | this.previous = previous; 20 | } 21 | 22 | 23 | /** 24 | * @return Return the system time in milliseconds when the event happened. 25 | */ 26 | public final long getTimestamp() { 27 | return this.timestamp; 28 | } 29 | 30 | /** 31 | * Return the up current when the event was generated. 32 | * @return true if current is up or false for ALL other current values 33 | */ 34 | public boolean isUp() { 35 | return this.current.equals(InstanceInfo.InstanceStatus.UP); 36 | } 37 | 38 | /** 39 | * @return The current at the time the event is generated. 40 | */ 41 | public InstanceInfo.InstanceStatus getStatus() { 42 | return current; 43 | } 44 | 45 | /** 46 | * @return Return the client status immediately before the change 47 | */ 48 | public InstanceInfo.InstanceStatus getPreviousStatus() { 49 | return previous; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return "StatusChangeEvent [timestamp=" + getTimestamp() + ", current=" + current + ", previous=" 55 | + previous + "]"; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/config/AbstractInstanceConfig.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.config; 2 | 3 | import com.pantheon.client.utils.Pair; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/11/17 14 | * @desc An abstract instance info configuration with some DEFAULT VALUE to get the users 15 | * started quickly.The users have to override only a few methods to register 16 | * their instance with pantheon server. 17 | **/ 18 | public abstract class AbstractInstanceConfig implements PantheonInstanceConfig { 19 | private static final Logger logger = LoggerFactory.getLogger(AbstractInstanceConfig.class); 20 | 21 | private static final int LEASE_EXPIRATION_DURATION_SECONDS = 10; 22 | private static final int LEASE_RENEWAL_INTERVAL_SECONDS = 3; 23 | private static final int DEFAULT_INSTANCE_PORT = 6755; 24 | 25 | private static final Pair hostInfo = getHostInfo(); 26 | 27 | protected AbstractInstanceConfig() { 28 | 29 | } 30 | 31 | @Override 32 | public String getInstanceHostName() { 33 | return hostInfo.second(); 34 | } 35 | 36 | @Override 37 | public String getInstanceIpAddress() { 38 | return hostInfo.first(); 39 | } 40 | 41 | @Override 42 | public Integer getLeaseRenewalIntervalInSeconds() { 43 | return LEASE_RENEWAL_INTERVAL_SECONDS; 44 | } 45 | 46 | @Override 47 | public Integer getLeaseExpirationDurationInSeconds() { 48 | return LEASE_EXPIRATION_DURATION_SECONDS; 49 | } 50 | 51 | @Override 52 | public Integer getInstancePort() { 53 | return DEFAULT_INSTANCE_PORT; 54 | } 55 | 56 | @Override 57 | public boolean shouldFilterOnlyUpInstances() { 58 | return true; 59 | } 60 | 61 | private static Pair getHostInfo() { 62 | Pair pair; 63 | try { 64 | InetAddress localHost = InetAddress.getLocalHost(); 65 | pair = new Pair(localHost.getHostAddress(), localHost.getHostName()); 66 | } catch (UnknownHostException e) { 67 | logger.error("Cannot get host info", e); 68 | pair = new Pair("", ""); 69 | } 70 | return pair; 71 | } 72 | 73 | @Override 74 | public Map getMetadataMap() { 75 | return null; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/config/PantheonInstanceConfig.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.config; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author Anthony 8 | * @create 2021/11/17 9 | * @desc Configuration information required by the instance to register with Pantheon server. 10 | **/ 11 | public interface PantheonInstanceConfig { 12 | 13 | /** 14 | * Get the name of the Service to be registered with pantheon. 15 | */ 16 | String getServiceName(); 17 | 18 | String getInstanceId(); 19 | 20 | /** 21 | * default localhost name 22 | */ 23 | String getInstanceHostName(); 24 | 25 | /** 26 | * default localhost ip address 27 | */ 28 | String getInstanceIpAddress(); 29 | 30 | Integer getLeaseRenewalIntervalInSeconds(); 31 | 32 | Integer getLeaseExpirationDurationInSeconds(); 33 | 34 | /** 35 | * instances connect one of these servers 36 | * 37 | * @return 38 | */ 39 | List getServerList(); 40 | 41 | Integer getInstancePort(); 42 | 43 | Integer setInstancePort(Integer port); 44 | 45 | /** 46 | * should fetch registry ,default true 47 | * @return 48 | */ 49 | boolean shouldFetchRegistry(); 50 | 51 | boolean shouldFilterOnlyUpInstances(); 52 | 53 | /** 54 | * Indicates how often(in seconds) to fetch the registry information from 55 | * the server. 56 | * 57 | * @return the fetch interval in seconds. 58 | */ 59 | int getRegistryFetchIntervalSeconds(); 60 | 61 | Map getMetadataMap(); 62 | } 63 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/discovery/DiscoveryClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.client.discovery; 3 | 4 | 5 | import com.pantheon.client.PantheonEventListener; 6 | import com.pantheon.client.appinfo.Application; 7 | import com.pantheon.client.appinfo.Applications; 8 | import com.pantheon.client.appinfo.InstanceInfo; 9 | import com.pantheon.client.config.PantheonInstanceConfig; 10 | 11 | import java.util.List; 12 | 13 | 14 | public interface DiscoveryClient { 15 | 16 | /** 17 | * Returns the corresponding {@link Application} object which is basically a 18 | * container of all registered appName {@link InstanceInfo}s. 19 | * 20 | * @param appName 21 | * @return a {@link Application} or null if we couldn't locate any app of 22 | * the requested appName 23 | */ 24 | Application getApplication(String appName); 25 | 26 | /** 27 | * Returns the {@link Applications} object which is basically a container of 28 | * all currently registered {@link Application}s. 29 | * 30 | * @return {@link Applications} 31 | */ 32 | Applications getApplications(); 33 | 34 | /** 35 | * return the {@link Applications} object which the service is subscribing 36 | * 37 | * @param serviceId 38 | * @return 39 | */ 40 | Applications getSubscribeApplications(String serviceId); 41 | 42 | /** 43 | * Shuts down Pantheon Client. Also sends a deregistration request to the pantheon server. 44 | */ 45 | void shutdown(); 46 | 47 | /** 48 | * @return the configuration of this pantheon client 49 | */ 50 | PantheonInstanceConfig getPantheonClientConfig(); 51 | 52 | 53 | 54 | /** 55 | * Gets the list of instances matching the given Address. 56 | * 57 | * @param address The address to match the instances for. 58 | * @return - The list of {@link InstanceInfo} objects matching the criteria 59 | */ 60 | List getInstance(String address); 61 | 62 | 63 | /** 64 | * Return the current instance status as seen on the Pantheon server. 65 | * @return 66 | */ 67 | InstanceInfo.InstanceStatus getInstanceRemoteStatus(); 68 | 69 | void registerEventListener(PantheonEventListener var1); 70 | 71 | boolean unregisterEventListener(PantheonEventListener var1); 72 | } 73 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/transport/ClientRemotingProcessor.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.transport; 2 | 3 | import com.pantheon.common.protocol.RequestCode; 4 | import com.pantheon.common.protocol.ResponseCode; 5 | import com.pantheon.common.protocol.header.GetConsumerRunningInfoRequestHeader; 6 | import com.pantheon.remoting.exception.RemotingCommandException; 7 | import com.pantheon.remoting.netty.AsyncNettyRequestProcessor; 8 | import com.pantheon.remoting.netty.NettyRequestProcessor; 9 | import com.pantheon.remoting.protocol.RemotingCommand; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * @author Anthony 16 | * @create 2021/11/27 17 | * @desc 18 | */ 19 | public class ClientRemotingProcessor extends AsyncNettyRequestProcessor implements NettyRequestProcessor { 20 | private static final Logger logger = LoggerFactory.getLogger(ClientRemotingProcessor.class); 21 | 22 | @Override 23 | public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { 24 | switch (request.getCode()) { 25 | case RequestCode.GET_CONSUMER_RUNNING_INFO: 26 | return this.getConsumerRunningInfo(ctx, request); 27 | default: 28 | break; 29 | } 30 | return null; 31 | } 32 | 33 | /** 34 | * server can load consumer state 35 | * @param ctx 36 | * @param request 37 | * @return 38 | */ 39 | private RemotingCommand getConsumerRunningInfo(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException { 40 | final RemotingCommand response = RemotingCommand.createResponseCommand(null); 41 | final GetConsumerRunningInfoRequestHeader requestHeader = 42 | (GetConsumerRunningInfoRequestHeader) request.decodeCommandCustomHeader(GetConsumerRunningInfoRequestHeader.class); 43 | // logger.info("receive getConsumerRunningInfo from: {} ,and clientId is {} ", RemotingHelper.parseChannelRemoteAddr(ctx.channel()),requestHeader.getClientId()); 44 | response.setCode(ResponseCode.SUCCESS); 45 | response.setRemark("test remark"); 46 | return response; 47 | } 48 | 49 | @Override 50 | public boolean rejectRequest() { 51 | return false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/transport/HeartBeatSender.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.transport; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2022/1/5 6 | * @desc The heartbeat sender which is responsible for sending heartbeat to remote server periodically per interval. 7 | */ 8 | public interface HeartBeatSender { 9 | 10 | boolean sendHeartbeat(); 11 | 12 | long intervalMs(); 13 | } 14 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/transport/Server.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.transport; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/18 6 | * @desc 7 | **/ 8 | public class Server { 9 | 10 | /** 11 | * node id 12 | */ 13 | private String id; 14 | /** 15 | * ip/hostname address 16 | */ 17 | private String address; 18 | /** 19 | * server port 20 | */ 21 | private int port; 22 | 23 | /** 24 | * server contains many slots 25 | */ 26 | private int slotNum; 27 | 28 | public Server(String id, String address, int port) { 29 | this.id = id; 30 | this.address = address; 31 | this.port = port; 32 | } 33 | 34 | public Server(String address, int port) { 35 | this.address = address; 36 | this.port = port; 37 | } 38 | 39 | public String getId() { 40 | return id; 41 | } 42 | 43 | public void setId(String id) { 44 | this.id = id; 45 | } 46 | 47 | public String getAddress() { 48 | return address; 49 | } 50 | 51 | public void setAddress(String address) { 52 | this.address = address; 53 | } 54 | 55 | public int getPort() { 56 | return port; 57 | } 58 | 59 | public void setPort(int port) { 60 | this.port = port; 61 | } 62 | 63 | public String getRemoteSocketAddress() { 64 | return getAddress() + ":" + getPort(); 65 | } 66 | 67 | public int getSlotNum() { 68 | return slotNum; 69 | } 70 | 71 | public void setSlotNum(int slotNum) { 72 | this.slotNum = slotNum; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "Server{" + 78 | "id=" + id + 79 | ", address='" + address + '\'' + 80 | ", port=" + port + 81 | '}'; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/utils/Archaius1Utils.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.utils; 2 | 3 | import com.netflix.config.ConfigurationManager; 4 | import com.netflix.config.DynamicPropertyFactory; 5 | import com.netflix.config.DynamicStringProperty; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * This is an INTERNAL class not for public use. 13 | * 14 | */ 15 | public final class Archaius1Utils { 16 | 17 | private static final Logger logger = LoggerFactory.getLogger(Archaius1Utils.class); 18 | private static final String TEST = "test"; 19 | private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; 20 | private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; 21 | 22 | public static DynamicPropertyFactory initConfig(String configName) { 23 | 24 | DynamicPropertyFactory configInstance = DynamicPropertyFactory.getInstance(); 25 | DynamicStringProperty PANTHEON_PROPS_FILE = configInstance.getStringProperty("pantheon.client.props", configName); 26 | 27 | String env = ConfigurationManager.getConfigInstance().getString(PANTHEON_ENVIRONMENT, TEST); 28 | ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env); 29 | 30 | String pantheonPropsFile = PANTHEON_PROPS_FILE.get(); 31 | try { 32 | ConfigurationManager.loadCascadedPropertiesFromResources(pantheonPropsFile); 33 | } catch (IOException e) { 34 | logger.warn( 35 | "Cannot find the properties specified : {}. This may be okay if there are other environment " 36 | + "specific properties or the configuration is installed with a different mechanism.", 37 | pantheonPropsFile); 38 | 39 | } 40 | 41 | return configInstance; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pantheon-client/src/main/java/com/pantheon/client/utils/Pair.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.client.utils; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/17 6 | * @desc An utility class for stores any information that needs to exist as a pair. 7 | **/ 8 | public class Pair { 9 | public E1 first() { 10 | return first; 11 | } 12 | 13 | public void setFirst(E1 first) { 14 | this.first = first; 15 | } 16 | 17 | public E2 second() { 18 | return second; 19 | } 20 | 21 | public void setSecond(E2 second) { 22 | this.second = second; 23 | } 24 | 25 | private E1 first; 26 | private E2 second; 27 | 28 | public Pair(E1 first, E2 second) { 29 | this.first = first; 30 | this.second = second; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pantheon-client/src/main/resources/pantheon-client-instance1.properties: -------------------------------------------------------------------------------- 1 | pantheon.environment=instance1 2 | pantheon.serviceName=instance1 3 | pantheon.instanceHostName=127.0.0.1 4 | pantheon.instanceIpAddress=127.0.0.1 5 | pantheon.controllerCandidateServers=127.0.0.1:9961,127.0.0.1:9962 6 | pantheon.leaseRenewalInterval=4 7 | pantheon.leaseDuration=8 8 | pantheon.instancePort=6756 9 | pantheon.registryFetchIntervalSeconds=10 -------------------------------------------------------------------------------- /pantheon-client/src/main/resources/pantheon-client-instance2.properties: -------------------------------------------------------------------------------- 1 | pantheon.environment=instance2 2 | pantheon.serviceName=instance2 3 | pantheon.instanceHostName=127.0.0.1 4 | pantheon.instanceIpAddress=127.0.0.1 5 | pantheon.controllerCandidateServers=127.0.0.1:9961,127.0.0.1:9962 6 | pantheon.leaseRenewalInterval=3 7 | pantheon.leaseDuration=9 8 | pantheon.instancePort=6757 9 | pantheon.registryFetchIntervalSeconds=10 -------------------------------------------------------------------------------- /pantheon-client/src/main/resources/pantheon-client.properties: -------------------------------------------------------------------------------- 1 | pantheon.environment=instance1 2 | pantheon.serviceName=instance1 3 | pantheon.instanceHostName=127.0.0.1 4 | pantheon.instanceIpAddress=127.0.0.1 5 | pantheon.controllerCandidateServers=127.0.0.1:9991,127.0.0.1:9992 6 | pantheon.leaseRenewalInterval=4 7 | pantheon.leaseDuration=8 8 | pantheon.registryFetchIntervalSeconds=10 -------------------------------------------------------------------------------- /pantheon-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 4.0.0 12 | pantheon-common 13 | jar 14 | pantheon-common ${project.version} 15 | 16 | 17 | 18 | 8 19 | 8 20 | 21 | 22 | 23 | javax.jms 24 | jms 25 | 1.1 26 | 27 | 28 | org.slf4j 29 | slf4j-api 30 | 1.6.1 31 | 32 | 33 | org.slf4j 34 | slf4j-log4j12 35 | 1.6.1 36 | 37 | 38 | log4j 39 | log4j 40 | 1.2.17 41 | 42 | 43 | com.alibaba 44 | fastjson 45 | 1.2.71 46 | 47 | 48 | io.netty 49 | netty-all 50 | 4.0.42.Final 51 | 52 | 53 | com.netflix.archaius 54 | archaius-core 55 | 0.7.6 56 | 57 | 58 | commons-configuration 59 | commons-configuration 60 | 1.8 61 | 62 | 63 | ${project.groupId} 64 | pantheon-remoting 65 | 1.0-SNAPSHOT 66 | 67 | 68 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/MessageType.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common; 2 | 3 | 4 | public class MessageType { 5 | 6 | public static final Integer TERMINATE = -1; 7 | 8 | public static final Integer VOTE = 1; 9 | 10 | public static final Integer SLOTS_ALLOCATION = 2; 11 | 12 | public static final Integer NODE_SLOTS = 3; 13 | 14 | public static final Integer SLOTS_REPLICA_ALLOCATION = 4; 15 | 16 | public static final Integer NODE_SLOTS_REPLICAS = 5; 17 | 18 | public static final Integer REPLICA_NODE_ID = 6; 19 | 20 | public static final Integer REPLICA_REGISTER = 7; 21 | 22 | public static final Integer REPLICA_HEARTBEAT = 8; 23 | 24 | public static final Integer REPLICA_NODE_IDS = 9; 25 | 26 | public static final Integer CONTROLLER_NODE_ID = 10; 27 | 28 | public static final Integer CHANGE_REPLICA_TO_SLOTS = 11; 29 | 30 | public static final Integer REFRESH_REPLICA_NODE_ID = 12; 31 | 32 | public static final Integer REFRESH_REPLICA_SLOTS = 13; 33 | 34 | public static final Integer REQUEST_SLOTS_DATA = 14; 35 | 36 | public static final Integer UPDATE_NODE_SLOTS = 15; 37 | 38 | public static final Integer UPDATE_REPLICA_NODE_ID = 16; 39 | 40 | public static final Integer TRANSFER_SLOTS = 17; 41 | 42 | public static final Integer UPDATE_SLOTS = 18; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common; 2 | 3 | 4 | import java.lang.reflect.Array; 5 | import java.util.Collection; 6 | import java.util.Map; 7 | import java.util.Optional; 8 | 9 | /** 10 | * @author Anthony 11 | * @create 2021/11/19 12 | * @desc 13 | **/ 14 | public class ObjectUtils { 15 | 16 | /** 17 | * Determine whether the given object is empty. 18 | *

This method supports the following object types. 19 | *

    20 | *
  • {@code Optional}: considered empty if {@link Optional#empty()}
  • 21 | *
  • {@code Array}: considered empty if its length is zero
  • 22 | *
  • {@link CharSequence}: considered empty if its length is zero
  • 23 | *
  • {@link Collection}: delegates to {@link Collection#isEmpty()}
  • 24 | *
  • {@link Map}: delegates to {@link Map#isEmpty()}
  • 25 | *
  • {@link Integer}: considered empty if its num is 0
  • 26 | *
  • {@link Long}: considered empty if its num is 0L
  • 27 | *
28 | *

If the given object is non-null and not one of the aforementioned 29 | * supported types, this method returns {@code false}. 30 | * 31 | * @param obj the object to check 32 | * @return {@code true} if the object is {@code null} or empty 33 | */ 34 | @SuppressWarnings("rawtypes") 35 | public static boolean isEmpty(Object obj) { 36 | if (obj == null) { 37 | return true; 38 | } 39 | 40 | if (obj instanceof Optional) { 41 | return !((Optional) obj).isPresent(); 42 | } 43 | if (obj instanceof CharSequence) { 44 | return ((CharSequence) obj).length() == 0; 45 | } 46 | if (obj.getClass().isArray()) { 47 | return Array.getLength(obj) == 0; 48 | } 49 | if (obj instanceof Collection) { 50 | return ((Collection) obj).isEmpty(); 51 | } 52 | if (obj instanceof Map) { 53 | return ((Map) obj).isEmpty(); 54 | } 55 | //0 is empty 56 | if (obj instanceof Integer) { 57 | return ((Integer) obj) == 0; 58 | } 59 | if (obj instanceof Long) { 60 | return ((Long) obj) == 0L; 61 | } 62 | // else 63 | return false; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/PantheonVersion.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common; 3 | 4 | public class PantheonVersion { 5 | 6 | public static final int CURRENT_VERSION = Version.V1_0_0_SNAPSHOT.ordinal(); 7 | 8 | public static String getVersionDesc(int value) { 9 | int length = Version.values().length; 10 | if (value >= length) { 11 | return Version.values()[length - 1].name(); 12 | } 13 | 14 | return Version.values()[value].name(); 15 | } 16 | 17 | public static Version value2Version(int value) { 18 | int length = Version.values().length; 19 | if (value >= length) { 20 | return Version.values()[length - 1]; 21 | } 22 | 23 | return Version.values()[value]; 24 | } 25 | 26 | public enum Version { 27 | V1_0_0_SNAPSHOT, 28 | HIGHER_VERSION 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/ServerNodeRole.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common; 2 | 3 | public enum ServerNodeRole { 4 | 5 | COMMON_NODE, 6 | 7 | CONTROLLER_NODE, 8 | 9 | CONTROLLER_CANDIDATE_NODE; 10 | } 11 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/ServiceState.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common; 2 | 3 | public enum ServiceState { 4 | /** 5 | * Service just created,not start 6 | */ 7 | CREATE_JUST, 8 | /** 9 | * Service Running 10 | */ 11 | RUNNING, 12 | /** 13 | * Service shutdown 14 | */ 15 | SHUTDOWN_ALREADY, 16 | /** 17 | * Service Start failure 18 | */ 19 | START_FAILED, 20 | 21 | /** 22 | * Service running failure 23 | */ 24 | SERVICE_FAILED; 25 | } 26 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/ShutdownHookThread.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common; 3 | 4 | 5 | import org.slf4j.Logger; 6 | 7 | import java.util.concurrent.Callable; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | 10 | /** 11 | * Through {@link Callable} interface, this hook can customization operations in anywhere. 12 | */ 13 | public class ShutdownHookThread extends Thread { 14 | 15 | private volatile boolean hasShutdown = false; 16 | private AtomicInteger shutdownTimes = new AtomicInteger(0); 17 | private final Logger log; 18 | private final Callable callback; 19 | 20 | /** 21 | * Create the standard hook thread, with a call back, by using {@link Callable} interface. 22 | * 23 | * @param log The log instance is used in hook thread. 24 | * @param callback The call back function. 25 | */ 26 | public ShutdownHookThread(Logger log, Callable callback) { 27 | super("ShutdownHook"); 28 | this.log = log; 29 | this.callback = callback; 30 | } 31 | 32 | /** 33 | * Thread run method. 34 | * Invoke when the jvm shutdown. 35 | * 1. count the invocation times. 36 | * 2. execute the {@link ShutdownHookThread#callback}, and time it. 37 | */ 38 | @Override 39 | public void run() { 40 | synchronized (this) { 41 | log.info("shutdown hook was invoked, " + this.shutdownTimes.incrementAndGet() + " times."); 42 | if (!this.hasShutdown) { 43 | this.hasShutdown = true; 44 | long beginTime = System.currentTimeMillis(); 45 | try { 46 | this.callback.call(); 47 | } catch (Exception e) { 48 | log.error("shutdown hook callback invoked failure.", e); 49 | } 50 | long consumingTimeTotal = System.currentTimeMillis() - beginTime; 51 | log.info("shutdown hook done, consuming time total(ms): " + consumingTimeTotal); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/ThreadFactoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicLong; 5 | 6 | public class ThreadFactoryImpl implements ThreadFactory { 7 | private final AtomicLong threadIndex = new AtomicLong(0); 8 | private final String threadNamePrefix; 9 | private final boolean daemon; 10 | 11 | public ThreadFactoryImpl(final String threadNamePrefix) { 12 | this(threadNamePrefix, false); 13 | } 14 | 15 | public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon) { 16 | this.threadNamePrefix = threadNamePrefix; 17 | this.daemon = daemon; 18 | } 19 | 20 | @Override 21 | public Thread newThread(Runnable r) { 22 | Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet()); 23 | thread.setDaemon(daemon); 24 | return thread; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/entity/Message.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.entity; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /** 6 | * 基础消息接口 7 | */ 8 | public interface Message { 9 | 10 | ByteBuffer getData(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/entity/Request.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.entity; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /** 6 | * 请求接口 7 | */ 8 | public abstract class Request implements Message { 9 | 10 | /** 11 | * 请求标识 12 | */ 13 | public static final Integer REQUEST_FLAG = 1; 14 | 15 | /** 16 | * 拉取slots分配数据请求 17 | */ 18 | public static final Integer FETCH_SLOTS_ALLOCATION = 1; 19 | /** 20 | * 拉取server节点地址列表请求 21 | */ 22 | public static final Integer FETCH_SERVER_ADDRESSES = 2; 23 | /** 24 | * 服务注册请求 25 | */ 26 | public static final Integer REGISTER = 3; 27 | /** 28 | * 心跳请求 29 | */ 30 | public static final Integer HEARTBEAT = 4; 31 | /** 32 | * 拉取server节点id 33 | */ 34 | public static final Integer FETCH_SERVER_NODE_ID = 5; 35 | /** 36 | * 订阅服务 37 | */ 38 | public static final Integer SUBSCRIBE = 6; 39 | /** 40 | * 服务实例变动 41 | */ 42 | public static final Integer SERVICE_CHANGED = 7; 43 | 44 | /** 45 | * 请求标识字节数 46 | */ 47 | public static final Integer REQUEST_FLAG_BYTES = 4; 48 | /** 49 | * 请求长度的字节数 50 | */ 51 | public static final Integer REQUEST_LENGTH_BYTES = 4; 52 | /** 53 | * 请求类型的字节数 54 | */ 55 | public static final Integer REQUEST_TYPE_BYTES = 4; 56 | /** 57 | * 请求ID的字节数 58 | */ 59 | public static final Integer REQUEST_ID_BYTES = 32; 60 | /** 61 | * 字符串类型的请求字段的长度的字节数 62 | */ 63 | public static final Integer REQUEST_STRING_FIELD_LENGTH_BYTES = 4; 64 | /** 65 | * 整数类型的请求字段的字节数 66 | */ 67 | public static final Integer REQUEST_INTEGER_FIELD_BYTES = 4; 68 | 69 | /** 70 | * 获取请求id 71 | * @return 72 | */ 73 | public abstract String getId(); 74 | 75 | public static Request deserialize(Integer requestType, ByteBuffer messageBuffer) { 76 | Request request = null; 77 | 78 | // if(requestType.equals(Request.FETCH_SLOTS_ALLOCATION)) { 79 | // request = FetchSlotsAllocationRequest.deserialize(messageBuffer); 80 | // } else if(requestType.equals(Request.FETCH_SERVER_ADDRESSES)) { 81 | // request = FetchServerAddressesRequest.deserialize(messageBuffer); 82 | // } else if(requestType.equals(Request.REGISTER)) { 83 | // request = RegisterRequest.deserialize(messageBuffer); 84 | // } else if(requestType.equals(Request.HEARTBEAT)) { 85 | // request = HeartbeatRequest.deserialize(messageBuffer); 86 | // } else if(requestType.equals(Request.FETCH_SERVER_NODE_ID)) { 87 | // request = FetchServerNodeIdRequest.deserialize(messageBuffer); 88 | // } else if(requestType.equals(Request.SUBSCRIBE)) { 89 | // request = SubscribeRequest.deserialize(messageBuffer); 90 | // } else if(requestType.equals(Request.SERVICE_CHANGED)) { 91 | // request = ServiceChangedRequest.deserialize(messageBuffer); 92 | // } 93 | 94 | return request; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/exception/InitException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.common.exception; 18 | 19 | public class InitException extends RuntimeException { 20 | private static final long serialVersionUID = -7256002576788700354L; 21 | 22 | private String status; 23 | private int code; 24 | 25 | public InitException(String status, int code) { 26 | super(); 27 | this.status = status; 28 | this.code = code; 29 | } 30 | 31 | public InitException(String status, int code, String message) { 32 | super(message); 33 | this.status = status; 34 | this.code = code; 35 | } 36 | 37 | public InitException(String message) { 38 | super(message); 39 | } 40 | 41 | public InitException(String message, Throwable throwable) { 42 | super(message, throwable); 43 | } 44 | 45 | public InitException(String status, int code, String message, Throwable throwable) { 46 | super(message, throwable); 47 | this.status = status; 48 | this.code = code; 49 | } 50 | 51 | public String getStatus() { 52 | return status; 53 | } 54 | 55 | public void setStatus(String status) { 56 | this.status = status; 57 | } 58 | 59 | public int getCode() { 60 | return code; 61 | } 62 | 63 | public void setCode(int code) { 64 | this.code = code; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/lifecycle/AbstractLifecycleComponent.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.lifecycle; 3 | 4 | import java.io.IOException; 5 | import java.io.UncheckedIOException; 6 | import java.util.List; 7 | import java.util.concurrent.CopyOnWriteArrayList; 8 | 9 | public abstract class AbstractLifecycleComponent implements LifecycleComponent { 10 | 11 | protected final Lifecycle lifecycle = new Lifecycle(); 12 | 13 | private final List listeners = new CopyOnWriteArrayList<>(); 14 | 15 | protected AbstractLifecycleComponent() {} 16 | 17 | @Override 18 | public Lifecycle.State lifecycleState() { 19 | return this.lifecycle.state(); 20 | } 21 | 22 | @Override 23 | public void addLifecycleListener(LifecycleListener listener) { 24 | listeners.add(listener); 25 | } 26 | 27 | @Override 28 | public void removeLifecycleListener(LifecycleListener listener) { 29 | listeners.remove(listener); 30 | } 31 | 32 | @Override 33 | public void start() { 34 | synchronized (lifecycle) { 35 | if (!lifecycle.canMoveToStarted()) { 36 | return; 37 | } 38 | for (LifecycleListener listener : listeners) { 39 | listener.beforeStart(); 40 | } 41 | doStart(); 42 | lifecycle.moveToStarted(); 43 | for (LifecycleListener listener : listeners) { 44 | listener.afterStart(); 45 | } 46 | } 47 | } 48 | 49 | protected abstract void doStart(); 50 | 51 | @Override 52 | public void stop() { 53 | synchronized (lifecycle) { 54 | if (!lifecycle.canMoveToStopped()) { 55 | return; 56 | } 57 | for (LifecycleListener listener : listeners) { 58 | listener.beforeStop(); 59 | } 60 | lifecycle.moveToStopped(); 61 | doStop(); 62 | for (LifecycleListener listener : listeners) { 63 | listener.afterStop(); 64 | } 65 | } 66 | } 67 | 68 | protected abstract void doStop(); 69 | 70 | @Override 71 | public void close() { 72 | synchronized (lifecycle) { 73 | if (lifecycle.started()) { 74 | stop(); 75 | } 76 | if (!lifecycle.canMoveToClosed()) { 77 | return; 78 | } 79 | for (LifecycleListener listener : listeners) { 80 | listener.beforeClose(); 81 | } 82 | lifecycle.moveToClosed(); 83 | try { 84 | doClose(); 85 | } catch (IOException e) { 86 | throw new UncheckedIOException(e); 87 | } finally { 88 | for (LifecycleListener listener : listeners) { 89 | listener.afterClose(); 90 | } 91 | } 92 | } 93 | } 94 | 95 | protected abstract void doClose() throws IOException; 96 | } 97 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleComponent.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.lifecycle; 3 | 4 | 5 | 6 | public interface LifecycleComponent extends Releasable { 7 | 8 | Lifecycle.State lifecycleState(); 9 | 10 | void addLifecycleListener(LifecycleListener listener); 11 | 12 | void removeLifecycleListener(LifecycleListener listener); 13 | 14 | void start(); 15 | 16 | void stop(); 17 | } 18 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/lifecycle/LifecycleListener.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.lifecycle; 3 | 4 | public abstract class LifecycleListener { 5 | 6 | public void beforeStart() { 7 | 8 | } 9 | 10 | public void afterStart() { 11 | 12 | } 13 | 14 | public void beforeStop() { 15 | 16 | } 17 | 18 | public void afterStop() { 19 | 20 | } 21 | 22 | public void beforeClose() { 23 | 24 | } 25 | 26 | public void afterClose() { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/lifecycle/Releasable.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.lifecycle; 3 | 4 | 5 | import java.io.Closeable; 6 | 7 | /** 8 | * Specialization of {@link AutoCloseable} that may only throw an {@link }. 9 | */ 10 | public interface Releasable extends Closeable { 11 | 12 | @Override 13 | void close(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/RemotingSysResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.protocol; 2 | 3 | 4 | public class RemotingSysResponseCode { 5 | 6 | public static final int SUCCESS = 0; 7 | 8 | public static final int SYSTEM_ERROR = 1; 9 | 10 | public static final int SYSTEM_BUSY = 2; 11 | 12 | public static final int REQUEST_CODE_NOT_SUPPORTED = 3; 13 | 14 | public static final int TRANSACTION_FAILED = 4; 15 | } 16 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/RequestCode.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.protocol; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/19 6 | * @desc 7 | **/ 8 | public class RequestCode { 9 | public static final int GET_SERVER_NODE_ID = 10; 10 | public static final int GET_SLOTS_ALLOCATION = 11; 11 | public static final int GET_SERVER_ADDRESSES= 12; 12 | public static final int GET_CONSUMER_RUNNING_INFO = 13; 13 | public static final int SERVICE_REGISTRY = 14; 14 | public static final int SERVICE_HEART_BEAT = 15; 15 | public static final int SERVICE_UNREGISTER = 16; 16 | public static final int GET_ALL_APP = 17; 17 | public static final int GET_DELTA_APP = 18; 18 | public static final int GET_IN_NEED_APP = 19; 19 | } 20 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.protocol; 2 | 3 | import com.pantheon.remoting.protocol.RemotingSysResponseCode; 4 | 5 | /** 6 | * @author Anthony 7 | * @create 2021/11/19 8 | * @desc 9 | **/ 10 | public class ResponseCode extends RemotingSysResponseCode { 11 | public static final int CONSUME_MSG_TIMEOUT = 100; 12 | } 13 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressRequestHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | public class FetchServerAddressRequestHeader implements CommandCustomHeader { 28 | 29 | @Override 30 | public void checkFields() throws RemotingCommandException { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/FetchServerAddressResponseHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | public class FetchServerAddressResponseHeader implements CommandCustomHeader { 28 | 29 | @Override 30 | public void checkFields() throws RemotingCommandException { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetConsumerRunningInfoRequestHeader.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.pantheon.common.protocol.header; 4 | 5 | 6 | import com.pantheon.remoting.CommandCustomHeader; 7 | import com.pantheon.remoting.annotation.CFNotNull; 8 | import com.pantheon.remoting.exception.RemotingCommandException; 9 | 10 | public class GetConsumerRunningInfoRequestHeader implements CommandCustomHeader { 11 | 12 | @CFNotNull 13 | private String clientId; 14 | 15 | 16 | @Override 17 | public void checkFields() throws RemotingCommandException { 18 | } 19 | 20 | 21 | public String getClientId() { 22 | return clientId; 23 | } 24 | 25 | public void setClientId(String clientId) { 26 | this.clientId = clientId; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressRequestHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | public class GetServerAddressRequestHeader implements CommandCustomHeader { 28 | 29 | @Override 30 | public void checkFields() throws RemotingCommandException { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerAddressResponseHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.annotation.CFNotNull; 26 | import com.pantheon.remoting.exception.RemotingCommandException; 27 | 28 | import java.util.List; 29 | 30 | public class GetServerAddressResponseHeader implements CommandCustomHeader { 31 | @CFNotNull 32 | private String serverAddresses; 33 | 34 | @Override 35 | public void checkFields() throws RemotingCommandException { 36 | } 37 | 38 | public String getServerAddresses() { 39 | return serverAddresses; 40 | } 41 | 42 | public void setServerAddresses(String serverAddresses) { 43 | this.serverAddresses = serverAddresses; 44 | } 45 | } 46 | 47 | // public List getServerAddresses() { 48 | // return serverAddresses; 49 | // } 50 | // 51 | // public void setServerAddresses(List serverAddresses) { 52 | // this.serverAddresses = serverAddresses; 53 | // } 54 | //} 55 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdRequestHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | public class GetServerNodeIdRequestHeader implements CommandCustomHeader { 28 | 29 | @Override 30 | public void checkFields() throws RemotingCommandException { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetServerNodeIdResponseHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.annotation.CFNotNull; 26 | import com.pantheon.remoting.exception.RemotingCommandException; 27 | 28 | public class GetServerNodeIdResponseHeader implements CommandCustomHeader { 29 | @CFNotNull 30 | private Integer serverNodeId; 31 | 32 | @Override 33 | public void checkFields() throws RemotingCommandException { 34 | } 35 | 36 | public Integer getServerNodeId() { 37 | return serverNodeId; 38 | } 39 | 40 | public void setServerNodeId(Integer serverNodeId) { 41 | this.serverNodeId = serverNodeId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsRequestHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | public class GetSlotsRequestHeader implements CommandCustomHeader { 28 | 29 | @Override 30 | public void checkFields() throws RemotingCommandException { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/header/GetSlotsResponseHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * $Id: DeleteTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $ 20 | */ 21 | package com.pantheon.common.protocol.header; 22 | 23 | 24 | import com.pantheon.remoting.CommandCustomHeader; 25 | import com.pantheon.remoting.exception.RemotingCommandException; 26 | 27 | import java.util.List; 28 | import java.util.Map; 29 | 30 | public class GetSlotsResponseHeader implements CommandCustomHeader { 31 | /** 32 | * slots allocation info 33 | */ 34 | private String slotsAllocation; 35 | @Override 36 | public void checkFields() throws RemotingCommandException { 37 | } 38 | 39 | public String getSlotsAllocation() { 40 | return slotsAllocation; 41 | } 42 | 43 | public void setSlotsAllocation(String slotsAllocation) { 44 | this.slotsAllocation = slotsAllocation; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/HeartBeat.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.protocol.heartBeat; 3 | 4 | 5 | import com.pantheon.remoting.protocol.RemotingSerializable; 6 | 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | /** 11 | * locate a instance with a appName and instanceId 12 | */ 13 | public class HeartBeat extends RemotingSerializable { 14 | private String serviceName; 15 | private String instanceId; 16 | private Set subscriptionDataSet = new HashSet(); 17 | 18 | public String getServiceName() { 19 | return serviceName; 20 | } 21 | 22 | public void setServiceName(String serviceName) { 23 | this.serviceName = serviceName; 24 | } 25 | 26 | public String getInstanceId() { 27 | return instanceId; 28 | } 29 | 30 | public void setInstanceId(String instanceId) { 31 | this.instanceId = instanceId; 32 | } 33 | 34 | public Set getSubscriptionDataSet() { 35 | return subscriptionDataSet; 36 | } 37 | 38 | public void setSubscriptionDataSet(Set subscriptionDataSet) { 39 | this.subscriptionDataSet = subscriptionDataSet; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/ServiceUnregister.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.common.protocol.heartBeat; 3 | 4 | 5 | import com.pantheon.remoting.protocol.RemotingSerializable; 6 | 7 | /** 8 | * locate a instance with a appName and instanceId 9 | */ 10 | public class ServiceUnregister extends RemotingSerializable { 11 | private String serviceName; 12 | private String instanceId; 13 | 14 | public String getServiceName() { 15 | return serviceName; 16 | } 17 | 18 | public void setServiceName(String serviceName) { 19 | this.serviceName = serviceName; 20 | } 21 | 22 | public String getInstanceId() { 23 | return instanceId; 24 | } 25 | 26 | public void setInstanceId(String instanceId) { 27 | this.instanceId = instanceId; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /pantheon-common/src/main/java/com/pantheon/common/protocol/heartBeat/SubscriptionData.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.common.protocol.heartBeat; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/12/13 6 | * @desc 7 | */ 8 | public class SubscriptionData { 9 | private Integer slotNum; 10 | private String serviceName; 11 | private String instanceId; 12 | private String clientId; 13 | 14 | public Integer getSlotNum() { 15 | return slotNum; 16 | } 17 | 18 | public void setSlotNum(Integer slotNum) { 19 | this.slotNum = slotNum; 20 | } 21 | 22 | public String getServiceName() { 23 | return serviceName; 24 | } 25 | 26 | public String getInstanceId() { 27 | return instanceId; 28 | } 29 | 30 | public void setServiceName(String serviceName) { 31 | this.serviceName = serviceName; 32 | } 33 | 34 | public void setInstanceId(String instanceId) { 35 | this.instanceId = instanceId; 36 | } 37 | 38 | public String getClientId() { 39 | return clientId; 40 | } 41 | 42 | public void setClientId(String clientId) { 43 | this.clientId = clientId; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pantheon-dubbo-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-dubbo-support 13 | 14 | 15 | 13 16 | 13 17 | 18 | 19 | -------------------------------------------------------------------------------- /pantheon-remoting/README.md: -------------------------------------------------------------------------------- 1 | Most of the this module introduce the code from [rocketmq github](https://github.com/apache/rocketmq) rocketmq-remoting module -------------------------------------------------------------------------------- /pantheon-remoting/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 4.0.0 12 | pantheon-remoting 13 | jar 14 | pantheon-remoting ${project.version} 15 | 16 | 17 | 8 18 | 8 19 | 20 | 21 | 22 | 23 | javax.jms 24 | jms 25 | 1.1 26 | 27 | 28 | org.slf4j 29 | slf4j-api 30 | 1.6.1 31 | 32 | 33 | org.slf4j 34 | slf4j-log4j12 35 | 1.6.1 36 | 37 | 38 | log4j 39 | log4j 40 | 1.2.17 41 | 42 | 43 | com.alibaba 44 | fastjson 45 | 1.2.71 46 | 47 | 48 | io.netty 49 | netty-all 50 | 4.0.42.Final 51 | 52 | 53 | com.netflix.archaius 54 | archaius-core 55 | 0.7.6 56 | 57 | 58 | commons-configuration 59 | commons-configuration 60 | 1.8 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/ChannelEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting; 18 | 19 | import io.netty.channel.Channel; 20 | 21 | /** 22 | * @author Anthony 23 | * @create 2021/11/17 24 | * @desc subscribe to this listener to get notified when channel event triggered 25 | **/ 26 | public interface ChannelEventListener { 27 | void onChannelConnect(final String remoteAddr, final Channel channel); 28 | 29 | void onChannelClose(final String remoteAddr, final Channel channel); 30 | 31 | void onChannelException(final String remoteAddr, final Channel channel); 32 | 33 | void onChannelIdle(final String remoteAddr, final Channel channel); 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/CommandCustomHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting; 18 | 19 | 20 | import com.pantheon.remoting.exception.RemotingCommandException; 21 | 22 | /** 23 | * @author Anthony 24 | * @create 2021/11/17 25 | * @desc 26 | **/ 27 | public interface CommandCustomHeader { 28 | void checkFields() throws RemotingCommandException; 29 | } 30 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/InvokeCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting; 18 | 19 | import com.pantheon.remoting.netty.ResponseFuture; 20 | 21 | /** 22 | * @author Anthony 23 | * @create 2021/11/17 24 | * @desc used for async message 25 | **/ 26 | public interface InvokeCallback { 27 | void operationComplete(final ResponseFuture responseFuture); 28 | } 29 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/RPCHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting; 19 | 20 | import com.pantheon.remoting.protocol.RemotingCommand; 21 | 22 | /** 23 | * @author Anthony 24 | * @create 2021/11/17 25 | * @desc 26 | **/ 27 | public interface RPCHook { 28 | void doBeforeRequest(final String remoteAddr, final RemotingCommand request); 29 | 30 | void doAfterResponse(final String remoteAddr, final RemotingCommand request, 31 | final RemotingCommand response); 32 | } 33 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting; 18 | 19 | 20 | import com.pantheon.remoting.exception.RemotingConnectException; 21 | import com.pantheon.remoting.exception.RemotingSendRequestException; 22 | import com.pantheon.remoting.exception.RemotingTimeoutException; 23 | import com.pantheon.remoting.exception.RemotingTooMuchRequestException; 24 | import com.pantheon.remoting.netty.NettyRequestProcessor; 25 | import com.pantheon.remoting.protocol.RemotingCommand; 26 | 27 | import java.util.List; 28 | import java.util.concurrent.ExecutorService; 29 | 30 | /** 31 | * @author Anthony 32 | * @create 2021/11/17 33 | * @desc 34 | **/ 35 | public interface RemotingClient extends RemotingService { 36 | 37 | void updateServerAddressList(final List addrs); 38 | 39 | List getServerAddressList(); 40 | 41 | RemotingCommand invokeSync(final String addr, final RemotingCommand request, 42 | final long timeoutMillis) throws InterruptedException, RemotingConnectException, 43 | RemotingSendRequestException, RemotingTimeoutException; 44 | 45 | void invokeAsync(final String addr, final RemotingCommand request, final long timeoutMillis, 46 | final InvokeCallback invokeCallback) throws InterruptedException, RemotingConnectException, 47 | RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException; 48 | 49 | void invokeOneway(final String addr, final RemotingCommand request, final long timeoutMillis) 50 | throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, 51 | RemotingTimeoutException, RemotingSendRequestException; 52 | 53 | void registerProcessor(final int requestCode, final NettyRequestProcessor processor, 54 | final ExecutorService executor); 55 | 56 | void setCallbackExecutor(final ExecutorService callbackExecutor); 57 | 58 | ExecutorService getCallbackExecutor(); 59 | 60 | boolean isChannelWritable(final String addr); 61 | } 62 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting; 18 | 19 | import com.pantheon.remoting.common.Pair; 20 | import com.pantheon.remoting.exception.RemotingSendRequestException; 21 | import com.pantheon.remoting.exception.RemotingTimeoutException; 22 | import com.pantheon.remoting.exception.RemotingTooMuchRequestException; 23 | import com.pantheon.remoting.netty.NettyRequestProcessor; 24 | import com.pantheon.remoting.protocol.RemotingCommand; 25 | import io.netty.channel.Channel; 26 | 27 | import java.util.concurrent.ExecutorService; 28 | 29 | /** 30 | * @author Anthony 31 | * @create 2021/11/17 32 | * @desc 33 | **/ 34 | public interface RemotingServer extends RemotingService { 35 | 36 | void registerProcessor(final int requestCode, final NettyRequestProcessor processor, 37 | final ExecutorService executor); 38 | 39 | void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor); 40 | 41 | int localListenPort(); 42 | 43 | Pair getProcessorPair(final int requestCode); 44 | 45 | RemotingCommand invokeSync(final Channel channel, final RemotingCommand request, 46 | final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, 47 | RemotingTimeoutException; 48 | 49 | void invokeAsync(final Channel channel, final RemotingCommand request, final long timeoutMillis, 50 | final InvokeCallback invokeCallback) throws InterruptedException, 51 | RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException; 52 | 53 | void invokeOneway(final Channel channel, final RemotingCommand request, final long timeoutMillis) 54 | throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, 55 | RemotingSendRequestException; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/RemotingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting; 19 | 20 | /** 21 | * @author Anthony 22 | * @create 2021/11/17 23 | * @desc 24 | **/ 25 | public interface RemotingService { 26 | void start(); 27 | 28 | void shutdown(); 29 | 30 | void registerRPCHook(RPCHook rpcHook); 31 | } 32 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNotNull.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.annotation; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * @author Anthony 27 | * @create 2021/11/17 28 | * @desc 29 | **/ 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) 33 | public @interface CFNotNull { 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/annotation/CFNullable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.annotation; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * @author Anthony 27 | * @create 2021/11/17 28 | * @desc 29 | **/ 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) 33 | public @interface CFNullable { 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/common/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.common; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class Pair { 25 | private T1 object1; 26 | private T2 object2; 27 | 28 | public Pair(T1 object1, T2 object2) { 29 | this.object1 = object1; 30 | this.object2 = object2; 31 | } 32 | 33 | public T1 getObject1() { 34 | return object1; 35 | } 36 | 37 | public void setObject1(T1 object1) { 38 | this.object1 = object1; 39 | } 40 | 41 | public T2 getObject2() { 42 | return object2; 43 | } 44 | 45 | public void setObject2(T2 object2) { 46 | this.object2 = object2; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/common/SemaphoreReleaseOnlyOnce.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.common; 18 | 19 | import java.util.concurrent.Semaphore; 20 | import java.util.concurrent.atomic.AtomicBoolean; 21 | 22 | /** 23 | * @author Anthony 24 | * @create 2021/11/17 25 | * @desc 26 | **/ 27 | public class SemaphoreReleaseOnlyOnce { 28 | private final AtomicBoolean released = new AtomicBoolean(false); 29 | private final Semaphore semaphore; 30 | 31 | public SemaphoreReleaseOnlyOnce(Semaphore semaphore) { 32 | this.semaphore = semaphore; 33 | } 34 | 35 | public void release() { 36 | if (this.semaphore != null) { 37 | if (this.released.compareAndSet(false, true)) { 38 | this.semaphore.release(); 39 | } 40 | } 41 | } 42 | 43 | public Semaphore getSemaphore() { 44 | return semaphore; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/common/ServiceThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.common; 18 | 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | 24 | /** 25 | * @author Anthony 26 | * @create 2021/11/17 27 | * @desc Base class for background thread 28 | **/ 29 | public abstract class ServiceThread implements Runnable { 30 | private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); 31 | 32 | private static final long JOIN_TIME = 90 * 1000; 33 | protected final Thread thread; 34 | protected volatile boolean hasNotified = false; 35 | protected volatile boolean stopped = false; 36 | 37 | public ServiceThread() { 38 | this.thread = new Thread(this, this.getServiceName()); 39 | } 40 | 41 | public abstract String getServiceName(); 42 | 43 | public void start() { 44 | this.thread.start(); 45 | } 46 | 47 | public void shutdown() { 48 | this.shutdown(false); 49 | } 50 | 51 | public void shutdown(final boolean interrupt) { 52 | this.stopped = true; 53 | logger.info("shutdown thread " + this.getServiceName() + " interrupt " + interrupt); 54 | synchronized (this) { 55 | if (!this.hasNotified) { 56 | this.hasNotified = true; 57 | this.notify(); 58 | } 59 | } 60 | 61 | try { 62 | if (interrupt) { 63 | this.thread.interrupt(); 64 | } 65 | 66 | long beginTime = System.currentTimeMillis(); 67 | this.thread.join(this.getJointime()); 68 | long elapsedTime = System.currentTimeMillis() - beginTime; 69 | logger.info("join thread " + this.getServiceName() + " elapsed time(ms) " + elapsedTime + " " 70 | + this.getJointime()); 71 | } catch (InterruptedException e) { 72 | logger.error("Interrupted", e); 73 | } 74 | } 75 | 76 | public long getJointime() { 77 | return JOIN_TIME; 78 | } 79 | 80 | public boolean isStopped() { 81 | return stopped; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/common/TlsMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.common; 19 | 20 | /** 21 | * For server, three SSL modes are supported: disabled, permissive and enforcing. 22 | *

    23 | *
  1. disabled: SSL is not supported; any incoming SSL handshake will be rejected, causing connection closed.
  2. 24 | *
  3. permissive: SSL is optional, aka, server in this mode can serve client connections with or without SSL;
  4. 25 | *
  5. enforcing: SSL is required, aka, non SSL connection will be rejected.
  6. 26 | *
27 | */ 28 | public enum TlsMode { 29 | 30 | DISABLED("disabled"), 31 | PERMISSIVE("permissive"), 32 | ENFORCING("enforcing"); 33 | 34 | private String name; 35 | 36 | TlsMode(String name) { 37 | this.name = name; 38 | } 39 | 40 | public static TlsMode parse(String mode) { 41 | for (TlsMode tlsMode : TlsMode.values()) { 42 | if (tlsMode.name.equals(mode)) { 43 | return tlsMode; 44 | } 45 | } 46 | 47 | return PERMISSIVE; 48 | } 49 | 50 | public String getName() { 51 | return name; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingCommandException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingCommandException extends RemotingException { 25 | private static final long serialVersionUID = -6061365915274953096L; 26 | 27 | public RemotingCommandException(String message) { 28 | super(message, null); 29 | } 30 | 31 | public RemotingCommandException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingConnectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingConnectException extends RemotingException { 25 | private static final long serialVersionUID = -5565366231695911316L; 26 | 27 | public RemotingConnectException(String addr) { 28 | this(addr, null); 29 | } 30 | 31 | public RemotingConnectException(String addr, Throwable cause) { 32 | super("connect to " + addr + " failed", cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingException extends Exception { 25 | private static final long serialVersionUID = -5690687334570505110L; 26 | 27 | public RemotingException(String message) { 28 | super(message); 29 | } 30 | 31 | public RemotingException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingSendRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingSendRequestException extends RemotingException { 25 | private static final long serialVersionUID = 5391285827332471674L; 26 | 27 | public RemotingSendRequestException(String addr) { 28 | this(addr, null); 29 | } 30 | 31 | public RemotingSendRequestException(String addr, Throwable cause) { 32 | super("send request to <" + addr + "> failed", cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTimeoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingTimeoutException extends RemotingException { 25 | 26 | private static final long serialVersionUID = 4106899185095245979L; 27 | 28 | public RemotingTimeoutException(String message) { 29 | super(message); 30 | } 31 | 32 | public RemotingTimeoutException(String addr, long timeoutMillis) { 33 | this(addr, timeoutMillis, null); 34 | } 35 | 36 | public RemotingTimeoutException(String addr, long timeoutMillis, Throwable cause) { 37 | super("wait response on the channel <" + addr + "> timeout, " + timeoutMillis + "(ms)", cause); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/exception/RemotingTooMuchRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.exception; 18 | 19 | /** 20 | * @author Anthony 21 | * @create 2021/11/17 22 | * @desc 23 | **/ 24 | public class RemotingTooMuchRequestException extends RemotingException { 25 | private static final long serialVersionUID = 4326919581254519654L; 26 | 27 | public RemotingTooMuchRequestException(String message) { 28 | super(message); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/AsyncNettyRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.netty; 19 | 20 | import com.pantheon.remoting.protocol.RemotingCommand; 21 | import io.netty.channel.ChannelHandlerContext; 22 | 23 | /** 24 | * @author Anthony 25 | * @create 2021/11/17 26 | * @desc add async support with {@link RemotingResponseCallback}on {@link NettyRequestProcessor} 27 | **/ 28 | public abstract class AsyncNettyRequestProcessor implements NettyRequestProcessor { 29 | 30 | public void asyncProcessRequest(ChannelHandlerContext ctx, RemotingCommand request, RemotingResponseCallback responseCallback) throws Exception { 31 | RemotingCommand response = processRequest(ctx, request); 32 | responseCallback.callback(response); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/FileRegionEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.netty; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.channel.ChannelHandlerContext; 22 | import io.netty.channel.FileRegion; 23 | import io.netty.handler.codec.MessageToByteEncoder; 24 | import io.netty.handler.ssl.SslHandler; 25 | 26 | import java.io.IOException; 27 | import java.nio.ByteBuffer; 28 | import java.nio.channels.WritableByteChannel; 29 | 30 | /** 31 | * extends from MessageToByteEncoder 32 | *

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

37 | */ 38 | public class FileRegionEncoder extends MessageToByteEncoder { 39 | 40 | /** 41 | * Encode a message into a {@link ByteBuf}. This method will be called for each written message that 42 | * can be handled by this encoder. 43 | * 44 | * @param ctx the {@link ChannelHandlerContext} which this {@link 45 | * MessageToByteEncoder} belongs to 46 | * @param msg the message to encode 47 | * @param out the {@link ByteBuf} into which the encoded message will be written 48 | * @throws Exception is thrown if an error occurs 49 | */ 50 | @Override 51 | protected void encode(ChannelHandlerContext ctx, FileRegion msg, final ByteBuf out) throws Exception { 52 | WritableByteChannel writableByteChannel = new WritableByteChannel() { 53 | @Override 54 | public int write(ByteBuffer src) throws IOException { 55 | out.writeBytes(src); 56 | return out.capacity(); 57 | } 58 | 59 | @Override 60 | public boolean isOpen() { 61 | return true; 62 | } 63 | 64 | @Override 65 | public void close() throws IOException { 66 | } 67 | }; 68 | 69 | long toTransfer = msg.count(); 70 | 71 | while (true) { 72 | long transferred = msg.transfered(); 73 | if (toTransfer - transferred <= 0) { 74 | break; 75 | } 76 | msg.transferTo(writableByteChannel, transferred); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.netty; 18 | 19 | import com.pantheon.remoting.common.RemotingHelper; 20 | import com.pantheon.remoting.common.RemotingUtil; 21 | import com.pantheon.remoting.protocol.RemotingCommand; 22 | import io.netty.buffer.ByteBuf; 23 | import io.netty.channel.ChannelHandlerContext; 24 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import java.nio.ByteBuffer; 29 | 30 | public class NettyDecoder extends LengthFieldBasedFrameDecoder { 31 | private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); 32 | 33 | private static final int FRAME_MAX_LENGTH = 34 | Integer.parseInt(System.getProperty("com.pantheon.remoting.frameMaxLength", "16777216")); 35 | 36 | public NettyDecoder() { 37 | super(FRAME_MAX_LENGTH, 0, 4, 0, 4); 38 | } 39 | 40 | @Override 41 | public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { 42 | ByteBuf frame = null; 43 | try { 44 | frame = (ByteBuf) super.decode(ctx, in); 45 | if (null == frame) { 46 | return null; 47 | } 48 | //netty‘s bytebuf to standard bytebuffer 49 | ByteBuffer byteBuffer = frame.nioBuffer(); 50 | //bytebuffer data convert to RemotingCommand 51 | return RemotingCommand.decode(byteBuffer); 52 | } catch (Exception e) { 53 | logger.error("decode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e); 54 | RemotingUtil.closeChannel(ctx.channel()); 55 | } finally { 56 | if (null != frame) { 57 | frame.release(); 58 | } 59 | } 60 | 61 | return null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.netty; 18 | 19 | import com.pantheon.remoting.common.RemotingHelper; 20 | import com.pantheon.remoting.common.RemotingUtil; 21 | import com.pantheon.remoting.protocol.RemotingCommand; 22 | import io.netty.buffer.ByteBuf; 23 | import io.netty.channel.ChannelHandler; 24 | import io.netty.channel.ChannelHandlerContext; 25 | import io.netty.handler.codec.MessageToByteEncoder; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.nio.ByteBuffer; 30 | 31 | 32 | @ChannelHandler.Sharable 33 | public class NettyEncoder extends MessageToByteEncoder { 34 | private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.PANTHEON_REMOTING); 35 | 36 | @Override 37 | public void encode(ChannelHandlerContext ctx, RemotingCommand remotingCommand, ByteBuf out) 38 | throws Exception { 39 | try { 40 | //encode header then write to ByteBuf 41 | ByteBuffer header = remotingCommand.encodeHeader(); 42 | out.writeBytes(header); 43 | //body write to ByteBuf 44 | byte[] body = remotingCommand.getBody(); 45 | if (body != null) { 46 | out.writeBytes(body); 47 | } 48 | } catch (Exception e) { 49 | logger.error("encode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e); 50 | if (remotingCommand != null) { 51 | logger.error(remotingCommand.toString()); 52 | } 53 | RemotingUtil.closeChannel(ctx.channel()); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.netty; 18 | 19 | import io.netty.channel.Channel; 20 | 21 | public class NettyEvent { 22 | private final NettyEventType type; 23 | private final String remoteAddr; 24 | private final Channel channel; 25 | 26 | public NettyEvent(NettyEventType type, String remoteAddr, Channel channel) { 27 | this.type = type; 28 | this.remoteAddr = remoteAddr; 29 | this.channel = channel; 30 | } 31 | 32 | public NettyEventType getType() { 33 | return type; 34 | } 35 | 36 | public String getRemoteAddr() { 37 | return remoteAddr; 38 | } 39 | 40 | public Channel getChannel() { 41 | return channel; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "NettyEvent [type=" + type + ", remoteAddr=" + remoteAddr + ", channel=" + channel + "]"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyEventType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.netty; 18 | 19 | public enum NettyEventType { 20 | CONNECT, 21 | CLOSE, 22 | IDLE, 23 | EXCEPTION 24 | } 25 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettyRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.netty; 18 | 19 | import com.pantheon.remoting.protocol.RemotingCommand; 20 | import io.netty.channel.ChannelHandlerContext; 21 | 22 | 23 | /** 24 | * @author Anthony 25 | * @create 2021/11/17 26 | * @desc Common remoting command processor 27 | **/ 28 | public interface NettyRequestProcessor { 29 | RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) 30 | throws Exception; 31 | 32 | boolean rejectRequest(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/NettySystemConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.netty; 19 | 20 | public class NettySystemConfig { 21 | public static final String COM_PANTHEON_REMOTING_NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE = 22 | "com.pantheon.remoting.nettyPooledByteBufAllocatorEnable"; 23 | public static final String COM_PANTHEON_REMOTING_SOCKET_SNDBUF_SIZE = 24 | "com.pantheon.remoting.socket.sndbuf.size"; 25 | public static final String COM_PANTHEON_REMOTING_SOCKET_RCVBUF_SIZE = 26 | "com.pantheon.remoting.socket.rcvbuf.size"; 27 | public static final String COM_PANTHEON_REMOTING_CLIENT_ASYNC_SEMAPHORE_VALUE = 28 | "com.pantheon.remoting.clientAsyncSemaphoreValue"; 29 | public static final String COM_PANTHEON_REMOTING_CLIENT_ONEWAY_SEMAPHORE_VALUE = 30 | "com.pantheon.remoting.clientOnewaySemaphoreValue"; 31 | 32 | public static final boolean NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE = // 33 | Boolean.parseBoolean(System.getProperty(COM_PANTHEON_REMOTING_NETTY_POOLED_BYTE_BUF_ALLOCATOR_ENABLE, "false")); 34 | public static final int CLIENT_ASYNC_SEMAPHORE_VALUE = // 35 | Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_CLIENT_ASYNC_SEMAPHORE_VALUE, "65535")); 36 | public static final int CLIENT_ONEWAY_SEMAPHORE_VALUE = 37 | Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_CLIENT_ONEWAY_SEMAPHORE_VALUE, "65535")); 38 | public static int socketSndbufSize = 39 | Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_SOCKET_SNDBUF_SIZE, "65535")); 40 | public static int socketRcvbufSize = 41 | Integer.parseInt(System.getProperty(COM_PANTHEON_REMOTING_SOCKET_RCVBUF_SIZE, "65535")); 42 | } 43 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/netty/RemotingResponseCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.netty; 19 | 20 | 21 | import com.pantheon.remoting.protocol.RemotingCommand; 22 | 23 | public interface RemotingResponseCallback { 24 | void callback(RemotingCommand response); 25 | } 26 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/LanguageCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.protocol; 19 | 20 | public enum LanguageCode { 21 | JAVA((byte) 0); 22 | 23 | private byte code; 24 | 25 | LanguageCode(byte code) { 26 | this.code = code; 27 | } 28 | 29 | public static LanguageCode valueOf(byte code) { 30 | for (LanguageCode languageCode : LanguageCode.values()) { 31 | if (languageCode.getCode() == code) { 32 | return languageCode; 33 | } 34 | } 35 | return null; 36 | } 37 | 38 | public byte getCode() { 39 | return code; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingCommandType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.protocol; 18 | 19 | public enum RemotingCommandType { 20 | REQUEST_COMMAND, 21 | RESPONSE_COMMAND; 22 | } 23 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSerializable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.pantheon.remoting.protocol; 18 | 19 | import com.alibaba.fastjson.JSON; 20 | 21 | import java.nio.charset.Charset; 22 | 23 | /** 24 | * @author Anthony 25 | * @create 2021/11/17 26 | * @desc fastjson to serialize and deserialize data 27 | **/ 28 | public abstract class RemotingSerializable { 29 | private final static Charset CHARSET_UTF8 = Charset.forName("UTF-8"); 30 | 31 | public static byte[] encode(final Object obj) { 32 | final String json = toJson(obj, false); 33 | if (json != null) { 34 | return json.getBytes(CHARSET_UTF8); 35 | } 36 | return null; 37 | } 38 | 39 | public static String toJson(final Object obj, boolean prettyFormat) { 40 | return JSON.toJSONString(obj, prettyFormat); 41 | } 42 | 43 | public static T decode(final byte[] data, Class classOfT) { 44 | final String json = new String(data, CHARSET_UTF8); 45 | return fromJson(json, classOfT); 46 | } 47 | 48 | public static T fromJson(String json, Class classOfT) { 49 | return JSON.parseObject(json, classOfT); 50 | } 51 | 52 | public byte[] encode() { 53 | final String json = this.toJson(); 54 | if (json != null) { 55 | return json.getBytes(CHARSET_UTF8); 56 | } 57 | return null; 58 | } 59 | 60 | public String toJson() { 61 | return toJson(false); 62 | } 63 | 64 | public String toJson(final boolean prettyFormat) { 65 | return toJson(this, prettyFormat); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/RemotingSysResponseCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.protocol; 19 | 20 | public class RemotingSysResponseCode { 21 | 22 | public static final int SUCCESS = 0; 23 | 24 | public static final int SYSTEM_ERROR = 1; 25 | 26 | public static final int SYSTEM_BUSY = 2; 27 | 28 | public static final int REQUEST_CODE_NOT_SUPPORTED = 3; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/java/com/pantheon/remoting/protocol/SerializeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.pantheon.remoting.protocol; 19 | 20 | /** 21 | * @author Anthony 22 | * @create 2021/11/17 23 | * @desc support JSON and our own (PANTHEON) serialization protocol 24 | **/ 25 | public enum SerializeType { 26 | JSON((byte) 0), 27 | PANTHEON((byte) 1); 28 | 29 | private byte code; 30 | 31 | SerializeType(byte code) { 32 | this.code = code; 33 | } 34 | 35 | public static SerializeType valueOf(byte code) { 36 | for (SerializeType serializeType : SerializeType.values()) { 37 | if (serializeType.getCode() == code) { 38 | return serializeType; 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | public byte getCode() { 45 | return code; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pantheon-remoting/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, CONSOLE 2 | 3 | # local : debug log to console 4 | log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CONSOLE.Threshold=DEBUG 6 | log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 8 | 9 | # test: log to file 10 | log4j.appender.TRACEFILE=org.apache.log4j.FileAppender 11 | log4j.appender.TRACEFILE.Threshold=DEBUG 12 | log4j.appender.TRACEFILE.File=/usr/local/pantheon/logs/pantheon.trace 13 | log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout 14 | log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n 15 | 16 | # prod: log to pantheon.log and pantheon.error 17 | log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender 18 | log4j.appender.ROLLINGFILE.Threshold=INFO 19 | log4j.appender.ROLLINGFILE.File=/usr/local/pantheon/logs/pantheon.log 20 | log4j.appender.ROLLINGFILE.MaxFileSize=10MB 21 | log4j.appender.ROLLINGFILE.MaxBackupIndex=10 22 | log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout 23 | log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 24 | 25 | log4j.appender.ERRORFILE=org.apache.log4j.RollingFileAppender 26 | log4j.appender.ERRORFILE.Threshold=WARN 27 | log4j.appender.ERRORFILE.File=/usr/local/pantheon/logs/pantheon.error 28 | log4j.appender.ERRORFILE.MaxFileSize=10MB 29 | log4j.appender.ERRORFILE.MaxBackupIndex=10 30 | log4j.appender.ERRORFILE.layout=org.apache.log4j.PatternLayout 31 | log4j.appender.ERRORFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 32 | 33 | 34 | -------------------------------------------------------------------------------- /pantheon-server/README.md: -------------------------------------------------------------------------------- 1 | pantheon server -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/ServerBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server; 2 | 3 | import com.netflix.config.ConfigurationManager; 4 | import com.pantheon.common.ShutdownHookThread; 5 | import com.pantheon.common.lifecycle.Lifecycle; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.concurrent.Callable; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/11/17 14 | * @desc 15 | **/ 16 | public class ServerBootstrap { 17 | private static final Logger logger = LoggerFactory.getLogger(ServerBootstrap.class); 18 | private static final String PANTHEON_ENVIRONMENT = "pantheon.environment"; 19 | private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; 20 | private static final String TEST = "test"; 21 | 22 | 23 | public static void main(String[] args) { 24 | logger.info("ServerBootstrap initializing......"); 25 | 26 | initPantheonEnvironment(); 27 | startServerNode(); 28 | } 29 | 30 | private static ServerNode startServerNode() { 31 | ServerNode serverNode =ServerNode.getInstance(); 32 | serverNode.start(); 33 | if (!serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) { 34 | serverNode.stop(); 35 | System.exit(-3); 36 | } 37 | Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(logger, (Callable) () -> { 38 | serverNode.stop(); 39 | return null; 40 | })); 41 | return serverNode; 42 | } 43 | 44 | public static void shutdown(final ServerNode serverNode) { 45 | serverNode.stop(); 46 | } 47 | 48 | 49 | /** 50 | * Users can override to initialize the environment themselves. 51 | */ 52 | protected static void initPantheonEnvironment() { 53 | String environment = ConfigurationManager.getConfigInstance().getString(PANTHEON_ENVIRONMENT); 54 | if (environment == null) { 55 | //default test environment 56 | ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); 57 | logger.info(PANTHEON_ENVIRONMENT + " value is not set, defaulting to test"); 58 | } 59 | logger.info("Setting the Pantheon configuration withe environment " + environment); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/client/ClientHousekeepingService.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.client; 2 | 3 | import com.pantheon.common.ThreadFactoryImpl; 4 | import com.pantheon.remoting.ChannelEventListener; 5 | import com.pantheon.server.ServerNode; 6 | import io.netty.channel.Channel; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.Executors; 11 | import java.util.concurrent.ScheduledExecutorService; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | public class ClientHousekeepingService implements ChannelEventListener { 15 | private static final Logger log = LoggerFactory.getLogger(ClientHousekeepingService.class); 16 | 17 | private final ServerNode serverNode; 18 | 19 | private ScheduledExecutorService scheduledExecutorService = Executors 20 | .newSingleThreadScheduledExecutor(new ThreadFactoryImpl("ClientHousekeepingScheduledThread")); 21 | 22 | public ClientHousekeepingService(final ServerNode serverNode) { 23 | this.serverNode = serverNode; 24 | } 25 | 26 | public void start() { 27 | 28 | this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { 29 | @Override 30 | public void run() { 31 | try { 32 | ClientHousekeepingService.this.scanExceptionChannel(); 33 | } catch (Throwable e) { 34 | log.error("Error occurred when scan not active client channels.", e); 35 | } 36 | } 37 | }, 1000 * 10, 1000 * 10, TimeUnit.MILLISECONDS); 38 | } 39 | 40 | private void scanExceptionChannel() { 41 | this.serverNode.getConsumerInfoManager().scanNotActiveChannel(); 42 | } 43 | 44 | public void shutdown() { 45 | this.scheduledExecutorService.shutdown(); 46 | } 47 | 48 | @Override 49 | public void onChannelConnect(String remoteAddr, Channel channel) { 50 | 51 | } 52 | 53 | @Override 54 | public void onChannelClose(String remoteAddr, Channel channel) { 55 | this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); 56 | } 57 | 58 | @Override 59 | public void onChannelException(String remoteAddr, Channel channel) { 60 | this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); 61 | } 62 | 63 | @Override 64 | public void onChannelIdle(String remoteAddr, Channel channel) { 65 | this.serverNode.getConsumerInfoManager().doChannelCloseEvent(remoteAddr, channel); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/client/ServerToClient.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.client; 2 | 3 | import com.pantheon.remoting.RemotingServer; 4 | import com.pantheon.remoting.exception.RemotingSendRequestException; 5 | import com.pantheon.remoting.exception.RemotingTimeoutException; 6 | import com.pantheon.remoting.protocol.RemotingCommand; 7 | import com.pantheon.server.ServerNode; 8 | import io.netty.channel.Channel; 9 | 10 | /** 11 | * @author Anthony 12 | * @create 2021/12/13 13 | * @desc server to client communication 14 | */ 15 | public class ServerToClient { 16 | private ServerNode serverNode; 17 | private RemotingServer remotingServer; 18 | 19 | public ServerToClient(ServerNode serverNode) { 20 | this.serverNode=serverNode; 21 | } 22 | 23 | public RemotingCommand callClient(final Channel channel, 24 | final RemotingCommand request 25 | ) throws RemotingSendRequestException, RemotingTimeoutException, InterruptedException { 26 | if(serverNode!=null&&remotingServer==null){ 27 | remotingServer=serverNode.getRemotingServer(); 28 | } 29 | if(remotingServer!=null){ 30 | return this.remotingServer.invokeSync(channel, request, 10000); 31 | } 32 | return null; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/config/PantheonServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.config; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/17 6 | * @desc Configuration information required by the Pantheon Server to operate. 7 | **/ 8 | public interface PantheonServerConfig { 9 | String getDataDir(); 10 | 11 | Boolean isControllerCandidate(); 12 | 13 | Integer getNodeId(); 14 | 15 | String getNodeIp(); 16 | 17 | Integer getNodeInternTcpPort(); 18 | 19 | Integer getNodeClientHttpPort(); 20 | 21 | Integer getNodeClientTcpPort(); 22 | 23 | Integer getClusterNodeCount(); 24 | 25 | String getControllerCandidateServers(); 26 | 27 | Integer getHeartBeatCheckInterval(); 28 | 29 | long getResponseCacheAutoExpirationInSeconds(); 30 | 31 | long getResponseCacheUpdateIntervalMs(); 32 | 33 | long getRetentionTimeInMSInDeltaQueue(); 34 | 35 | long getDeltaRetentionTimerIntervalInMs(); 36 | } 37 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/lease/LeaseManager.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pantheon.server.lease; 3 | 4 | 5 | /** 6 | * This class is responsible for creating/renewing and evicting a lease 7 | * for a particular instance. 8 | * 9 | *

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

15 | */ 16 | public interface LeaseManager { 17 | 18 | /** 19 | * Assign a new {@link Lease} to the passed in {@link T}. 20 | * 21 | * @param r 22 | * - T to register 23 | * @param leaseDuration 24 | * - whether this is a replicated entry from another pantheon node. 25 | */ 26 | void register(T r, int leaseDuration); 27 | 28 | /** 29 | * Cancel the {@link Lease} associated with the passed in appName 30 | * and id. 31 | * 32 | * @param appName 33 | * - unique id of the application. 34 | * @param id 35 | * - unique id within appName. 36 | * @return true, if the operation was successful, false otherwise. 37 | */ 38 | boolean cancel(String appName, String id); 39 | 40 | /** 41 | * Renew the {@link Lease} associated with the passed in appName 42 | * and id. 43 | * 44 | * @param id - unique id within appName 45 | * - whether this is a replicated entry from another ds node 46 | * @return whether the operation of successful 47 | */ 48 | boolean renew(String appName, String id); 49 | 50 | /** 51 | * Evict {@link T}s with expired {@link Lease}(s). 52 | */ 53 | void evict(); 54 | } 55 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/network/IOThreadRunningSignal.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.network; 2 | 3 | /** 4 | * io thread running signal 5 | */ 6 | public class IOThreadRunningSignal { 7 | 8 | private volatile Boolean isRunning; 9 | 10 | public IOThreadRunningSignal(Boolean isRunning) { 11 | this.isRunning = isRunning; 12 | } 13 | 14 | public Boolean isRunning() { 15 | return isRunning; 16 | } 17 | 18 | public void setIsRunning(Boolean isRunning) { 19 | this.isRunning = isRunning; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/network/ServerWriteIOThread.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.network; 2 | 3 | import com.pantheon.common.lifecycle.Lifecycle; 4 | import com.pantheon.server.ServerNode; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.io.DataOutputStream; 9 | import java.io.IOException; 10 | import java.net.Socket; 11 | import java.nio.ByteBuffer; 12 | import java.util.concurrent.LinkedBlockingQueue; 13 | 14 | 15 | public class ServerWriteIOThread extends Thread { 16 | 17 | private static final Logger LOGGER = LoggerFactory.getLogger(ServerWriteIOThread.class); 18 | 19 | public static final Integer TERMINATE_MESSAGE_CAPACITY = 4; 20 | 21 | /** 22 | * remote node id 23 | */ 24 | private Integer remoteNodeId; 25 | /** 26 | * master connections 27 | */ 28 | private Socket socket; 29 | /** 30 | * outputStream for remote node 31 | */ 32 | private DataOutputStream outputStream; 33 | /** 34 | * send queue 35 | */ 36 | private LinkedBlockingQueue sendQueue; 37 | /** 38 | * thread is running 39 | */ 40 | private IOThreadRunningSignal ioThreadRunningSignal; 41 | 42 | public ServerWriteIOThread( 43 | Integer remoteNodeId, 44 | Socket socket, 45 | LinkedBlockingQueue sendQueue, 46 | IOThreadRunningSignal ioThreadRunningSignal) { 47 | this.remoteNodeId = remoteNodeId; 48 | this.socket = socket; 49 | try { 50 | this.outputStream = new DataOutputStream(socket.getOutputStream()); 51 | } catch (IOException e) { 52 | LOGGER.error("get data output stream from socket error......", e); 53 | } 54 | this.sendQueue = sendQueue; 55 | this.ioThreadRunningSignal = ioThreadRunningSignal; 56 | } 57 | 58 | 59 | @Override 60 | public void run() { 61 | ServerNode serverNode = ServerNode.getInstance(); 62 | while ((serverNode.lifecycleState().equals(Lifecycle.State.INITIALIZED) 63 | || serverNode.lifecycleState().equals(Lifecycle.State.STARTED)) && ioThreadRunningSignal.isRunning()) { 64 | try { 65 | // blocking take message 66 | ByteBuffer message = sendQueue.take(); 67 | 68 | // receive terminate message 69 | if (message.capacity() == TERMINATE_MESSAGE_CAPACITY) { 70 | continue; 71 | } 72 | outputStream.writeInt(message.capacity()); 73 | outputStream.write(message.array()); 74 | outputStream.flush(); 75 | } catch (InterruptedException e) { 76 | LOGGER.error("get message from send queue error......", e); 77 | serverNode.stop(); 78 | } catch (IOException e) { 79 | LOGGER.error("send message to remote node error: " + socket.getRemoteSocketAddress()); 80 | serverNode.stop(); 81 | } 82 | } 83 | 84 | LOGGER.info("write connection with【" + remoteNodeId + "】will finish......"); 85 | if (serverNode.lifecycleState().equals(Lifecycle.State.STOPPED)) { 86 | LOGGER.error("write connection with【" + remoteNodeId + "】collapsed......"); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/node/ControllerNode.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.node; 2 | 3 | public class ControllerNode { 4 | 5 | private Integer nodeId; 6 | 7 | private ControllerNode() { 8 | 9 | } 10 | 11 | static class Singleton { 12 | static ControllerNode instance = new ControllerNode(); 13 | } 14 | 15 | public static ControllerNode getInstance() { 16 | return Singleton.instance; 17 | } 18 | 19 | public Integer getNodeId() { 20 | return nodeId; 21 | } 22 | 23 | public static void setNodeId(Integer nodeId) { 24 | getInstance().nodeId = nodeId; 25 | } 26 | 27 | public static Boolean isControllerNode(Integer nodeId) { 28 | return getInstance().nodeId.equals(nodeId); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/node/ControllerVote.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.node; 2 | 3 | 4 | import com.pantheon.common.MessageType; 5 | 6 | import java.nio.ByteBuffer; 7 | 8 | 9 | public class ControllerVote { 10 | 11 | /** 12 | * voter's id 13 | */ 14 | private Integer voterNodeId; 15 | /** 16 | * vote which controller 17 | */ 18 | private Integer controllerNodeId; 19 | /** 20 | * vote round 21 | */ 22 | private Integer voteRound; 23 | 24 | public ControllerVote(Integer voterNodeId, Integer controllerNodeId, Integer voteRound) { 25 | this.voterNodeId = voterNodeId; 26 | this.controllerNodeId = controllerNodeId; 27 | this.voteRound = voteRound; 28 | } 29 | 30 | public ControllerVote(ByteBuffer message) { 31 | this.voterNodeId = message.getInt(); 32 | this.controllerNodeId = message.getInt(); 33 | this.voteRound = message.getInt(); 34 | } 35 | 36 | public Integer getVoterNodeId() { 37 | return voterNodeId; 38 | } 39 | 40 | public void setVoterNodeId(Integer voterNodeId) { 41 | this.voterNodeId = voterNodeId; 42 | } 43 | 44 | public Integer getControllerNodeId() { 45 | return controllerNodeId; 46 | } 47 | 48 | public void setControllerNodeId(Integer controllerNodeId) { 49 | this.controllerNodeId = controllerNodeId; 50 | } 51 | 52 | public Integer getVoteRound() { 53 | return voteRound; 54 | } 55 | 56 | public void setVoteRound(Integer voteRound) { 57 | this.voteRound = voteRound; 58 | } 59 | 60 | public ByteBuffer getMessageByteBuffer() { 61 | byte[] bytes = new byte[16]; 62 | ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); 63 | byteBuffer.clear(); 64 | 65 | byteBuffer.putInt(MessageType.VOTE); 66 | byteBuffer.putInt(voterNodeId); 67 | byteBuffer.putInt(controllerNodeId); 68 | byteBuffer.putInt(voteRound); 69 | 70 | return byteBuffer; 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return "Vote{" + 76 | "voterNodeId=" + voterNodeId + 77 | ", controllerNodeId=" + controllerNodeId + 78 | ", voteRound=" + voteRound + 79 | '}'; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNode.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.node; 2 | 3 | public class RemoteServerNode { 4 | 5 | /** 6 | * remote server's node id 7 | */ 8 | private Integer nodeId; 9 | /** 10 | * whether a controller candidate 11 | */ 12 | private Boolean isControllerCandidate; 13 | /** 14 | * whether a controller 15 | */ 16 | private Boolean isController = false; 17 | /** 18 | * remote server's node ip 19 | */ 20 | private String ip; 21 | /** 22 | * remote server's port for client connection 23 | */ 24 | private Integer clientPort; 25 | 26 | public RemoteServerNode(Integer nodeId, 27 | Boolean isControllerCandidate, 28 | String ip, 29 | Integer clientPort, 30 | Boolean isContorller) { 31 | this.nodeId = nodeId; 32 | this.isControllerCandidate = isControllerCandidate; 33 | this.ip = ip; 34 | this.clientPort = clientPort; 35 | this.isController = isController(); 36 | } 37 | 38 | public Integer getNodeId() { 39 | return nodeId; 40 | } 41 | 42 | public void setNodeId(Integer nodeId) { 43 | this.nodeId = nodeId; 44 | } 45 | 46 | public Boolean isControllerCandidate() { 47 | return isControllerCandidate; 48 | } 49 | 50 | public void setControllerCandidate(Boolean controllerCandidate) { 51 | isControllerCandidate = controllerCandidate; 52 | } 53 | 54 | public Boolean isController() { 55 | return isController; 56 | } 57 | 58 | public void setController(Boolean controller) { 59 | isController = controller; 60 | } 61 | 62 | public String getIp() { 63 | return ip; 64 | } 65 | 66 | public void setIp(String ip) { 67 | this.ip = ip; 68 | } 69 | 70 | public Integer getClientPort() { 71 | return clientPort; 72 | } 73 | 74 | public void setClientPort(Integer clientPort) { 75 | this.clientPort = clientPort; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "RemoteMasterNode{" + 81 | "nodeId=" + nodeId + 82 | ", isControllerCandidate=" + isControllerCandidate + 83 | ", ip='" + ip + '\'' + 84 | ", clientPort=" + clientPort + 85 | '}'; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/node/RemoteServerNodeManager.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.node; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | /** 8 | * save remote servers connecting with current node 9 | */ 10 | public class RemoteServerNodeManager { 11 | 12 | private RemoteServerNodeManager() { 13 | 14 | } 15 | 16 | static class Singleton { 17 | static RemoteServerNodeManager instance = new RemoteServerNodeManager(); 18 | } 19 | 20 | public static RemoteServerNodeManager getInstance() { 21 | return Singleton.instance; 22 | } 23 | 24 | /** 25 | * save remote server nodes 26 | */ 27 | private ConcurrentHashMap remoteServerNodes = 28 | new ConcurrentHashMap(); 29 | 30 | 31 | public void addRemoteServerNode(RemoteServerNode remoteServerNode) { 32 | remoteServerNodes.put(remoteServerNode.getNodeId(), remoteServerNode); 33 | } 34 | 35 | /** 36 | * get all other controller candidates 37 | * @return 38 | */ 39 | public List getOtherControllerCandidates() { 40 | List otherControllerCandidates = new ArrayList(); 41 | 42 | for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { 43 | if(remoteServerNode.isControllerCandidate()) { 44 | otherControllerCandidates.add(remoteServerNode); 45 | } 46 | } 47 | 48 | return otherControllerCandidates; 49 | } 50 | 51 | /** 52 | * get all other master nodes 53 | * @return 54 | */ 55 | public List getRemoteServerNodes() { 56 | return new ArrayList<>(remoteServerNodes.values()); 57 | } 58 | 59 | /** 60 | * remove server node in memory 61 | * @param remoteNodeId 62 | */ 63 | public void removeServerNode(Integer remoteNodeId) { 64 | remoteServerNodes.remove(remoteNodeId); 65 | } 66 | 67 | public RemoteServerNode getRemoteServerNode(Integer remoteNodeId) { 68 | return remoteServerNodes.get(remoteNodeId); 69 | } 70 | 71 | public boolean hasController() { 72 | for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { 73 | if(remoteServerNode.isController()) { 74 | return true; 75 | } 76 | } 77 | return false; 78 | } 79 | 80 | public RemoteServerNode getController() { 81 | for(RemoteServerNode remoteServerNode : remoteServerNodes.values()) { 82 | if(remoteServerNode.isController()) { 83 | return remoteServerNode; 84 | } 85 | } 86 | return null; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/persist/FilePersistUtils.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.persist; 2 | 3 | import com.pantheon.server.config.ArchaiusPantheonServerConfig; 4 | import com.pantheon.server.config.CachedPantheonServerConfig; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.io.BufferedOutputStream; 9 | import java.io.DataOutputStream; 10 | import java.io.File; 11 | import java.io.FileOutputStream; 12 | import java.util.zip.Adler32; 13 | import java.util.zip.Checksum; 14 | 15 | public class FilePersistUtils { 16 | 17 | private static final Logger LOGGER = LoggerFactory.getLogger(FilePersistUtils.class); 18 | 19 | 20 | /** 21 | * save to disk 22 | * @param bytes 23 | * @param filename 24 | * @return 25 | */ 26 | public static Boolean persist(byte[] bytes, String filename) { 27 | try { 28 | // get data saving directory 29 | File dataDir = new File(CachedPantheonServerConfig.getInstance().getDataDir()); 30 | if(!dataDir.exists()) { 31 | dataDir.mkdirs(); 32 | } 33 | 34 | File file = new File(dataDir, filename); 35 | FileOutputStream fileOutputStream = new FileOutputStream(file); 36 | BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); 37 | DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); 38 | 39 | //checksum for data in disk 40 | Checksum checksum = new Adler32(); 41 | checksum.update(bytes, 0, bytes.length); 42 | long checksumValue = checksum.getValue(); 43 | dataOutputStream.writeLong(checksumValue); 44 | dataOutputStream.writeInt(bytes.length); 45 | dataOutputStream.write(bytes); 46 | //flush to fileOutputStream 47 | bufferedOutputStream.flush(); 48 | // flush to os cache 49 | fileOutputStream.flush(); 50 | // flush to disk 51 | fileOutputStream.getChannel().force(false); 52 | } catch(Exception e) { 53 | LOGGER.error("persist file error......", e); 54 | return false; 55 | } 56 | return true; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/registry/Key.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.registry; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/11/30 6 | * @desc 7 | */ 8 | public class Key { 9 | private final String entityName; 10 | private final String hashKey; 11 | private final ACCEPT accept; 12 | 13 | public enum ACCEPT { 14 | FULL, COMPACT 15 | } 16 | 17 | 18 | public Key(String entityName,ACCEPT accept) { 19 | this.entityName = entityName; 20 | this.accept =accept; 21 | hashKey = this.entityName+this.accept; 22 | } 23 | 24 | public String getName() { 25 | return entityName; 26 | } 27 | 28 | public String getHashKey() { 29 | return hashKey; 30 | } 31 | 32 | 33 | @Override 34 | public int hashCode() { 35 | String hashKey = getHashKey(); 36 | return hashKey.hashCode(); 37 | } 38 | 39 | @Override 40 | public boolean equals(Object other) { 41 | if (other instanceof Key) { 42 | return getHashKey().equals(((Key) other).getHashKey()); 43 | } else { 44 | return false; 45 | } 46 | } 47 | 48 | 49 | public String toStringCompact() { 50 | StringBuilder sb = new StringBuilder(); 51 | sb.append("{name=").append(entityName).append(", accept=").append(accept).append('}'); 52 | return sb.toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/registry/LeaseExistsRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.registry; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | import com.pantheon.server.rule.InstanceStatusOverrideRule; 7 | import com.pantheon.server.rule.StatusOverrideResult; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | /** 12 | * This rule matches if we have an existing lease for the instance that is UP or OUT_OF_SERVICE. 13 | */ 14 | public class LeaseExistsRule implements InstanceStatusOverrideRule { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(LeaseExistsRule.class); 17 | 18 | @Override 19 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 20 | Lease existingLease) { 21 | InstanceInfo.InstanceStatus existingStatus = null; 22 | if (existingLease != null) { 23 | existingStatus = existingLease.getHolder().getStatus(); 24 | } 25 | // Allow server to have its way when the status is UP or OUT_OF_SERVICE 26 | if ((existingStatus != null) 27 | && (InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(existingStatus) 28 | || InstanceInfo.InstanceStatus.UP.equals(existingStatus))) { 29 | logger.debug("There is already an existing lease with status {} for instance {}", 30 | existingLease.getHolder().getStatus().name(), 31 | existingLease.getHolder().getId()); 32 | return StatusOverrideResult.matchingStatus(existingLease.getHolder().getStatus()); 33 | } 34 | return StatusOverrideResult.NO_MATCH; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return LeaseExistsRule.class.getName(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/registry/OverrideExistsRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.registry; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | import com.pantheon.server.rule.InstanceStatusOverrideRule; 7 | import com.pantheon.server.rule.StatusOverrideResult; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * This rule checks to see if we have overrides for an instance and if we do then we return those. 15 | * 16 | */ 17 | public class OverrideExistsRule implements InstanceStatusOverrideRule { 18 | 19 | private static final Logger logger = LoggerFactory.getLogger(OverrideExistsRule.class); 20 | 21 | private Map statusOverrides; 22 | 23 | public OverrideExistsRule(Map statusOverrides) { 24 | this.statusOverrides = statusOverrides; 25 | } 26 | 27 | @Override 28 | public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease existingLease) { 29 | InstanceInfo.InstanceStatus overridden = statusOverrides.get(instanceInfo.getId()); 30 | // If there are instance specific overrides, then they win 31 | if (overridden != null) { 32 | logger.debug("The instance specific override for instance {} and the value is {}", 33 | instanceInfo.getId(), overridden.name()); 34 | return StatusOverrideResult.matchingStatus(overridden); 35 | } 36 | return StatusOverrideResult.NO_MATCH; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return OverrideExistsRule.class.getName(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/registry/ResponseCache.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.registry; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | /** 6 | * @author Anthony 7 | * @create 2021/11/30 8 | * @desc 9 | */ 10 | public interface ResponseCache { 11 | 12 | void invalidate(String appName); 13 | 14 | AtomicLong getVersionDelta(); 15 | 16 | 17 | /** 18 | * Get the cached information about applications. 19 | * 20 | *

21 | * 22 | * @param key the key for which the cached information needs to be obtained. 23 | * @return payload which contains information about the applications. 24 | */ 25 | String get(Key key); 26 | 27 | /** 28 | * Get the compressed information about the applications. 29 | * 30 | * @param key the key for which the compressed cached information needs to be obtained. 31 | * @return compressed payload which contains information about the applications. 32 | */ 33 | byte[] getGZIP(Key key); 34 | } 35 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/rule/AlwaysMatchInstanceStatusRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.rule; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * This rule matches always and returns the current status of the instance. 11 | * 12 | */ 13 | public class AlwaysMatchInstanceStatusRule implements InstanceStatusOverrideRule { 14 | private static final Logger logger = LoggerFactory.getLogger(AlwaysMatchInstanceStatusRule.class); 15 | 16 | @Override 17 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 18 | Lease existingLease) { 19 | logger.debug("Returning the default instance status {} for instance {}", instanceInfo.getStatus(), 20 | instanceInfo.getId()); 21 | return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return AlwaysMatchInstanceStatusRule.class.getName(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/rule/DownOrStartingRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.rule; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * This rule matches if the instance is DOWN or STARTING. 11 | * 12 | */ 13 | public class DownOrStartingRule implements InstanceStatusOverrideRule { 14 | private static final Logger logger = LoggerFactory.getLogger(DownOrStartingRule.class); 15 | 16 | @Override 17 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 18 | Lease existingLease) { 19 | if ((!InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())) 20 | && (!InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(instanceInfo.getStatus()))) { 21 | logger.debug("Trusting the instance status {} for instance {}", 22 | instanceInfo.getStatus(), instanceInfo.getId()); 23 | return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); 24 | } 25 | return StatusOverrideResult.NO_MATCH; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return DownOrStartingRule.class.getName(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/rule/FirstMatchWinsCompositeRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.rule; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * This rule takes an ordered list of rules and returns the result of the first match or the 12 | * result of the {@link AlwaysMatchInstanceStatusRule}. 13 | * 14 | */ 15 | public class FirstMatchWinsCompositeRule implements InstanceStatusOverrideRule { 16 | 17 | private final InstanceStatusOverrideRule[] rules; 18 | private final InstanceStatusOverrideRule defaultRule; 19 | private final String compositeRuleName; 20 | 21 | public FirstMatchWinsCompositeRule(InstanceStatusOverrideRule... rules) { 22 | this.rules = rules; 23 | this.defaultRule = new AlwaysMatchInstanceStatusRule(); 24 | // Let's build up and "cache" the rule name to be used by toString(); 25 | List ruleNames = new ArrayList<>(rules.length+1); 26 | for (int i = 0; i < rules.length; ++i) { 27 | ruleNames.add(rules[i].toString()); 28 | } 29 | ruleNames.add(defaultRule.toString()); 30 | compositeRuleName = ruleNames.toString(); 31 | } 32 | 33 | @Override 34 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 35 | Lease existingLease) { 36 | for (int i = 0; i < this.rules.length; ++i) { 37 | StatusOverrideResult result = this.rules[i].apply(instanceInfo, existingLease); 38 | if (result.matches()) { 39 | return result; 40 | } 41 | } 42 | return defaultRule.apply(instanceInfo, existingLease); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return this.compositeRuleName; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/rule/InstanceStatusOverrideRule.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.rule; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.server.lease.Lease; 6 | import com.pantheon.server.registry.InstanceRegistryImpl; 7 | 8 | /** 9 | * A single rule that if matched it returns an instance status. 10 | * The idea is to use an ordered list of such rules and pick the first result that matches. 11 | * 12 | * It is designed to be used by 13 | * {@link InstanceRegistryImpl#getOverriddenInstanceStatus(InstanceInfo, Lease)} 14 | * 15 | */ 16 | public interface InstanceStatusOverrideRule { 17 | 18 | /** 19 | * Match this rule. 20 | * 21 | * @param instanceInfo The instance info whose status we care about. 22 | * @param existingLease Does the instance have an existing lease already? If so let's consider that. 23 | * @return A result with whether we matched and what we propose the status to be overriden to. 24 | */ 25 | StatusOverrideResult apply(final InstanceInfo instanceInfo, 26 | final Lease existingLease); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/rule/StatusOverrideResult.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.rule; 2 | 3 | 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | 6 | /** 7 | * Container for a result computed by an {@link InstanceStatusOverrideRule}. 8 | * 9 | */ 10 | public class StatusOverrideResult { 11 | 12 | public static StatusOverrideResult NO_MATCH = new StatusOverrideResult(false, null); 13 | 14 | public static StatusOverrideResult matchingStatus(InstanceInfo.InstanceStatus status) { 15 | return new StatusOverrideResult(true, status); 16 | } 17 | 18 | // Does the rule match? 19 | private final boolean matches; 20 | 21 | // The status computed by the rule. 22 | private final InstanceInfo.InstanceStatus status; 23 | 24 | private StatusOverrideResult(boolean matches, InstanceInfo.InstanceStatus status) { 25 | this.matches = matches; 26 | this.status = status; 27 | } 28 | 29 | public boolean matches() { 30 | return matches; 31 | } 32 | 33 | public InstanceInfo.InstanceStatus status() { 34 | return status; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/slot/Slot.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.slot; 2 | 3 | 4 | import com.pantheon.server.registry.InstanceRegistryImpl; 5 | import com.pantheon.server.slot.registry.ServiceInstance; 6 | import com.pantheon.server.slot.registry.ServiceRegistry; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Slot play a role of routing and partitioning services data 12 | */ 13 | public class Slot { 14 | 15 | /** 16 | * slot num 17 | */ 18 | private Integer slotNo; 19 | 20 | private InstanceRegistryImpl instanceRegistry; 21 | 22 | 23 | public Slot(Integer slotNo) { 24 | this.slotNo = slotNo; 25 | } 26 | 27 | 28 | 29 | public Slot(Integer slotNo,InstanceRegistryImpl instanceRegistry) { 30 | this.slotNo = slotNo; 31 | this.instanceRegistry =instanceRegistry; 32 | } 33 | 34 | public void setInstanceRegistry(InstanceRegistryImpl instanceRegistry) { 35 | this.instanceRegistry = instanceRegistry; 36 | } 37 | 38 | public void setSlotNo(Integer slotNo) { 39 | this.slotNo = slotNo; 40 | } 41 | 42 | public InstanceRegistryImpl getInstanceRegistry() { 43 | return instanceRegistry; 44 | } 45 | 46 | public Integer getSlotNo() { 47 | return slotNo; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/slot/Slots.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.slot; 2 | 3 | 4 | import com.pantheon.server.slot.registry.ServiceRegistry; 5 | 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | /** 9 | * slots in current node 10 | */ 11 | public class Slots { 12 | 13 | /** 14 | * slots in memory 15 | */ 16 | private ConcurrentHashMap slots = 17 | new ConcurrentHashMap<>(); 18 | /** 19 | * corresponding replica slots id 20 | */ 21 | private Integer replicaNodeId; 22 | 23 | /** 24 | * slots initialization 25 | * 26 | * @param slotScope 27 | */ 28 | public void init(String slotScope) { 29 | String[] slotScopeSplited = slotScope.split(","); 30 | Integer startSlotNo = Integer.valueOf(slotScopeSplited[0]); 31 | Integer endSlotNo = Integer.valueOf(slotScopeSplited[1]); 32 | 33 | // ServiceRegistry serviceRegistry = new ServiceRegistry(false); 34 | //todo put map when use 35 | for (Integer slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) { 36 | slots.put(slotNo, new Slot(slotNo)); 37 | } 38 | } 39 | 40 | public void putSlot(Integer slotNo, Slot slot) { 41 | slots.put(slotNo, slot); 42 | } 43 | 44 | /** 45 | * corresponding replica slots id 46 | * 47 | * @param replicaNodeId 48 | */ 49 | public void setReplicaNodeId(Integer replicaNodeId) { 50 | this.replicaNodeId = replicaNodeId; 51 | } 52 | 53 | public Slot getSlot(Integer slotNo) { 54 | return slots.get(slotNo); 55 | } 56 | 57 | public void removeSlot(Integer slotNo) { 58 | slots.remove(slotNo); 59 | } 60 | 61 | public Integer getReplicaNodeId() { 62 | return replicaNodeId; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/slot/SlotsReplica.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.slot; 2 | 3 | import com.pantheon.server.slot.registry.ServiceRegistry; 4 | 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | 8 | /** 9 | * slots replica 10 | * 11 | * 1 todo build with new register mechanism 12 | * 2 todo load specific instances not all 13 | */ 14 | public class SlotsReplica { 15 | 16 | private ConcurrentHashMap slots = 17 | new ConcurrentHashMap<>(); 18 | 19 | public void init(String slotScope) { 20 | String[] slotScopeSplited = slotScope.split(","); 21 | Integer startSlotNo = Integer.valueOf(slotScopeSplited[0]); 22 | Integer endSlotNo = Integer.valueOf(slotScopeSplited[1]); 23 | for(Integer slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) { 24 | slots.put(slotNo, new Slot(slotNo)); 25 | } 26 | } 27 | 28 | public Slot getSlot(Integer slotNo) { 29 | return slots.get(slotNo); 30 | } 31 | 32 | public ConcurrentHashMap getSlots() { 33 | return slots; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.slot.registry; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * when service changed, get notified in {@link ServiceChangedListener#onChange(String, List)} 9 | */ 10 | public class ServiceChangedListener { 11 | 12 | /** 13 | * identifier for client connection 14 | */ 15 | private String clientConnectionId; 16 | 17 | public ServiceChangedListener(String clientConnectionId) { 18 | this.clientConnectionId = clientConnectionId; 19 | } 20 | 21 | /** 22 | * notify this method when service changed 23 | * 24 | * @param serviceInstances 25 | */ 26 | public void onChange(String serviceName, List serviceInstances) { 27 | List serviceInstanceAddresses = new ArrayList(); 28 | for (ServiceInstance serviceInstance : serviceInstances) { 29 | serviceInstanceAddresses.add(serviceInstance.getAddress()); 30 | } 31 | 32 | // build and send a request of service changed to client connection 33 | // Request request = new ServiceChangedRequest.Builder() 34 | // .serviceName(serviceName) 35 | // .serviceInstanceAddresses(serviceInstanceAddresses) 36 | // .build(); 37 | 38 | // ClientMessageQueues clientRequestQueues = ClientMessageQueues.getInstance(); 39 | // clientRequestQueues.offerMessage(clientConnectionId, request); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /pantheon-server/src/main/java/com/pantheon/server/slot/registry/ServiceInstance.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.server.slot.registry; 2 | 3 | import java.util.Objects; 4 | 5 | 6 | public class ServiceInstance { 7 | 8 | private String serviceName; 9 | private String serviceInstanceIp; 10 | private Integer serviceInstancePort; 11 | private volatile Long latestHeartbeatTime; 12 | 13 | public ServiceInstance(String serviceName, String serviceInstanceIp, Integer serviceInstancePort) { 14 | this.serviceName = serviceName; 15 | this.serviceInstanceIp = serviceInstanceIp; 16 | this.serviceInstancePort = serviceInstancePort; 17 | } 18 | 19 | public String getServiceName() { 20 | return serviceName; 21 | } 22 | 23 | public void setServiceName(String serviceName) { 24 | this.serviceName = serviceName; 25 | } 26 | 27 | public String getServiceInstanceIp() { 28 | return serviceInstanceIp; 29 | } 30 | 31 | public void setServiceInstanceIp(String serviceInstanceIp) { 32 | this.serviceInstanceIp = serviceInstanceIp; 33 | } 34 | 35 | public Integer getServiceInstancePort() { 36 | return serviceInstancePort; 37 | } 38 | 39 | public void setServiceInstancePort(Integer serviceInstancePort) { 40 | this.serviceInstancePort = serviceInstancePort; 41 | } 42 | 43 | public String getServiceInstanceId() { 44 | return serviceName + "_" + serviceInstanceIp + "_" + serviceInstancePort; 45 | } 46 | 47 | public Long getLatestHeartbeatTime() { 48 | return latestHeartbeatTime; 49 | } 50 | 51 | public void setLatestHeartbeatTime(Long latestHeartbeatTime) { 52 | this.latestHeartbeatTime = latestHeartbeatTime; 53 | } 54 | 55 | public String getAddress() { 56 | return serviceName + "," + serviceInstanceIp + "," + serviceInstancePort; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return "ServiceInstance{" + 62 | "serviceName='" + serviceName + '\'' + 63 | ", serviceInstanceIp='" + serviceInstanceIp + '\'' + 64 | ", serviceInstancePort=" + serviceInstancePort + 65 | '}'; 66 | } 67 | 68 | public static String getServiceInstanceId(String serviceName, 69 | String serviceInstanceIp, 70 | Integer serviceInstancePort) { 71 | return serviceName + "_" + serviceInstanceIp + "_" + serviceInstancePort; 72 | } 73 | 74 | @Override 75 | public boolean equals(Object o) { 76 | if (this == o) return true; 77 | if (o == null || getClass() != o.getClass()) return false; 78 | ServiceInstance that = (ServiceInstance) o; 79 | return serviceName.equals(that.serviceName) && 80 | serviceInstanceIp.equals(that.serviceInstanceIp) && 81 | serviceInstancePort.equals(that.serviceInstancePort); 82 | } 83 | 84 | @Override 85 | public int hashCode() { 86 | return Objects.hash(serviceName, serviceInstanceIp, serviceInstancePort); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /pantheon-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | pantheon.environment=dev 2 | pantheon.dataDir="/usr/local/1" -------------------------------------------------------------------------------- /pantheon-server/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, CONSOLE 2 | 3 | # local : debug log to console 4 | log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CONSOLE.Threshold=DEBUG 6 | log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 8 | 9 | # test: log to file 10 | log4j.appender.TRACEFILE=org.apache.log4j.FileAppender 11 | log4j.appender.TRACEFILE.Threshold=DEBUG 12 | log4j.appender.TRACEFILE.File=/usr/local/pantheon/logs/pantheon.trace 13 | log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout 14 | log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n 15 | 16 | # prod: log to pantheon.log and pantheon.error 17 | log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender 18 | log4j.appender.ROLLINGFILE.Threshold=INFO 19 | log4j.appender.ROLLINGFILE.File=/usr/local/pantheon/logs/pantheon.log 20 | log4j.appender.ROLLINGFILE.MaxFileSize=10MB 21 | log4j.appender.ROLLINGFILE.MaxBackupIndex=10 22 | log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout 23 | log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 24 | 25 | log4j.appender.ERRORFILE=org.apache.log4j.RollingFileAppender 26 | log4j.appender.ERRORFILE.Threshold=WARN 27 | log4j.appender.ERRORFILE.File=/usr/local/pantheon/logs/pantheon.error 28 | log4j.appender.ERRORFILE.MaxFileSize=10MB 29 | log4j.appender.ERRORFILE.MaxBackupIndex=10 30 | log4j.appender.ERRORFILE.layout=org.apache.log4j.PatternLayout 31 | log4j.appender.ERRORFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n 32 | 33 | 34 | -------------------------------------------------------------------------------- /pantheon-server/src/main/resources/pantheon-server-test1.properties: -------------------------------------------------------------------------------- 1 | # node id 2 | pantheon.nodeId=111 3 | # node ip 4 | pantheon.nodeIp= 127.0.0.1 5 | # intern tcp port 6 | pantheon.nodeInternTcpPort=9971 7 | # client http port 8 | pantheon.nodeClientHttpPort=9981 9 | # client tcp port 10 | pantheon.nodeClientTcpPort=9961 11 | # whether a controller candidate 12 | pantheon.isControllerCandidate=true 13 | # dir to save data 14 | pantheon.dataDir= /Users/anthony/iCloud Drive (Archive)/Desktop/my company/openSource/pantheon/pantheon-server/target/node1 15 | # all servers count 16 | pantheon.clusterNodeCount=2 17 | # all controller candidate 18 | pantheon.controllerCandidateServers=127.0.0.1:9971,127.0.0.1:9972 19 | # heartbeat check interval 20 | pantheon.heartbeatCheckInterval=3 21 | # heart beat timeout 22 | pantheon.heartbeatTimeoutPeriod=5 23 | -------------------------------------------------------------------------------- /pantheon-server/src/main/resources/pantheon-server-test2.properties: -------------------------------------------------------------------------------- 1 | # node id 2 | pantheon.nodeId=222 3 | # node ip 4 | pantheon.nodeIp= 127.0.0.1 5 | # intern tcp port 6 | pantheon.nodeInternTcpPort=9972 7 | # client http port 8 | pantheon.nodeClientHttpPort=9982 9 | # client tcp port 10 | pantheon.nodeClientTcpPort=9962 11 | # whether a controller candidate 12 | pantheon.isControllerCandidate=true 13 | # dir to save data 14 | pantheon.dataDir= /Users/anthony/iCloud Drive (Archive)/Desktop/my company/openSource/pantheon/pantheon-server/target/node2 15 | # all servers count 16 | pantheon.clusterNodeCount=2 17 | # all controller candidate 18 | pantheon.controllerCandidateServers=127.0.0.1:9971,127.0.0.1:9972 19 | # heartbeat check interval 20 | pantheon.heartbeatCheckInterval=3 21 | # heart beat timeout 22 | pantheon.heartbeatTimeoutPeriod=5 -------------------------------------------------------------------------------- /pantheon-server/src/main/resources/pantheon-server.properties: -------------------------------------------------------------------------------- 1 | pantheon.environment=dev 2 | pantheon.nodeId=1 3 | pantheon.nodeIp= 127.0.0.1 4 | pantheon.nodeInternTcpPort=9971 5 | pantheon.nodeClientHttpPort=9981 6 | pantheon.nodeClientTcpPort=9991 7 | pantheon.isControllerCandidate=true 8 | pantheon.dataDir= /usr/local/node1 9 | pantheon.clusterNodeCount=2 10 | pantheon.controllerCandidateServers=127.0.0.1:9991,127.0.0.1:9992 11 | pantheon.heartbeatCheckInterval=3 12 | pantheon.heartbeatTimeoutPeriod=5 -------------------------------------------------------------------------------- /pantheon-spring-cloud-gateway-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-spring-cloud-gateway-support 13 | 14 | 15 | 13 16 | 13 17 | 18 | 19 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client-new/README.md: -------------------------------------------------------------------------------- 1 | Reference from spring-cloud-netflix-eureka-client-3.0.4.RELEASE.jar -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client-new/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-spring-cloud-netflix-client-v3.4 13 | 14 | 15 | 13 16 | 13 17 | 18 | 19 | 20 | 21 | 22 | ${project.groupId} 23 | pantheon-client 24 | 1.0-SNAPSHOT 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-configuration-processor 29 | 2.4.10 30 | compile 31 | true 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-actuator 36 | 2.4.10 37 | compile 38 | true 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-webflux 43 | 2.4.10 44 | compile 45 | true 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-config-client 50 | 3.0.5 51 | compile 52 | true 53 | 54 | 55 | org.springframework.cloud 56 | spring-cloud-config-server 57 | 3.0.5 58 | compile 59 | true 60 | 61 | 62 | org.springframework.cloud 63 | spring-cloud-loadbalancer 64 | 3.0.4 65 | compile 66 | true 67 | 68 | 69 | javax.inject 70 | javax.inject 71 | 1 72 | compile 73 | true 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-autoconfigure-processor 78 | 2.4.10 79 | compile 80 | true 81 | 82 | 83 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/README.md: -------------------------------------------------------------------------------- 1 | Reference from spring-cloud-netflix-eureka-client-1.4.5.RELEASE.jar -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-spring-cloud-netflix-client 13 | 14 | 15 | 8 16 | 8 17 | 18 | 19 | 20 | 21 | org.springframework.cloud 22 | spring-cloud-commons 23 | 1.3.4.RELEASE 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-netflix-core 28 | 1.4.5.RELEASE 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-context 33 | 1.3.4.RELEASE 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-actuator 38 | 1.5.14.RELEASE 39 | 40 | 41 | ${project.groupId} 42 | pantheon-client 43 | 1.0-SNAPSHOT 44 | 45 | 46 | org.springframework.cloud 47 | spring-cloud-config-client 48 | 1.4.4.RELEASE 49 | 50 | 51 | com.netflix.ribbon 52 | ribbon 53 | 2.2.5 54 | 55 | 56 | com.netflix.ribbon 57 | ribbon-core 58 | 2.2.5 59 | 60 | 61 | com.netflix.ribbon 62 | ribbon-loadbalancer 63 | 2.2.5 64 | 65 | 66 | com.netflix.ribbon 67 | ribbon-httpclient 68 | 2.2.5 69 | 70 | 71 | javax.inject 72 | javax.inject 73 | 1 74 | 75 | 76 | com.google.guava 77 | guava 78 | 19.0 79 | compile 80 | 81 | 82 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/AutoServiceRegistration.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/12/17 6 | * @desc 7 | **/ 8 | public interface AutoServiceRegistration { 9 | } 10 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/EnablePantheonClient.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Inherited; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author Anthony 12 | * @create 2021/12/14 13 | * @desc All it does is turn on discovery and let the autoconfiguration 14 | * find the pantheon classes if they are available 15 | **/ 16 | @Target(ElementType.TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | @Inherited 20 | public @interface EnablePantheonClient { 21 | } 22 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/HealthCheckHandler.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client; 2 | 3 | import com.pantheon.client.appinfo.InstanceInfo; 4 | 5 | /** 6 | * @author Anthony 7 | * @create 2021/12/17 8 | * @desc 9 | **/ 10 | public interface HealthCheckHandler { 11 | InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus var1); 12 | } 13 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/InstanceInfoFactory.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client; 2 | 3 | import com.pantheon.client.appinfo.InstanceInfo; 4 | import com.pantheon.client.appinfo.LeaseInfo; 5 | import com.pantheon.client.config.PantheonInstanceConfig; 6 | import org.apache.commons.logging.Log; 7 | import org.apache.commons.logging.LogFactory; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/12/16 14 | * @desc 15 | **/ 16 | public class InstanceInfoFactory { 17 | 18 | private static final Log log = LogFactory.getLog(InstanceInfoFactory.class); 19 | 20 | public InstanceInfo create(PantheonInstanceConfig config) { 21 | LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder() 22 | .setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds()) 23 | .setDurationInSecs(config.getLeaseExpirationDurationInSeconds()); 24 | 25 | // Builder the instance information to be registered with pantheon 26 | // server 27 | InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); 28 | 29 | 30 | builder.setAppName(config.getServiceName()) 31 | .setInstanceId(config.getInstanceId()) 32 | .setIPAddr(config.getInstanceIpAddress()).setHostName(config.getInstanceHostName()) 33 | .setPort(config.getInstancePort()); 34 | 35 | InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.STARTING; 36 | if (log.isInfoEnabled()) { 37 | log.info("Setting initial instance status as: " + initialStatus); 38 | } 39 | builder.setStatus(initialStatus); 40 | 41 | // Add any user-specific metadata information 42 | for (Map.Entry mapEntry : config.getMetadataMap().entrySet()) { 43 | String key = mapEntry.getKey(); 44 | String value = mapEntry.getValue(); 45 | builder.add(key, value); 46 | } 47 | 48 | InstanceInfo instanceInfo = builder.build(); 49 | instanceInfo.setLeaseInfo(leaseInfoBuilder.build()); 50 | return instanceInfo; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/PantheonClientAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client; 2 | 3 | /** 4 | * @author Anthony 5 | * @create 2021/12/17 6 | * @desc 7 | **/ 8 | public class PantheonClientAutoConfiguration { 9 | } 10 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.config; 2 | 3 | import com.pantheon.client.DiscoveryClientNode; 4 | import com.pantheon.netflix.client.PantheonDiscoveryClientConfiguration; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.context.ConfigurableApplicationContext; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | /** 13 | * @author Anthony 14 | * @create 2021/12/17 15 | * @desc 16 | **/ 17 | @ConditionalOnBean({PantheonDiscoveryClientConfiguration.class}) 18 | @ConditionalOnProperty( 19 | value = {"spring.cloud.config.discovery.enabled"}, 20 | matchIfMissing = false 21 | ) 22 | public class PantheonDiscoveryClientConfigServiceAutoConfiguration { 23 | @Autowired 24 | private ConfigurableApplicationContext context; 25 | 26 | public PantheonDiscoveryClientConfigServiceAutoConfiguration() { 27 | } 28 | 29 | @PostConstruct 30 | public void init() { 31 | if (this.context.getParent() != null && this.context.getBeanNamesForType(DiscoveryClientNode.class).length > 0 && this.context.getParent().getBeanNamesForType(DiscoveryClientNode.class).length > 0) { 32 | ((DiscoveryClientNode)this.context.getParent().getBean(DiscoveryClientNode.class)).shutdown(); 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/config/PantheonDiscoveryClientConfigServiceBootstrapConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.config; 2 | 3 | import com.pantheon.netflix.client.PantheonClientAutoConfiguration; 4 | import com.pantheon.netflix.client.PantheonDiscoveryClientConfiguration; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Import; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/12/17 14 | * @desc 15 | **/ 16 | @ConditionalOnClass({ConfigServicePropertySourceLocator.class}) 17 | @ConditionalOnProperty( 18 | value = {"spring.cloud.config.discovery.enabled"}, 19 | matchIfMissing = false 20 | ) 21 | @Configuration 22 | @Import({PantheonDiscoveryClientConfiguration.class, PantheonClientAutoConfiguration.class}) 23 | public class PantheonDiscoveryClientConfigServiceBootstrapConfiguration { 24 | public PantheonDiscoveryClientConfigServiceBootstrapConfiguration() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DefaultNIWSServerListFilter.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.loadbalancer; 2 | 3 | import com.netflix.loadbalancer.Server; 4 | import com.netflix.loadbalancer.ZoneAffinityServerListFilter; 5 | 6 | /** 7 | * @author Anthony 8 | * @create 2021/12/20 9 | * @desc The Default NIWS Filter - deals with filtering out servers based on the Zone affinity and other related properties 10 | **/ 11 | public class DefaultNIWSServerListFilter extends ZoneAffinityServerListFilter { 12 | public DefaultNIWSServerListFilter() { 13 | } 14 | } -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/DiscoveryEnabledServer.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.loadbalancer; 2 | 3 | import com.netflix.loadbalancer.Server; 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.sun.xml.internal.ws.wsdl.writer.document.PortType; 6 | 7 | /** 8 | * @author Anthony 9 | * @create 2021/12/20 10 | * @desc Servers that were obtained via Discovery and hence contain meta data in the form of InstanceInfo 11 | **/ 12 | @SuppressWarnings({"EQ_DOESNT_OVERRIDE_EQUALS"}) 13 | public class DiscoveryEnabledServer extends Server { 14 | private final InstanceInfo instanceInfo; 15 | private final MetaInfo serviceInfo; 16 | 17 | public DiscoveryEnabledServer(InstanceInfo instanceInfo, boolean useSecurePort) { 18 | this(instanceInfo, useSecurePort, false); 19 | } 20 | 21 | public DiscoveryEnabledServer(final InstanceInfo instanceInfo, boolean useSecurePort, boolean useIpAddr) { 22 | super(useIpAddr ? instanceInfo.getIPAddr() : instanceInfo.getHostName(), instanceInfo.getPort()); 23 | if (useSecurePort) { 24 | super.setPort(instanceInfo.getSecurePort()); 25 | } 26 | 27 | this.instanceInfo = instanceInfo; 28 | this.serviceInfo = new MetaInfo() { 29 | public String getAppName() { 30 | return instanceInfo.getAppName(); 31 | } 32 | 33 | public String getServerGroup() { 34 | return instanceInfo.getAppGroupName(); 35 | } 36 | 37 | public String getServiceIdForDiscovery() { 38 | return instanceInfo.getInstanceId(); 39 | } 40 | 41 | public String getInstanceId() { 42 | return instanceInfo.getId(); 43 | } 44 | }; 45 | } 46 | 47 | public InstanceInfo getInstanceInfo() { 48 | return this.instanceInfo; 49 | } 50 | 51 | public MetaInfo getMetaInfo() { 52 | return this.serviceInfo; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/LegacyPantheonClientProvider.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.loadbalancer; 2 | 3 | import com.pantheon.client.ClientManager; 4 | import com.pantheon.client.DiscoveryClientNode; 5 | import com.pantheon.client.config.DefaultInstanceConfig; 6 | import com.pantheon.client.discovery.DiscoveryClient; 7 | 8 | import javax.inject.Provider; 9 | 10 | /** 11 | * @author Anthony 12 | * @create 2021/12/20 13 | * @desc 14 | **/ 15 | class LegacyPantheonClientProvider implements Provider { 16 | private volatile DiscoveryClientNode pantheonClient; 17 | 18 | LegacyPantheonClientProvider() { 19 | } 20 | 21 | public synchronized DiscoveryClient get() { 22 | if (this.pantheonClient == null) { 23 | this.pantheonClient = ClientManager.getInstance().getOrCreateClientNode(); 24 | } 25 | 26 | return this.pantheonClient; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/loadbalancer/NIWSDiscoveryPing.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.loadbalancer; 2 | 3 | import com.netflix.client.config.IClientConfig; 4 | import com.netflix.loadbalancer.AbstractLoadBalancerPing; 5 | import com.netflix.loadbalancer.BaseLoadBalancer; 6 | import com.netflix.loadbalancer.Server; 7 | import com.pantheon.client.appinfo.InstanceInfo; 8 | 9 | /** 10 | * @author Anthony 11 | * @create 2021/12/20 12 | * @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 13 | **/ 14 | public class NIWSDiscoveryPing extends AbstractLoadBalancerPing { 15 | BaseLoadBalancer lb = null; 16 | 17 | public NIWSDiscoveryPing() { 18 | } 19 | 20 | public BaseLoadBalancer getLb() { 21 | return this.lb; 22 | } 23 | 24 | public void setLb(BaseLoadBalancer lb) { 25 | this.lb = lb; 26 | } 27 | 28 | public boolean isAlive(Server server) { 29 | boolean isAlive = true; 30 | if (server != null && server instanceof DiscoveryEnabledServer) { 31 | DiscoveryEnabledServer dServer = (DiscoveryEnabledServer)server; 32 | InstanceInfo instanceInfo = dServer.getInstanceInfo(); 33 | if (instanceInfo != null) { 34 | InstanceInfo.InstanceStatus status = instanceInfo.getStatus(); 35 | if (status != null) { 36 | // InstanceStatus.UP means alive in ribbon and pantheon discovery 37 | isAlive = status.equals(InstanceInfo.InstanceStatus.UP); 38 | } 39 | } 40 | } 41 | 42 | return isAlive; 43 | } 44 | 45 | public void initWithNiwsConfig(IClientConfig clientConfig) { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServer.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.ribbon; 2 | 3 | import com.netflix.loadbalancer.Server; 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; 6 | 7 | /** 8 | * @author Anthony 9 | * @create 2021/12/20 10 | * @desc 11 | **/ 12 | class DomainExtractingServer extends DiscoveryEnabledServer { 13 | private String id; 14 | 15 | public String getId() { 16 | return this.id; 17 | } 18 | 19 | public void setId(String id) { 20 | this.id = id; 21 | } 22 | 23 | public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, boolean useIpAddr, boolean approximateZoneFromHostname) { 24 | super(server.getInstanceInfo(), useSecurePort, useIpAddr); 25 | if (server.getInstanceInfo().getMetadata().containsKey("zone")) { 26 | this.setZone((String)server.getInstanceInfo().getMetadata().get("zone")); 27 | } else if (approximateZoneFromHostname) { 28 | this.setZone(ZoneUtils.extractApproximateZone(server.getHost())); 29 | } else { 30 | this.setZone(server.getZone()); 31 | } 32 | 33 | this.setId(this.extractId(server)); 34 | this.setAlive(server.isAlive()); 35 | this.setReadyToServe(server.isReadyToServe()); 36 | } 37 | 38 | private String extractId(Server server) { 39 | if (server instanceof DiscoveryEnabledServer) { 40 | DiscoveryEnabledServer enabled = (DiscoveryEnabledServer)server; 41 | InstanceInfo instance = enabled.getInstanceInfo(); 42 | if (instance.getMetadata().containsKey("instanceId")) { 43 | return instance.getHostName() + ":" + (String)instance.getMetadata().get("instanceId"); 44 | } 45 | } 46 | 47 | return super.getId(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/DomainExtractingServerList.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.ribbon; 2 | 3 | import com.netflix.client.config.CommonClientConfigKey; 4 | import com.netflix.client.config.IClientConfig; 5 | import com.netflix.loadbalancer.ServerList; 6 | import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledNIWSServerList; 7 | import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | 13 | /** 14 | * @author Anthony 15 | * @create 2021/12/20 16 | * @desc {@link #getInitialListOfServers()} and {@link #getUpdatedListOfServers()} use {@link DiscoveryEnabledNIWSServerList} to load server list dynamically 17 | **/ 18 | public class DomainExtractingServerList implements ServerList { 19 | private ServerList list; 20 | private IClientConfig clientConfig; 21 | private boolean approximateZoneFromHostname; 22 | 23 | public DomainExtractingServerList(ServerList list, IClientConfig clientConfig, boolean approximateZoneFromHostname) { 24 | this.list = list; 25 | this.clientConfig = clientConfig; 26 | this.approximateZoneFromHostname = approximateZoneFromHostname; 27 | } 28 | 29 | public List getInitialListOfServers() { 30 | List servers = this.setZones(this.list.getInitialListOfServers()); 31 | return servers; 32 | } 33 | 34 | public List getUpdatedListOfServers() { 35 | List servers = this.setZones(this.list.getUpdatedListOfServers()); 36 | return servers; 37 | } 38 | 39 | private List setZones(List servers) { 40 | List result = new ArrayList(); 41 | boolean isSecure = this.clientConfig.getPropertyAsBoolean(CommonClientConfigKey.IsSecure, Boolean.TRUE); 42 | boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE); 43 | Iterator var5 = servers.iterator(); 44 | 45 | while (var5.hasNext()) { 46 | DiscoveryEnabledServer server = (DiscoveryEnabledServer) var5.next(); 47 | result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr, this.approximateZoneFromHostname)); 48 | } 49 | 50 | return result; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/PantheonServerIntrospector.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.ribbon; 2 | 3 | import com.netflix.loadbalancer.Server; 4 | import com.pantheon.client.appinfo.InstanceInfo; 5 | import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledServer; 6 | import com.sun.xml.internal.ws.wsdl.writer.document.PortType; 7 | import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Anthony 13 | * @create 2021/12/20 14 | * @desc 15 | **/ 16 | public class PantheonServerIntrospector extends DefaultServerIntrospector { 17 | public PantheonServerIntrospector() { 18 | } 19 | 20 | public boolean isSecure(Server server) { 21 | if (server instanceof DiscoveryEnabledServer) { 22 | return false; 23 | // DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer)server; 24 | // return discoveryServer.getInstanceInfo().isPortEnabled( InstanceInfo.PortType.SECURE); 25 | } else { 26 | return super.isSecure(server); 27 | } 28 | } 29 | 30 | public Map getMetadata(Server server) { 31 | if (server instanceof DiscoveryEnabledServer) { 32 | DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; 33 | return discoveryServer.getInstanceInfo().getMetadata(); 34 | } else { 35 | return super.getMetadata(server); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/RibbonPantheonAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.ribbon; 2 | 3 | import com.pantheon.netflix.client.loadbalancer.DiscoveryEnabledNIWSServerList; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 10 | import org.springframework.cloud.client.discovery.DiscoveryClient; 11 | import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; 12 | import org.springframework.cloud.netflix.ribbon.RibbonClients; 13 | import org.springframework.cloud.netflix.ribbon.SpringClientFactory; 14 | import org.springframework.context.annotation.Conditional; 15 | import org.springframework.context.annotation.Configuration; 16 | 17 | import java.lang.annotation.Documented; 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * @author Anthony 25 | * @create 2021/12/20 26 | * @desc Spring configuration for configuring Ribbon defaults to be Pantheon based if Pantheon client is enabled 27 | **/ 28 | @Configuration 29 | @EnableConfigurationProperties 30 | @RibbonPantheonAutoConfiguration.ConditionalOnRibbonAndPantheonEnabled 31 | @AutoConfigureAfter({RibbonAutoConfiguration.class}) 32 | @RibbonClients( 33 | defaultConfiguration = {PantheonRibbonClientConfiguration.class} 34 | ) 35 | public class RibbonPantheonAutoConfiguration { 36 | public RibbonPantheonAutoConfiguration() { 37 | } 38 | 39 | private static class OnRibbonAndPantheonEnabledCondition extends AllNestedConditions { 40 | public OnRibbonAndPantheonEnabledCondition() { 41 | super(ConfigurationPhase.REGISTER_BEAN); 42 | } 43 | 44 | @ConditionalOnProperty( 45 | value = {"pantheon.client.enabled"}, 46 | matchIfMissing = true 47 | ) 48 | static class OnPantheonClientEnabled { 49 | OnPantheonClientEnabled() { 50 | } 51 | } 52 | 53 | @ConditionalOnBean({DiscoveryClient.class}) 54 | static class PantheonBeans { 55 | PantheonBeans() { 56 | } 57 | } 58 | 59 | @ConditionalOnClass({DiscoveryEnabledNIWSServerList.class}) 60 | @ConditionalOnBean({SpringClientFactory.class}) 61 | @ConditionalOnProperty( 62 | value = {"ribbon.pantheon.enabled"}, 63 | matchIfMissing = true 64 | ) 65 | static class Defaults { 66 | Defaults() { 67 | } 68 | } 69 | } 70 | 71 | @Target({ElementType.TYPE, ElementType.METHOD}) 72 | @Retention(RetentionPolicy.RUNTIME) 73 | @Documented 74 | @Conditional({RibbonPantheonAutoConfiguration.OnRibbonAndPantheonEnabledCondition.class}) 75 | @interface ConditionalOnRibbonAndPantheonEnabled { 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/ribbon/ZoneUtils.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.ribbon; 2 | 3 | import org.springframework.util.StringUtils; 4 | 5 | /** 6 | * @author Anthony 7 | * @create 2021/12/20 8 | * @desc 9 | **/ 10 | public class ZoneUtils { 11 | public ZoneUtils() { 12 | } 13 | 14 | public static String extractApproximateZone(String host) { 15 | String[] split = StringUtils.split(host, "."); 16 | return split == null ? host : split[1]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-client/src/main/java/com/pantheon/netflix/client/serviceregistry/PantheonServiceRegistry.java: -------------------------------------------------------------------------------- 1 | package com.pantheon.netflix.client.serviceregistry; 2 | 3 | import com.pantheon.client.appinfo.InstanceInfo; 4 | import org.apache.commons.logging.Log; 5 | import org.apache.commons.logging.LogFactory; 6 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry; 7 | 8 | import java.util.HashMap; 9 | 10 | /** 11 | * @author Anthony 12 | * @create 2021/12/17 13 | * @desc 14 | **/ 15 | public class PantheonServiceRegistry implements ServiceRegistry { 16 | private static final Log log = LogFactory.getLog(PantheonServiceRegistry.class); 17 | 18 | public PantheonServiceRegistry() { 19 | } 20 | 21 | public void register(PantheonRegistration reg) { 22 | this.maybeInitializeClient(reg); 23 | if (log.isInfoEnabled()) { 24 | // log.info("Registering application " + reg.getInstanceConfig().getServiceName() + " with pantheon with status " + reg.getInstanceConfig().getInitialStatus()); 25 | } 26 | 27 | //todo reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus()); 28 | if (reg.getHealthCheckHandler() != null) { 29 | //todo reg.getEurekaClient().registerHealthCheck(reg.getHealthCheckHandler()); 30 | } 31 | 32 | } 33 | 34 | private void maybeInitializeClient(PantheonRegistration reg) { 35 | // reg.getApplicationInfoManager().getInfo(); 36 | reg.getPantheonClient().getApplications(); 37 | } 38 | 39 | public void deregister(PantheonRegistration reg) { 40 | // if (reg.getApplicationInfoManager().getInfo() != null) { 41 | // if (log.isInfoEnabled()) { 42 | // log.info("Unregistering application " + reg.getInstanceConfig().getAppname() + " with eureka with status DOWN"); 43 | // } 44 | // 45 | // reg.getApplicationInfoManager().setInstanceStatus(InstanceStatus.DOWN); 46 | // } 47 | 48 | } 49 | 50 | public void setStatus(PantheonRegistration registration, String status) { 51 | // InstanceInfo info = registration.getApplicationInfoManager().getInfo(); 52 | if ("CANCEL_OVERRIDE".equalsIgnoreCase(status)) { 53 | // registration.getEurekaClient().cancelOverrideStatus(info); 54 | } else { 55 | InstanceInfo.InstanceStatus newStatus = InstanceInfo.InstanceStatus.toEnum(status); 56 | // registration.getEurekaClient().setStatus(newStatus, info); 57 | } 58 | } 59 | 60 | public Object getStatus(PantheonRegistration registration) { 61 | HashMap status = new HashMap(); 62 | // InstanceInfo info = registration.getApplicationInfoManager().getInfo(); 63 | InstanceInfo info=new InstanceInfo(); 64 | status.put("status", info.getStatus().toString()); 65 | status.put("overriddenStatus", info.getOverriddenStatus().toString()); 66 | return status; 67 | } 68 | 69 | public void close() { 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pantheon-spring-cloud-netflix-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-spring-cloud-netflix-server 13 | 14 | 15 | 8 16 | 8 17 | 18 | 19 | 20 | 21 | org.springframework.cloud 22 | spring-cloud-commons 23 | 1.3.4.RELEASE 24 | 25 | 26 | -------------------------------------------------------------------------------- /pantheon-zuul-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | pantheon 7 | com.pantheon 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | pantheon-zuul-support 13 | 14 | 15 | 13 16 | 13 17 | 18 | 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.pantheon 8 | pantheon 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | pantheon-server 13 | pantheon-client 14 | pantheon-common 15 | pantheon-remoting 16 | pantheon-spring-cloud-netflix-client 17 | pantheon-spring-cloud-netflix-server 18 | pantheon-dubbo-support 19 | pantheon-zuul-support 20 | pantheon-spring-cloud-gateway-support 21 | 22 | 23 | 24 | 25 | 8 26 | 8 27 | 28 | 29 | 30 | repository.jboss.org-public 31 | JBoss.org Maven repository 32 | https://repository.jboss.org/nexus/content/groups/public 33 | 34 | 35 | 36 | 37 | javax.jms 38 | jms 39 | 1.1 40 | 41 | 42 | org.slf4j 43 | slf4j-api 44 | 1.6.1 45 | 46 | 47 | org.slf4j 48 | slf4j-log4j12 49 | 1.6.1 50 | 51 | 52 | log4j 53 | log4j 54 | 1.2.17 55 | 56 | 57 | com.alibaba 58 | fastjson 59 | 1.2.71 60 | 61 | 62 | io.netty 63 | netty-all 64 | 4.0.42.Final 65 | 66 | 67 | com.netflix.archaius 68 | archaius-core 69 | 0.7.6 70 | 71 | 72 | commons-configuration 73 | commons-configuration 74 | 1.8 75 | 76 | 77 | 78 | --------------------------------------------------------------------------------