diff --git a/plugins/mobius/org.polarsys.chess.mobius/transformations/CHESS2SAN.qvto b/plugins/mobius/org.polarsys.chess.mobius/transformations/CHESS2SAN.qvto index 7cc8e0a61cf1c5a9b55954e50422b69c90609d3b..5a67b381f6d2bd43874bfc32559830d0dd27dd2f 100644 --- a/plugins/mobius/org.polarsys.chess.mobius/transformations/CHESS2SAN.qvto +++ b/plugins/mobius/org.polarsys.chess.mobius/transformations/CHESS2SAN.qvto @@ -49,6 +49,8 @@ property rootComponent : Class; property rootComponentInstance : InstanceSpecification; property umlInstancesConnectors : Set(UML::InstanceSpecification) = Set{}; --Instances of connectors property umlAtomicInstances : Set(UML::InstanceSpecification) = Set{}; --Instances of terminal instances +property instancePackage : Package; + property sbaTransitions : Sequence(OclAny) = Sequence{CHESS::ThreatsPropagation::Failure, CHESS::ThreatsPropagation::InternalPropagation, CHESS::ThreatsPropagation::InternalFault}; @@ -65,7 +67,7 @@ property attackScenarioCurrentStartPlace : SAN::Place; main() { this.model := source.rootObjects()![Model]; - var selectedInstSpec : Package = model.findElementByQualifiedName(selectedPlatformQName).oclAsType(Package); + instancePackage := model.findElementByQualifiedName(selectedPlatformQName).oclAsType(Package); log ("analysis context: " + analysisContextQName); analysisContext := model.findElementByQualifiedName(analysisContextQName).oclAsType(Class); @@ -74,10 +76,10 @@ main() { analysisContext.initAttackScenario(); analysisContext.initRewards(); - this.rootComponentInstance := selectedInstSpec.ownedElement[InstanceSpecification]-> - selectOne(name = selectedInstSpec.name.substringBefore("_instSpec")); - this.rootComponent := selectedInstSpec.ownedElement[InstanceSpecification]-> - selectOne(name = selectedInstSpec.name.substringBefore("_instSpec")).classifier![Class]; + this.rootComponentInstance := instancePackage.ownedElement[InstanceSpecification]-> + selectOne(name = instancePackage.name.substringBefore("_instSpec")); + this.rootComponent := instancePackage.ownedElement[InstanceSpecification]-> + selectOne(name = instancePackage.name.substringBefore("_instSpec")).classifier![Class]; //this.rootComponent.ownedComment += object Comment {body := "hello CHESS"; annotatedElement += rootComponent;}; //this.rootComponent.UmlComponent2SANnode(); var sanModel := this.rootComponentInstance.map UMLInstance2SANModel(); @@ -87,7 +89,7 @@ main() { //failure propagation //retrieve the set of connector instances - var instances : Set(UML::Element) = selectedInstSpec.ownedElement->select(i | i.oclIsKindOf(InstanceSpecification)); + var instances : Set(UML::Element) = instancePackage.ownedElement->select(i | i.oclIsKindOf(InstanceSpecification)); --log ("found instances"+ instances->size().toString()); @@ -1485,18 +1487,45 @@ query UML::Class::initAttackScenario(){ } -//TODO use AnalysisContext.??? property + query UML::Class::initRewards(){ var analysis : CHESS::StateBasedAnalysis::CyberSecurityAnalysis := self.getStereotypeApplication(CYBERSECURITYANALYSIS_STEREOTYPE).oclAsType(CHESS::StateBasedAnalysis::CyberSecurityAnalysis); - this.rewardStates := analysis.context; - //TODO here I just copy the name of the state from the analysis context...for each state, I should check that it exist actually in the model + analysis.context-> forEach (reward){ + if (reward.toString().startsWith('*.')){ //support for wildcard, e.g. *.ErrorState ->all instances having ErorState are interested by the reward + var stateName := reward.toString().substring(3, reward.toString().size()); + //check all errorModel instances + var children := getAllErrorModelBehaviourInstance(); + var errorModel : UML::StateMachine; + children -> forEach(child){ + log ("CHECKING instance " + child.name); + errorModel := child.getErrorModel(); + //if (errorModel != null and not errorModel->oclIsInvalid()){ //this is actually guaranteed + var vertexes := errorModel.region->asSequence()->first().oclAsType(UML::Region).subvertex; + vertexes ->forEach(vertex){ + if (vertex.name = stateName){ + this.rewardStates += child.name+"."+vertex.oclAsType(UML::State).name; + } + } + //} + } + }else{ + //TODO here I just copy the name of the state from the analysis context...for each state, I should check that it exist actually in the model + //Assumption: reward = <instance name>.<error model state name> + this.rewardStates+=reward; + } + }; this.rewardStates -> forEach(state){ - log("rewards state: " + state); + log("reward states of interest: " + state); }; } +query getAllErrorModelBehaviourInstance() : Set(UML::InstanceSpecification){ + var set := instancePackage.ownedElement->selectByKind(InstanceSpecification)->select(i:InstanceSpecification | not (i->oclAsType(UML::InstanceSpecification).getErrorModel()=null)); + return set; +} + //returns the UML Messages associated (through vulnerability) to transition query UML::Transition::getAttackMessages() : Set(UML::Message){