Commit 76216127 authored by Gianluca Filippone's avatar Gianluca Filippone
Browse files

Started implementing functions to show average statistics for choreography instances

parent fb2418b9
/*
* 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.AVGCoordinationDelegateTO;
import eu.chorevolution.idm.common.to.ChoreographyTO;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
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 AVGInstanceStatsPage 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 AvgInstanceStatisticsBundle bundle;
public AVGInstanceStatsPage(final PageParameters parameters) {
super(parameters);
restClient = new ChoreographyRestClient();
choreographyId = parameters.get("chor").toLong();
ChoreographyTO choreography = restClient.getChoreography(choreographyId);
body.add(new Label("header",
getString("header_title") + " of" + " " + choreography.getName()));
List<AVGCoordinationDelegateTO> cds = restClient.averageCdList(choreographyId);
bundle = new AvgInstanceStatisticsBundle(cds);
WebMarkupContainer content = new WebMarkupContainer("content");
content.setOutputMarkupId(true);
content.add(new Label("duration",
getString("duration") + " " + restClient.getAverageInstanceExecutionTime(choreographyId) + " ms"
));
RepeatingView chartList = new RepeatingView("stats");
//Total overhead and total execution time per CD
chartList.add(new StatsWidget(chartList.newChildId()) {
@Override
public void create() {
Bar bar = new Bar();
bar.getData().getLabels().addAll(bundle.labels);
BarDataSet overheadDataSet = new BarDataSet(bundle.overheads);
overheadDataSet.setFillColor("rgba(227,20,20,0.6)");
overheadDataSet.setStrokeColor("rgba(227,20,20,0.8)");
bar.getData().getDatasets().add(overheadDataSet);
BarDataSet sleepDataSet = new BarDataSet(bundle.waitTimes);
sleepDataSet.setFillColor("rgba(20,227,20,0.6)");
sleepDataSet.setStrokeColor("rgba(20,227,20,0.8)");
bar.getData().getDatasets().add(sleepDataSet);
BarDataSet serviceDataSet = new BarDataSet(bundle.serviceExecTimes);
serviceDataSet.setFillColor("rgba(20,20,227,0.6)");
serviceDataSet.setStrokeColor("rgba(20,20,227,0.8)");
bar.getData().getDatasets().add(serviceDataSet);
add(new BarChartPanel("chart", Model.of(bar)));
add(new Label("title", getString("cd_overhead_title")));
add(new Label("caption", getString("cd_overhead_caption")));
}
});
//Operations executed and sent messages per CD
chartList.add(new StatsWidget(chartList.newChildId()) {
private static final long serialVersionUID = -8150750732895436230L;
@Override
public void create() {
Bar bar = new Bar();
bar.getData().getLabels().addAll(bundle.labels);
BarDataSet operationsDataSet = new BarDataSet(bundle.operations);
operationsDataSet.setFillColor("rgba(151,187,205,0.6)");
operationsDataSet.setStrokeColor("rgba(151,187,205,0.8)");
bar.getData().getDatasets().add(operationsDataSet);
bar.getData().getDatasets().add(new BarDataSet(bundle.messages));
add(new BarChartPanel("chart", Model.of(bar)));
add(new Label("title", getString("cd_operations_title")));
add(new Label("caption", getString("cd_operations_caption")));
}
});
//Total task execution time and total overhead
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 execution = bundle.totalServiceExecution;
long overhead = bundle.totalOverhead;
long sleep = bundle.totalWait;
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) execution, "rgb(20,20,227)",
getString("service_execution_time") + ": " + execution
));
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) overhead, "rgb(227,20,20)", getString("overhead") + ": " + overhead
));
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) sleep, "rgb(20,227,20)", getString("sleep_time") + ": " + sleep
));
add(new DoughnutChartPanel("chart", Model.of(doughnut)));
add(new Label("title", getString("total_overhead_title")));
add(new Label("caption", getString("total_overhead_caption")));
}
});
//Total executed operations and sent messages
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 %>");
doughnut.getData().add(
new LabeledDoughnutChartData(
bundle.totalMessages,
"rgb(220,220,220)",
getString("sent_messages") + ": " + bundle.totalMessages
));
doughnut.getData().add(
new LabeledDoughnutChartData(
bundle.totalOperations,
"rgb(151,187,205)",
getString("executed_operations") + ": " + bundle.totalOperations
));
add(new DoughnutChartPanel("chart", Model.of(doughnut)));
add(new Label("title", getString("total_operations_title")));
add(new Label("caption", getString("total_operations_caption")));
}
});
content.add(chartList);
content.add(new Label("cds", "TO BE IMPLEMENTED"));
//content.add(new CDPanel("cds", getPageReference(), instanceId));
// Re-enable when entilements for this service will be defined
//MetaDataRoleAuthorizationStrategy.authorize(content, ENABLE, CamelEntitlement.ROUTE_LIST);
body.add(content);
}
private class AvgInstanceStatisticsBundle implements Serializable {
private static final long serialVersionUID = 3642028474262240172L;
private List<String> labels;
private List<Long> overheads;
private List<Long> serviceExecTimes;
private List<Long> waitTimes;
private List<Integer> operations;
private List<Integer> messages;
private int totalMessages;
private int totalOperations;
private long totalServiceExecution;
private long totalOverhead;
private long totalWait;
AvgInstanceStatisticsBundle(final List<AVGCoordinationDelegateTO> cds) {
labels = new LinkedList<>();
overheads = new LinkedList<>();
serviceExecTimes = new LinkedList<>();
waitTimes = new LinkedList<>();
operations = new LinkedList<>();
messages = new LinkedList<>();
totalMessages = 0;
totalOperations = 0;
totalServiceExecution = 0;
totalOverhead = 0;
totalWait = 0;
//TODO refactor statistics calculus
/*for (AVGCoordinationDelegateTO cd : cds) {
labels.add(cd.getName());
overheads.add(
cd.getCoordinationAlgorithmReasoningTime()
+ cd.getNetworkOverheadForCoordinationMessagesExchangeTime()
);
serviceExecTimes.add(
cd.getServiceExecutionTime() + cd.getNetworkOverheadForBusinessMessagesExchangeTime()
);
waitTimes.add(
cd.getWaitTimeForSchedulingOperation() + cd.getWaitTimeForSynchronizing()
);
operations.add(cd.getExecutedOperations());
messages.add(cd.getCoordinationMessages());
totalMessages = totalMessages + cd.getCoordinationMessages();
totalOperations = totalOperations + cd.getExecutedOperations();
totalServiceExecution = totalServiceExecution
+ cd.getServiceExecutionTime()
+ cd.getNetworkOverheadForBusinessMessagesExchangeTime();
totalOverhead = totalOverhead
+ cd.getCoordinationAlgorithmReasoningTime()
+ cd.getNetworkOverheadForCoordinationMessagesExchangeTime();
totalWait = totalWait + cd.getWaitTimeForSchedulingOperation() + cd.getWaitTimeForSynchronizing();
}*/
}
}
}
......@@ -15,12 +15,15 @@
*/
package org.apache.syncope.client.console.pages;
import com.googlecode.wicket.jquery.ui.markup.html.link.Link;
import eu.chorevolution.idm.common.to.ChoreographyTO;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.syncope.client.console.panels.InstancePanel;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.NonCachingImage;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.ByteArrayResource;
public class InstancePage extends BaseExtPage {
......@@ -37,12 +40,34 @@ public class InstancePage extends BaseExtPage {
Long choreographyId = parameters.get("chor").toLong();
ChoreographyTO choreography = restClient.getChoreography(choreographyId);
body.add(new Label("header", getString("header_title") + " of Choreography " + choreography.getName()));
body.add(new Label("header", getString("choreography") + " " + choreography.getName()));
WebMarkupContainer content = new WebMarkupContainer("content");
content.setOutputMarkupId(true);
if (choreography.getImage() != null) {
content.add(new NonCachingImage("choreography_image",
new ByteArrayResource(choreography.getImageType().getContentType(), choreography.getImage())));
} else {
content.add(new Label("choreography_image", "No image available for this choreography"));
}
content.add(new Label("description", getString("description")));
content.add(new Label("choreography_description", choreography.getDescription()));
content.add(new Label("instances_title", getString("instances")));
content.add(new InstancePanel("instances", getPageReference(), choreographyId));
Double averageInstanceExecutionTime = restClient.getAverageInstanceExecutionTime(choreographyId);
content.add(new Label("avg_instances", getString("average") + ": " + averageInstanceExecutionTime + " ms"));
content.add(new Link("avg_link") {
@Override
public void onClick() {
PageParameters param = new PageParameters();
param.add("chor", choreographyId);
setResponsePage(InstancePage.class, param);
}
});
// Re-enable when entilements for this service will be defined
//MetaDataRoleAuthorizationStrategy.authorize(content, ENABLE, CamelEntitlement.ROUTE_LIST);
body.add(content);
......
......@@ -99,18 +99,18 @@ public class CDPanel extends AbstractSearchResultPanel<
protected List<IColumn<CoordinationDelegateTO, String>> getColumns() {
final List<IColumn<CoordinationDelegateTO, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("name", "Name"), "Name", "name"));
columns.add(new PropertyColumn<>(new ResourceModel("executedOperations", "Executed Operations"),
columns.add(new PropertyColumn<>(new ResourceModel("executedOperations", "# Executed Operations"),
"executedOperations"));
columns.add(new PropertyColumn<>(new ResourceModel("coordinationMessages", "Coordination Messages"),
columns.add(new PropertyColumn<>(new ResourceModel("coordinationMessages", "# Coordination Messages"),
"coordinationMessages"));
columns.add(new PropertyColumn<>(new ResourceModel("coordinationAlgorithmReasoningTime",
"Algorithm Reasoning (ms)"), "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",
"Scheduling Operation Wait Time (ms)"), "waitTimeForSchedulingOperation"));
"Waiting Time For Forwarding Service Request (ms)"), "waitTimeForSchedulingOperation"));
columns.add(new PropertyColumn<>(new ResourceModel("waitTimeForSynchronizing",
"Synchronizing Wait Time (ms)"), "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",
......
......@@ -65,7 +65,7 @@ public class InstancePanel extends AbstractSearchResultPanel<
this.choreographyId = choreographyId;
setFooterVisibility(true);
setFooterVisibility(false);
modal.addSumbitButton();
modal.size(Modal.Size.Large);
initResultTable();
......@@ -100,7 +100,8 @@ public class InstancePanel extends AbstractSearchResultPanel<
"Id", "choreographyInstanceId"));
columns.add(new PropertyColumn<>(new ResourceModel("instanceDescription", "Description"),
"instanceDescription"));
columns.add(new PropertyColumn<>(new ResourceModel("executionTime", "Execution Time (ms)"), "executionTime"));
columns.add(new PropertyColumn<>(new ResourceModel("executionTime", "Overall Execution Time (ms)"),
"executionTime"));
columns.add(new AbstractColumn<ChoreographyInstanceTO, String>(new ResourceModel("actions", "")) {
private static final long serialVersionUID = -3503023501954863131L;
......
......@@ -39,7 +39,7 @@ 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.InstanceStatsPage;
import org.apache.syncope.client.console.pages.CDDetailPage;
import org.apache.syncope.client.console.panels.OperationPanel.OperationProvider;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
......@@ -97,7 +97,7 @@ public class OperationPanel extends AbstractSearchResultPanel<
@Override
protected String paginatorRowsKey() {
return InstanceStatsPage.PREF_STATS_PAGINATOR_ROWS;
return CDDetailPage.PREF_STATS_PAGINATOR_ROWS;
}
@Override
......@@ -109,16 +109,16 @@ public class OperationPanel extends AbstractSearchResultPanel<
protected List<IColumn<OperationDataTO, String>> getColumns() {
final List<IColumn<OperationDataTO, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("name"), "Name", "name"));
columns.add(new PropertyColumn<>(new ResourceModel("messageNumber", "Coordination Messages"),
columns.add(new PropertyColumn<>(new ResourceModel("messageNumber", "# Coordination Messages"),
"messageNumber"));
columns.add(new PropertyColumn<>(new ResourceModel("coordinationAlgorithmReasoningTime",
"Algorithm Reasoning (ms)"), "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",
"Scheduling Operation Wait Time (ms)"), "waitTimeForSchedulingOperation"));
"Waiting Time For Forwarding Service Request (ms)"), "waitTimeForSchedulingOperation"));
columns.add(new PropertyColumn<>(new ResourceModel("waitTimeForSynchronizing",
"Synchronizing Wait Time (ms)"), "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",
......
......@@ -15,6 +15,7 @@
*/
package org.apache.syncope.client.console.rest;
import eu.chorevolution.idm.common.to.AVGCoordinationDelegateTO;
import eu.chorevolution.idm.common.to.OperationDataTO;
import eu.chorevolution.idm.common.to.ChoreographyInstanceTO;
import eu.chorevolution.idm.common.to.ChoreographyTO;
......@@ -57,4 +58,12 @@ public class ChoreographyRestClient extends BaseRestClient {
public CoordinationDelegateTO getCD(final Long choreographyInstancePK, final String cdName) {
return getService(ConsoleInterfaceService.class).getCd(choreographyInstancePK, cdName);
}
public Double getAverageInstanceExecutionTime(final Long choreographyId) {
return getService(ConsoleInterfaceService.class).getAverageInstanceExecutionTime(choreographyId);
}
public List<AVGCoordinationDelegateTO> averageCdList(final Long choreographyId) {
return getService(ConsoleInterfaceService.class).averageCdList(choreographyId);
}
}
<!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">
<h4>
<span wicket:id="duration"></span>
</h4>
<div class="row">
<div class="col-md-6" wicket:id="stats"/>
</div>
<div class="box">
<div class="box-body" wicket:id="cds"/>
</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=Stats for
description=Description
duration=Instance duration:
#
# 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=Statistiche per
description=Descrizione
duration=Durata dell'istanza:
#
# 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=Estatistica para
description=Descri\u00e7\u00e3o
duration=Dura\u00e7\u00e3o de la inst\u00e2ncia:
......@@ -15,17 +15,39 @@ 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>
<wicket:extend>
<section class="content-header">
<h1>
<span wicket:id="header"></span>
</h1>
</section>
<section class="content" wicket:id="content">
<div class="box">
<div class="box-body" wicket:id="instances"/>
</div>
</section>
</wicket:extend>
<section class="content" wicket:id="content">
<div class="thumbnail">
<img wicket:id="choreography_image"/>
<div class="caption">
<h3>
<span wicket:id="description"></span>
</h3>