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@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> +