modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
| 442 +++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
| 286 +-----
2 files changed, 285 insertions(+), 443 deletions(-)
New commits:
commit ab5629677b79df0286df8ced99e919264e0b6aba
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Nov 21 12:31:24 2013 +0200
[BZ 1038067] - Resource Summary/Activity shows summary of disabled
metrics - fixing the issue for resource groups (Autogroups and
compatible ones).
Also doing some refactoring, because the same code was in the portlet
for resource and for group, so I moved the common functionality to the
group portled and resource portlet overrides the different parts. What
would be even better is to introduce a common abstract class in the new
package
org.rhq.coregui.client.dashboard.portlets.common (the same way it is
done in the org.rhq.coregui.client.inventory.common package). However,
all the portlets follow this pattern (ResourcePortlet extends
GroupPortles), so it would be inconsistent.
After the refactoring, the code is more flat because the callback hell is
not so evil when using own methods for each callback. The toll for it is
the number of arguments that has to be passed to those methods
representing the state that is needed inside the method.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
index c1d7269..e9ee86c 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
@@ -20,9 +20,9 @@ package org.rhq.coregui.client.dashboard.portlets.groups;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.Timer;
@@ -49,14 +49,15 @@ import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.MeasurementScheduleCriteria;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementSchedule;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.GroupCategory;
-import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
@@ -73,9 +74,10 @@ import
org.rhq.coregui.client.inventory.common.detail.summary.AbstractActivityVi
import org.rhq.coregui.client.inventory.common.graph.CustomDateRangeState;
import
org.rhq.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView;
import
org.rhq.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3MultiLineGraph;
-import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.Log;
+import org.rhq.coregui.client.util.async.Command;
+import org.rhq.coregui.client.util.async.CountDownLatch;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
/**
@@ -101,6 +103,9 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements
CustomSettin
//instance ui widgets
protected Timer refreshTimer;
+
+ private volatile List<MeasurementSchedule> enabledSchedules = null;
+ private volatile boolean renderChart = false;
// final version needed to pass to anon classes
// so we can call refresh in anon callback handler
@@ -221,10 +226,80 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements
CustomSettin
*/
protected void getRecentMetrics() {
+ renderChart = true;
+
//display container
final VLayout column = new VLayout();
column.setHeight(10);//pack
+ final CountDownLatch latch = CountDownLatch.create(2, new Command() {
+ @Override
+ public void execute() {
+ if (enabledSchedules.isEmpty() || !renderChart) {
+ DynamicForm row = getEmptyDataForm();
+ column.addMember(row);
+ return;
+ }
+ //build id mapping for measurementDefinition instances Ex. Free Memory
-> MeasurementDefinition[100071]
+ final HashMap<String, MeasurementDefinition> measurementDefMap =
new HashMap<String, MeasurementDefinition>();
+ for (MeasurementSchedule schedule : enabledSchedules) {
+ measurementDefMap.put(schedule.getDefinition().getDisplayName(),
schedule.getDefinition());
+ }
+ Set<String> displayNamesSet = measurementDefMap.keySet();
+ //bundle definition ids for async call.
+ int[] definitionArrayIds = new int[displayNamesSet.size()];
+ final String[] displayOrder = new String[displayNamesSet.size()];
+ displayNamesSet.toArray(displayOrder);
+ //sort the charting data ex. Free Memory, Free Swap Space,..System Load
+ Arrays.sort(displayOrder);
+
+ //organize definitionArrayIds for ordered request on server.
+ int index = 0;
+ for (String definitionToDisplay : displayOrder) {
+ definitionArrayIds[index++] =
measurementDefMap.get(definitionToDisplay)
+ .getId();
+ }
+
+ fetchEnabledMetrics(enabledSchedules, definitionArrayIds, displayOrder,
measurementDefMap, column);
+ }
+ });
+
+ //fetch only enabled schedules
+ fetchEnabledSchedules(latch);
+
+ //fetch the resource type
+ fetchResourceType(latch, column);
+
+ //cleanup
+ for (Canvas child : recentMeasurementsContent.getChildren()) {
+ child.destroy();
+ }
+ recentMeasurementsContent.addChild(column);
+ recentMeasurementsContent.markForRedraw();
+ }
+
+ private void fetchEnabledSchedules(final CountDownLatch latch) {
+ MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.addFilterEnabled(true);
+ criteria.fetchDefinition(true);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+ addFilterKey(criteria);
+
GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria,
new AsyncCallback<PageList<MeasurementSchedule>>() {
+
+ @Override
+ public void onSuccess(PageList<MeasurementSchedule> result) {
+ enabledSchedules = result;
+ latch.countDown();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ latch.countDown();
+ }
+ });
+ }
+
+ protected void fetchResourceType(final CountDownLatch latch, final VLayout layout) {
//locate resourceGroupRef
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
criteria.addFilterId(this.groupId);
@@ -251,211 +326,18 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements
CustomSettin
Log.debug("Error retrieving resource group composite for group
[" + groupId + "]:"
+ caught.getMessage());
setRefreshing(false);
+ latch.countDown();
}
@Override
public void onSuccess(PageList<ResourceGroupComposite> results) {
- if (!results.isEmpty()) {
- final ResourceGroupComposite groupComposite = results.get(0);
- final ResourceGroup group = groupComposite.getResourceGroup();
- if (group.getGroupCategory() == GroupCategory.COMPATIBLE) {
- // Load the fully fetched ResourceType.
- ResourceType groupType = group.getResourceType();
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(
- groupType.getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.content,
- ResourceTypeRepository.MetadataType.operations,
- ResourceTypeRepository.MetadataType.measurements,
- ResourceTypeRepository.MetadataType.events,
-
ResourceTypeRepository.MetadataType.resourceConfigurationDefinition),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- group.setResourceType(type);
- //metric definitions
- Set<MeasurementDefinition> definitions =
type.getMetricDefinitions();
-
- //build id mapping for measurementDefinition
instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String,
MeasurementDefinition> measurementDefMap = new HashMap<String,
MeasurementDefinition>();
- for (MeasurementDefinition definition :
definitions) {
-
measurementDefMap.put(definition.getDisplayName(), definition);
- }
- //bundle definition ids for asynch call.
- int[] definitionArrayIds = new
int[definitions.size()];
- final String[] displayOrder = new
String[definitions.size()];
-
measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free
Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request
on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder)
{
- definitionArrayIds[index++] =
measurementDefMap.get(definitionToDisplay)
- .getId();
- }
-
-
GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(
- groupId, definitionArrayIds,
-
CustomDateRangeState.getInstance().getStartTime(),
-
CustomDateRangeState.getInstance().getEndTime(), 60,
- new
AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught)
{
- Log.debug("Error retrieving
recent metrics charting data for group ["
- + groupId + "]:" +
caught.getMessage());
- setRefreshing(false);
- }
-
- @Override
- public void onSuccess(
-
List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved
charting data
- for (int index = 0; index <
displayOrder.length; index++) {
- //retrieve the correct
measurement definition
- final MeasurementDefinition
md = measurementDefMap
-
.get(displayOrder[index]);
-
- //load the data results for
the given metric definition
-
List<MeasurementDataNumericHighLowComposite> data = results
- .get(index);
-
- //locate last and minimum
values.
- double lastValue = -1;
- double minValue =
Double.MAX_VALUE;//
- for
(MeasurementDataNumericHighLowComposite d : data) {
- if
((!Double.isNaN(d.getValue()))
- &&
(!String.valueOf(d.getValue()).contains("NaN"))) {
- if (d.getValue() <
minValue) {
- minValue =
d.getValue();
- }
- lastValue =
d.getValue();
- }
- }
-
- //collapse the data into
comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList =
"";
-
- for
(MeasurementDataNumericHighLowComposite d : data) {
- if
((!Double.isNaN(d.getValue()))
- &&
(!String.valueOf(d.getValue()).contains("NaN"))) {
- commaDelimitedList +=
d.getValue() + ",";
- }
- }
- DynamicForm row = new
DynamicForm();
- row.setNumCols(3);
- row.setColWidths(65,
"*", 100);
- row.setWidth100();
- row.setAutoHeight();
-
row.setOverflow(Overflow.VISIBLE);
- HTMLFlow graph = new
HTMLFlow();
- //
String contents = "<span id='sparkline_" + index + "'
class='dynamicsparkline' width='0'>"
- //
+ commaDelimitedList + "</span>";
- String contents =
"<span id='sparkline_" + index
- + "'
class='dynamicsparkline' width='0' " + "values='"
- + commaDelimitedList +
"'>...</span>";
- graph.setContents(contents);
-
graph.setContentsType(ContentsType.PAGE);
- //disable scrollbars on span
- graph.setScrollbarSize(0);
-
- CanvasItem graphContainer =
new CanvasItem();
-
graphContainer.setShowTitle(false);
-
graphContainer.setHeight(16);
- graphContainer.setWidth(60);
-
graphContainer.setCanvas(graph);
-
- final String title =
md.getDisplayName();
- LinkItem link =
AbstractActivityView.newLinkItem(title,
- null);
- link.setTooltip(title);
-
link.setTitleVAlign(VerticalAlignment.TOP);
-
link.setAlign(Alignment.LEFT);
- link.setClipValue(true);
- link.setWrap(true);
- link.setHeight(26);
- if
(!BrowserUtility.isBrowserPreIE9()) {
-
- link.addClickHandler(new
ClickHandler() {
- @Override
- public void
onClick(ClickEvent event) {
- ChartViewWindow
window = new ChartViewWindow(
- title,
"", refreshablePortlet);
-
CompositeGroupD3GraphListView graph = new CompositeGroupD3MultiLineGraph(
- groupId,
md.getId(), isAutoGroup);
-
window.addItem(graph);
-
graph.populateData();
- window.show();
- }
- });
- } else {
- link.disable();
- }
-
- //Value
- String convertedValue =
AbstractActivityView
-
.convertLastValueForDisplay(lastValue, md);
- StaticTextItem value =
AbstractActivityView
-
.newTextItem(convertedValue);
-
value.setVAlign(VerticalAlignment.TOP);
-
value.setAlign(Alignment.RIGHT);
-
value.setWidth("100%");
-
- row.setItems(graphContainer,
link, value);
- row.setWidth100();
- //if graph content returned
- if
((!md.getName().trim().contains("Trait."))
- && (lastValue !=
-1)) {
- column.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when
there are results but no chartable entries.
- DynamicForm row =
AbstractActivityView
-
.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- } else {
- //insert see more link
- DynamicForm row = new
DynamicForm();
- String link = LinkManager
-
.getGroupMonitoringGraphsLink(context);
-
AbstractActivityView.addSeeMoreLink(row, link, column);
- }
- //call out to 3rd party
javascript lib
- new Timer() {
- @Override
- public void run() {
-
BrowserUtility.graphSparkLines();
- }
- }.schedule(200);
-
- } else {
- DynamicForm row =
AbstractActivityView.createEmptyDisplayRow(
-
AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- }
- setRefreshing(false);
- }
- }
- );
- }
- });
- }
- } else {
- DynamicForm row = AbstractActivityView
-
.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- setRefreshing(false);
+ if (results.isEmpty()
+ || results.get(0).getResourceGroup().getGroupCategory() !=
GroupCategory.COMPATIBLE) {
+ renderChart = false;
}
+ latch.countDown();
}
});
-
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
}
@Override
@@ -497,10 +379,10 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements
CustomSettin
protected void setRefreshing(boolean currentlyRefreshing) {
this.currentlyLoading = currentlyRefreshing;
}
- public static class ChartViewWindow extends Window {
+ public static class ChartViewWindow extends Window {
- public ChartViewWindow(String title, String windowTitle,final GroupMetricsPortlet
portlet) {
+ public ChartViewWindow(String title, String windowTitle, final
GroupMetricsPortlet portlet) {
super();
if ((windowTitle != null) && (!windowTitle.trim().isEmpty())) {
setTitle(windowTitle + ": " + title);
@@ -533,4 +415,156 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements
CustomSettin
}
}
+
+ protected void fetchEnabledMetrics(List<MeasurementSchedule> schedules, int[]
definitionArrayIds,
+ final String[] displayOrder, final Map<String, MeasurementDefinition>
measurementDefMap, final VLayout layout) {
+ GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(groupId,
definitionArrayIds,
+ CustomDateRangeState.getInstance().getStartTime(),
CustomDateRangeState.getInstance().getEndTime(), 60,
+ new
AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for
group [" + groupId + "]:"
+ + caught.getMessage());
+ setRefreshing(false);
+ }
+
+ @Override
+ public void
onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ renderData(results, displayOrder, measurementDefMap, layout);
+ }
+ });
+ }
+
+
+ protected void
renderData(List<List<MeasurementDataNumericHighLowComposite>> results,
String[] displayOrder, Map<String, MeasurementDefinition> measurementDefMap, VLayout
layout) {
+ if (!results.isEmpty() && !measurementDefMap.isEmpty()) {
+ boolean someChartedData = false;
+ //iterate over the retrieved charting data
+ for (int index = 0; index < displayOrder.length; index++) {
+ //retrieve the correct measurement definition
+ final MeasurementDefinition md = measurementDefMap
+ .get(displayOrder[index]);
+
+ //load the data results for the given metric definition
+ List<MeasurementDataNumericHighLowComposite> data = results
+ .get(index);
+
+ //locate last and minimum values.
+ double lastValue = -1;
+ double minValue = Double.MAX_VALUE;
+ //collapse the data into comma delimited list for consumption by third
party javascript library(jquery.sparkline)
+ String commaDelimitedList = "";
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ &&
(!String.valueOf(d.getValue()).contains("NaN"))) {
+ commaDelimitedList += d.getValue() + ",";
+ if (d.getValue() < minValue) {
+ minValue = d.getValue();
+ }
+ lastValue = d.getValue();
+ }
+ }
+ DynamicForm row = new DynamicForm();
+ row.setNumCols(3);
+ row.setColWidths(65, "*", 100);
+ row.setWidth100();
+ row.setAutoHeight();
+ row.setOverflow(Overflow.VISIBLE);
+ HTMLFlow graph = new HTMLFlow();
+ String contents = "<span id='sparkline_" + index
+ + "' class='dynamicsparkline' width='0'
" + "values='"
+ + commaDelimitedList + "'>...</span>";
+ graph.setContents(contents);
+ graph.setContentsType(ContentsType.PAGE);
+ //disable scrollbars on span
+ graph.setScrollbarSize(0);
+
+ CanvasItem graphContainer = new CanvasItem();
+ graphContainer.setShowTitle(false);
+ graphContainer.setHeight(16);
+ graphContainer.setWidth(60);
+ graphContainer.setCanvas(graph);
+
+ final String title = md.getDisplayName();
+ LinkItem link = AbstractActivityView.newLinkItem(title,
+ null);
+ link.setTooltip(title);
+ link.setTitleVAlign(VerticalAlignment.TOP);
+ link.setAlign(Alignment.LEFT);
+ link.setClipValue(true);
+ link.setWrap(true);
+ link.setHeight(26);
+ if (!BrowserUtility.isBrowserPreIE9()) {
+
+ link.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ showPopupWithChart(title, md);
+ }
+ });
+ } else {
+ link.disable();
+ }
+
+ //Value
+ String convertedValue = AbstractActivityView
+ .convertLastValueForDisplay(lastValue, md);
+ StaticTextItem value = AbstractActivityView
+ .newTextItem(convertedValue);
+ value.setVAlign(VerticalAlignment.TOP);
+ value.setWidth("100%");
+
+ row.setItems(graphContainer, link, value);
+ row.setWidth100();
+ //if graph content returned
+ if ((!md.getName().trim().contains("Trait."))
+ && (lastValue != -1)) {
+ layout.addMember(row);
+ someChartedData = true;
+ }
+ }
+ if (!someChartedData) {// when there are results but no chartable entries.
+ DynamicForm row = getEmptyDataForm();
+ layout.addMember(row);
+ } else {
+ //insert see more link
+ DynamicForm row = new DynamicForm();
+ String link = getSeeMoreLink();
+ AbstractActivityView.addSeeMoreLink(row, link, layout);
+ }
+ //call out to 3rd party javascript lib
+ new Timer() {
+ @Override
+ public void run() {
+ BrowserUtility.graphSparkLines();
+ }
+ }.schedule(200);
+
+ } else {
+ DynamicForm row = getEmptyDataForm();
+ layout.addMember(row);
+ }
+ setRefreshing(false);
+ }
+
+ protected void showPopupWithChart(final String title, final MeasurementDefinition md)
{
+ ChartViewWindow window = new ChartViewWindow(title, "",
refreshablePortlet);
+ CompositeGroupD3GraphListView graph = new CompositeGroupD3MultiLineGraph(groupId,
md.getId(), isAutoGroup());
+ window.addItem(graph);
+ graph.populateData();
+ window.show();
+ }
+
+ protected DynamicForm getEmptyDataForm() {
+ return
AbstractActivityView.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
+ }
+
+ protected String getSeeMoreLink() {
+ return LinkManager.getGroupMonitoringGraphsLink(context);
+ }
+
+ protected MeasurementScheduleCriteria addFilterKey(MeasurementScheduleCriteria
criteria) {
+ criteria.addFilterResourceGroupId(groupId);
+ return criteria;
+ }
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
index df4e659..93d2d7c 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
@@ -18,27 +18,12 @@
*/
package org.rhq.coregui.client.dashboard.portlets.resource;
-import java.util.Arrays;
import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
-import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.ContentsType;
-import com.smartgwt.client.types.Overflow;
-import com.smartgwt.client.types.VerticalAlignment;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.LinkItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
-import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.common.EntityContext;
@@ -50,7 +35,6 @@ import
org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowCo
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.dashboard.Portlet;
@@ -61,9 +45,7 @@ import
org.rhq.coregui.client.inventory.common.detail.summary.AbstractActivityVi
import org.rhq.coregui.client.inventory.common.graph.CustomDateRangeState;
import org.rhq.coregui.client.inventory.resource.detail.monitoring.D3GraphListView;
import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.Log;
-import org.rhq.coregui.client.util.async.Command;
import org.rhq.coregui.client.util.async.CountDownLatch;
/**
@@ -77,18 +59,14 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
public static final String KEY = "ResourceMetrics";
// A default displayed, persisted name for the portlet
public static final String NAME = MSG.view_portlet_defaultName_resource_metrics();
-
- private int resourceId = -1;
- private ChartViewWindow window;
- private D3GraphListView graphView;
+ private int resourceId = -1;
public ResourceMetricsPortlet(int resourceId) {
super(EntityContext.forResource(-1));
this.resourceId = resourceId;
}
-
- private volatile List<MeasurementSchedule> enabledSchedules = null;
+
private volatile Resource resource = null;
public static final class Factory implements PortletViewFactory {
@@ -104,37 +82,54 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
}
}
- /** Fetches recent metric information and updates the DynamicForm instance with
i)sparkline information,
- * ii) link to recent metric graph for more details and iii) last metric value
formatted to show significant
- * digits.
- */
@Override
- protected void getRecentMetrics() {
-
- //display container
- final VLayout column = new VLayout();
- column.setHeight(10);//pack
- column.setWidth100();
-
- final CountDownLatch latch = CountDownLatch.create(2, new Command() {
-
- @Override
- public void execute() {
- showEnabledMetrics(enabledSchedules == null ? null :
getEnabledDefinitions(enabledSchedules), column, resource);
- }
-
- private Set<MeasurementDefinition>
getEnabledDefinitions(List<MeasurementSchedule> enabledSchedules) {
- Set<MeasurementDefinition> enabledDefinitions = new
HashSet<MeasurementDefinition>(enabledSchedules.size());
- for (MeasurementSchedule schedule : enabledSchedules) {
- enabledDefinitions.add(schedule.getDefinition());
+ protected void showPopupWithChart(String title, MeasurementDefinition md) {
+ ChartViewWindow window = new ChartViewWindow(title, "",
refreshablePortlet);
+ D3GraphListView graphView = D3GraphListView.createSingleGraph(resource,
md.getId(), true);
+ window.addItem(graphView);
+ window.show();
+ }
+
+ @Override
+ protected DynamicForm getEmptyDataForm() {
+ return
AbstractActivityView.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
+ }
+
+ @Override
+ protected String getSeeMoreLink() {
+ return LinkManager.getResourceMonitoringGraphsLink(resourceId);
+ }
+
+ @Override
+ protected MeasurementScheduleCriteria addFilterKey(MeasurementScheduleCriteria
criteria) {
+ criteria.addFilterResourceId(resourceId);
+ return criteria;
+ }
+
+ @Override
+ protected void fetchEnabledMetrics(List<MeasurementSchedule> schedules, int[]
definitionArrayIds,
+ final String[] displayOrder, final Map<String, MeasurementDefinition>
measurementDefMap, final VLayout layout) {
+ GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId,
definitionArrayIds,
+ CustomDateRangeState.getInstance().getStartTime(),
CustomDateRangeState.getInstance().getEndTime(), 60,
+ new
AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for
resource [" + resourceId + "]:"
+ + caught.getMessage());
+ setRefreshing(false);
+ }
+
+ @Override
+ public void
onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ renderData(results, displayOrder, measurementDefMap, layout);
}
- return enabledDefinitions;
}
- });
-
- //fetch only enabled schedules
- fetchEnabledSchedules(latch);
+ );
+ }
+
+ @Override
+ protected void fetchResourceType(final CountDownLatch latch, final VLayout layout) {
//locate resource reference
ResourceCriteria criteria = new ResourceCriteria();
criteria.addFilterId(this.resourceId);
@@ -170,192 +165,5 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
}
}
});
-
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
- }
-
- private void fetchEnabledSchedules(final CountDownLatch latch) {
- MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
- criteria.addFilterResourceId(resourceId);
- criteria.addFilterEnabled(true);
- criteria.fetchDefinition(true);
- criteria.setPageControl(PageControl.getUnlimitedInstance());
-
GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria,
new AsyncCallback<PageList<MeasurementSchedule>>() {
-
- @Override
- public void onSuccess(PageList<MeasurementSchedule> result) {
- enabledSchedules = result;
- latch.countDown();
- }
-
- @Override
- public void onFailure(Throwable caught) {
- latch.countDown();
- }
- });
- }
-
-
- private void showEnabledMetrics(final Set<MeasurementDefinition> definitions,
final VLayout layout, final Resource resource) {
- if (resource == null || definitions == null) {
- Log.warn("Unable to render recent metrics properly.");
- return;
- }
-
- //build id mapping for measurementDefinition instances Ex. Free Memory ->
MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new
HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
- //bundle definition ids for async call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] =
measurementDefMap.get(definitionToDisplay).getId();
- }
-
- GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId,
definitionArrayIds,
- CustomDateRangeState.getInstance().getStartTime(),
CustomDateRangeState.getInstance().getEndTime(), 60,
- new
AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for
resource [" + resourceId + "]:"
- + caught.getMessage());
- setRefreshing(false);
- }
-
- @Override
- public void
onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
- //retrieve the correct measurement definition
- final MeasurementDefinition md =
measurementDefMap.get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data =
results.get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue())) &&
(!String.valueOf(d.getValue()).contains("NaN"))) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
-
- //collapse the data into comma delimited list for consumption
by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue())) &&
(!String.valueOf(d.getValue()).contains("NaN"))) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- DynamicForm row = new DynamicForm();
- row.setNumCols(3);
- row.setColWidths(65, "*", 100);
- row.setWidth100();
- row.setAutoHeight();
- row.setOverflow(Overflow.VISIBLE);
- HTMLFlow sparklineGraph = new HTMLFlow();
- String contents = "<span id='sparkline_" +
index + "' class='dynamicsparkline' width='0' "
- + "values='" + commaDelimitedList +
"'>...</span>";
- sparklineGraph.setContents(contents);
- sparklineGraph.setContentsType(ContentsType.PAGE);
- //disable scrollbars on span
- sparklineGraph.setScrollbarSize(0);
-
- CanvasItem sparklineContainer = new CanvasItem();
- sparklineContainer.setShowTitle(false);
- sparklineContainer.setHeight(16);
- sparklineContainer.setWidth(60);
- sparklineContainer.setCanvas(sparklineGraph);
-
- //Link/title element
- final String title = md.getDisplayName();
- LinkItem link = AbstractActivityView.newLinkItem(title,
null);
- link.setTooltip(title);
- link.setTitleVAlign(VerticalAlignment.TOP);
- link.setAlign(Alignment.LEFT);
- link.setClipValue(true);
- link.setWrap(true);
- link.setHeight(26);
- link.setWidth("100%");
- if (!BrowserUtility.isBrowserPreIE9()) {
- link.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- window = new ChartViewWindow(title, "",
refreshablePortlet);
-
- graphView =
D3GraphListView.createSingleGraph(resource, md.getId(), true);
-
- window.addItem(graphView);
- window.show();
- }
- });
- } else {
- link.disable();
- }
-
- //Value
- String convertedValue;
- convertedValue =
AbstractActivityView.convertLastValueForDisplay(lastValue, md);
- StaticTextItem value =
AbstractActivityView.newTextItem(convertedValue);
- value.setVAlign(VerticalAlignment.TOP);
- value.setAlign(Alignment.RIGHT);
-
- row.setItems(sparklineContainer, link, value);
- row.setWidth100();
-
- //if graph content returned
- if ((!md.getName().trim().contains("Trait."))
&& (lastValue != -1)) {
- layout.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable
entries.
- DynamicForm row =
AbstractActivityView.createEmptyDisplayRow(
-
- AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- layout.addMember(row);
- } else {
- //insert see more link
- DynamicForm row = new DynamicForm();
- String link =
LinkManager.getResourceMonitoringGraphsLink(resourceId);
- AbstractActivityView.addSeeMoreLink(row, link, layout);
- }
- //call out to 3rd party javascript lib
- new Timer() {
- @Override
- public void run() {
- BrowserUtility.graphSparkLines();
- }
- }.schedule(200);
- } else {
- DynamicForm row = AbstractActivityView
-
.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- layout.addMember(row);
- }
- setRefreshing(false);
- }
- }
-
- );
}
}