All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.qwazr.cluster.manager.ClusterManager Maven / Gradle / Ivy

There is a newer version: 1.5.2
Show newest version
/**
 * Copyright 2015-2016 Emmanuel Keller / QWAZR
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.qwazr.cluster.manager; import com.datastax.driver.core.utils.UUIDs; import com.qwazr.cluster.service.ClusterNodeJson; import com.qwazr.cluster.service.ClusterServiceImpl; import com.qwazr.cluster.service.ClusterServiceStatusJson; import com.qwazr.cluster.service.ClusterStatusJson; import com.qwazr.utils.ArrayUtils; import com.qwazr.utils.StringUtils; import com.qwazr.utils.server.ServerBuilder; import com.qwazr.utils.server.ServerConfiguration; import com.qwazr.utils.server.ServerException; import org.apache.commons.lang3.RandomUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.*; public class ClusterManager { public final static String SERVICE_NAME_CLUSTER = "cluster"; private static final Logger LOGGER = LoggerFactory.getLogger(ClusterManager.class); public static ClusterManager INSTANCE = null; public synchronized static void load(final ServerBuilder builder, final Collection masters, final Collection myGroups) { if (INSTANCE != null) throw new RuntimeException("Already loaded"); try { INSTANCE = new ClusterManager(builder, masters, myGroups); } catch (URISyntaxException | UnknownHostException e) { throw new RuntimeException(e); } } ClusterNodeMap clusterNodeMap; final ClusterNodeAddress me; final ClusterNodeAddress webApp; final Set myServices; final Set myGroups; final UUID nodeLiveId; private final Set masters; private final ProtocolListener protocolListener; private ClusterManager(final ServerBuilder builder, final Collection masters, final Collection myGroups) throws URISyntaxException, UnknownHostException { this.nodeLiveId = UUIDs.timeBased(); final ServerConfiguration serverConfig = builder.getServerConfiguration(); me = new ClusterNodeAddress(serverConfig.webServiceConnector.addressPort, serverConfig.webServiceConnector.port); webApp = new ClusterNodeAddress(serverConfig.webAppConnector.addressPort, serverConfig.webAppConnector.port); if (LOGGER.isInfoEnabled()) LOGGER.info("Server: " + me.httpAddressKey + " Groups: " + ArrayUtils.prettyPrint(myGroups)); this.myGroups = myGroups != null ? new HashSet<>(myGroups) : null; this.myServices = new HashSet<>(); // Will be filled later using server hook if (masters != null && !masters.isEmpty()) { this.masters = new HashSet<>(); masters.forEach(master -> this.masters .add(new ClusterNodeAddress(master, serverConfig.webServiceConnector.port).httpAddressKey)); } else this.masters = null; clusterNodeMap = new ClusterNodeMap(me.address); clusterNodeMap.register(me.httpAddressKey); clusterNodeMap.register(masters); if (serverConfig.multicastConnector.address != null && serverConfig.multicastConnector.port != -1) protocolListener = new MulticastListener(this, serverConfig.multicastConnector.address, serverConfig.multicastConnector.port); else protocolListener = new DatagramListener(this); builder.registerWebService(ClusterServiceImpl.class); builder.registerPacketListener(protocolListener); builder.registerStartedListener(server -> { protocolListener.joinCluster(server.getServiceNames()); protocolListener.start(); }); builder.registerShutdownListener(server -> protocolListener.leaveCluster()); } public boolean isGroup(String group) { if (group == null) return true; if (myGroups == null) return true; if (group.isEmpty()) return true; return myGroups.contains(group); } public boolean isLeader(final String group, final String service) throws ServerException { SortedSet nodes = clusterNodeMap.getGroupService(group, service); if (nodes == null || nodes.isEmpty()) { if (LOGGER.isWarnEnabled()) LOGGER.warn("No node available for this service/group: " + service + '/' + group); return false; } return me.httpAddressKey.equals(nodes.first()); } final public ClusterStatusJson getStatus() { final Map nodesMap = clusterNodeMap.getNodesMap(); final TreeMap nodesJsonMap = new TreeMap<>(); if (nodesMap != null) { final long currentMs = System.currentTimeMillis(); nodesMap.forEach((address, clusterNode) -> { final Integer timeToLive; final Long expirationTimeMs = clusterNode.getExpirationTimeMs(); if (expirationTimeMs != null) timeToLive = (int) ((expirationTimeMs - currentMs) / 1000); else timeToLive = null; final ClusterNodeJson clusterNodeJson = new ClusterNodeJson(clusterNode.address.httpAddressKey, clusterNode.nodeLiveId, timeToLive, clusterNode.groups, clusterNode.services); nodesJsonMap.put(address, clusterNodeJson); }); } return new ClusterStatusJson(me.httpAddressKey, myServices.contains("webapps") ? webApp.httpAddressKey : null, nodesJsonMap, clusterNodeMap.getGroups(), clusterNodeMap.getServices(), masters, protocolListener.getLastExecutionDate()); } final public Set getNodes() { final Map nodesMap = clusterNodeMap.getNodesMap(); return nodesMap == null ? Collections.emptySet() : nodesMap.keySet(); } final public TreeMap getServicesStatus(final String group) { final TreeMap servicesStatus = new TreeMap(); final Set services = clusterNodeMap.getServices().keySet(); if (services == null || services.isEmpty()) return servicesStatus; services.forEach(service -> { final SortedSet nodes = getNodesByGroupByService(group, service); if (nodes != null && !nodes.isEmpty()) servicesStatus.put(service, ClusterServiceStatusJson.findStatus(nodes.size())); }); return servicesStatus; } final public ClusterServiceStatusJson getServiceStatus(final String group, final String service) { final SortedSet nodes = getNodesByGroupByService(group, service); return nodes == null || nodes.isEmpty() ? new ClusterServiceStatusJson() : new ClusterServiceStatusJson(nodes); } final public SortedSet getNodesByGroupByService(final String group, final String service) { if (StringUtils.isEmpty(group)) return clusterNodeMap.getByService(service); else if (StringUtils.isEmpty(service)) return clusterNodeMap.getByGroup(group); else return clusterNodeMap.getGroupService(group, service); } final public String getLeaderNode(final String group, final String service) { final SortedSet nodes = getNodesByGroupByService(group, service); if (nodes == null || nodes.isEmpty()) return null; return nodes.first(); } final public String getRandomNode(final String group, final String service) { final SortedSet nodes = getNodesByGroupByService(group, service); if (nodes == null || nodes.isEmpty()) return null; int rand = RandomUtils.nextInt(0, nodes.size()); Iterator it = nodes.iterator(); for (; ; ) { final String node = it.next(); if (rand == 0) return node; rand--; } } public final String getHttpAddressKey() { return me.httpAddressKey; } final boolean isMe(final AddressContent message) { if (message == null) return false; if (nodeLiveId.equals(message.getNodeLiveId())) return true; if (me.httpAddressKey.equals(message.getAddress())) return true; return false; } final boolean isMaster(final ClusterNodeAddress nodeAddress) { if (nodeAddress == null || masters == null) return false; return masters.contains(nodeAddress.httpAddressKey); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy