summaryrefslogtreecommitdiffstats
path: root/src/org.gluster.storage.management.gateway/src/org/gluster/storage/management/gateway/tasks/ServerSyncTask.java
blob: 59874ad685b8e5c744ace7f4a65696f696133b8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*******************************************************************************
 * Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
 * 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
 * <http://www.gnu.org/licenses/>.
 *******************************************************************************/
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: <br>
 * 1. Auto-discovery of servers eligible to be added to the Gluster cluster. <br>
 * 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<ClusterInfo> clusterDao;
	
	private static final Logger logger = Logger.getLogger(ServerSyncTask.class);

	public void perform() {
		discoverServers();
		syncClusterServerMapping();
	}
	
	private void syncClusterServerMapping() {
		List<ClusterInfo> clusters = clusterService.getAllClusters();
		for(ClusterInfo cluster : clusters) {
			try {
				List<ServerInfo> servers = cluster.getServers();
				if(servers.isEmpty()) {
					logger.info("Cluster [" + cluster.getName() + "] is empty, nothing to sync!");
					continue;
				}
				List<GlusterServer> 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<ServerInfo> servers, List<GlusterServer> actualServers) {
		List<String> addedServers = findAddedServers(cluster.getName(), servers, actualServers);
		for(String addedServer : addedServers) {
			clusterService.mapServerToCluster(cluster.getName(), addedServer);
		}
	}

	private void updateRemovedServers(ClusterInfo cluster, List<ServerInfo> servers, List<GlusterServer> actualServers) {
		List<String> removedServers = findRemovedServers(servers, actualServers);
		for(String removedServer : removedServers) {
			clusterService.unmapServerFromCluster(cluster.getName(), removedServer);
		}
	}
	
	private List<String> findRemovedServers(List<ServerInfo> servers, List<GlusterServer> actualServers) {
		List<String> removedServers = new ArrayList<String>();
		
		for(ServerInfo server : servers) {
			if (!GlusterCoreUtil.containsEntityWithName(actualServers, server.getName(), true)) {
				removedServers.add(server.getName());
			}
		}
		return removedServers;
	}
	
	private List<String> findAddedServers(String clusterName, List<ServerInfo> servers, List<GlusterServer> actualServers) {
		List<String> addedServers = new ArrayList<String>();
		for(GlusterServer actualServer : actualServers) {
			if(!serverExists(servers, actualServer.getName())) {
				addedServers.add(actualServer.getName());
			}
		}
		return addedServers;
	}

	private boolean serverExists(List<ServerInfo> 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<String> serverNameList = new ArrayList<String>();
		
		ProcessResult result = serverUtil.executeGlusterScript(true, discoveryMechanism + SCRIPT_NAME_SFX, new ArrayList<String>());
		if(result.isSuccess()) {
			List<String> 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);
	}
}