modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java | 78 ++++++++++ modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml | 8 + 2 files changed, 86 insertions(+)
New commits: commit 14edae37060b25ebcfed621deef0281c72b1cea2 Author: John Sanda jsanda@redhat.com Date: Sun Jul 21 21:22:43 2013 -0400
adding resource operation to update internode auth conf file
The operation updates the file on disk and then invokes the JMX operation to have the authenticator reload the configuration so that the changes can be picked up without having to restart the node.
diff --git a/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java b/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java index 380da65..006dd26 100644 --- a/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java +++ b/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java @@ -26,7 +26,12 @@ package org.rhq.plugins.storage;
import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashSet; import java.util.List; +import java.util.Set;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,6 +41,7 @@ import org.mc4j.ems.connection.bean.attribute.EmsAttribute; import org.mc4j.ems.connection.bean.operation.EmsOperation;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.configuration.PropertySimple; @@ -43,7 +49,10 @@ import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.rhq.core.pluginapi.operation.OperationFacet; import org.rhq.core.pluginapi.operation.OperationResult; +import org.rhq.core.util.StringUtil; import org.rhq.core.util.exception.ThrowableUtil; +import org.rhq.core.util.file.FileUtil; +import org.rhq.core.util.stream.StreamUtil; import org.rhq.plugins.cassandra.CassandraNodeComponent; import org.rhq.plugins.cassandra.util.KeyspaceService;
@@ -84,6 +93,8 @@ public class StorageNodeComponent extends CassandraNodeComponent implements Oper return readRepair(); } else if (name.equals("updateConfiguration")) { return updateConfiguration(parameters); + } else if (name.equals("updateKnownNodes")) { + return updateKnownNodes(parameters); } else { return super.invokeOperation(name, parameters); } @@ -95,6 +106,73 @@ public class StorageNodeComponent extends CassandraNodeComponent implements Oper return result; }
+ private OperationResult updateKnownNodes(Configuration params) { + OperationResult result = new OperationResult(); + + PropertyList propertyList = params.getList("ipAddresses"); + Set<String> ipAddresses = new HashSet<String>(); + + for (Property property : propertyList.getList()) { + PropertySimple propertySimple = (PropertySimple) property; + ipAddresses.add(propertySimple.getStringValue()); + } + + log.info("Updating known nodes to " + ipAddresses); + + File confDir = new File(getBasedir(), "conf"); + File authFile = new File(confDir, "rhq-storage-auth.conf"); + File authBackupFile = new File(confDir, "." + authFile.getName() + ".bak"); + + if (authBackupFile.exists()) { + if (log.isDebugEnabled()) { + log.debug(authBackupFile + " already exists. Deleting it now in preparation of creating new backup " + + "for " + authFile.getName()); + } + if (!authBackupFile.delete()) { + String msg = "Failed to delete backup file " + authBackupFile + ". The operation will abort " + + "since " + authFile + " cannot reliably be backed up before making changes. Please delete " + + authBackupFile + " manually and reschedule the operation once the file has been removed."; + log.error(msg); + result.setErrorMessage(msg); + + return result; + } + } + + try { + FileUtil.copyFile(authFile, authBackupFile); + } catch (IOException e) { + String msg = "Failed to backup " + authFile + " prior to making updates. The operation will abort due " + + "to unexpected error"; + log.error(msg, e); + result.setErrorMessage(msg + ": " + ThrowableUtil.getRootMessage(e)); + return result; + } + + try { + StreamUtil.copy(new StringReader(StringUtil.collectionToString(ipAddresses, "\n")), + new FileWriter(authFile), true); + } catch (IOException e) { + log.error("An error occurred while updating " + authFile, e); + try { + FileUtil.copyFile(authBackupFile, authFile); + } catch (IOException e1) { + log.error("Failed to revert backup of " + authFile, e1); + } + result.setErrorMessage("There was an unexpected error while updating " + authFile + ". Make sure that " + + "it matches " + authBackupFile + " and then reschedule the operation."); + return result; + } + + EmsBean authBean = getEmsConnection().getBean("org.rhq.cassandra.auth:type=RhqInternodeAuthenticator"); + EmsOperation emsOperation = authBean.getOperation("reloadConfiguration"); + emsOperation.invoke(); + + result.setSimpleResult("Successfully updated the set of known nodes."); + + return result; + } + private OperationResult nodeAdded(Configuration params) { boolean runRepair = params.getSimple("runRepair").getBooleanValue(); boolean updateSeedsList = params.getSimple("updateSeedsList").getBooleanValue(); diff --git a/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml index 6ed31b7..8156d02 100644 --- a/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml @@ -93,6 +93,14 @@ </results> </operation>
+ <operation name="updateKnownNodes"> + <parameters> + <c:list-property name="ipAddresses"> + <c:simple-property name="ipAddress"/> + </c:list-property> + </parameters> + </operation> + <operation name="prepareForUpgrade" description="Prepares the storage node for upgrade (this operation consists of following steps: 1) turning off the RPC server, 2) turning off the gossiper, 3) taking the snapshot (backuping the data), 4) invoking the drain operation"> <parameters> <c:simple-property name="snapshotName" required="false" type="string" displayName="Snapshot Name"
rhq-commits@lists.fedorahosted.org