Commit 738caed8 authored by Gianluca Filippone's avatar Gianluca Filippone
Browse files

Added average page for operations

parent b6a4ccec
/*
* Copyright 2016 The CHOReVOLUTION project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.syncope.client.console.pages;
import com.pingunaut.wicket.chartjs.chart.impl.Bar;
import com.pingunaut.wicket.chartjs.chart.impl.Doughnut;
import com.pingunaut.wicket.chartjs.core.panel.BarChartPanel;
import com.pingunaut.wicket.chartjs.core.panel.DoughnutChartPanel;
import com.pingunaut.wicket.chartjs.data.sets.BarDataSet;
import eu.chorevolution.idm.common.to.AVGOperationDataTO;
import eu.chorevolution.idm.common.to.CoordinationDelegateTO;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import org.apache.syncope.client.console.panels.AVGOperationPanel;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.widget.StatsWidget;
import org.apache.syncope.client.console.widgets.LabeledDoughnutChartData;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;
public class AVGCDDetailPage extends BaseExtPage {
private static final long serialVersionUID = 3932245590233237182L;
public static final String PREF_STATS_PAGINATOR_ROWS = "stats.paginator.rows";
private final ChoreographyRestClient restClient;
private final Long choreographyId;
private final String cdName;
private final CDStatisticsBundle bundle;
public AVGCDDetailPage(final PageParameters parameters) {
super(parameters);
restClient = new ChoreographyRestClient();
choreographyId = parameters.get("chor").toLong();
cdName = parameters.get("cd").toString();
CoordinationDelegateTO cd = restClient.getCD(choreographyId, cdName);
body.add(new Label("header", getString("header_title") + " " + cd.getName()));
List<AVGOperationDataTO> operations = restClient.averageOperationList(choreographyId, cdName);
bundle = new CDStatisticsBundle(operations);
WebMarkupContainer content = new WebMarkupContainer("content");
content.setOutputMarkupId(true);
RepeatingView chartList = new RepeatingView("stats");
// Sleeptime, Overhead and Execution time for each operation
chartList.add(new StatsWidget(chartList.newChildId()) {
@Override
public void create() {
Bar bar = new Bar();
bar.getData().getLabels().addAll(bundle.labels);
//Coordination Algorithm Reasoning Time (Red)
BarDataSet algorithmReasoningDataSet = new BarDataSet(bundle.coordinationAlgorithmReasoningTimes);
algorithmReasoningDataSet.setFillColor("rgba(227,20,20,0.6)");
algorithmReasoningDataSet.setStrokeColor("rgba(227,20,20,0.8)");
bar.getData().getDatasets().add(algorithmReasoningDataSet);
//Network Overhead For Coordination Messages (Red)
BarDataSet networkCoordinationOverheadDataSet =
new BarDataSet(bundle.networkOverheadForCoordinationMessagesExchangeTimes);
networkCoordinationOverheadDataSet.setFillColor("rgba(227,20,20,0.6)");
networkCoordinationOverheadDataSet.setStrokeColor("rgba(227,20,20,0.8)");
bar.getData().getDatasets().add(networkCoordinationOverheadDataSet);
//Wait Times (Green)
BarDataSet waitScheduleTimeDataSet = new BarDataSet(bundle.waitTimesForSchedulingOperation);
waitScheduleTimeDataSet.setFillColor("rgba(20,227,20,0.6)");
waitScheduleTimeDataSet.setStrokeColor("rgba(20,227,20,0.8)");
bar.getData().getDatasets().add(waitScheduleTimeDataSet);
BarDataSet waitSyncrhoTimeDataSet = new BarDataSet(bundle.waitTimesForSynchronizing);
waitSyncrhoTimeDataSet.setFillColor("rgba(20,227,20,0.6)");
waitSyncrhoTimeDataSet.setStrokeColor("rgba(20,227,20,0.8)");
bar.getData().getDatasets().add(waitSyncrhoTimeDataSet);
//Service Execution Time (Blue)
BarDataSet serviceExecutionTimeDataSet = new BarDataSet(bundle.serviceExecutionTimes);
serviceExecutionTimeDataSet.setFillColor("rgba(20,20,227,0.6)");
serviceExecutionTimeDataSet.setStrokeColor("rgba(20,20,227,0.8)");
bar.getData().getDatasets().add(serviceExecutionTimeDataSet);
//Network Overhead For Business Messages (Blue)
BarDataSet networkBusinessOverheadDataSet =
new BarDataSet(bundle.networkOverheadForBusinessMessagesExchangeTimes);
networkBusinessOverheadDataSet.setFillColor("rgba(20,20,227,0.6)");
networkBusinessOverheadDataSet.setStrokeColor("rgba(20,20,227,0.8)");
bar.getData().getDatasets().add(networkBusinessOverheadDataSet);
add(new BarChartPanel("chart", Model.of(bar)));
add(new Label("title", getString("overhead_sleep_execution_title")));
add(new Label("caption", getString("overhead_sleep_execution_caption")));
}
});
chartList.add(new StatsWidget(chartList.newChildId()) {
private static final long serialVersionUID = -8150750732895436230L;
@Override
public void create() {
Doughnut doughnut = new Doughnut();
doughnut.getOptions().setResponsive(true);
doughnut.getOptions().setMaintainAspectRatio(true);
doughnut.getOptions().setTooltipTemplate("<%= label %>");
long serviceExecutionTime = cd.getServiceExecutionTime();
long networkOverheadForBusinessMessagesExchangeTime
= cd.getNetworkOverheadForBusinessMessagesExchangeTime();
long coordinationAlgorithmReasoningTime = cd.getCoordinationAlgorithmReasoningTime();
long networkOverheadForCoordinationMessagesExchangeTime
= cd.getNetworkOverheadForCoordinationMessagesExchangeTime();
long waitTimeForSchedulingOperation = cd.getWaitTimeForSchedulingOperation();
long waitTimeForSynchronizing = cd.getWaitTimeForSynchronizing();
// Service Execution and Network Business Overhead (Blue)
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) serviceExecutionTime, "rgb(20,20,227)",
"serviceExecutionTime" + ": " + serviceExecutionTime + " ms"
));
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) networkOverheadForBusinessMessagesExchangeTime, "rgb(20,20,227)",
"networkOverheadForBusinessMessagesExchangeTime" + ": "
+ networkOverheadForBusinessMessagesExchangeTime + " ms"
));
// Coordination Algorithm Reasoning Time and Network Coordination Overhead (Red)
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) coordinationAlgorithmReasoningTime, "rgb(227,20,20)",
"coordinationAlgorithmReasoningTime" + ": "
+ coordinationAlgorithmReasoningTime + " ms"
));
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) networkOverheadForCoordinationMessagesExchangeTime, "rgb(227,20,20)",
"networkOverheadForCoordinationMessagesExchangeTime" + ": "
+ networkOverheadForCoordinationMessagesExchangeTime + " ms"
));
// Wait times (Green)
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) waitTimeForSchedulingOperation, "rgb(20,227,20)",
"waitTimeForSchedulingOperation" + ": "
+ waitTimeForSchedulingOperation + " ms"
));
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) waitTimeForSynchronizing, "rgb(20,227,20)",
"waitTimeForSynchronizing" + ": "
+ waitTimeForSynchronizing + " ms"
));
add(new DoughnutChartPanel("chart", Model.of(doughnut)));
add(new Label("title", getString("total_operation_overhead_title")));
add(new Label("caption", getString("total_operation_overhead_caption")));
}
});
content.add(chartList);
content.add(new AVGOperationPanel("operations", getPageReference(), choreographyId, cdName));
body.add(content);
}
private class CDStatisticsBundle implements Serializable {
private static final long serialVersionUID = 3642028474262240172L;
private List<String> labels;
private List<Double> coordinationAlgorithmReasoningTimes;
private List<Double> networkOverheadForCoordinationMessagesExchangeTimes;
private List<Double> waitTimesForSchedulingOperation;
private List<Double> waitTimesForSynchronizing;
private List<Double> serviceExecutionTimes;
private List<Double> networkOverheadForBusinessMessagesExchangeTimes;
private List<Integer> minSentMessages;
private List<Integer> maxSentMessages;
CDStatisticsBundle(final List<AVGOperationDataTO> operations) {
labels = new LinkedList<>();
coordinationAlgorithmReasoningTimes = new LinkedList<>();
networkOverheadForCoordinationMessagesExchangeTimes = new LinkedList<>();
waitTimesForSchedulingOperation = new LinkedList<>();
waitTimesForSynchronizing = new LinkedList<>();
serviceExecutionTimes = new LinkedList<>();
networkOverheadForBusinessMessagesExchangeTimes = new LinkedList<>();
minSentMessages = new LinkedList<>();
maxSentMessages = new LinkedList<>();
for (AVGOperationDataTO operation : operations) {
labels.add(operation.getName());
coordinationAlgorithmReasoningTimes.add(operation.getCoordinationAlgorithmReasoningTime());
networkOverheadForCoordinationMessagesExchangeTimes.add(
operation.getNetworkOverheadForCoordinationMessagesExchangeTime());
waitTimesForSchedulingOperation.add(operation.getWaitTimeForSchedulingOperation());
waitTimesForSynchronizing.add(operation.getWaitTimeForSynchronizing());
serviceExecutionTimes.add(operation.getServiceExecutionTime());
networkOverheadForBusinessMessagesExchangeTimes.add(
operation.getNetworkOverheadForBusinessMessagesExchangeTime());
minSentMessages.add(operation.getMinMessageNumber());
maxSentMessages.add(operation.getMaxMessageNumber());
}
}
}
}
......@@ -17,6 +17,7 @@ package org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import eu.chorevolution.idm.common.to.AVGCoordinationDelegateTO;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
......@@ -24,17 +25,24 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.syncope.client.console.commons.SearchableDataProvider;
import org.apache.syncope.client.console.pages.AVGCDDetailPage;
import org.apache.syncope.client.console.pages.InstanceStatsPage;
import org.apache.syncope.client.console.panels.AVGCDPanel.CDProvider;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
public class AVGCDPanel extends AbstractSearchResultPanel<
AVGCoordinationDelegateTO, AVGCoordinationDelegateTO, CDProvider, ChoreographyRestClient> {
......@@ -114,7 +122,7 @@ public class AVGCDPanel extends AbstractSearchResultPanel<
"Service Execution Time (ms)"), "serviceExecutionTime"));
columns.add(new PropertyColumn<>(new ResourceModel("networkOverheadForBusinessMessagesExchangeTime",
"Network Business Overhead (ms)"), "networkOverheadForBusinessMessagesExchangeTime"));
/*columns.add(new AbstractColumn<AVGCoordinationDelegateTO, String>(new ResourceModel("actions", "")) {
columns.add(new AbstractColumn<AVGCoordinationDelegateTO, String>(new ResourceModel("actions", "")) {
private static final long serialVersionUID = -3503023501954863131L;
......@@ -136,14 +144,14 @@ public class AVGCDPanel extends AbstractSearchResultPanel<
@Override
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
PageParameters param = new PageParameters();
param.add("instance", choreographyId);
param.add("chor", choreographyId);
param.add("cd", model.getObject().getName());
setResponsePage(CDDetailPage.class, param);
setResponsePage(AVGCDDetailPage.class, param);
}
}, ActionLink.ActionType.SEARCH);
item.add(actionLinks.build(componentId));
}
});*/
});
return columns;
......
/*
* Copyright 2016 The CHOReVOLUTION project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2016 The CHOReVOLUTION project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import eu.chorevolution.idm.common.to.AVGOperationDataTO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.syncope.client.console.commons.SearchableDataProvider;
import org.apache.syncope.client.console.pages.CDDetailPage;
import org.apache.syncope.client.console.panels.AVGOperationPanel.AVGOperationProvider;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.wicket.PageReference;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
public class AVGOperationPanel extends AbstractSearchResultPanel<
AVGOperationDataTO, AVGOperationDataTO, AVGOperationProvider, ChoreographyRestClient> {
private static final long serialVersionUID = 3727444742501082182L;
private Long choreographyId;
private String cdName;
public AVGOperationPanel(final String id, final PageReference pageRef,
final Long choreographyId, final String cdName) {
super(id, new AbstractSearchResultPanel.Builder<AVGOperationDataTO, AVGOperationDataTO, ChoreographyRestClient>(
new ChoreographyRestClient(), pageRef) {
private static final long serialVersionUID = 4218621294354212530L;
@Override
protected WizardMgtPanel<AVGOperationDataTO> newInstance(final String id) {
return new AVGOperationPanel(id, this);
}
}.disableCheckBoxes());
this.choreographyId = choreographyId;
this.cdName = cdName;
setFooterVisibility(true);
modal.addSumbitButton();
modal.size(Modal.Size.Large);
initResultTable();
}
private AVGOperationPanel(
final String id,
final AbstractSearchResultPanel.Builder<AVGOperationDataTO,
AVGOperationDataTO, ChoreographyRestClient> builder) {
super(id, builder);
}
@Override
protected AVGOperationProvider dataProvider() {
return new AVGOperationProvider(rows);
}
@Override
protected String paginatorRowsKey() {
return CDDetailPage.PREF_STATS_PAGINATOR_ROWS;
}
@Override
protected Collection<ActionLink.ActionType> getBulkActions() {
return Collections.<ActionLink.ActionType>emptyList();
}
@Override
protected List<IColumn<AVGOperationDataTO, String>> getColumns() {
final List<IColumn<AVGOperationDataTO, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("name"), "Name", "name"));
columns.add(new PropertyColumn<>(new ResourceModel("minMessageNumber", "# Min Coordination Messages"),
"minMessageNumber"));
columns.add(new PropertyColumn<>(new ResourceModel("maxMessageNumber", "# Max Coordination Messages"),
"maxMessageNumber"));
columns.add(new PropertyColumn<>(new ResourceModel("coordinationAlgorithmReasoningTime",
"Coordination Logic Execution Time (ms)"), "coordinationAlgorithmReasoningTime"));
columns.add(new PropertyColumn<>(new ResourceModel("networkOverheadForCoordinationMessagesExchangeTime",
"Network Coordination Overhead Time (ms)"), "networkOverheadForCoordinationMessagesExchangeTime"));
columns.add(new PropertyColumn<>(new ResourceModel("waitTimeForSchedulingOperation",
"Waiting Time For Forwarding Service Request (ms)"), "waitTimeForSchedulingOperation"));
columns.add(new PropertyColumn<>(new ResourceModel("waitTimeForSynchronizing",
"Waiting Time For Synchronizing With Other CDs (ms)"), "waitTimeForSynchronizing"));
columns.add(new PropertyColumn<>(new ResourceModel("serviceExecutionTime",
"Service Execution Time (ms)"), "serviceExecutionTime"));
columns.add(new PropertyColumn<>(new ResourceModel("networkOverheadForBusinessMessagesExchangeTime",
"Network Business Overhead (ms)"), "networkOverheadForBusinessMessagesExchangeTime"));
return columns;
}
protected final class AVGOperationProvider extends SearchableDataProvider<AVGOperationDataTO> {
private static final long serialVersionUID = -185944053385660794L;
private final Comparator<AVGOperationDataTO> comparator;
private AVGOperationProvider(final int paginatorRows) {
super(paginatorRows);
comparator = new Comparator<AVGOperationDataTO>() {
@Override
public int compare(final AVGOperationDataTO o1, final AVGOperationDataTO o2) {
return o1.getName().compareTo(o2.getName());
}
};
}
@Override
public Iterator<AVGOperationDataTO> iterator(final long first, final long count) {
List<AVGOperationDataTO> list = restClient.averageOperationList(choreographyId, cdName);
Collections.sort(list, comparator);
return list.subList((int) first, (int) first + (int) count).iterator();
}
@Override
public long size() {
return restClient.operationList(choreographyId, cdName).size();
}
@Override
public IModel<AVGOperationDataTO> model(final AVGOperationDataTO object) {
return new CompoundPropertyModel<>(object);
}
}
}
......@@ -16,6 +16,7 @@
package org.apache.syncope.client.console.rest;
import eu.chorevolution.idm.common.to.AVGCoordinationDelegateTO;
import eu.chorevolution.idm.common.to.AVGOperationDataTO;
import eu.chorevolution.idm.common.to.OperationDataTO;
import eu.chorevolution.idm.common.to.ChoreographyInstanceTO;
import eu.chorevolution.idm.common.to.ChoreographyTO;
......@@ -66,4 +67,10 @@ public class ChoreographyRestClient extends BaseRestClient {
public List<AVGCoordinationDelegateTO> averageCdList(final Long choreographyId) {
return getService(ConsoleInterfaceService.class).averageCdList(choreographyId);
}
public List<AVGOperationDataTO> averageOperationList(
final Long choreographyId,
final String cdName) {
return getService(ConsoleInterfaceService.class).averageOperationList(choreographyId, cdName);
}
}
<!DOCTYPE html>
<!--
Copyright 2016 The CHOReVOLUTION project
*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
*
http://www.apache.org/licenses/LICENSE-2.0
*
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:extend>
<section class="content-header">
<h1>
<span wicket:id="header"></span>
</h1>
</section>
<section class="content" wicket:id="content">
<div class="row">
<div class="col-md-6" wicket:id="stats"/>
</div>
<div class="box">
<div class="box-body" wicket:id="operations"/>
</div>
</section>
</wicket:extend>
</html>
\ No newline at end of file
#
# Copyright 2016 The CHOReVOLUTION project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Average details of CD
description=Description
#
# Copyright 2016 The CHOReVOLUTION project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at