modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
| 2
modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeConfigurationComposite.java
| 98 ++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
| 113 ++++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
| 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerRemote.java
| 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/scheduler/jobs/StorageNodeMaintenanceJob.java
| 3
modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java
| 16 +
modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
| 13 +
8 files changed, 246 insertions(+), 9 deletions(-)
New commits:
commit 11b8ae9cff9ca5085bfe317a01653cc8b81d8bb7
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 17 14:14:02 2013 -0500
Initial implementation for the Storage Node configuration composite. The final
resource operation still needs to be implemented but the rest of the functionality is
implemented.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
index 14043db..575edc74 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
@@ -90,7 +90,7 @@ public class StorageNode implements Serializable {
public static final long serialVersionUID = 1L;
public static final String QUERY_FIND_ALL = "StorageNode.findAll";
- public static final String QUERY_FIND_BY_ADDRESS =
"StorageNode.findByName";
+ public static final String QUERY_FIND_BY_ADDRESS =
"StorageNode.findByAddress";
public static final String QUERY_FIND_ALL_NOT_INSTALLED =
"StorageNode.findAllCloudMembers";
public static final String QUERY_DELETE_BY_ID = "StorageNode.deleteById";
public static final String QUERY_FIND_ALL_NORMAL =
"StorageNode.findAllNormalCloudMembers";
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeConfigurationComposite.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeConfigurationComposite.java
new file mode 100644
index 0000000..e2c64f9
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeConfigurationComposite.java
@@ -0,0 +1,98 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.core.domain.cloud;
+
+import java.io.Serializable;
+
+/**
+ * @author Stefan Negrea
+ */
+public class StorageNodeConfigurationComposite implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private StorageNode storageNode;
+ private int jmxPort;
+ private String heapSize;
+
+ public StorageNodeConfigurationComposite() {
+ // GWT needs this
+ }
+
+ public StorageNodeConfigurationComposite(StorageNode storageNode) {
+ this.storageNode = storageNode;
+ }
+
+ /**
+ * @return associated storage node
+ */
+ public StorageNode getStorageNode() {
+ return storageNode;
+ }
+
+ /**
+ * @param storageNode storage node
+ */
+ protected void setStorageNode(StorageNode storageNode) {
+ this.storageNode = storageNode;
+ }
+
+
+ /**
+ * @return the JMX port
+ */
+ public int getJmxPort() {
+ return jmxPort;
+ }
+
+ /**
+ * @param jmxPort JMX port to set
+ */
+ public void setJmxPort(int jmxPort) {
+ this.jmxPort = jmxPort;
+ }
+
+ /**
+ * @return the heap size
+ */
+ public String getHeapSize() {
+ return heapSize;
+ }
+
+ /**
+ * @param heapSize heap size to set
+ */
+ public void setHeapSize(String heapSize) {
+ this.heapSize = heapSize;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
builder.append("storageNode.addresss=").append(storageNode.getAddress()).append(",
");
+ builder.append("heapSize=").append(heapSize).append(", ");
+ builder.append("jmxPort=").append(jmxPort).append("");
+ return builder.toString();
+ }
+}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
index fa51fe1..3f1ec69 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
@@ -51,14 +51,18 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.cloud.Server;
import org.rhq.core.domain.cloud.StorageNode;
import org.rhq.core.domain.cloud.StorageNode.OperationMode;
+import org.rhq.core.domain.cloud.StorageNodeConfigurationComposite;
import org.rhq.core.domain.cloud.StorageNodeLoadComposite;
import org.rhq.core.domain.common.JobTrigger;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
import org.rhq.core.domain.criteria.StorageNodeCriteria;
import org.rhq.core.domain.measurement.MeasurementAggregate;
import org.rhq.core.domain.measurement.MeasurementUnits;
+import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.operation.ResourceOperationHistory;
import org.rhq.core.domain.operation.bean.GroupOperationSchedule;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
@@ -72,6 +76,7 @@ import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.authz.RequiredPermissions;
import org.rhq.enterprise.server.cloud.instance.ServerManagerLocal;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementDataManagerLocal;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
@@ -96,6 +101,11 @@ public class StorageNodeManagerBean implements
StorageNodeManagerLocal, StorageN
private static final String RHQ_STORAGE_JMX_PORT_PROPERTY = "jmxPort";
private static final String RHQ_STORAGE_ADDRESS_PROPERTY = "host";
+ private static final int OPERATION_QUERY_TIMEOUT = 1000;
+ private static final int MAX_ITERATIONS = 5;
+ private static final String UPDATE_CONFIGURATION_OPERATION =
"updateConfiguration";
+ private static final String RESTART_OPERATION = "restart";
+
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
@@ -120,6 +130,9 @@ public class StorageNodeManagerBean implements
StorageNodeManagerLocal, StorageN
@EJB
private AlertManagerLocal alertManager;
+ @EJB
+ private ConfigurationManagerLocal configurationManager;
+
@Override
public void linkResource(Resource resource) {
List<StorageNode> storageNodes = this.getStorageNodes();
@@ -438,6 +451,19 @@ public class StorageNodeManagerBean implements
StorageNodeManagerLocal, StorageN
entityManager.flush();
}
+ private StorageNode findStorageNodeByAddress(String address) {
+ TypedQuery<StorageNode> query = entityManager.<StorageNode>
createNamedQuery(StorageNode.QUERY_FIND_BY_ADDRESS,
+ StorageNode.class);
+ query.setParameter("address", address);
+ List<StorageNode> result = query.getResultList();
+
+ if (result != null && result.size() > 0) {
+ return result.get(0);
+ }
+
+ return null;
+ }
+
private StorageNodeLoadComposite.MeasurementAggregateWithUnits
getMeasurementAggregateWithUnits(Subject subject,
int schedId, MeasurementUnits units, long beginTime, long endTime) {
MeasurementAggregate measurementAggregate =
measurementManager.getAggregate(subject, schedId, beginTime,
@@ -559,4 +585,91 @@ public class StorageNodeManagerBean implements
StorageNodeManagerLocal, StorageN
return resourceIdsWithAlertDefinitions.toArray(new
Integer[resourceIdsWithAlertDefinitions.size()]);
}
+
+ @Override
+ public StorageNodeConfigurationComposite retrieveConfiguration(Subject subject,
StorageNode storageNode) {
+ StorageNodeConfigurationComposite configuration = new
StorageNodeConfigurationComposite(storageNode);
+
+ if (storageNode != null && storageNode.getResource() != null) {
+ Resource storageNodeResource = storageNode.getResource();
+ Configuration storageNodeConfiguration =
configurationManager.getResourceConfiguration(subject,
+ storageNodeResource.getId());
+
+
configuration.setHeapSize(storageNodeConfiguration.getSimpleValue("maxHeapSize"));
+ configuration.setJmxPort(storageNode.getJmxPort());
+ }
+
+ return configuration;
+ }
+
+ @Override
+ public boolean updateConfiguration(Subject subject, StorageNodeConfigurationComposite
storageNodeConfiguration) {
+ StorageNode storageNode =
findStorageNodeByAddress(storageNodeConfiguration.getStorageNode().getAddress());
+
+ if (storageNode != null && storageNode.getResource() != null) {
+ Resource storageNodeResource = storageNode.getResource();
+ Configuration parameters = new Configuration();
+ parameters.setSimpleValue("jmxPort",
storageNodeConfiguration.getJmxPort() + "");
+ parameters.setSimpleValue("heapSize",
storageNodeConfiguration.getHeapSize() + "");
+
+ boolean updateConfigurationResult = runOperationAndWaitForResult(subject,
storageNodeResource,
+ UPDATE_CONFIGURATION_OPERATION, parameters);
+
+ if (updateConfigurationResult) {
+ boolean restartResult = runOperationAndWaitForResult(subject,
storageNodeResource, RESTART_OPERATION,
+ null);
+
+ if (restartResult) {
+ storageNode.setJmxPort(storageNodeConfiguration.getJmxPort());
+ entityManager.persist(storageNode);
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private boolean runOperationAndWaitForResult(Subject subject, Resource
storageNodeResource, String operationToRun,
+ Configuration parameters) {
+
+ //scheduling the operation
+ long operationStartTime = System.currentTimeMillis();
+ operationManager.scheduleResourceOperation(subject, storageNodeResource.getId(),
operationToRun, 0, 0, 0, 0,
+ parameters, "Run by StorageNodeManagerBean");
+
+ //waiting for the operation result then return it
+ int iteration = 0;
+ boolean successResultFound = false;
+ while (iteration < MAX_ITERATIONS && !successResultFound) {
+ ResourceOperationHistoryCriteria criteria = new
ResourceOperationHistoryCriteria();
+ criteria.addFilterResourceIds(storageNodeResource.getId());
+ criteria.addFilterStartTime(operationStartTime);
+ criteria.addFilterOperationName(operationToRun);
+ criteria.addFilterStatus(OperationRequestStatus.SUCCESS);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+
+ PageList<ResourceOperationHistory> results =
operationManager.findResourceOperationHistoriesByCriteria(
+ subject, criteria);
+
+ if (results != null && results.size() > 0) {
+ successResultFound = true;
+ }
+
+ if (successResultFound) {
+ break;
+ } else {
+ try {
+ Thread.sleep(OPERATION_QUERY_TIMEOUT);
+ } catch (Exception e) {
+ log.error(e);
+ }
+ }
+
+ iteration++;
+ }
+
+ return successResultFound;
+ }
}
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
index a9b2514..6fca820 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
@@ -25,6 +25,7 @@ import javax.ejb.Local;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.cloud.StorageNode;
+import org.rhq.core.domain.cloud.StorageNodeConfigurationComposite;
import org.rhq.core.domain.cloud.StorageNodeLoadComposite;
import org.rhq.core.domain.criteria.StorageNodeCriteria;
import org.rhq.core.domain.resource.Resource;
@@ -56,6 +57,10 @@ public interface StorageNodeManagerLocal {
*/
StorageNodeLoadComposite getLoad(Subject subject, StorageNode node, long beginTime,
long endTime);
+ StorageNodeConfigurationComposite retrieveConfiguration(Subject subject, StorageNode
storageNode);
+
+ boolean updateConfiguration(Subject subject, StorageNodeConfigurationComposite
storageNodeConfiguration);
+
/**
* Fetches the list of StorageNode entities based on provided criteria.
*
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerRemote.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerRemote.java
index 72432db..7be1b07 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerRemote.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerRemote.java
@@ -23,6 +23,7 @@ import javax.ejb.Remote;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.cloud.StorageNode;
+import org.rhq.core.domain.cloud.StorageNodeConfigurationComposite;
import org.rhq.core.domain.cloud.StorageNodeLoadComposite;
import org.rhq.core.domain.criteria.StorageNodeCriteria;
import org.rhq.core.domain.util.PageList;
@@ -48,6 +49,10 @@ public interface StorageNodeManagerRemote {
*/
StorageNodeLoadComposite getLoad(Subject subject, StorageNode node, long beginTime,
long endTime);
+ StorageNodeConfigurationComposite retrieveConfiguration(Subject subject, StorageNode
storageNode);
+
+ boolean updateConfiguration(Subject subject, StorageNodeConfigurationComposite
storageNodeConfiguration);
+
/**
* <p>Fetches the list of {@link StorageNode} entities based on provided
criteria.</p>
*
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/scheduler/jobs/StorageNodeMaintenanceJob.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/scheduler/jobs/StorageNodeMaintenanceJob.java
index 6b1940d..54ca4c2 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/scheduler/jobs/StorageNodeMaintenanceJob.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/scheduler/jobs/StorageNodeMaintenanceJob.java
@@ -71,7 +71,6 @@ public class StorageNodeMaintenanceJob extends AbstractStatefulJob {
private final static String RUN_REPAIR_PROPERTY = "runRepair";
private final static String UPDATE_SEEDS_LIST = "updateSeedsList";
private final static String SEEDS_LIST = "seedsList";
- private final static String SUCCEED_PROPERTY = "succeed";
private static final String USERNAME_PROP = "rhq.cassandra.username";
private static final String PASSWORD_PROP = "rhq.cassandra.password";
@@ -169,8 +168,6 @@ public class StorageNodeMaintenanceJob extends AbstractStatefulJob {
List<Resource> childResources =
LookupUtil.getResourceManager().findResourcesByCriteria(
LookupUtil.getSubjectManager().getOverlord(), c);
-
-
for (Resource childResource : childResources) {
if (STORAGE_SERVICE.equals(childResource.getName())) {
try {
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 6194146..380da65 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
@@ -82,11 +82,19 @@ public class StorageNodeComponent extends CassandraNodeComponent
implements Oper
return prepareForUpgrade(parameters);
} else if (name.equals("readRepair")) {
return readRepair();
+ } else if (name.equals("updateConfiguration")) {
+ return updateConfiguration(parameters);
} else {
return super.invokeOperation(name, parameters);
}
}
+ private OperationResult updateConfiguration(Configuration params) {
+ OperationResult result = new OperationResult("Configuration
updated.");
+ //TODO: implement updates to various sub-resources here
+ return result;
+ }
+
private OperationResult nodeAdded(Configuration params) {
boolean runRepair = params.getSimple("runRepair").getBooleanValue();
boolean updateSeedsList =
params.getSimple("updateSeedsList").getBooleanValue();
@@ -222,12 +230,12 @@ public class StorageNodeComponent extends CassandraNodeComponent
implements Oper
}
return result;
}
-
+
private OperationResult prepareForUpgrade(Configuration parameters) throws Exception
{
EmsConnection emsConnection = getEmsConnection();
EmsBean storageService =
emsConnection.getBean("org.apache.cassandra.db:type=StorageService");
Class<?>[] emptyParams = new Class<?>[0];
-
+
if (log.isDebugEnabled()) {
log.debug("Disabling native transport...");
}
@@ -249,7 +257,7 @@ public class StorageNodeComponent extends CassandraNodeComponent
implements Oper
snapshotName = System.currentTimeMillis() + "";
}
operation.invoke(snapshotName, new String[] {});
-
+
// max 2 sec
waitForTaskToComplete(500, 10, 150);
@@ -261,7 +269,7 @@ public class StorageNodeComponent extends CassandraNodeComponent
implements Oper
return new OperationResult();
}
-
+
private void waitForTaskToComplete(int initialWaiting, int maxTries, int sleepMillis)
{
// initial waiting
try {
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 5a60d19..6ed31b7 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
@@ -73,7 +73,7 @@
</c:list-property>
</results>
</operation>
-
+
<operation name="addNodeMaintenance">
<parameters>
<c:simple-property name="runRepair" type="boolean"
default="true"/>
@@ -111,6 +111,16 @@
</parameters>
</operation>
+ <operation name="updateConfiguration" description="Updates the node
configuration. Will require a separate server restart for the settings to take
effect.">
+ <parameters>
+ <c:simple-property name="heapSize" type="string"
description="The heap size to be used for both -Xms and -Xmx JVM options."/>
+ <c:simple-property name="jmxPort" type="integer"
description="JMX port JVM option."/>
+ </parameters>
+ <results>
+ <c:simple-property name="operationResult" description="Outcome
of updating the configuration."/>
+ </results>
+ </operation>
+
<resource-configuration>
<c:group name="MemorySettings">
<c:simple-property name="minHeapSize"
@@ -195,3 +205,4 @@
<service name="Keyspace" sourcePlugin="Cassandra"
sourceType="Keyspace"/>
</server>
</plugin>
+