Java tutorial
/** JEM, the BEE - Job Entry Manager, the Batch Execution Environment Copyright (C) 2012-2015 Simone "Busy" Businaro This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.pepstock.jem.node.swarm; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.net.InetSocketAddress; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.pepstock.jem.log.LogAppl; import org.pepstock.jem.node.ExecutionEnvironment; import org.pepstock.jem.node.Main; import org.pepstock.jem.node.NodeInfo; import org.pepstock.jem.node.NodeInfoUtility; import org.pepstock.jem.node.Queues; import org.pepstock.jem.node.Status; import org.pepstock.jem.node.configuration.SwarmConfiguration; import org.pepstock.jem.node.swarm.listeners.NodeListener; import com.hazelcast.config.Config; import com.hazelcast.config.ExecutorConfig; import com.hazelcast.config.Join; import com.hazelcast.config.NetworkConfig; import com.hazelcast.config.PartitionGroupConfig.MemberGroupType; import com.hazelcast.core.Cluster; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.core.Member; /** * Is the Main class used to handle the hazelcast instance of the swarm * environment and other object used to hanlde the routhing phase. * * @author Simone "Busy" Businaro * */ public class Swarm { /** * It represent the hazelcast configuration for the swarm environment */ private SwarmConfiguration activeConfiguration = null; /** * The hazelcast instance for the swarm environment */ private HazelcastInstance swarmInstance = null; /** * It's a listener for the ROUTING QUEUE. * * @see org.pepstock.jem.node.Queues#ROUTING_QUEUE */ private RoutingQueueManager routingQueueManager = null; /** * It's a listener for the OUTPUT QUEUE * * @see org.pepstock.jem.node.Queues#OUTPUT_QUEUE */ private OutputQueueManager outputQueueManager = null; /** * It's a listener for the SWARM NODES MAP * * @see org.pepstock.jem.gwt.server.swarm.SwarmQueues#NODES_MAP */ private MapSwarmNodesManager mapSwarmNodesManager = null; /** * It is a bean that describe this member of the cluster */ private NodeInfo nodeInfo = new NodeInfo(); /** * It is the status of the node. */ private Status status = Status.DRAINED; /** * Constructor that initialized the MAIN instance */ public Swarm() { } /** * * @return the SwarmConfiguration that represent the the hazelcast * configuration for the swarm environment */ public SwarmConfiguration getActiveConfiguration() { IMap<String, SwarmConfiguration> routingConfigMap = Main.getHazelcast().getMap(Queues.ROUTING_CONFIG_MAP); // if there is no routing configuration insert default one, it will // happen the first time if (!routingConfigMap.containsKey(SwarmConfiguration.DEFAULT_NAME)) { activeConfiguration = new SwarmConfiguration(); try { routingConfigMap.lock(SwarmConfiguration.DEFAULT_NAME); routingConfigMap.put(SwarmConfiguration.DEFAULT_NAME, activeConfiguration); } finally { routingConfigMap.unlock(SwarmConfiguration.DEFAULT_NAME); } } else { try { routingConfigMap.lock(SwarmConfiguration.DEFAULT_NAME); activeConfiguration = routingConfigMap.get(SwarmConfiguration.DEFAULT_NAME); } finally { routingConfigMap.unlock(SwarmConfiguration.DEFAULT_NAME); } } return activeConfiguration; } /** * @return the hazelcast instance for the swarm environment. The swarm * environment is the environment composed by all the light members * of different environments */ public HazelcastInstance getHazelcastInstance() { return swarmInstance; } /** * @return the RoutingQueueManager that is a listener for the routing map * and it also contains the logic to route job */ public RoutingQueueManager getRoutingQueueManager() { return routingQueueManager; } /** * Start the hazelcast instance for the swarm environment only if this node * is in the list of nodes present in the configuration and MainSwarm is in * {@link Status#DRAINED}. The swarm environment is the environment composed * by all the light members of different environments. * @return true if node is started or if node is node part of the configured swarm nodes. * @throws SwarmException * * @throws Exception * */ public boolean start() throws SwarmException { getActiveConfiguration(); List<String> allowHosts = activeConfiguration.getNetworks(); String localHost = Main.getHazelcast().getCluster().getLocalMember().getInetSocketAddress().getAddress() .getHostAddress(); if (allowHosts.contains(localHost) && getStatus().equals(Status.DRAINED)) { setStatus(Status.STARTING); if (activeConfiguration.isEnabled()) { LogAppl.getInstance().emit(SwarmNodeMessage.JEMO001I); // start up hazelcast swarm instace try { startUpHazelcast(); } catch (SwarmException e) { setStatus(Status.DRAINED); throw e; } Cluster cluster = swarmInstance.getCluster(); Member member = cluster.getLocalMember(); // initialized nodeInputBean initNodeInfo(member); setStatus(Status.ACTIVE); // initialized RoutingManager routingQueueManager = new RoutingQueueManager(); // initialized OutputQueueManager outputQueueManager = new OutputQueueManager(); // initialized MapSwarmNodeManager mapSwarmNodesManager = new MapSwarmNodesManager(); registerNode(); Main.getNode().setSwarmNode(true); NodeInfoUtility.storeNodeInfo(Main.getNode()); return true; } else { setStatus(Status.DRAINED); LogAppl.getInstance().emit(SwarmNodeMessage.JEMO002I); return false; } } return false; } /** * Shut down the hazelcast instance for the swarm environment only if * MainSwarm is in {@link Status#ACTIVE}. The swarm environment is the * environment composed by all the light members of different environments. * <p> * Before shutting down check if a job is been routed or is been send back * to the routing environment. If so wait last operations and then shut down * the member. * @return <code>true</code> if it was able to close the swarm * */ public boolean shutDown() { if (getStatus().equals(Status.ACTIVE)) { LogAppl.getInstance().emit(SwarmNodeMessage.JEMO003I); setStatus(Status.SHUTTING_DOWN); // wait until the end of last route job and the end of last // notify // output // job while (!getRoutingQueueManager().isRouteEnded() || !getOutputQueueManager().isNotifyOutputEnded()) { try { Thread.sleep(1000); } catch (InterruptedException e) { LogAppl.getInstance().emit(SwarmNodeMessage.JEMO015E, e); } } swarmInstance.getLifecycleService().shutdown(); swarmInstance = null; LogAppl.getInstance().emit(SwarmNodeMessage.JEMO004I); setStatus(Status.DRAINED); Main.getNode().setSwarmNode(false); NodeInfoUtility.storeNodeInfo(Main.getNode()); return true; } return false; } /** * Start up the hazelcast for the swarm environment. The swarm environment * is the environment made by all the ligth members of differents * environment. * * @throws Exception */ private void startUpHazelcast() throws SwarmException { Config cfg = new Config(); cfg.getGroupConfig().setName(activeConfiguration.getGroupName()); cfg.getGroupConfig().setPassword(activeConfiguration.getGroupPassword()); // NETWORK COnfig NetworkConfig network = cfg.getNetworkConfig(); network.setPort(activeConfiguration.getPort()); network.setPortAutoIncrement(true); network.getInterfaces().setEnabled(true) .addInterface(Main.getNetworkInterface().getAddress().getHostAddress()); // JOIN Join join = network.getJoin(); join.getTcpIpConfig().setEnabled(true); join.getMulticastConfig().setEnabled(false); if (activeConfiguration.getNetworks().isEmpty()) { throw new SwarmException(SwarmNodeMessage.JEMO020E); } for (String tcpNode : activeConfiguration.getNetworks()) { join.getTcpIpConfig().addMember(tcpNode); } // ALL OTHER cfg.getPartitionGroupConfig().setEnabled(true); cfg.getPartitionGroupConfig().setGroupType(MemberGroupType.HOST_AWARE); cfg.getProperties().setProperty("hazelcast.logging.type", "log4j"); ExecutorConfig executor = new ExecutorConfig("pool", 16, 64, 60); cfg.addExecutorConfig(executor); swarmInstance = Hazelcast.newHazelcastInstance(cfg); swarmInstance.getCluster().addMembershipListener(new NodeListener()); } /** * Register the NodeInfo inside the SWARM NODES MAP * * @see org.pepstock.jem.gwt.server.swarm.SwarmQueues#NODES_MAP */ private void registerNode() { IMap<String, NodeInfo> map = swarmInstance.getMap(SwarmQueues.NODES_MAP); map.put(nodeInfo.getKey(), nodeInfo); } /** * Initializes the nodeInfo that will be store in the SWARM NODES MAP * * @see org.pepstock.jem.gwt.server.swarm.SwarmQueues#NODES_MAP * @param member this hazelcast member of the swarm environment */ private void initNodeInfo(Member member) { // set uuid of member of hazelcast as key nodeInfo.setKey(member.getUuid()); // set port and ip address InetSocketAddress address = member.getInetSocketAddress(); nodeInfo.setPort(address.getPort()); nodeInfo.setIpaddress(address.getAddress().getHostAddress()); // sets label to be displayed by GRS nodeInfo.setLabel(nodeInfo.getIpaddress() + ":" + nodeInfo.getPort()); // use JMX to extract current process id nodeInfo.setProcessId(ManagementFactory.getRuntimeMXBean().getName()); // set hostname String hostname = StringUtils.substringAfter(nodeInfo.getProcessId(), "@"); nodeInfo.setHostname(hostname); OperatingSystemMXBean bean = ManagementFactory.getOperatingSystemMXBean(); nodeInfo.getNodeInfoBean().setSystemArchitecture(bean.getArch()); nodeInfo.getNodeInfoBean().setAvailableProcessors(bean.getAvailableProcessors()); nodeInfo.getNodeInfoBean().setSystemName(bean.getName()); ExecutionEnvironment executionEnvironment = new ExecutionEnvironment(); // the environment will be that of jem one not the swarm one. executionEnvironment.setEnvironment(Main.EXECUTION_ENVIRONMENT.getEnvironment()); nodeInfo.setExecutionEnvironment(executionEnvironment); nodeInfo.setJemVersion(Main.getNode().getJemVersion()); } /** * @return the nodeInfo, a bean that describe this member of the cluster */ public NodeInfo getNodeInfo() { return nodeInfo; } /** * @return the mapSwarmNodesManager, the manager responsible for handle * event associated with the SWARM NODES MAP * * @see org.pepstock.jem.gwt.server.swarm.SwarmQueues#NODES_MAP */ public MapSwarmNodesManager getMapSwarmNodesManager() { return mapSwarmNodesManager; } /** * @return the outputQueueManager, the manager responsible for handle event * associated with the OUTPUT QUEUE relative to the routing * operation * * @see org.pepstock.jem.node.Queues#OUTPUT_QUEUE */ public OutputQueueManager getOutputQueueManager() { return outputQueueManager; } /** * @return the status of this node that belong to the Swarm Environment. * Status is used to see if specific operation can be done relative * to this node of the Swarm Environment. */ public Status getStatus() { return status; } /** * @param status the status to set. Is the status of this node that belong * to the Swarm Environment. Status is used to see if specific * operation can be done relative to this node of the Swarm * Environment. */ public void setStatus(Status status) { this.status = status; nodeInfo.setStatus(status); if (swarmInstance != null && swarmInstance.getLifecycleService().isRunning()) { // update Map if node is present IMap<String, NodeInfo> membersMap = swarmInstance.getMap(SwarmQueues.NODES_MAP); String key = nodeInfo.getKey(); if (key != null && membersMap.containsKey(key)) { try { membersMap.lock(key); NodeInfo info = membersMap.get(key); info.setStatus(status); membersMap.replace(info.getKey(), info); } finally { membersMap.unlock(key); } } } } }