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

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

There is a newer version: 1.5.2
Show newest version
/*
 * Copyright 2015-2018 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; import com.qwazr.server.GenericServerBuilder; import com.qwazr.server.ServerException; import com.qwazr.server.configuration.ServerConfiguration; import com.qwazr.utils.ArrayUtils; import com.qwazr.utils.HashUtils; import com.qwazr.utils.LoggerUtils; import com.qwazr.utils.StringUtils; import org.apache.commons.lang3.RandomUtils; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.logging.Logger; public class ClusterManager { private static final Logger LOGGER = LoggerUtils.getLogger(ClusterManager.class); final 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 final ExecutorService executorService; private final ClusterServiceImpl service; public ClusterManager(final ExecutorService executorService, final ServerConfiguration configuration) { this.executorService = executorService; this.nodeLiveId = HashUtils.newTimeBasedUUID(); me = new ClusterNodeAddress(configuration.webServiceConnector.addressPort, configuration.webServiceConnector.port); webApp = new ClusterNodeAddress(configuration.webAppConnector.addressPort, configuration.webAppConnector.port); LOGGER.info(() -> "Server: " + me.httpAddressKey + " Groups: " + ArrayUtils.prettyPrint(configuration.groups)); this.myGroups = configuration.groups != null ? new HashSet<>(configuration.groups) : null; this.myServices = new HashSet<>(); if (configuration.masters != null && !configuration.masters.isEmpty()) { this.masters = new HashSet<>(); configuration.masters.forEach(master -> this.masters.add( new ClusterNodeAddress(master, configuration.webServiceConnector.port).httpAddressKey)); } else this.masters = null; clusterNodeMap = new ClusterNodeMap(this, me.address); clusterNodeMap.register(me.httpAddressKey); clusterNodeMap.register(masters); if (configuration.multicastConnector.address != null && configuration.multicastConnector.port != -1) protocolListener = new MulticastListener(this, configuration.multicastConnector.address, configuration.multicastConnector.port); else protocolListener = new DatagramListener(this); service = new ClusterServiceImpl(this); } public ClusterServiceInterface getService() { return service; } public ClusterManager registerProtocolListener(final GenericServerBuilder builder, final Set services) { builder.packetListener(protocolListener); builder.startedListener(server -> protocolListener.joinCluster(services)); builder.shutdownListener(server -> protocolListener.leaveCluster()); builder.shutdownListener(server -> protocolListener.shutdown()); executorService.submit(protocolListener); return this; } @Override public int hashCode() { return Objects.hashCode(nodeLiveId); } 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 service, final String group) throws ServerException { final SortedSet nodes = clusterNodeMap.getGroupService(group, service); if (nodes == null || nodes.isEmpty()) { LOGGER.warning(() -> "No node available for this service/group: " + service + '/' + group); return false; } return me.httpAddressKey.equals(nodes.first()); } final 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, timeToLive); nodesJsonMap.put(address, clusterNodeJson); }); } return new ClusterStatusJson(me.httpAddressKey, nodeLiveId, myServices.contains("webapps") ? webApp.httpAddressKey : null, nodesJsonMap, clusterNodeMap.getGroups(), clusterNodeMap.getServices(), masters, protocolListener.getLastExecutionDate()); } final Set getNodes() { final Map nodesMap = clusterNodeMap.getNodesMap(); return nodesMap == null ? Collections.emptySet() : nodesMap.keySet(); } final TreeMap getServicesStatus(final String group) { final TreeMap servicesStatus = new TreeMap<>(); final Set services = clusterNodeMap.getServices().keySet(); if (services.isEmpty()) return servicesStatus; services.forEach(service -> { final SortedSet nodes = getNodesByGroupByService(group, service); if (nodes != null && !nodes.isEmpty()) servicesStatus.put(service, ClusterServiceStatusJson.StatusEnum.of(nodes)); }); return servicesStatus; } final ClusterServiceStatusJson getServiceStatus(final String group, final String service) { final SortedSet nodes = getNodesByGroupByService(group, service); return ClusterServiceStatusJson.of(nodes); } final 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 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 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--; } } 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