/* * * RHQ Management Platform * Copyright (C) 2005-2012 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package org.rhq.cassandra.schema; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author Stefan Negrea */ class TopologyManager extends AbstractManager { private static final String TOPOLOGY_BASE_FOLDER = "topology"; private final Log log = LogFactory.getLog(TopologyManager.class); private enum Task { UpdateReplicationFactor("0001.xml"), UpdateGCGrace("0002.xml"); private final String file; private Task(String file) { this.file = file; } protected String getFile() { return TOPOLOGY_BASE_FOLDER + "/" + this.file; } } public TopologyManager(String username, String password, String[] nodes, int cqlPort, SessionManager sessionManager, UpdateFolderFactory updateFolderFactory) { super(username, password, nodes, cqlPort, sessionManager, updateFolderFactory); } /** * Updates cluster topology settings: * 1) replication factor * 2) gc grace period * * @return true if update successful, false otherwise. */ public void updateTopology() { initClusterSession(); if (schemaExists()) { log.info("Applying topology updates..."); updateReplicationFactor(); updateGCGrace(); } else { log.info("Topology updates cannot be applied because the schema is not installed."); } } /** * Update replication factor based on the current set of storage nodes. * * @return true if successful, false otherwise. */ private void updateReplicationFactor() { log.info("Starting to execute " + Task.UpdateReplicationFactor + " task."); int newReplicationFactor = calculateNewReplicationFactor(); int existingReplicationFactor = queryReplicationFactor(); if (existingReplicationFactor == newReplicationFactor) { log.info("No need to update replication factor. Replication factor already " + newReplicationFactor); } else { execute(new UpdateFile(Task.UpdateReplicationFactor.getFile()), "replication_factor", newReplicationFactor + ""); log.info("Updated replication factor from " + existingReplicationFactor + " to " + newReplicationFactor); } log.info("Successfully executed " + Task.UpdateReplicationFactor + " task."); } /** * Update gc grace interval based on the current set of storage nodes. */ private void updateGCGrace() { log.info("Starting to execute " + Task.UpdateGCGrace + " task."); int gcGraceSeconds = 864000; if (getActualClusterSize() == 1) { gcGraceSeconds = 0; } else { gcGraceSeconds = 691200; // 8 days } for (Table table : Table.values()) { updateGCGraceSeconds(table.getTableName(), gcGraceSeconds); } log.info("Updated gc_grace_seconds to " + gcGraceSeconds); log.info("Successfully executed " + Task.UpdateGCGrace + " task."); } private void updateGCGraceSeconds(String table, int gcGraceSeconds) { execute("ALTER COLUMNFAMILY " + table + " WITH gc_grace_seconds = " + gcGraceSeconds); } }