/******************************************************************************* * Copyright (c) 2006-2011 Gluster, Inc. * This file is part of Gluster Management Gateway. * * Gluster Management Gateway 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 (at your option) any later version. * * Gluster Management Gateway 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 * . *******************************************************************************/ package org.gluster.storage.management.gateway.tasks; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.gluster.storage.management.core.constants.CoreConstants; import org.gluster.storage.management.core.constants.GlusterConstants; import org.gluster.storage.management.core.model.GlusterServer; import org.gluster.storage.management.core.utils.GlusterCoreUtil; import org.gluster.storage.management.core.utils.ProcessResult; import org.gluster.storage.management.gateway.data.ClusterInfo; import org.gluster.storage.management.gateway.data.PersistenceDao; import org.gluster.storage.management.gateway.data.ServerInfo; import org.gluster.storage.management.gateway.services.ClusterService; import org.gluster.storage.management.gateway.services.DiscoveredServerService; import org.gluster.storage.management.gateway.services.GlusterServerService; import org.gluster.storage.management.gateway.utils.ServerUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Task for syncing server details. This performs two things:
* 1. Auto-discovery of servers eligible to be added to the Gluster cluster.
* 2. Syncing of cluster-server mapping with actual servers of the cluster. This mapping can go out of sync if user * adds/removes servers manually using the CLI. */ @Component public class ServerSyncTask { private static final String SCRIPT_NAME_SFX = "-discover-servers.py"; @Autowired private ServerUtil serverUtil; @Autowired private DiscoveredServerService discoveredServersService; @Autowired private GlusterServerService glusterServerService; @Autowired private String discoveryMechanism; @Autowired private ClusterService clusterService; @Autowired private PersistenceDao clusterDao; private static final Logger logger = Logger.getLogger(ServerSyncTask.class); public void perform() { discoverServers(); syncClusterServerMapping(); } private void syncClusterServerMapping() { List clusters = clusterService.getAllClusters(); for(ClusterInfo cluster : clusters) { try { List servers = cluster.getServers(); if(servers.isEmpty()) { logger.info("Cluster [" + cluster.getName() + "] is empty, nothing to sync!"); continue; } List actualServers = glusterServerService.getGlusterServers(cluster.getName(), false, null, null); updateRemovedServers(cluster, servers, actualServers); updateAddedServers(cluster, servers, actualServers); } catch(Exception e) { // log error and continue with next cluster logger.error("Couldn't sync cluster-server mapping for cluster [" + cluster.getName() + "]!", e); continue; } } } private void updateAddedServers(ClusterInfo cluster, List servers, List actualServers) { List addedServers = findAddedServers(cluster.getName(), servers, actualServers); for(String addedServer : addedServers) { clusterService.mapServerToCluster(cluster.getName(), addedServer); } } private void updateRemovedServers(ClusterInfo cluster, List servers, List actualServers) { List removedServers = findRemovedServers(servers, actualServers); for(String removedServer : removedServers) { clusterService.unmapServerFromCluster(cluster.getName(), removedServer); } } private List findRemovedServers(List servers, List actualServers) { List removedServers = new ArrayList(); for(ServerInfo server : servers) { if (!GlusterCoreUtil.containsEntityWithName(actualServers, server.getName(), true)) { removedServers.add(server.getName()); } } return removedServers; } private List findAddedServers(String clusterName, List servers, List actualServers) { List addedServers = new ArrayList(); for(GlusterServer actualServer : actualServers) { if(!serverExists(servers, actualServer.getName())) { addedServers.add(actualServer.getName()); } } return addedServers; } private boolean serverExists(List servers, String name) { for(ServerInfo server : servers) { if(server.getName().equalsIgnoreCase(name)) { return true; } } return false; } private void discoverServers() { if(discoveryMechanism.equals(GlusterConstants.NONE)) { return; } List serverNameList = new ArrayList(); ProcessResult result = serverUtil.executeGlusterScript(true, discoveryMechanism + SCRIPT_NAME_SFX, new ArrayList()); if(result.isSuccess()) { List existingServers = clusterDao.findBySQL("select name from server_info"); String serverNames = result.getOutput(); String[] parts = serverNames.split(CoreConstants.NEWLINE); for(String serverName : parts) { // The server discovery mechanism will return every server that has not been "peer probed". However we // need to filter out those servers that are the "first" server of a new cluster, and hence are still // not peer probed. if(!existingServers.contains(serverName)) { serverNameList.add(serverName); } } } discoveredServersService.setDiscoveredServerNames(serverNameList); } }