blob: e55a1c3190cf4759ba10d1f7f3bc1f098587e1a3 [file] [log] [blame]
/*******************************************************************************
*
* Copyright (C) 2011-2016
* Mälardalen University, Sweden
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License
* v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*******************************************************************************/
import CommonUtilities;
modeltype Chess uses 'http://CHESS';
modeltype MXML uses 'http://www.mdh.se/concerto/monitoring/xml/monitoringxml';
modeltype UML uses 'http://www.eclipse.org/uml2/5.0.0/UML';
modeltype GQAM uses "http://www.eclipse.org/papyrus/GQAM/1";
modeltype SAM uses "http://www.eclipse.org/papyrus/SAM/1";
modeltype ECORE uses "http://www.eclipse.org/emf/2002/Ecore";
transformation MonitoringXML2Chess(in source : MXML, inout target : Chess);
property selectedAnalysisContext : Class;
property model : Model;
property chessRootPSM : Package;
property mxmlRoot : MXML::Monitoring;
main() {
this.mxmlRoot := source.rootObjects()![MXML::Monitoring];
var rtAnalysisContext : String := mxmlRoot.analysisContext.name;
this.model := target.rootObjects()![Model];
this.selectedAnalysisContext := model.findElementByQualifiedName(rtAnalysisContext).oclAsType(Class);
var psmView : Package = model.getView("PSMView").oclAsType(Package);
this.chessRootPSM := psmView.getCodeGenerationSA(selectedAnalysisContext.name);
log("Backpropagating monitored values to " + chessRootPSM.name);
mxmlRoot.ThreadNames.propagateMonitoredThread2Chess();
mxmlRoot.SharedResources.propagateMonitoredResources2Chess();
log("Backpropagation completed.");
}
query MXML::Thread::propagateMonitoredThread2Chess() {
var schedRes : Class := self.getSchedulableResource(chessRootPSM);
var e2eFlow : UML::Activity := chessRootPSM.getSaEndtoEndFlow(schedRes);
log("Backpropagating "+self.name+" task data...");
self.period.propagatePeriod2ArrivalPattern(e2eFlow);
self.executiontime.propagateExecutionTime2ExecTime(e2eFlow);
self.responsetime.propagateResponseTime2Latency(e2eFlow);
self.blockingtime.propagateBlockingTime2BlockT(e2eFlow);
}
query MXML::Resource::propagateMonitoredResources2Chess() {
// TO BE IMPLEMENTED ACCORDINGLY
}
//NOTE: The ArrivalPattern is written into the model as a plain string
query MXML::Period::propagatePeriod2ArrivalPattern(e2eFlow : UML::Activity) {
var iNode := e2eFlow.ownedElement -> selectOne(initial | initial.oclIsTypeOf(InitialNode));
var gaWorkload := iNode.getStereotypeApplications() -> selectByType(GQAM::GaWorkloadEvent) -> asOrderedSet() -> first().oclAsType(GQAM::GaWorkloadEvent);
gaWorkload.pattern := "SporadicPattern(minInterarrival=(value="+self.minimum.value.toString()+", unit="+self.minimum.unit+"), "+
"maxInterarrival=(value="+self.maximum.value.toString()+", unit="+self.maximum.unit+"), "+
"avgInterarrival=(value="+self.average.value.toString()+", unit="+self.average.unit+"), "+
"jitter=(value="+self.jitter.value.toString()+", unit="+self.jitter.unit+"))";
}
//NOTE: The ExecutionTime is written into the model as a plain string
query MXML::ExecutionTime::propagateExecutionTime2ExecTime(e2eFlow : UML::Activity) {
var sStep := e2eFlow.ownedElement -> selectOne(saStepNode | saStepNode.oclIsTypeOf(UML::OpaqueAction) and saStepNode.isStereotyped("MARTE::MARTE_AnalysisModel::SAM::SaStep"));
var saStep := sStep.getStereotypeApplications() -> selectByType(SAM::SaStep) -> asOrderedSet() -> first().oclAsType(SAM::SaStep);
saStep.execTime := "(best="+self.minimum.value.toString()+", unit="+self.minimum.unit+", "+
"worst="+self.maximum.value.toString()+", unit="+self.maximum.unit+", "+
"average="+self.average.value.toString()+", unit="+self.average.unit+")";
}
//NOTE: The ResponseTime is written into the model as a plain string
query MXML::ResponseTime::propagateResponseTime2Latency(e2eFlow : UML::Activity) {
var latEl := e2eFlow.ownedElement -> selectOne(gaL | gaL.isStereotyped("MARTE::MARTE_AnalysisModel::GQAM::GaLatencyObs"));
var latencyEl := latEl.getStereotypeApplications() -> selectByType(GQAM::GaLatencyObs) -> asOrderedSet() -> first().oclAsType(GQAM::GaLatencyObs);
log("propagateResponseTime2Latency max="+self.maximum.value.toString());
latencyEl.latency := "(best="+self.minimum.value.toString()+", unit="+self.minimum.unit+", "+
"worst="+self.maximum.value.toString()+", unit="+self.maximum.unit+", "+
"average="+self.average.value.toString()+", unit="+self.average.unit+")";
latencyEl.maxJitter := "(value="+self.jitter.value.toString()+", unit="+self.jitter.unit+")";
}
//NOTE: The BlockingTime is written into the model as a plain string
query MXML::BlockingTime::propagateBlockingTime2BlockT(e2eFlow : UML::Activity) {
var sStep := e2eFlow.ownedElement -> selectOne(saStepNode | saStepNode.oclIsTypeOf(UML::OpaqueAction) and saStepNode.isStereotyped("MARTE::MARTE_AnalysisModel::SAM::SaStep"));
var saStep := sStep.getStereotypeApplications() -> selectByType(SAM::SaStep) -> asOrderedSet() -> first().oclAsType(SAM::SaStep);
saStep.blockT := "(best="+self.minimum.value.toString()+", unit="+self.minimum.unit+", "+
"worst="+self.maximum.value.toString()+", unit="+self.maximum.unit+", "+
"average="+self.average.value.toString()+", unit="+self.average.unit+")";
}
query Package::getCodeGenerationSA(saContextName : String) : Package {
var seq := self.packagedElement[Package]-> union(self.packagedElement[Package].packagedElement[Package]);
return seq -> selectOne(p | p.isStereotyped("CHESS::Core::PSMPackage") and p.name = saContextName + "_PSM");
}
//NOTE: Search for a match in the collection of Schedulable Resources in the Task subpackage and return the classifier
query MXML::Thread::getSchedulableResource(acPSM : Package) : UML::Class {
var ac := acPSM.packagedElement[Class]-> union(acPSM.packagedElement[Package].packagedElement[Class]);
return ac -> selectOne(sr | sr.name = self.name+"_task").oclAsType(Class);
}
query Package::getSaEndtoEndFlow(schedRes : Class) : UML::Activity {
var ac := self.packagedElement[Package]-> union(self.packagedElement[Package].packagedElement[Package]);
var actx := ac -> selectOne(p | p.name = "AnalysisContext").oclAsType(Package);
var saClass : Class := actx.packagedElement[Class] -> selectOne(saCl | saCl.isStereotyped("MARTE::MARTE_AnalysisModel::SAM::SaAnalysisContext")).oclAsType(Class);
saClass.ownedElement[OpaqueAction]-> union(saClass.ownedElement[Activity].ownedElement[OpaqueAction]) -> forEach(a | a.isStereotyped("MARTE::MARTE_AnalysisModel::SAM::SaStep")) {
var saStep := a.getStereotypeApplications() -> selectByType(SAM::SaStep) -> asOrderedSet() -> first().oclAsType(SAM::SaStep);
if saStep.concurRes.base_Classifier = schedRes then return a.owner.oclAsType(UML::Activity) endif;
};
return null;
}