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

Added CD average stats page

parent 76216127
......@@ -25,6 +25,7 @@ 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.panels.AVGCDPanel;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.widget.StatsWidget;
import org.apache.syncope.client.console.widgets.LabeledDoughnutChartData;
......@@ -55,7 +56,7 @@ public class AVGInstanceStatsPage extends BaseExtPage {
ChoreographyTO choreography = restClient.getChoreography(choreographyId);
body.add(new Label("header",
getString("header_title") + " of" + " " + choreography.getName()));
getString("header_title") + choreography.getName()));
List<AVGCoordinationDelegateTO> cds = restClient.averageCdList(choreographyId);
bundle = new AvgInstanceStatisticsBundle(cds);
......@@ -63,8 +64,8 @@ public class AVGInstanceStatsPage extends BaseExtPage {
WebMarkupContainer content = new WebMarkupContainer("content");
content.setOutputMarkupId(true);
content.add(new Label("duration",
getString("duration") + " " + restClient.getAverageInstanceExecutionTime(choreographyId) + " ms"
content.add(new Label("average_duration",
getString("average_duration") + " " + restClient.getAverageInstanceExecutionTime(choreographyId) + " ms"
));
RepeatingView chartList = new RepeatingView("stats");
......@@ -107,12 +108,12 @@ public class AVGInstanceStatsPage extends BaseExtPage {
Bar bar = new Bar();
bar.getData().getLabels().addAll(bundle.labels);
BarDataSet operationsDataSet = new BarDataSet(bundle.operations);
BarDataSet operationsDataSet = new BarDataSet(bundle.meanOperations);
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));
bar.getData().getDatasets().add(new BarDataSet(bundle.meanMessages));
add(new BarChartPanel("chart", Model.of(bar)));
add(new Label("title", getString("cd_operations_title")));
......@@ -130,9 +131,9 @@ public class AVGInstanceStatsPage extends BaseExtPage {
doughnut.getOptions().setResponsive(true);
doughnut.getOptions().setMaintainAspectRatio(true);
doughnut.getOptions().setTooltipTemplate("<%= label %>");
long execution = bundle.totalServiceExecution;
long overhead = bundle.totalOverhead;
long sleep = bundle.totalWait;
double execution = bundle.totalServiceExecution;
double overhead = bundle.totalOverhead;
double sleep = bundle.totalWait;
doughnut.getData().add(
new LabeledDoughnutChartData(
(int) execution, "rgb(20,20,227)",
......@@ -152,7 +153,7 @@ public class AVGInstanceStatsPage extends BaseExtPage {
}
});
//Total executed operations and sent messages
chartList.add(new StatsWidget(chartList.newChildId()) {
/*chartList.add(new StatsWidget(chartList.newChildId()) {
private static final long serialVersionUID = -8150750732895436230L;
......@@ -178,11 +179,10 @@ public class AVGInstanceStatsPage extends BaseExtPage {
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));
content.add(new AVGCDPanel("cds", getPageReference(), choreographyId));
// Re-enable when entilements for this service will be defined
//MetaDataRoleAuthorizationStrategy.authorize(content, ENABLE, CamelEntitlement.ROUTE_LIST);
body.add(content);
......@@ -194,41 +194,34 @@ public class AVGInstanceStatsPage extends BaseExtPage {
private List<String> labels;
private List<Long> overheads;
private List<Long> serviceExecTimes;
private List<Double> overheads;
private List<Long> waitTimes;
private List<Double> serviceExecTimes;
private List<Integer> operations;
private List<Double> waitTimes;
private List<Integer> messages;
private List<Double> meanMessages;
private int totalMessages;
private List<Double> meanOperations;
private int totalOperations;
private double totalServiceExecution;
private long totalServiceExecution;
private double totalOverhead;
private long totalOverhead;
private long totalWait;
private double 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;
meanMessages = new LinkedList<>();
meanOperations = new LinkedList<>();
totalServiceExecution = 0;
totalOverhead = 0;
totalWait = 0;
//TODO refactor statistics calculus
/*for (AVGCoordinationDelegateTO cd : cds) {
for (AVGCoordinationDelegateTO cd : cds) {
labels.add(cd.getName());
overheads.add(
cd.getCoordinationAlgorithmReasoningTime()
......@@ -240,10 +233,8 @@ public class AVGInstanceStatsPage extends BaseExtPage {
waitTimes.add(
cd.getWaitTimeForSchedulingOperation() + cd.getWaitTimeForSynchronizing()
);
operations.add(cd.getExecutedOperations());
messages.add(cd.getCoordinationMessages());
totalMessages = totalMessages + cd.getCoordinationMessages();
totalOperations = totalOperations + cd.getExecutedOperations();
meanOperations.add(Double.valueOf(cd.getMaxExecutedOperations() + cd.getMinExecutedOperations()) / 2);
meanMessages.add(Double.valueOf(cd.getMaxCoordinationMessages() + cd.getMinCoordinationMessages()) / 2);
totalServiceExecution = totalServiceExecution
+ cd.getServiceExecutionTime()
+ cd.getNetworkOverheadForBusinessMessagesExchangeTime();
......@@ -251,7 +242,7 @@ public class AVGInstanceStatsPage extends BaseExtPage {
+ cd.getCoordinationAlgorithmReasoningTime()
+ cd.getNetworkOverheadForCoordinationMessagesExchangeTime();
totalWait = totalWait + cd.getWaitTimeForSchedulingOperation() + cd.getWaitTimeForSynchronizing();
}*/
}
}
}
......
......@@ -64,7 +64,7 @@ public class InstancePage extends BaseExtPage {
public void onClick() {
PageParameters param = new PageParameters();
param.add("chor", choreographyId);
setResponsePage(InstancePage.class, param);
setResponsePage(AVGInstanceStatsPage.class, param);
}
});
......
......@@ -56,7 +56,8 @@ public class InstanceStatsPage extends BaseExtPage {
ChoreographyInstanceTO choreographyInstance = restClient.getChoreographyInstance(instanceId);
body.add(new Label("header",
getString("header_title") + " of" + " " + choreographyInstance.getChoreographyName()));
getString("header_title") + choreographyInstance.getChoreographyInstanceId()
+ " of " + choreographyInstance.getChoreographyName()));
List<CoordinationDelegateTO> cds = restClient.cdList(instanceId);
bundle = new InstanceStatisticsBundle(cds);
......
/*
* 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.AVGCoordinationDelegateTO;
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.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.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 AVGCDPanel extends AbstractSearchResultPanel<
AVGCoordinationDelegateTO, AVGCoordinationDelegateTO, CDProvider, ChoreographyRestClient> {
private static final long serialVersionUID = 3727444742501082182L;
private Long choreographyId;
public AVGCDPanel(final String id, final PageReference pageRef,
final Long choreographyId) {
super(id,
new AbstractSearchResultPanel.Builder<AVGCoordinationDelegateTO,
AVGCoordinationDelegateTO, ChoreographyRestClient>(
new ChoreographyRestClient(), pageRef) {
private static final long serialVersionUID = 8769126634538601689L;
@Override
protected WizardMgtPanel<AVGCoordinationDelegateTO> newInstance(final String id) {
return new AVGCDPanel(id, this);
}
}.disableCheckBoxes());
this.choreographyId = choreographyId;
setFooterVisibility(true);
modal.addSumbitButton();
modal.size(Modal.Size.Large);
initResultTable();
}
private AVGCDPanel(
final String id,
final AbstractSearchResultPanel.Builder<AVGCoordinationDelegateTO,
AVGCoordinationDelegateTO, ChoreographyRestClient> builder) {
super(id, builder);
}
@Override
protected CDProvider dataProvider() {
return new CDProvider(rows);
}
@Override
protected String paginatorRowsKey() {
return InstanceStatsPage.PREF_STATS_PAGINATOR_ROWS;
}
@Override
protected Collection<ActionLink.ActionType> getBulkActions() {
return Collections.<ActionLink.ActionType>emptyList();
}
@Override
protected List<IColumn<AVGCoordinationDelegateTO, String>> getColumns() {
final List<IColumn<AVGCoordinationDelegateTO, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("name", "Name"), "Name", "name"));
columns.add(new PropertyColumn<>(new ResourceModel("minExecutedOperations", "# Min Executed Operations"),
"minExecutedOperations"));
columns.add(new PropertyColumn<>(new ResourceModel("maxExecutedOperations", "# Max Executed Operations"),
"maxExecutedOperations"));
columns.add(new PropertyColumn<>(new ResourceModel("minCoordinationMessages", "# Min Coordination Messages"),
"minCoordinationMessages"));
columns.add(new PropertyColumn<>(new ResourceModel("maxCoordinationMessages", "# Max Coordination Messages"),
"maxCoordinationMessages"));
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"));
/*columns.add(new AbstractColumn<AVGCoordinationDelegateTO, String>(new ResourceModel("actions", "")) {
private static final long serialVersionUID = -3503023501954863131L;
@Override
public String getCssClass() {
return "action";
}
@Override
public void populateItem(final Item<ICellPopulator<AVGCoordinationDelegateTO>> item,
final String componentId,
final IModel<AVGCoordinationDelegateTO> model) {
ActionLinksPanel.Builder<Serializable> actionLinks = ActionLinksPanel.builder();
actionLinks.setDisableIndicator(true);
actionLinks.add(new ActionLink<Serializable>() {
private static final long serialVersionUID = -3722207913631435501L;
@Override
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
PageParameters param = new PageParameters();
param.add("instance", choreographyId);
param.add("cd", model.getObject().getName());
setResponsePage(CDDetailPage.class, param);
}
}, ActionLink.ActionType.SEARCH);
item.add(actionLinks.build(componentId));
}
});*/
return columns;
}
protected final class CDProvider extends SearchableDataProvider<AVGCoordinationDelegateTO> {
private static final long serialVersionUID = -185944053385660794L;
private final Comparator<AVGCoordinationDelegateTO> comparator;
private CDProvider(final int paginatorRows) {
super(paginatorRows);
comparator = new Comparator<AVGCoordinationDelegateTO>() {
@Override
public int compare(final AVGCoordinationDelegateTO o1, final AVGCoordinationDelegateTO o2) {
return o1.getName().compareTo(o2.getName());
}
};
}
@Override
public Iterator<AVGCoordinationDelegateTO> iterator(final long first, final long count) {
List<AVGCoordinationDelegateTO> list = restClient.averageCdList(choreographyId);
Collections.sort(list, comparator);
return list.subList((int) first, (int) first + (int) count).iterator();
}
@Override
public long size() {
return restClient.averageCdList(choreographyId).size();
}
@Override
public IModel<AVGCoordinationDelegateTO> model(final AVGCoordinationDelegateTO object) {
return new CompoundPropertyModel<>(object);
}
}
}
......@@ -24,7 +24,7 @@ limitations under the License.
<section class="content" wicket:id="content">
<h4>
<span wicket:id="duration"></span>
<span wicket:id="average_duration"></span>
</h4>
<div class="row">
<div class="col-md-6" wicket:id="stats"/>
......
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Stats for
header_title=Average Data for choreography
description=Description
duration=Instance duration:
average_duration=Average instances execution time:
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Statistiche per
header_title=Dati medi per la coreografia
description=Descrizione
duration=Durata dell'istanza:
average_duration=Tempo medio di esecuzione delle istanze:
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Estatistica para
header_title=Dados m\u00e9dios para coreografia
description=Descri\u00e7\u00e3o
duration=Dura\u00e7\u00e3o de la inst\u00e2ncia:
average_duration=Tempo m\u00e9dio de execu\u00e7\u00e3o de inst\u00e2ncias:
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Stats for
header_title=Stats for instance
description=Description
duration=Instance duration:
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Statistiche per
header_title=Statistiche per l'istanza
description=Descrizione
duration=Durata dell'istanza:
......@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
header_title=Estatistica para
header_title=Estatistica para instancia
description=Descri\u00e7\u00e3o
duration=Dura\u00e7\u00e3o de la inst\u00e2ncia:
......@@ -15,6 +15,7 @@
*/
package org.apache.syncope.core.logic;
import eu.chorevolution.idm.common.to.AVGCoordinationDelegateTO;
import eu.chorevolution.idm.common.to.ChoreographyInstanceTO;
import eu.chorevolution.idm.common.to.ChoreographyTO;
import eu.chorevolution.idm.common.to.CoordinationDelegateTO;
......@@ -390,7 +391,106 @@ public class MonitorLogic extends AbstractTransactionalLogic<AbstractBaseBean> {
for (ChoreographyInstanceTO choreographyInstance : choreographyInstanceTOs) {
avgInstanceExevutionTime = avgInstanceExevutionTime + choreographyInstance.getExecutionTime();
}
return choreographyInstanceTOs.size() == 0 ? avgInstanceExevutionTime
: avgInstanceExevutionTime / Double.valueOf(choreographyInstanceTOs.size());
if (choreographyInstanceTOs.isEmpty()) {
return avgInstanceExevutionTime;
} else {
avgInstanceExevutionTime = avgInstanceExevutionTime / Double.valueOf(choreographyInstanceTOs.size());
return Double.valueOf(Math.round(avgInstanceExevutionTime * 100d)) / 100d;
}
}
public List<AVGCoordinationDelegateTO> averageCdList(final Long choreographyId) {
List<AVGCoordinationDelegateTO> aVGCoordinationDelegateTOs = new LinkedList<>();
List<ChoreographyInstance> choreographyInstances = choreographyInstanceDAO.findByChoreographyId(choreographyId);
List<String> cdNames = eventDAO.findCdsByChoreography(choreographyId);
for (String cdName : cdNames) {
int maxExecutedOperations = 0;
int minExecutedOperations = -1;
int maxCoordinationMessages = 0;
int minCoordinationMessages = -1;
double totalServiceExecutionTime = 0.0d;
double totalNetworkOverheadForBusinessMessagesExchangeTime = 0.0d;
double totalCoordinationAlgorithmReasoningTime = 0.0d;
double totalNetworkOverheadForCoordinationMessagesExchangeTime = 0.0d;
double totalWaitTimeForSchedulingOperation = 0.0d;
double totalWaitTimeForSynchronizing = 0.0d;
int assignments = 0;
for (ChoreographyInstance choreographyInstance : choreographyInstances) {
CoordinationDelegateTO coordinationDelegateTO = getCd(choreographyInstance.getId(), cdName);
if (coordinationDelegateTO != null) {
if (maxExecutedOperations < coordinationDelegateTO.getExecutedOperations()) {
maxExecutedOperations = coordinationDelegateTO.getExecutedOperations();
}
if (minExecutedOperations > coordinationDelegateTO.getExecutedOperations()
|| minExecutedOperations == -1) {
minExecutedOperations = coordinationDelegateTO.getExecutedOperations();
}
if (maxCoordinationMessages < coordinationDelegateTO.getCoordinationMessages()) {
maxCoordinationMessages = coordinationDelegateTO.getCoordinationMessages();
}
if (minCoordinationMessages > coordinationDelegateTO.getCoordinationMessages()
|| minCoordinationMessages == -1) {
minCoordinationMessages = coordinationDelegateTO.getCoordinationMessages();
}
totalServiceExecutionTime =
totalServiceExecutionTime + coordinationDelegateTO.getServiceExecutionTime();
totalNetworkOverheadForBusinessMessagesExchangeTime =
totalNetworkOverheadForBusinessMessagesExchangeTime
+ coordinationDelegateTO.getNetworkOverheadForBusinessMessagesExchangeTime();
totalCoordinationAlgorithmReasoningTime =
totalCoordinationAlgorithmReasoningTime
+ coordinationDelegateTO.getCoordinationAlgorithmReasoningTime();
totalNetworkOverheadForCoordinationMessagesExchangeTime =
totalNetworkOverheadForCoordinationMessagesExchangeTime
+ coordinationDelegateTO.getNetworkOverheadForCoordinationMessagesExchangeTime();
totalWaitTimeForSchedulingOperation =
totalWaitTimeForSchedulingOperation
+ coordinationDelegateTO.getWaitTimeForSchedulingOperation();
totalWaitTimeForSynchronizing =
totalWaitTimeForSynchronizing + coordinationDelegateTO.getWaitTimeForSynchronizing();
++assignments;
}
}
if (assignments > 0) {
AVGCoordinationDelegateTO aVGCoordinationDelegateTO = new AVGCoordinationDelegateTO();
aVGCoordinationDelegateTO.setChoreographyId(choreographyId);
aVGCoordinationDelegateTO.setName(cdName);
aVGCoordinationDelegateTO.setMaxExecutedOperations(maxExecutedOperations);
aVGCoordinationDelegateTO.setMinExecutedOperations(minExecutedOperations);
aVGCoordinationDelegateTO.setMaxCoordinationMessages(maxCoordinationMessages);
aVGCoordinationDelegateTO.setMinCoordinationMessages(minCoordinationMessages);
aVGCoordinationDelegateTO.setServiceExecutionTime(totalServiceExecutionTime / assignments);
aVGCoordinationDelegateTO.setNetworkOverheadForBusinessMessagesExchangeTime(
totalNetworkOverheadForBusinessMessagesExchangeTime / assignments
);
aVGCoordinationDelegateTO.setCoordinationAlgorithmReasoningTime(
totalCoordinationAlgorithmReasoningTime / assignments
);
aVGCoordinationDelegateTO.setNetworkOverheadForCoordinationMessagesExchangeTime(
totalNetworkOverheadForCoordinationMessagesExchangeTime / assignments
);
aVGCoordinationDelegateTO.setWaitTimeForSchedulingOperation(
totalWaitTimeForSchedulingOperation / assignments
);
aVGCoordinationDelegateTO.setWaitTimeForSynchronizing(totalWaitTimeForSynchronizing / assignments);
aVGCoordinationDelegateTOs.add(aVGCoordinationDelegateTO);
}
}
return aVGCoordinationDelegateTOs;
}
}
......@@ -37,6 +37,8 @@ public interface EventDAO extends DAO<Event, Long> {
List<String> findOperationsByArtifact(Long choreographyInstancePK, String artifactName);
List<String> findCdsByChoreography(Long choreographyId);
void save(Event event);
void delete(Event event);
......