Skip to content
This repository has been archived by the owner on Jul 11, 2022. It is now read-only.

Commit

Permalink
[1071282] disk size used by storage metric is invisible when no metri…
Browse files Browse the repository at this point in the history
…c is collected

[1071291] no-data-available metric values for storage node metrics

The --no-data-available-- is our standard text formatting when a Double is
either null or NaN (using MeasumenentConvertClient).  So I couldn't just change
that across the board.  But in this instance I agree the table looked
odd and inconsistent.  So, now using "NaN" in this scenario.  As for the
missing metric entry, certain metrics are simply not able to be reported
immediately.  For the one in question I made sure it is there, if possible,
with "NaN" values.

But understand that it is possible to actually get no metrics for a very
brief period after import. Also, it is possible the metric set may lack a
metroc or two for a brief period.  The fix covers things as best as
possible. Remember that this entire issue goes away very quickly, as soon
as metrics are initially reported.

Probably more important than the BZ changes were some fixes I found along
the way:
- limit the StorageNode.QUERY_FIND_UNACKED_ALERTS_COUNTS query to committed
  storage node resources, otherwise it can report incorrectly. (sorry for the
  file reformat)
- Fix the AVAILABILITY column handling, use our more common approach to
  avoid some issues. It was working a bit by luck.
- Fix the STATUS field record value, it should be a string.
- Change some formatting to allow more space both for the metrics table
  as a whole (in the detail view) and also the metric name column.
- Fix clusterStatusItem value, it should be a String.
- Fix messageItem value, it should be a String.
- Protect against a potential bad widget ID
- Apply CellFormatters prior to setting ListGridFields, and Fix == to be
  equals() to ensure proper CellFormatter is applied
  • Loading branch information
jshaughn committed Aug 27, 2014
1 parent e27ef38 commit 536f7ec
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,20 @@
+ " FROM StorageNode s " //
+ "LEFT JOIN FETCH s.resource r " //
+ " WHERE s.address = :address"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODE, query =
"SELECT s FROM StorageNode s WHERE s.operationMode = :operationMode"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODES, query =
"SELECT s FROM StorageNode s WHERE s.operationMode IN (:operationModes)"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODE_EXCLUDING, query =
"SELECT s FROM StorageNode s WHERE s.operationMode = :operationMode AND s <> :storageNode"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODE, query = "SELECT s FROM StorageNode s WHERE s.operationMode = :operationMode"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODES, query = "SELECT s FROM StorageNode s WHERE s.operationMode IN (:operationModes)"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_BY_MODE_EXCLUDING, query = "SELECT s FROM StorageNode s WHERE s.operationMode = :operationMode AND s <> :storageNode"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_NOT_INSTALLED, query = "SELECT s FROM StorageNode s WHERE NOT s.operationMode = 'INSTALLED'"),
@NamedQuery(name = StorageNode.QUERY_FIND_ALL_NORMAL, query = "SELECT s FROM StorageNode s WHERE s.operationMode = 'NORMAL'"),
@NamedQuery(name = StorageNode.QUERY_DELETE_BY_ID, query = "" //
+ "DELETE FROM StorageNode s WHERE s.id = :storageNodeId "),
@NamedQuery(name = StorageNode.QUERY_DELETE_BY_ID, query = "DELETE FROM StorageNode s WHERE s.id = :storageNodeId "),
@NamedQuery(name = StorageNode.QUERY_FIND_SCHEDULE_IDS_BY_PARENT_RESOURCE_ID_AND_MEASUREMENT_DEFINITION_NAMES, query = "" //
+ " SELECT def.name, def.id, ms.id, res.id FROM MeasurementSchedule ms " //
+ " JOIN ms.definition def " //
+ " JOIN ms.resource res " //
+ " WHERE ms.definition = def " //
+ " AND res.parentResource.id = :parrentId " //
+ " AND ms.enabled = true" //
+ " AND def.name IN (:metricNames)"), //

+ " AND def.name IN (:metricNames)"),
@NamedQuery(name = StorageNode.QUERY_FIND_SCHEDULE_IDS_BY_GRANDPARENT_RESOURCE_ID_AND_MEASUREMENT_DEFINITION_NAMES, query = "" //
+ " SELECT def.name, def.id, ms.id, res.id FROM MeasurementSchedule ms " //
+ " JOIN ms.definition def " //
Expand All @@ -89,14 +84,14 @@
+ " UPDATE StorageNode s " //
+ " SET s.resource = NULL " //
+ " WHERE s.resource.id in (:resourceIds)"),
@NamedQuery(name = StorageNode.QUERY_UPDATE_OPERATION_MODE, query =
"UPDATE StorageNode s SET s.operationMode = :newOperationMode WHERE s.operationMode = :oldOperationMode"),
@NamedQuery(name = StorageNode.QUERY_FIND_UNACKED_ALERTS_COUNTS, query =
" SELECT resource.id, COUNT(alert.id)"
+ " FROM Alert alert JOIN alert.alertDefinition alertDef JOIN alertDef.resource resource"
+ " WHERE alert.acknowledgeTime = -1 AND resource.resourceType.plugin = 'RHQStorage'"
+ " GROUP BY resource.id")
})
@NamedQuery(name = StorageNode.QUERY_UPDATE_OPERATION_MODE, query = "UPDATE StorageNode s SET s.operationMode = :newOperationMode WHERE s.operationMode = :oldOperationMode"),
@NamedQuery(name = StorageNode.QUERY_FIND_UNACKED_ALERTS_COUNTS, query = "" //
+ " SELECT resource.id, COUNT(alert.id) "
+ " FROM Alert alert JOIN alert.alertDefinition alertDef JOIN alertDef.resource resource" //
+ " WHERE resource.inventoryStatus = 'COMMITTED' " //
+ " AND alert.acknowledgeTime = -1 " //
+ " AND resource.resourceType.plugin = 'RHQStorage' " //
+ " GROUP BY resource.id") })
@SequenceGenerator(allocationSize = org.rhq.core.domain.util.Constants.ALLOCATION_SIZE, name = "RHQ_STORAGE_NODE_ID_SEQ", sequenceName = "RHQ_STORAGE_NODE_ID_SEQ")
@Table(name = "RHQ_STORAGE_NODE")
public class StorageNode implements Serializable {
Expand Down Expand Up @@ -153,7 +148,7 @@ public class StorageNode implements Serializable {
private Resource resource;

@JoinColumn(name = "RESOURCE_OP_HIST_ID", referencedColumnName = "ID", nullable = true)
@OneToOne(optional = true, cascade = {CascadeType.REMOVE})
@OneToOne(optional = true, cascade = { CascadeType.REMOVE })
private ResourceOperationHistory failedOperation;

// required for JPA
Expand Down Expand Up @@ -244,16 +239,16 @@ public Status getStatus() {
if (operationMode == OperationMode.INSTALLED) {
return Status.INSTALLED;
}
if (operationMode == OperationMode.ANNOUNCE || operationMode == OperationMode.BOOTSTRAP ||
operationMode == OperationMode.ADD_MAINTENANCE) {
if (operationMode == OperationMode.ANNOUNCE || operationMode == OperationMode.BOOTSTRAP
|| operationMode == OperationMode.ADD_MAINTENANCE) {
if (errorMessage == null && failedOperation == null) {
return Status.JOINING;
} else {
return Status.DOWN;
}
}
if (operationMode == OperationMode.DECOMMISSION || operationMode == OperationMode.UNANNOUNCE ||
operationMode == OperationMode.REMOVE_MAINTENANCE || operationMode == OperationMode.UNINSTALL) {
if (operationMode == OperationMode.DECOMMISSION || operationMode == OperationMode.UNANNOUNCE
|| operationMode == OperationMode.REMOVE_MAINTENANCE || operationMode == OperationMode.UNINSTALL) {
if (errorMessage == null && failedOperation == null) {
return Status.LEAVING;
} else {
Expand All @@ -267,22 +262,21 @@ public Status getStatus() {
}

public enum OperationMode {
DECOMMISSION("Remove the storage node from service"),
DOWN("This storage node is down"), //
DECOMMISSION("Remove the storage node from service"), DOWN("This storage node is down"), //
INSTALLED("This storage node is newly installed but not yet operational"), //
MAINTENANCE("This storage node is in maintenance mode"), //
NORMAL("This storage node is running normally"),
ANNOUNCE("The storage node is installed but not yet part of the cluster. It is being announced so that it " +
"can join the cluster."),
UNANNOUNCE("The storage node has been decommissioned and the cluster is being notified to stop accepting " +
"gossip from its IP address."),
BOOTSTRAP("The storage is installed but not yet part of the cluster. It is getting bootstrapped into the " +
"cluster"),
ADD_MAINTENANCE("The storage node is running and is preparing to undergo routine maintenance that is " +
"necessary when a new node joins the cluster."),
REMOVE_MAINTENANCE("The storage node is no longer part of the cluster. Remaining storage node are " +
"undergoing cluster maintenance due to the topology change."),
UNINSTALL("The storage node is being removed from inventory and its bits on disk are getting purged.");
NORMAL("This storage node is running normally"), ANNOUNCE(
"The storage node is installed but not yet part of the cluster. It is being announced so that it "
+ "can join the cluster."), UNANNOUNCE(
"The storage node has been decommissioned and the cluster is being notified to stop accepting "
+ "gossip from its IP address."), BOOTSTRAP(
"The storage is installed but not yet part of the cluster. It is getting bootstrapped into the "
+ "cluster"), ADD_MAINTENANCE(
"The storage node is running and is preparing to undergo routine maintenance that is "
+ "necessary when a new node joins the cluster."), REMOVE_MAINTENANCE(
"The storage node is no longer part of the cluster. Remaining storage node are "
+ "undergoing cluster maintenance due to the topology change."), UNINSTALL(
"The storage node is being removed from inventory and its bits on disk are getting purged.");

public final String message;

Expand All @@ -296,17 +290,13 @@ public String getMessage() {
}

public enum Status {
INSTALLED,
DOWN,
NORMAL,
JOINING,
LEAVING
INSTALLED, DOWN, NORMAL, JOINING, LEAVING
}

@Override
public String toString() {
return "StorageNode[id=" + id + ", address=" + address + ", cqlPort=" + cqlPort
+ ", operationMode=" + operationMode + ", mtime=" + mtime + "]";
return "StorageNode[id=" + id + ", address=" + address + ", cqlPort=" + cqlPort + ", operationMode="
+ operationMode + ", mtime=" + mtime + "]";
}

@PrePersist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGridField;
Expand All @@ -57,13 +56,16 @@
import org.rhq.core.domain.criteria.StorageNodeCriteria;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementAggregate;
import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.operation.ResourceOperationHistory;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.coregui.client.CoreGUI;
import org.rhq.coregui.client.ImageManager;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.admin.storage.StorageNodeDatasourceField.StorageNodeLoadCompositeDatasourceField;
import org.rhq.coregui.client.components.table.IconField;
import org.rhq.coregui.client.components.table.TimestampCellFormatter;
import org.rhq.coregui.client.gwt.GWTServiceLookup;
import org.rhq.coregui.client.util.Log;
Expand Down Expand Up @@ -120,6 +122,7 @@ public List<ListGridField> getListGridFields() {
fields.add(idField);

fields.add(FIELD_ADDRESS.getListGridField("*"));

fields.add(FIELD_ALERTS.getListGridField("170"));

ListGridField field = FIELD_MEMORY.getListGridField("120");
Expand Down Expand Up @@ -151,7 +154,6 @@ public String format(Object value, ListGridRecord listGridRecord, int i, int i1)
return value.toString();
}
});

field.setShowHover(true);
field.setHoverCustomizer(new HoverCustomizer() {
public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
Expand All @@ -172,17 +174,8 @@ public String hoverHTML(Object value, ListGridRecord record, int rowNum, int col
// resourceIdField.setHidden(true);
fields.add(resourceIdField);

field = FIELD_AVAILABILITY.getListGridField("65");
field.setAlign(Alignment.CENTER);
field.setShowHover(true);
field.setHoverCustomizer(new HoverCustomizer() {
public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
Object availability = record.getAttribute(FIELD_AVAILABILITY.propertyName());
return "Storage Node is " + availability == null ? AvailabilityType.UNKNOWN.toString() : availability
.toString();
}
});
fields.add(field);
IconField availabilityField = new IconField(FIELD_AVAILABILITY.propertyName(), FIELD_AVAILABILITY.title(), 70);
fields.add(availabilityField);

return fields;
}
Expand Down Expand Up @@ -245,7 +238,7 @@ public ListGridRecord copyValues(StorageNodeLoadComposite from) {
record.setAttribute(FIELD_ADDRESS.propertyName(), from.getHostname());
record.setAttribute(FIELD_CQL_PORT.propertyName(), node.getCqlPort());
record.setAttribute(FIELD_OPERATION_MODE.propertyName(), node.getOperationMode());
record.setAttribute(FIELD_STATUS.propertyName(), node.getStatus());
record.setAttribute(FIELD_STATUS.propertyName(), node.getStatus().toString());
record.setAttribute(FIELD_CTIME.propertyName(), node.getCtime());
record.setAttribute(FIELD_ERROR_MESSAGE.propertyName(), node.getErrorMessage());
if (node.getFailedOperation() != null && node.getFailedOperation().getResource() != null) {
Expand All @@ -256,8 +249,13 @@ public ListGridRecord copyValues(StorageNodeLoadComposite from) {
}
if (node.getResource() != null) {
record.setAttribute(FIELD_RESOURCE_ID.propertyName(), node.getResource().getId());
record.setAttribute(FIELD_AVAILABILITY.propertyName(), node.getResource().getCurrentAvailability()
.getAvailabilityType());
record.setAttribute(
FIELD_AVAILABILITY.propertyName(),
ImageManager.getAvailabilityIconFromAvailType(node.getResource().getCurrentAvailability()
.getAvailabilityType()));
} else {
record.setAttribute(FIELD_AVAILABILITY.propertyName(),
ImageManager.getAvailabilityIconFromAvailType(AvailabilityType.UNKNOWN));
}
}
int value = from.getUnackAlerts();
Expand Down Expand Up @@ -365,9 +363,9 @@ public String hoverHTML(Object o, ListGridRecord listGridRecord, int i, int i2)
}
});
fields.add(nameField);
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_MIN.getListGridField("130"));
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_AVG.getListGridField("130"));
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_MAX.getListGridField("130"));
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_MIN.getListGridField("100"));
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_AVG.getListGridField("100"));
fields.add(StorageNodeLoadCompositeDatasourceField.FIELD_MAX.getListGridField("100"));
ListGridField hoverField = new ListGridField("hover", "hover");
hoverField.setHidden(true);
fields.add(hoverField);
Expand Down Expand Up @@ -474,28 +472,41 @@ public boolean add(ListGridRecord record) {

private ListGridRecord makeListGridRecord(MeasurementAggregateWithUnits aggregateWithUnits, String name,
String hover, String id) {
if (aggregateWithUnits == null)
return null;
ListGridRecord record = new ListGridRecord();

record.setAttribute("id", id);
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_NAME.propertyName(), name);
record.setAttribute(
StorageNodeLoadCompositeDatasourceField.FIELD_MIN.propertyName(),
MeasurementConverterClient.format(aggregateWithUnits.getAggregate().getMin(),
aggregateWithUnits.getUnits(), true));
record.setAttribute("avgFloat", aggregateWithUnits.getAggregate().getAvg());
record.setAttribute(
StorageNodeLoadCompositeDatasourceField.FIELD_AVG.propertyName(),
MeasurementConverterClient.format(aggregateWithUnits.getAggregate().getAvg(),
aggregateWithUnits.getUnits(), true));
record.setAttribute(
StorageNodeLoadCompositeDatasourceField.FIELD_MAX.propertyName(),
MeasurementConverterClient.format(aggregateWithUnits.getAggregate().getMax(),
aggregateWithUnits.getUnits(), true));
record.setAttribute("hover", hover);
if (aggregateWithUnits == null) {
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_MIN.propertyName(),
format(null, null, true));
record.setAttribute("avgFloat", Double.NaN);
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_AVG.propertyName(),
format(null, null, true));
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_MAX.propertyName(),
format(null, null, true));
record.setAttribute("hover", hover);
} else {
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_MIN.propertyName(),
format(aggregateWithUnits.getAggregate().getMin(), aggregateWithUnits.getUnits(), true));
record.setAttribute("avgFloat", aggregateWithUnits.getAggregate().getAvg());
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_AVG.propertyName(),
format(aggregateWithUnits.getAggregate().getAvg(), aggregateWithUnits.getUnits(), true));
record.setAttribute(StorageNodeLoadCompositeDatasourceField.FIELD_MAX.propertyName(),
format(aggregateWithUnits.getAggregate().getMax(), aggregateWithUnits.getUnits(), true));
record.setAttribute("hover", hover);
}
return record;
}

// We avoid the use of --no-data-available-- here, for BZ1071291
private static String format(Double value, MeasurementUnits targetUnits, boolean bestFit) {
if (null == value || value.isNaN()) {
return "NaN";
}

return MeasurementConverterClient.format(value, targetUnits, bestFit);
}

@Override
protected StorageNodeCriteria getFetchCriteria(DSRequest request) {
return new StorageNodeCriteria();
Expand Down

0 comments on commit 536f7ec

Please sign in to comment.