EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.reliability.solver.pcm2markov]

COVERAGE SUMMARY FOR SOURCE FILE [MarkovSeffVisitor.java]

nameclass, %method, %block, %line, %
MarkovSeffVisitor.java0%   (0/1)0%   (0/34)0%   (0/2430)0%   (0/570)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MarkovSeffVisitor0%   (0/1)0%   (0/34)0%   (0/2430)0%   (0/570)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/3)
MarkovSeffVisitor (MarkovTransformationSource, ContextWrapper, List, MarkovEv... 0%   (0/1)0%   (0/30)0%   (0/10)
addFailureDescription (List, FailureDescription): void 0%   (0/1)0%   (0/37)0%   (0/15)
caseAbstractInternalControlFlowAction (AbstractInternalControlFlowAction): Ma... 0%   (0/1)0%   (0/74)0%   (0/16)
caseAcquireAction (AcquireAction): MarkovChain 0%   (0/1)0%   (0/46)0%   (0/7)
caseBranchAction (BranchAction): MarkovChain 0%   (0/1)0%   (0/228)0%   (0/44)
caseCollectionIteratorAction (CollectionIteratorAction): MarkovChain 0%   (0/1)0%   (0/125)0%   (0/26)
caseContainerAvailability (ResourceContainer): MarkovChain 0%   (0/1)0%   (0/16)0%   (0/5)
caseContainerAvailabilityForIteratedResourceStates (ResourceContainer): Marko... 0%   (0/1)0%   (0/125)0%   (0/24)
caseContainerAvailabilityForResourceState (ResourceContainer): MarkovChain 0%   (0/1)0%   (0/30)0%   (0/9)
caseExternalCallAction (ExternalCallAction): MarkovChain 0%   (0/1)0%   (0/109)0%   (0/26)
caseExternalCallActionInsideSystem (ExternalCallAction): MarkovChain 0%   (0/1)0%   (0/209)0%   (0/48)
caseExternalCallActionOutsideSystem (ExternalCallAction): MarkovChain 0%   (0/1)0%   (0/116)0%   (0/44)
caseForkAction (ForkAction): MarkovChain 0%   (0/1)0%   (0/144)0%   (0/32)
caseInternalAction (InternalAction): MarkovChain 0%   (0/1)0%   (0/54)0%   (0/10)
caseInternalActionForIteratedResourceStates (InternalAction): MarkovChain 0%   (0/1)0%   (0/124)0%   (0/22)
caseInternalActionForResourceState (InternalAction): MarkovChain 0%   (0/1)0%   (0/34)0%   (0/10)
caseLoopAction (LoopAction): MarkovChain 0%   (0/1)0%   (0/125)0%   (0/25)
caseMessageTransfer (CommunicationLinkResourceSpecification): MarkovChain 0%   (0/1)0%   (0/13)0%   (0/5)
caseReleaseAction (ReleaseAction): MarkovChain 0%   (0/1)0%   (0/46)0%   (0/7)
caseResourceDemandingBehaviour (ResourceDemandingBehaviour): MarkovChain 0%   (0/1)0%   (0/73)0%   (0/17)
caseResourceDemandingSEFF (ResourceDemandingSEFF): MarkovChain 0%   (0/1)0%   (0/109)0%   (0/21)
caseSetVariableAction (SetVariableAction): MarkovChain 0%   (0/1)0%   (0/46)0%   (0/7)
caseStartAction (StartAction): MarkovChain 0%   (0/1)0%   (0/46)0%   (0/7)
caseStopAction (StopAction): MarkovChain 0%   (0/1)0%   (0/46)0%   (0/7)
getFailureDescriptionsForCommunicationLink (CommunicationLinkResourceSpecific... 0%   (0/1)0%   (0/21)0%   (0/11)
getFailureDescriptionsForResourceState (List): List 0%   (0/1)0%   (0/59)0%   (0/17)
getFailureTypeIds (FailureHandlingEntity): List 0%   (0/1)0%   (0/62)0%   (0/18)
getInternalActionSoftwareFailureDescriptions (InternalAction): List 0%   (0/1)0%   (0/38)0%   (0/13)
getResourceDescriptors (InternalAction): List 0%   (0/1)0%   (0/52)0%   (0/16)
getResourceDescriptors (ResourceContainer, boolean): List 0%   (0/1)0%   (0/54)0%   (0/18)
getResourceStateProbability (List): double 0%   (0/1)0%   (0/23)0%   (0/5)
processRecoveryActionBehaviour (RecoveryAction, RecoveryActionBehaviour): Mar... 0%   (0/1)0%   (0/84)0%   (0/20)
setResourceState (List, long): void 0%   (0/1)0%   (0/27)0%   (0/5)

1package de.uka.ipd.sdq.reliability.solver.pcm2markov;
2 
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.List;
6 
7import org.apache.log4j.Logger;
8import org.eclipse.emf.common.util.EList;
9 
10import de.uka.ipd.sdq.markov.MarkovChain;
11import de.uka.ipd.sdq.markov.State;
12import de.uka.ipd.sdq.markov.StateType;
13import de.uka.ipd.sdq.pcm.reliability.ExternalFailureOccurrenceDescription;
14import de.uka.ipd.sdq.pcm.reliability.FailureType;
15import de.uka.ipd.sdq.pcm.reliability.HardwareInducedFailureType;
16import de.uka.ipd.sdq.pcm.reliability.InternalFailureOccurrenceDescription;
17import de.uka.ipd.sdq.pcm.reliability.NetworkInducedFailureType;
18import de.uka.ipd.sdq.pcm.reliability.SoftwareInducedFailureType;
19import de.uka.ipd.sdq.pcm.repository.Role;
20import de.uka.ipd.sdq.pcm.repository.Signature;
21import de.uka.ipd.sdq.pcm.resourceenvironment.CommunicationLinkResourceSpecification;
22import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification;
23import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer;
24import de.uka.ipd.sdq.pcm.seff.AbstractAction;
25import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition;
26import de.uka.ipd.sdq.pcm.seff.AbstractInternalControlFlowAction;
27import de.uka.ipd.sdq.pcm.seff.AcquireAction;
28import de.uka.ipd.sdq.pcm.seff.BranchAction;
29import de.uka.ipd.sdq.pcm.seff.CollectionIteratorAction;
30import de.uka.ipd.sdq.pcm.seff.ExternalCallAction;
31import de.uka.ipd.sdq.pcm.seff.ForkAction;
32import de.uka.ipd.sdq.pcm.seff.ForkedBehaviour;
33import de.uka.ipd.sdq.pcm.seff.InternalAction;
34import de.uka.ipd.sdq.pcm.seff.LoopAction;
35import de.uka.ipd.sdq.pcm.seff.ReleaseAction;
36import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour;
37import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF;
38import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification;
39import de.uka.ipd.sdq.pcm.seff.SetVariableAction;
40import de.uka.ipd.sdq.pcm.seff.StartAction;
41import de.uka.ipd.sdq.pcm.seff.StopAction;
42import de.uka.ipd.sdq.pcm.seff.SynchronisationPoint;
43import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand;
44import de.uka.ipd.sdq.pcm.seff.seff_reliability.FailureHandlingEntity;
45import de.uka.ipd.sdq.pcm.seff.seff_reliability.RecoveryAction;
46import de.uka.ipd.sdq.pcm.seff.seff_reliability.RecoveryActionBehaviour;
47import de.uka.ipd.sdq.pcm.seff.util.SeffSwitch;
48import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper;
49import de.uka.ipd.sdq.pcmsolver.visitors.EMFQueryHelper;
50import de.uka.ipd.sdq.probfunction.math.ManagedPMF;
51import de.uka.ipd.sdq.reliability.core.MarkovEvaluationType;
52import de.uka.ipd.sdq.reliability.core.MarkovHardwareInducedFailureType;
53import de.uka.ipd.sdq.reliability.core.MarkovNetworkInducedFailureType;
54import de.uka.ipd.sdq.reliability.core.MarkovSoftwareInducedFailureType;
55 
56/**
57 * This class represents a visitor for an RDSEFF within a PCM instance. The
58 * visitor is used in the transformation from PCM with solved dependencies into
59 * a Markov Chain Model for reliability prediction.
60 * 
61 * @author brosch
62 */
63public class MarkovSeffVisitor extends SeffSwitch<MarkovChain> {
64 
65        /**
66         * A logger to give detailed information about the PCM instance traversal.
67         */
68        private static Logger logger = Logger.getLogger(MarkovSeffVisitor.class
69                        .getName());
70 
71        /**
72         * The ContextWrapper provides easy access to the decorations of the solved
73         * PCM instance.
74         */
75        private ContextWrapper contextWrapper;
76 
77        /**
78         * The degree of distinction between failure types.
79         */
80        private MarkovEvaluationType evaluationType;
81 
82        /**
83         * The Markov Builder is used to create Markov Chain instances.
84         */
85        private MarkovBuilder markovBuilder;
86 
87        /**
88         * Indicates if the Markov Chain reduction is performed during the
89         * transformation. If so, then the chain as a whole never exists, because
90         * during construction, it is already reduced again.
91         */
92        private boolean optimize;
93 
94        /**
95         * The prefix list enables unique naming of all Markov states, which in turn
96         * allows to search for differences between two chains.
97         */
98        private List<String> prefixes;
99 
100        /**
101         * Indicates if the resulting Makov model shall be augmented with tracing
102         * information for diagnostic purposes.
103         */
104        private boolean recordTraces;
105 
106        /**
107         * Indicates if resource states are handled according to the simpler
108         * "always ask" strategy, which may yield less accurate results, but avoids
109         * iterating over all possible state combinations.
110         */
111        private boolean simplifiedStateHandling;
112 
113        /**
114         * A provider of information about the PCM instance and the corresponding
115         * resource descriptors.
116         */
117        private MarkovTransformationSource transformationState;
118 
119        /**
120         * The constructor.
121         * 
122         * @param transformationState
123         *            the Markov transformation state
124         * @param wrapper
125         *            the ContextWrapper provides easy access to the decorations of
126         *            the solved PCM instance
127         * @param prefixes
128         *            the list of prefixes for state names
129         * @param evaluationType
130         *            the degree of differentiation between failure types
131         * @param simplifiedStateHandling
132         *            controls the handling of physical resource states
133         * @param optimize
134         *            controls if Markov Chain reduction is performed during
135         *            transformation
136         * @param recordTraces
137         *            controls if traces shall be recorded during transformation
138         */
139        public MarkovSeffVisitor(
140                        final MarkovTransformationSource transformationState,
141                        final ContextWrapper wrapper, final List<String> prefixes,
142                        final MarkovEvaluationType evaluationType,
143                        final boolean simplifiedStateHandling, final boolean optimize,
144                        final boolean recordTraces) {
145                this.transformationState = transformationState;
146                this.contextWrapper = wrapper;
147                this.prefixes = prefixes;
148                this.evaluationType = evaluationType;
149                this.optimize = optimize;
150                this.recordTraces = recordTraces;
151                this.simplifiedStateHandling = simplifiedStateHandling;
152                this.markovBuilder = new MarkovBuilder(recordTraces);
153        }
154 
155        /**
156         * Adds a new failure description to a list of existing descriptions.
157         * 
158         * @param failureDescriptions
159         *            the list of descriptions
160         * @param newFailureDescription
161         *            the failure description to add
162         */
163        private void addFailureDescription(
164                        List<FailureDescription> failureDescriptions,
165                        FailureDescription newFailureDescription) {
166                FailureDescription existingFailureDescription = null;
167                Iterator<FailureDescription> iterator = failureDescriptions.iterator();
168                while (iterator.hasNext()) {
169                        FailureDescription comparator = iterator.next();
170                        if (newFailureDescription.getFailureType().equals(
171                                        comparator.getFailureType())) {
172                                existingFailureDescription = comparator;
173                                break;
174                        }
175                }
176                if (existingFailureDescription == null) {
177                        failureDescriptions.add(newFailureDescription);
178                } else {
179                        existingFailureDescription
180                                        .setFailureProbability(existingFailureDescription
181                                                        .getFailureProbability()
182                                                        + newFailureDescription.getFailureProbability());
183                }
184        }
185 
186        /**
187         * Handles RecoveryActions.
188         * 
189         * This is a workaround using the case for
190         * AbstractInternalControlFlowActions, because RecoveryActions are not
191         * directly contained in the SEFF package, and thus there is no case for
192         * them.
193         * 
194         * First, for each RecoveryActionBehaviour a specific Markov chain is built.
195         * Then, specific chains are appended to each other according to the
196         * specification of handled failure types.
197         * 
198         * @param controlFlowAction
199         *            the control flow action
200         * @return the resulting Markov Chain.
201         */
202        @Override
203        public MarkovChain caseAbstractInternalControlFlowAction(
204                        final AbstractInternalControlFlowAction controlFlowAction) {
205 
206                // Only consider RecoveryBlockActions:
207                if (!(controlFlowAction instanceof RecoveryAction)) {
208                        return null;
209                }
210                RecoveryAction action = (RecoveryAction) controlFlowAction;
211 
212                // Logging & naming:
213                String name = action.getEntityName() + "[" + action.getId() + "]";
214                prefixes.add(name);
215                logger.debug("Visit RecoveryAction: " + name);
216 
217                // Retrieve the list of RecoveryBlockBehaviours:
218                List<RecoveryActionBehaviour> behaviours = action
219                                .getRecoveryActionBehaviours__RecoveryAction();
220                if (behaviours.size() == 0) {
221                        throw new MarkovException("RecoveryAction '"
222                                        + action.getEntityName()
223                                        + "' does not specify any behaviours.");
224                }
225 
226                // Create the resulting Markov chain:
227                MarkovChain resultChain = processRecoveryActionBehaviour(action, action
228                                .getPrimaryBehaviour__RecoveryAction());
229 
230                // Naming:
231                prefixes.remove(prefixes.size() - 1);
232 
233                // Return the result:
234                return resultChain;
235        }
236 
237        /**
238         * An Acquire Action returns a trivial Markov Chain.
239         * 
240         * @param acquireAction
241         *            the acquire action
242         * @return the resulting Markov Chain.
243         */
244        @Override
245        public MarkovChain caseAcquireAction(final AcquireAction acquireAction) {
246 
247                // Logging & naming:
248                String name = acquireAction.getEntityName() + "["
249                                + acquireAction.getId() + "]";
250                prefixes.add(name);
251                logger.debug("Visit AcquireAction: " + name);
252 
253                // Create a Markov chain for the Acquire action:
254                MarkovChain resultChain = markovBuilder.initBasicMarkovChain(prefixes);
255 
256                // Naming:
257                prefixes.remove(prefixes.size() - 1);
258 
259                // Return the result:
260                return resultChain;
261        }
262 
263        /**
264         * For a BranchAction, first the Markov Chain of each of the transition
265         * behaviours is built. The results are then inserted into a new Markov
266         * Chain that has one State for each of the possible branches.
267         * 
268         * @param branchAction
269         *            the BranchAction
270         * @return the resulting Markov Chain
271         */
272        @Override
273        public MarkovChain caseBranchAction(final BranchAction branchAction) {
274 
275                // Logging & naming:
276                String name = branchAction.getEntityName() + "[" + branchAction.getId()
277                                + "]";
278                prefixes.add(name);
279                logger.debug("Visit BranchAction: " + name);
280 
281                // Determine the inner Markov Chains associated with the branch
282                // behaviors:
283                EList<AbstractBranchTransition> transitions = branchAction
284                                .getBranches_Branch();
285                ArrayList<MarkovChain> specificMarkovChains = new ArrayList<MarkovChain>();
286                ArrayList<Double> branchProbabilities = new ArrayList<Double>();
287                double branchProbabilitySum = 0.0;
288                for (int i = 0; i < transitions.size(); i++) {
289                        Double branchProbability = contextWrapper
290                                        .getBranchProbability(transitions.get(i));
291                        branchProbabilitySum += branchProbability;
292                        if (branchProbability > 1.0) {
293                                throw new MarkovException(
294                                                "Error in solved parametric dependencies detected: "
295                                                                + "BranchAction \""
296                                                                + branchAction.getEntityName()
297                                                                + "\" has probability " + branchProbability
298                                                                + ", which is greater than 1.0");
299                        }
300                        if (branchProbabilitySum > 1.0) {
301                                throw new MarkovException(
302                                                "Error in solved parametric dependencies detected: "
303                                                                + "Branch probabilities of BranchAction \""
304                                                                + branchAction.getEntityName()
305                                                                + "\" sum up to more than 1.0");
306                        }
307                        branchProbabilities.add(branchProbability);
308 
309                        // Handle only branches with positive branch probabilities; other
310                        // branches don't influence the reliability. Furthermore, branches
311                        // with zero probability could not be handled anyway, because the
312                        // dependency solver omits them and leaves their parametric
313                        // dependencies unsolved (see also Bug 615).
314                        if (branchProbability > 0.0) {
315                                prefixes.add(transitions.get(i).getEntityName() + "["
316                                                + transitions.get(i).getId() + "]");
317                                specificMarkovChains.add((MarkovChain) doSwitch(transitions
318                                                .get(i).getBranchBehaviour_BranchTransition()));
319                                prefixes.remove(prefixes.size() - 1);
320                        }
321                }
322 
323                // Initialize the aggregate Markov Chain representing the loop:
324                MarkovChain aggregateMarkovChain = markovBuilder.initBranchMarkovChain(
325                                prefixes, branchProbabilities);
326 
327                // Incorporate the specific MarkovChain into the aggregate one:
328                ArrayList<State> statesToReplace = new ArrayList<State>();
329                for (int i = 0; i < aggregateMarkovChain.getStates().size(); i++) {
330                        if (aggregateMarkovChain.getStates().get(i).getType().equals(
331                                        StateType.DEFAULT)) {
332                                statesToReplace.add(aggregateMarkovChain.getStates().get(i));
333                        }
334                }
335                for (int i = 0; i < statesToReplace.size(); i++) {
336                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
337                                        specificMarkovChains.get(i), statesToReplace.get(i),
338                                        optimize, false);
339                }
340 
341                // Naming:
342                prefixes.remove(prefixes.size() - 1);
343 
344                // Return the result:
345                return aggregateMarkovChain;
346        }
347 
348        /**
349         * A collection iterator action is handled the same way as an ordinary loop.
350         * 
351         * @param collectionIteratorAction
352         *            the CollectionIteratoraction
353         * @return the resulting Markov Chain
354         */
355        @Override
356        public MarkovChain caseCollectionIteratorAction(
357                        final CollectionIteratorAction collectionIteratorAction) {
358 
359                // Logging & naming:
360                String name = collectionIteratorAction.getEntityName() + "["
361                                + collectionIteratorAction.getId() + "]";
362                prefixes.add(name);
363                logger.debug("Visit CollectionIteratorAction: " + name);
364 
365                // Determine the inner Markov Chain associated with the loop behaviour:
366                ArrayList<String> prefixesCopy = new ArrayList<String>();
367                prefixesCopy.addAll(prefixes);
368                prefixes.clear();
369                MarkovChain specificMarkovChain = (MarkovChain) doSwitch(collectionIteratorAction
370                                .getBodyBehaviour_Loop());
371                prefixes.addAll(prefixesCopy);
372 
373                // Get the solved loop probability mass function:
374                ManagedPMF pmf = contextWrapper
375                                .getLoopIterations(collectionIteratorAction);
376 
377                // Initialize the aggregate Markov Chain representing the loop:
378                MarkovChain aggregateMarkovChain = markovBuilder.initLoopMarkovChain(
379                                prefixes, pmf);
380 
381                // Incorporate the specific MarkovChain into the aggregate one:
382                ArrayList<State> statesToReplace = new ArrayList<State>();
383                for (int i = 0; i < aggregateMarkovChain.getStates().size(); i++) {
384                        if (aggregateMarkovChain.getStates().get(i).getType().equals(
385                                        StateType.DEFAULT)) {
386                                statesToReplace.add(aggregateMarkovChain.getStates().get(i));
387                        }
388                }
389                for (int i = 0; i < statesToReplace.size(); i++) {
390                        markovBuilder
391                                        .incorporateMarkovChain(aggregateMarkovChain,
392                                                        specificMarkovChain, statesToReplace.get(i),
393                                                        optimize, true);
394                }
395 
396                // Naming:
397                prefixes.remove(prefixes.size() - 1);
398 
399                // Return the result:
400                return aggregateMarkovChain;
401        }
402 
403        /**
404         * Evaluates the availability of a resource container. Returns a
405         * corresponding Markov chain.
406         * 
407         * @param descriptors
408         *            the list of required resources and their states
409         * @return the resulting Markov chain
410         */
411        private MarkovChain caseContainerAvailability(
412                        final ResourceContainer container) {
413 
414                // Check for the requested type of analysis:
415                MarkovChain resultChain = null;
416                if (simplifiedStateHandling) {
417                        // Simplified state handling; iterate over all resource states like
418                        // a branch:
419                        resultChain = caseContainerAvailabilityForIteratedResourceStates(container);
420                } else {
421                        // Full state handling; container availability is evaluated
422                        // only once (for the current resource state):
423                        resultChain = caseContainerAvailabilityForResourceState(container);
424                }
425 
426                // Return the result:
427                return resultChain;
428        }
429 
430        /**
431         * Evaluates the availability of a resource container through iteration over
432         * the possible states of its required resources. Returns a corresponding
433         * Markov chain.
434         * 
435         * @param container
436         *            the resource container
437         * @return the resulting Markov chain
438         */
439        private MarkovChain caseContainerAvailabilityForIteratedResourceStates(
440                        final ResourceContainer container) {
441 
442                // Create the result chain:
443                MarkovChain resultChain;
444 
445                // Retrieve descriptors for the resources required by the container:
446                List<ProcessingResourceDescriptor> descriptors = getResourceDescriptors(
447                                container, true);
448 
449                // Create the state probabilities and specific state chains:
450                ArrayList<Double> stateProbabilities = new ArrayList<Double>();
451                ArrayList<MarkovChain> stateChains = new ArrayList<MarkovChain>();
452                ArrayList<String> prefixesCopy = new ArrayList<String>();
453                prefixesCopy.addAll(prefixes);
454                prefixes.clear();
455                for (long i = 0; i < Math.pow(2, descriptors.size()); i++) {
456                        setResourceState(descriptors, i);
457                        stateProbabilities.add(getResourceStateProbability(descriptors));
458                        stateChains
459                                        .add(caseContainerAvailabilityForResourceState(container));
460                }
461                prefixes.addAll(prefixesCopy);
462 
463                // Initialize the aggregate Markov chain representing the branch:
464                resultChain = markovBuilder.initBranchMarkovChain(prefixes,
465                                stateProbabilities);
466 
467                // Incorporate the specific Markov chains into the aggregate one:
468                ArrayList<State> statesToReplace = new ArrayList<State>();
469                for (int i = 0; i < resultChain.getStates().size(); i++) {
470                        if (resultChain.getStates().get(i).getType().equals(
471                                        StateType.DEFAULT)) {
472                                statesToReplace.add(resultChain.getStates().get(i));
473                        }
474                }
475                for (int i = 0; i < statesToReplace.size(); i++) {
476                        markovBuilder.incorporateMarkovChain(resultChain, stateChains
477                                        .get(i), statesToReplace.get(i), optimize, true);
478                }
479 
480                // Return the result:
481                return resultChain;
482        }
483 
484        /**
485         * Evaluates the availability of a resource container. Returns a
486         * corresponding Markov chain.
487         * 
488         * @param descriptors
489         *            the list of required resources and their states
490         * @return the resulting Markov chain
491         */
492        private MarkovChain caseContainerAvailabilityForResourceState(
493                        final ResourceContainer container) {
494 
495                // Retrieve the resource failure descriptions:
496                List<ProcessingResourceDescriptor> descriptors = getResourceDescriptors(
497                                container, true);
498                List<FailureDescription> failureDescriptions = getFailureDescriptionsForResourceState(descriptors);
499 
500                MarkovChain resultChain = null;
501                if (failureDescriptions.isEmpty()) {
502                        // All resource available:
503                        resultChain = markovBuilder.initBasicMarkovChain(prefixes);
504                } else {
505                        // If there are unavailable resources, build a Markov chain
506                        // that reflects each unavailable resource:
507                        resultChain = markovBuilder.initResourceFailureMarkovChain(
508                                        prefixes, failureDescriptions);
509                }
510 
511                // Return the result:
512                return resultChain;
513        }
514 
515        /**
516         * Handles an ExternalCallAction. Generates a Markov Chain of the executing
517         * behavior. The Markov Chain is generated by
518         * {@link MarkovSeffVisitor.createExternalCallActionChain}. If an retry
519         * count is set in the internal action, the chain is repeatedly appended to
520         * the main chains failure state.
521         * 
522         * @param externalCallAction
523         *            the ExternalCallAction
524         * @return the resulting Markov Chain.
525         */
526        @Override
527        public MarkovChain caseExternalCallAction(
528                        final ExternalCallAction externalCallAction) {
529 
530                // Logging & naming:
531                String name = externalCallAction.getEntityName() + "["
532                                + externalCallAction.getId() + "]";
533                prefixes.add(name);
534                logger.debug("Visit ExternalCallAction: " + name);
535 
536                // Get a reference to the executing SEFF:
537                ServiceEffectSpecification seff = contextWrapper
538                                .getNextSEFF(externalCallAction);
539 
540                // Build a specific Markov Chain depending on the type of call:
541                MarkovChain resultChain = null;
542                if (seff == null) {
543 
544                        // A system external call might fail according to
545                        // FailureOccurrenceDescriptions given as
546                        // SpecifiedReliabilityAnnotations to the system:
547                        resultChain = caseExternalCallActionOutsideSystem(externalCallAction);
548 
549                } else {
550 
551                        // If the call is not system external, build a Markov chain that
552                        // reflects the service-providing behaviour of the call:
553                        resultChain = caseExternalCallActionInsideSystem(externalCallAction);
554                }
555 
556                // If a retry policy has been specified for this external call,
557                // and if the differentiation of failure types is fine-grained enough,
558                // then reflect the failure handling behaviour accordingly:
559                if ((evaluationType != MarkovEvaluationType.SINGLE)
560                                && (evaluationType != MarkovEvaluationType.CLASSES)) {
561                        int retryCount = externalCallAction.getRetryCount();
562                        if (retryCount < 0) {
563                                logger.warn("Retry count of ExternalCallAction \""
564                                                + externalCallAction.getEntityName()
565                                                + "\" is negative. Assuming 0.");
566                                retryCount = 0;
567                        }
568                        List<String> failureTypeIds = getFailureTypeIds(externalCallAction);
569                        MarkovChain handlingChain = markovBuilder
570                                        .copyMarkovChain(resultChain);
571                        for (int i = 0; i < retryCount; ++i) {
572                                markovBuilder.appendFailureHandlingMarkovChain(resultChain,
573                                                handlingChain, failureTypeIds, optimize);
574                        }
575                }
576 
577                // Naming:
578                prefixes.remove(prefixes.size() - 1);
579 
580                // Return the result:
581                return resultChain;
582        }
583 
584        /**
585         * Evaluates an external call action that does not leave the system
586         * boundaries. Returns a corresponding Markov chain.
587         * 
588         * @param call
589         *            the ExternalCallAction
590         * @return the resulting Markov Chain.
591         */
592        private MarkovChain caseExternalCallActionInsideSystem(
593                        final ExternalCallAction call) {
594 
595                // Get a reference to the executing SEFF:
596                ServiceEffectSpecification seff = contextWrapper.getNextSEFF(call);
597 
598                // For the new SEFF, we need a new ContextWrapper. As during the
599                // creation of the new ContextWrapper, the old one is altered (which
600                // is certainly bad programming style!), we need to save a copy of
601                // the old one and restore it after generating the new one:
602                ContextWrapper originalContextWrapper = (ContextWrapper) contextWrapper
603                                .clone();
604                List<ContextWrapper> contextWrapperList = contextWrapper
605                                .getContextWrapperFor(call);
606 
607                // FIXME: The Reliability solver does not support replication yet
608                if (contextWrapperList.size() > 1) {
609                        logger
610                                        .error("The Reliability solver only supports one AllocationContext per AssemblyContext. Picking one of the called Allocation contexts for call "
611                                                        + call.getEntityName()
612                                                        + " "
613                                                        + call.getId()
614                                                        + " ignoring the others. Results will be inaccurate.");
615                } else if (contextWrapperList.size() == 0) {
616                        throw new RuntimeException(
617                                        "Internal Error: Could not create a Context Wrapper for call "
618                                                        + call.getEntityName() + " " + call.getId());
619                }
620                ContextWrapper newContextWrapper = contextWrapperList.get(0);
621                contextWrapper = originalContextWrapper;
622 
623                // Build the Markov chain of the executing SEFF:
624                MarkovChain resultChain = null;
625                MarkovChain innerMarkovChain = new MarkovSeffVisitor(
626                                this.transformationState, newContextWrapper, prefixes,
627                                evaluationType, simplifiedStateHandling, optimize, recordTraces)
628                                .doSwitch(seff);
629 
630                // Check if the external call crosses the border of one resource
631                // container and uses a communication link (if the specification
632                // of the communication link is omitted in the model, we treat
633                // the link as being perfect, i.e. never failing):
634                CommunicationLinkResourceSpecification commLink = contextWrapper
635                                .getConcreteLinkingResource(call, newContextWrapper.getAllCtx());
636 
637                // If a communication link is specified and used by the call,
638                // consider the possibility that the call fails:
639                if (commLink != null) {
640 
641                        // The call can be modeled as a behavior with three steps: the
642                        // sending of the message, the remote execution, and the message
643                        // return. All of these steps contribute a potential for failure:
644                        ArrayList<State> states = new ArrayList<State>();
645                        ArrayList<String> names = new ArrayList<String>();
646                        names.add("MessageTransfer(1)");
647                        names.add("ServiceExecution");
648                        names.add("MessageTransfer(2)");
649                        MarkovChain aggregateMarkovChain = markovBuilder
650                                        .initSequentialMarkovChain(prefixes, names, states);
651 
652                        // The first and last steps can be modeled like an Internal
653                        // Action which either fails or succeeds:
654                        prefixes.add(names.get(0));
655                        MarkovChain messagingMarkovChain = caseMessageTransfer(commLink);
656                        prefixes.remove(prefixes.size() - 1);
657                        prefixes.add(names.get(2));
658                        MarkovChain returnMarkovChain = caseMessageTransfer(commLink);
659                        prefixes.remove(prefixes.size() - 1);
660 
661                        // The second step is the already computed inner Markov Chain.
662                        // Incorporate all steps into the aggregate chain:
663                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
664                                        messagingMarkovChain, states.get(0), optimize, false);
665                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
666                                        innerMarkovChain, states.get(1), optimize, false);
667                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
668                                        returnMarkovChain, states.get(2), optimize, false);
669 
670                        // Return the result:
671                        resultChain = aggregateMarkovChain;
672 
673                } else {
674 
675                        // If the call is local, or if the specification of the
676                        // communication link has been omitted, then the Markov
677                        // Chain just has to reflect the inner SEFF behavior:
678                        resultChain = innerMarkovChain;
679                }
680 
681                // Return the result:
682                return resultChain;
683        }
684 
685        /**
686         * Evaluates an external call action that leaves the system boundaries.
687         * Returns a corresponding Markov chain.
688         * 
689         * @param externalCallAction
690         * @return the resulting Markov chain
691         */
692        private MarkovChain caseExternalCallActionOutsideSystem(
693                        final ExternalCallAction externalCallAction) {
694 
695                // Create the result chain:
696                MarkovChain resultChain;
697 
698                // Get the raw failure occurrence descriptions of the system-external
699                // call:
700                List<ExternalFailureOccurrenceDescription> rawFailureDescriptions = contextWrapper
701                                .getFailureOccurrenceDescriptionsForSystemExternalCall(externalCallAction);
702 
703                // Retrieve the failure descriptions list:
704                List<FailureDescription> resultFailureDescriptions = new ArrayList<FailureDescription>();
705                for (ExternalFailureOccurrenceDescription description : rawFailureDescriptions) {
706                        Role role = description
707                                        .getSpecifiedReliabilityAnnotation__ExternalFailureOccurrenceDescription()
708                                        .getRole_SpecifiedQoSAnnotation();
709                        Signature signature = description
710                                        .getSpecifiedReliabilityAnnotation__ExternalFailureOccurrenceDescription()
711                                        .getSignature_SpecifiedQoSAnnation();
712                        FailureType failureType = description
713                                        .getFailureType__ExternalFailureOccurrenceDescription();
714                        FailureDescription newFailureDescription = null;
715                        if (failureType instanceof SoftwareInducedFailureType) {
716                                newFailureDescription = new FailureDescription(
717                                                MarkovSoftwareInducedFailureType
718                                                                .createExternalFailureType(evaluationType,
719                                                                                failureType.getId(), signature.getId(),
720                                                                                role.getId()), description
721                                                                .getFailureProbability());
722                        } else if (failureType instanceof HardwareInducedFailureType) {
723                                newFailureDescription = new FailureDescription(
724                                                MarkovHardwareInducedFailureType
725                                                                .createExternalFailureType(
726                                                                                evaluationType,
727                                                                                ((HardwareInducedFailureType) failureType)
728                                                                                                .getProcessingResourceType__HardwareInducedFailureType()
729                                                                                                .getId(), signature.getId(),
730                                                                                role.getId()), description
731                                                                .getFailureProbability());
732                        } else if (failureType instanceof NetworkInducedFailureType) {
733                                newFailureDescription = new FailureDescription(
734                                                MarkovNetworkInducedFailureType
735                                                                .createExternalFailureType(
736                                                                                evaluationType,
737                                                                                ((NetworkInducedFailureType) failureType)
738                                                                                                .getCommunicationLinkResourceType__NetworkInducedFailureType()
739                                                                                                .getId(), signature.getId(),
740                                                                                role.getId()), description
741                                                                .getFailureProbability());
742                        }
743                        addFailureDescription(resultFailureDescriptions,
744                                        newFailureDescription);
745                }
746 
747                // Check if failure descriptions exist for the system-external call:
748                if (resultFailureDescriptions.size() > 0) {
749                        // Create a chain that reflects the existing failure descriptions:
750                        resultChain = markovBuilder.initBasicMarkovChainWithFailures(
751                                        prefixes, resultFailureDescriptions);
752                } else {
753                        // Create a basic chain:
754                        resultChain = markovBuilder.initBasicMarkovChain(prefixes);
755                }
756 
757                // Return the result:
758                return resultChain;
759        }
760 
761        /**
762         * Handles fork actions.
763         * 
764         * All forked behaviours are handled sequentially.
765         */
766        @Override
767        public MarkovChain caseForkAction(ForkAction forkAction) {
768 
769                // Logging & naming:
770                String name = forkAction.getEntityName() + "[" + forkAction.getId()
771                                + "]";
772                prefixes.add(name);
773                logger.debug("Visit ForkAction: " + name);
774 
775                // Go through the list of forked behaviours that are contained in the
776                // fork action. Each behaviour creates its own specific Markov Chain:
777                ArrayList<MarkovChain> chains = new ArrayList<MarkovChain>();
778                ArrayList<ForkedBehaviour> behaviours = new ArrayList<ForkedBehaviour>();
779                for (int i = 0; i < forkAction
780                                .getAsynchronousForkedBehaviours_ForkAction().size(); i++) {
781                        chains.add((MarkovChain) doSwitch(forkAction
782                                        .getAsynchronousForkedBehaviours_ForkAction().get(i)));
783                        behaviours.add(forkAction
784                                        .getAsynchronousForkedBehaviours_ForkAction().get(i));
785                }
786                SynchronisationPoint synch = forkAction
787                                .getSynchronisingBehaviours_ForkAction();
788                if (synch != null) {
789                        for (int i = 0; i < synch
790                                        .getSynchronousForkedBehaviours_SynchronisationPoint()
791                                        .size(); i++) {
792                                chains.add((MarkovChain) doSwitch(synch
793                                                .getSynchronousForkedBehaviours_SynchronisationPoint()
794                                                .get(i)));
795                                behaviours.add(synch
796                                                .getSynchronousForkedBehaviours_SynchronisationPoint()
797                                                .get(i));
798                        }
799                }
800 
801                // Initialize a new aggregate Markov Chain that has one state for each
802                // behaviour of the fork action:
803                ArrayList<State> states = new ArrayList<State>();
804                MarkovChain aggregateMarkovChain = markovBuilder.initForkMarkovChain(
805                                prefixes, behaviours, states);
806 
807                // Incorporate the specific Chains into the aggregate Chain:
808                for (int i = 0; i < behaviours.size(); i++) {
809                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain, chains
810                                        .get(i), states.get(i), optimize, false);
811                }
812 
813                // Naming:
814                prefixes.remove(prefixes.size() - 1);
815 
816                // Return the result:
817                return aggregateMarkovChain;
818        }
819 
820        /**
821         * An InternalAction is an actual possible point of failure, either because
822         * a software failure might happen, or because a required physical resource
823         * may be currently unavailable.
824         * 
825         * A Markov chain is returned that reflects all possible outcomes and their
826         * probabilities.
827         * 
828         * @param internalAction
829         *            the InternalAction
830         * @return the resulting Markov Chain
831         */
832        @Override
833        public MarkovChain caseInternalAction(final InternalAction internalAction) {
834 
835                // Logging & naming:
836                String name = internalAction.getEntityName() + "["
837                                + internalAction.getId() + "]";
838                prefixes.add(name);
839                logger.debug("Visit InternalAction: " + name);
840 
841                // Check for the requested type of analysis:
842                MarkovChain resultChain = null;
843                if (simplifiedStateHandling) {
844                        // Simplified state handling; iterate over all resource states like
845                        // a branch:
846                        resultChain = caseInternalActionForIteratedResourceStates(internalAction);
847                } else {
848                        // Full state handling; internal action is evaluated
849                        // only once (for the current resource state):
850                        resultChain = caseInternalActionForResourceState(internalAction);
851                }
852 
853                // Naming:
854                prefixes.remove(prefixes.size() - 1);
855 
856                // Return the result:
857                return resultChain;
858        }
859 
860        /**
861         * Evaluates an internal action through iteration over the possible states
862         * of its required resources. Returns a corresponding Markov chain.
863         * 
864         * @param internalAction
865         *            the internal action
866         * @return the resulting Markov chain
867         */
868        private MarkovChain caseInternalActionForIteratedResourceStates(
869                        final InternalAction internalAction) {
870 
871                // Create the result chain:
872                MarkovChain resultChain;
873 
874                // Retrieve descriptors for the resources required by this internal
875                // action:
876                List<ProcessingResourceDescriptor> descriptors = getResourceDescriptors(internalAction);
877 
878                // Create the state probabilities and specific state chains:
879                ArrayList<Double> stateProbabilities = new ArrayList<Double>();
880                ArrayList<MarkovChain> stateChains = new ArrayList<MarkovChain>();
881                ArrayList<String> prefixesCopy = new ArrayList<String>();
882                prefixesCopy.addAll(prefixes);
883                prefixes.clear();
884                for (long i = 0; i < Math.pow(2, descriptors.size()); i++) {
885                        setResourceState(descriptors, i);
886                        stateProbabilities.add(getResourceStateProbability(descriptors));
887                        stateChains.add(caseInternalActionForResourceState(internalAction));
888                }
889                prefixes.addAll(prefixesCopy);
890 
891                // Initialize the aggregate Markov chain representing the branch:
892                resultChain = markovBuilder.initBranchMarkovChain(prefixes,
893                                stateProbabilities);
894 
895                // Incorporate the specific Markov chains into the aggregate one:
896                ArrayList<State> statesToReplace = new ArrayList<State>();
897                for (int i = 0; i < resultChain.getStates().size(); i++) {
898                        if (resultChain.getStates().get(i).getType().equals(
899                                        StateType.DEFAULT)) {
900                                statesToReplace.add(resultChain.getStates().get(i));
901                        }
902                }
903                for (int i = 0; i < statesToReplace.size(); i++) {
904                        markovBuilder.incorporateMarkovChain(resultChain, stateChains
905                                        .get(i), statesToReplace.get(i), optimize, true);
906                }
907 
908                // Return the result:
909                return resultChain;
910        }
911 
912        /**
913         * Evaluates an internal action for one specific resource state and returns
914         * the resulting Markov chain.
915         * 
916         * @param internalAction
917         *            the internal action
918         * @return the resulting Markov chain
919         */
920        private MarkovChain caseInternalActionForResourceState(
921                        final InternalAction internalAction) {
922 
923                // Retrieve descriptors for the resources required by this internal
924                // action:
925                List<ProcessingResourceDescriptor> descriptors = getResourceDescriptors(internalAction);
926 
927                // Retrieve the resource failure descriptions:
928                List<FailureDescription> failureDescriptions = getFailureDescriptionsForResourceState(descriptors);
929 
930                MarkovChain resultChain = null;
931                if (failureDescriptions.isEmpty()) {
932 
933                        // If all required resources are available, build a Markov chain
934                        // that reflects the potential application failures:
935                        failureDescriptions = getInternalActionSoftwareFailureDescriptions(internalAction);
936 
937                        // Build the Markov chain:
938                        resultChain = markovBuilder.initBasicMarkovChainWithFailures(
939                                        prefixes, failureDescriptions);
940                } else {
941 
942                        // If there are unavailable resources, build a Markov chain
943                        // that reflects each unavailable resource:
944                        resultChain = markovBuilder.initResourceFailureMarkovChain(
945                                        prefixes, failureDescriptions);
946                }
947 
948                // Return the result:
949                return resultChain;
950        }
951 
952        /**
953         * For a LoopAction, first the Markov Chain of the body behaviour is built.
954         * The result is then inserted into a new Markov Chain that has one State
955         * for each of the possible iteration counts of the loop.
956         * 
957         * @param loopAction
958         *            the LoopAction
959         * @return the resulting Markov Chain
960         */
961        @Override
962        public MarkovChain caseLoopAction(final LoopAction loopAction) {
963 
964                // Logging & naming:
965                String name = loopAction.getEntityName() + "[" + loopAction.getId()
966                                + "]";
967                prefixes.add(name);
968                logger.debug("Visit LoopAction: " + name);
969 
970                // Determine the inner Markov Chain associated with the loop behaviour:
971                ArrayList<String> prefixesCopy = new ArrayList<String>();
972                prefixesCopy.addAll(prefixes);
973                prefixes.clear();
974                MarkovChain specificMarkovChain = (MarkovChain) doSwitch(loopAction
975                                .getBodyBehaviour_Loop());
976                prefixes.addAll(prefixesCopy);
977 
978                // Get the solved loop probability mass function:
979                ManagedPMF pmf = contextWrapper.getLoopIterations(loopAction);
980 
981                // Initialize the aggregate Markov Chain representing the loop:
982                MarkovChain aggregateMarkovChain = markovBuilder.initLoopMarkovChain(
983                                prefixes, pmf);
984 
985                // Incorporate the specific MarkovChain into the aggregate one:
986                ArrayList<State> statesToReplace = new ArrayList<State>();
987                for (int i = 0; i < aggregateMarkovChain.getStates().size(); i++) {
988                        if (aggregateMarkovChain.getStates().get(i).getType().equals(
989                                        StateType.DEFAULT)) {
990                                statesToReplace.add(aggregateMarkovChain.getStates().get(i));
991                        }
992                }
993                for (int i = 0; i < statesToReplace.size(); i++) {
994                        markovBuilder
995                                        .incorporateMarkovChain(aggregateMarkovChain,
996                                                        specificMarkovChain, statesToReplace.get(i),
997                                                        optimize, true);
998                }
999 
1000                // Naming:
1001                prefixes.remove(prefixes.size() - 1);
1002 
1003                // Return the result:
1004                return aggregateMarkovChain;
1005        }
1006 
1007        /**
1008         * Evaluates a message transfer over a communication link. Returns a
1009         * corresponding Markov chain.
1010         * 
1011         * @param commLink
1012         *            the communication link
1013         * @return the resulting Markov chain
1014         */
1015        private MarkovChain caseMessageTransfer(
1016                        CommunicationLinkResourceSpecification commLink) {
1017                List<FailureDescription> commFailureDescriptions = getFailureDescriptionsForCommunicationLink(commLink);
1018                MarkovChain messagingMarkovChain = markovBuilder
1019                                .initBasicMarkovChainWithFailures(prefixes,
1020                                                commFailureDescriptions);
1021                return messagingMarkovChain;
1022        }
1023 
1024        /**
1025         * A Release Action returns a trivial Markov Chain.
1026         * 
1027         * @param releaseAction
1028         *            the release action
1029         * @return the resulting Markov Chain.
1030         */
1031        @Override
1032        public MarkovChain caseReleaseAction(final ReleaseAction releaseAction) {
1033 
1034                // Logging & naming:
1035                String name = releaseAction.getEntityName() + "["
1036                                + releaseAction.getId() + "]";
1037                prefixes.add(name);
1038                logger.debug("Visit ReleaseAction: " + name);
1039 
1040                // Create a Markov chain for the Release action:
1041                MarkovChain resultChain = markovBuilder.initBasicMarkovChain(prefixes);
1042 
1043                // Naming:
1044                prefixes.remove(prefixes.size() - 1);
1045 
1046                // Return the result:
1047                return resultChain;
1048        }
1049 
1050        /**
1051         * Evaluates a resource demanding behaviour by considering all actions in
1052         * the behaviour. Returns a corresponding Markov chain.
1053         * 
1054         * @param behaviour
1055         *            the ResourceDemandingBehaviour
1056         * @return the resulting Markov Chain
1057         */
1058        @Override
1059        public MarkovChain caseResourceDemandingBehaviour(
1060                        final ResourceDemandingBehaviour behaviour) {
1061 
1062                // Logging & naming:
1063                logger.debug("Visit ResourceDemandingBehaviour");
1064 
1065                // Go through the chain of actions that constitute this Behaviour. Each
1066                // action is expected to create its own specific Markov Chain:
1067                ArrayList<AbstractAction> actions = new ArrayList<AbstractAction>();
1068                ArrayList<MarkovChain> chains = new ArrayList<MarkovChain>();
1069                AbstractAction action = (StartAction) EMFQueryHelper.getObjectByType(
1070                                behaviour.getSteps_Behaviour(), StartAction.class);
1071                while (action != null) {
1072                        MarkovChain specificMarkovChain = (MarkovChain) doSwitch(action);
1073                        actions.add(action);
1074                        chains.add(specificMarkovChain);
1075                        action = action.getSuccessor_AbstractAction();
1076                }
1077 
1078                // Initialize a new aggregate Markov Chain that has one state for each
1079                // action of the action chain:
1080                ArrayList<State> states = new ArrayList<State>();
1081                MarkovChain aggregateMarkovChain = markovBuilder
1082                                .initBehaviourMarkovChainByAction(prefixes, actions, states);
1083 
1084                // Incorporate the specific Chains into the aggregate Chain:
1085                for (int i = 0; i < actions.size(); i++) {
1086                        markovBuilder.incorporateMarkovChain(aggregateMarkovChain, chains
1087                                        .get(i), states.get(i), optimize, false);
1088                }
1089 
1090                // Return the resulting Markov Chain:
1091                return aggregateMarkovChain;
1092        }
1093 
1094        /**
1095         * Evaluates a resource demanding SEFF. In addition to the behavioural
1096         * evaluation, also the availability of the executing resource container is
1097         * checked. Returns a corresponding Markov chain.
1098         * 
1099         * @param seff
1100         *            the ResourceDemandingSEFF
1101         * @return the resulting Markov Chain
1102         */
1103        @Override
1104        public MarkovChain caseResourceDemandingSEFF(
1105                        final ResourceDemandingSEFF seff) {
1106 
1107                // Logging & naming:
1108                logger.debug("Visit ResourceDemandingSEFF: [" + seff.getId() + "]");
1109 
1110                // Consider both the execution of the SEFF itself and the possibility
1111                // that the executing resource container is unavailable:
1112                ArrayList<State> states = new ArrayList<State>();
1113                ArrayList<String> names = new ArrayList<String>();
1114                names.add("ContainerAvailability");
1115                names.add("ServiceExecution");
1116                MarkovChain aggregateMarkovChain = markovBuilder
1117                                .initSequentialMarkovChain(prefixes, names, states);
1118 
1119                // Model both aspects with an own specific Markov chain:
1120                prefixes.add(names.get(0));
1121                ResourceContainer container = contextWrapper.getAllCtx()
1122                                .getResourceContainer_AllocationContext();
1123                MarkovChain containerAvailabilityMarkovChain = caseContainerAvailability(container);
1124                prefixes.remove(prefixes.size() - 1);
1125                prefixes.add(names.get(1));
1126                MarkovChain innerMarkovChain = caseResourceDemandingBehaviour(seff);
1127                prefixes.remove(prefixes.size() - 1);
1128 
1129                // Incorporate all steps into the aggregate chain:
1130                markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
1131                                containerAvailabilityMarkovChain, states.get(0), optimize,
1132                                false);
1133                markovBuilder.incorporateMarkovChain(aggregateMarkovChain,
1134                                innerMarkovChain, states.get(1), optimize, false);
1135 
1136                // Return the result:
1137                return aggregateMarkovChain;
1138        }
1139 
1140        /**
1141         * A SetVariableAction returns a trivial Markov Chain.
1142         * 
1143         * @param setVariableAction
1144         *            the SetVariableAction
1145         * @return the resulting Markov Chain
1146         */
1147        @Override
1148        public MarkovChain caseSetVariableAction(
1149                        final SetVariableAction setVariableAction) {
1150 
1151                // Logging & naming:
1152                String name = setVariableAction.getEntityName() + "["
1153                                + setVariableAction.getId() + "]";
1154                prefixes.add(name);
1155                logger.debug("Visit SetVariableAction: " + name);
1156 
1157                // Build the Markov chain for the SetVariable action:
1158                MarkovChain resultChain = markovBuilder.initBasicMarkovChain(prefixes);
1159 
1160                // Naming:
1161                prefixes.remove(prefixes.size() - 1);
1162 
1163                // Return the result:
1164                return resultChain;
1165        }
1166 
1167        /**
1168         * A StartAction returns a trivial Markov Chain.
1169         * 
1170         * @param startAction
1171         *            the StartAction
1172         * @return the resulting trivial Markov Chain
1173         */
1174        @Override
1175        public MarkovChain caseStartAction(final StartAction startAction) {
1176 
1177                // Logging & naming:
1178                String name = startAction.getEntityName() + "[" + startAction.getId()
1179                                + "]";
1180                prefixes.add(name);
1181                logger.debug("Visit StartAction: " + name);
1182 
1183                // Build the Markov chain for the Start action:
1184                MarkovChain resultChain = markovBuilder.initBasicMarkovChain(prefixes);
1185 
1186                // Naming:
1187                prefixes.remove(prefixes.size() - 1);
1188 
1189                // Return the result:
1190                return resultChain;
1191        }
1192 
1193        /**
1194         * A StopAction returns a trivial Markov Chain.
1195         * 
1196         * @param stopAction
1197         *            the StopAction
1198         * @return the resulting trivial Markov Chain
1199         */
1200        @Override
1201        public MarkovChain caseStopAction(final StopAction stopAction) {
1202 
1203                // Logging & naming:
1204                String name = stopAction.getEntityName() + "[" + stopAction.getId()
1205                                + "]";
1206                prefixes.add(name);
1207                logger.debug("Visit StopAction: " + name);
1208 
1209                // Build the Markov chain for the Stop action:
1210                MarkovChain resultChain = markovBuilder.initBasicMarkovChain(prefixes);
1211 
1212                // Naming:
1213                prefixes.remove(prefixes.size() - 1);
1214 
1215                // Return the result:
1216                return resultChain;
1217        }
1218 
1219        /**
1220         * Retrieves a list of failureDescriptions for a communication link.
1221         * 
1222         * @param commLink
1223         *            the communication link
1224         * @return the list of failure descriptions
1225         */
1226        private List<FailureDescription> getFailureDescriptionsForCommunicationLink(
1227                        CommunicationLinkResourceSpecification commLink) {
1228                List<FailureDescription> commFailureDescriptions = new ArrayList<FailureDescription>();
1229                commFailureDescriptions
1230                                .add(new FailureDescription(
1231                                                MarkovNetworkInducedFailureType
1232                                                                .createInternalFailureType(
1233                                                                                evaluationType,
1234                                                                                commLink
1235                                                                                                .getLinkingResource_CommunicationLinkResourceSpecification(),
1236                                                                                commLink
1237                                                                                                .getCommunicationLinkResourceType_CommunicationLinkResourceSpecification()),
1238                                                commLink.getFailureProbability()));
1239                return commFailureDescriptions;
1240        }
1241 
1242        /**
1243         * Retrieves a list of failure descriptions for resource unavailability
1244         * failures under a given resource state.
1245         * 
1246         * @param descriptors
1247         *            the list of resources and their states
1248         * @return the list of failure descriptions
1249         */
1250        private List<FailureDescription> getFailureDescriptionsForResourceState(
1251                        final List<ProcessingResourceDescriptor> descriptors) {
1252 
1253                // List all possible unavailability failures:
1254                List<FailureDescription> failureDescriptions = new ArrayList<FailureDescription>();
1255                FailureDescription newFailureDescription = null;
1256 
1257                // Check if any of the resources is unavailable:
1258                for (ProcessingResourceDescriptor descriptor : descriptors) {
1259 
1260                        // Get the current state of the resource:
1261                        MarkovResourceState state = descriptor.getCurrentState();
1262                        if (state == null) {
1263                                logger.error("Resource state no set for "
1264                                                + descriptor.getType().getName()
1265                                                + " resource demand. Assume resource state = OK.");
1266                                continue;
1267                        }
1268 
1269                        // If the resource is unavailable, create a corresponding
1270                        // failure description:
1271                        if (state.equals(MarkovResourceState.NA)) {
1272                                newFailureDescription = new FailureDescription(
1273                                                MarkovHardwareInducedFailureType
1274                                                                .createInternalFailureType(evaluationType,
1275                                                                                descriptor.getResourceContainerId(),
1276                                                                                descriptor.getType().getId()), 1.0);
1277                                addFailureDescription(failureDescriptions,
1278                                                newFailureDescription);
1279                        }
1280                }
1281 
1282                // Return the result:
1283                return failureDescriptions;
1284        }
1285 
1286        /**
1287         * Returns the ids of the failure types that a given failure handling entity
1288         * can handle.
1289         * 
1290         * @param entity
1291         *            the failure handling entity
1292         * @return the list of failure type names
1293         */
1294        private List<String> getFailureTypeIds(final FailureHandlingEntity entity) {
1295                List<String> failureTypes = new ArrayList<String>();
1296                for (FailureType failureType : entity
1297                                .getFailureTypes_FailureHandlingEntity()) {
1298                        if (failureType instanceof SoftwareInducedFailureType) {
1299                                failureTypes.add(failureType.getId());
1300                        } else if (failureType instanceof HardwareInducedFailureType) {
1301                                failureTypes
1302                                                .add(((HardwareInducedFailureType) failureType)
1303                                                                .getProcessingResourceType__HardwareInducedFailureType()
1304                                                                .getId());
1305                        } else if (failureType instanceof NetworkInducedFailureType) {
1306                                failureTypes
1307                                                .add(((NetworkInducedFailureType) failureType)
1308                                                                .getCommunicationLinkResourceType__NetworkInducedFailureType()
1309                                                                .getId());
1310                        } else {
1311                                throw new MarkovException("Unsupported failure type "
1312                                                + failureType.getClass().getName());
1313                        }
1314                }
1315 
1316                return failureTypes;
1317        }
1318 
1319        /**
1320         * Retrieves a list of software failure descriptions for a given internal
1321         * action.
1322         * 
1323         * @param internalAction
1324         *            the internal action
1325         * @return the list of software failure descriptions
1326         */
1327        private List<FailureDescription> getInternalActionSoftwareFailureDescriptions(
1328                        final InternalAction internalAction) {
1329 
1330                // List all possible software failures:
1331                List<FailureDescription> failureDescriptions = new ArrayList<FailureDescription>();
1332                FailureDescription newFailureDescription = null;
1333 
1334                // Go through all failure occurrence descriptions of the internal
1335                // action:
1336                for (InternalFailureOccurrenceDescription description : internalAction
1337                                .getInternalFailureOccurrenceDescriptions__InternalAction()) {
1338                        newFailureDescription = new FailureDescription(
1339                                        MarkovSoftwareInducedFailureType
1340                                                        .createInternalFailureType(
1341                                                                        evaluationType,
1342                                                                        description
1343                                                                                        .getSoftwareInducedFailureType__InternalFailureOccurrenceDescription()
1344                                                                                        .getId(), internalAction.getId()),
1345                                        description.getFailureProbability());
1346                        addFailureDescription(failureDescriptions, newFailureDescription);
1347                }
1348 
1349                // Return the result:
1350                return failureDescriptions;
1351        }
1352 
1353        /**
1354         * Retrieves the list of required physical resources of a given internal
1355         * action.
1356         * 
1357         * @param internalAction
1358         *            the internal action
1359         * @return the resulting list of resources
1360         */
1361        private List<ProcessingResourceDescriptor> getResourceDescriptors(
1362                        final InternalAction internalAction) {
1363 
1364                // Create the resource list:
1365                ArrayList<ProcessingResourceDescriptor> resultList = new ArrayList<ProcessingResourceDescriptor>();
1366 
1367                // Go through the list of resource demands:
1368                for (ParametricResourceDemand demand : internalAction
1369                                .getResourceDemand_Action()) {
1370 
1371                        // Special case: ignore resource demands of type
1372                        // "SystemExternalResource", as they have been internally introduced
1373                        // by the dependency solver:
1374                        if (demand.getRequiredResource_ParametricResourceDemand()
1375                                        .getEntityName().equals("SystemExternalResource")) {
1376                                continue;
1377                        }
1378 
1379                        // Get the descriptor that corresponds to the demand:
1380                        ProcessingResourceDescriptor descriptor = transformationState
1381                                        .getDescriptor(demand, contextWrapper);
1382                        if (descriptor == null) {
1383                                logger.error("Missing resource description for "
1384                                                + demand.getRequiredResource_ParametricResourceDemand()
1385                                                                .getEntityName()
1386                                                + " resource demand. Assume resource state = OK.");
1387                                continue;
1388                        }
1389 
1390                        // Add the descriptor to the list:
1391                        resultList.add(descriptor);
1392                }
1393 
1394                // Return the result:
1395                return resultList;
1396        }
1397 
1398        /**
1399         * Retrieves the list of physical resources contained within the given
1400         * resource container.
1401         * 
1402         * @param resourceContainer
1403         *            the resource container
1404         * @param searchForRequiredResources
1405         *            if set to TRUE, only the resources required by this container
1406         *            will be returned
1407         * @return the resulting list of resources
1408         */
1409        private List<ProcessingResourceDescriptor> getResourceDescriptors(
1410                        final ResourceContainer resourceContainer,
1411                        final boolean searchForRequiredResources) {
1412 
1413                // Create the resource list:
1414                ArrayList<ProcessingResourceDescriptor> resultList = new ArrayList<ProcessingResourceDescriptor>();
1415 
1416                // Go through the list of specified resources:
1417                for (ProcessingResourceSpecification resource : resourceContainer
1418                                .getActiveResourceSpecifications_ResourceContainer()) {
1419 
1420                        // Check if this is a required resource:
1421                        if (searchForRequiredResources && !resource.isRequiredByContainer()) {
1422                                continue;
1423                        }
1424 
1425                        // Get the descriptor that corresponds to the specified resource:
1426                        ProcessingResourceDescriptor descriptor = transformationState
1427                                        .getDescriptor(resource);
1428                        if (descriptor == null) {
1429                                logger
1430                                                .error("Missing resource description for resource "
1431                                                                + resource
1432                                                                                .getActiveResourceType_ActiveResourceSpecification()
1433                                                                                .getEntityName() + " in container "
1434                                                                + resourceContainer.getEntityName()
1435                                                                + ". Assume resource state = OK.");
1436                                continue;
1437                        }
1438 
1439                        // Add the descriptor to the list:
1440                        resultList.add(descriptor);
1441                }
1442 
1443                // Return the result:
1444                return resultList;
1445        }
1446 
1447        /**
1448         * Retrieves the probability of a certain resource state.
1449         * 
1450         * @param descriptors
1451         *            the list of resources
1452         * @return the state probability
1453         */
1454        private double getResourceStateProbability(
1455                        List<ProcessingResourceDescriptor> descriptors) {
1456                // All single resource states are independent; hence, the
1457                // overall state probability is the product over all single
1458                // state probabilities:
1459                double stateProbability = 1.0;
1460                for (ProcessingResourceDescriptor descriptor : descriptors) {
1461                        stateProbability *= descriptor.getStateProbability(descriptor
1462                                        .getCurrentState());
1463                }
1464                return stateProbability;
1465        }
1466 
1467        /**
1468         * Returns a Markov chain that reflects a recovery action behaviour
1469         * including its failure handling alternatives.
1470         * 
1471         * @param action
1472         *            the surrounding recovery block action
1473         * @param behaviour
1474         *            the behaviour to evaluate
1475         * @return the resulting Markov chain
1476         */
1477        private MarkovChain processRecoveryActionBehaviour(RecoveryAction action,
1478                        RecoveryActionBehaviour behaviour) {
1479 
1480                // Step 1: evaluate the behaviour itself:
1481                prefixes.add("Alternative("
1482                                + action.getRecoveryActionBehaviours__RecoveryAction().indexOf(
1483                                                behaviour) + ")");
1484                MarkovChain resultChain = caseResourceDemandingBehaviour(behaviour);
1485                prefixes.remove(prefixes.size() - 1);
1486 
1487                // Step 2: consider any existing failure handling alternatives if
1488                // the differentiation of failure types is fine-grained enough:
1489                if ((evaluationType != MarkovEvaluationType.SINGLE)
1490                                && (evaluationType != MarkovEvaluationType.CLASSES)
1491                                && (behaviour
1492                                                .getFailureHandlingAlternatives__RecoveryActionBehaviour()
1493                                                .size() > 0)) {
1494 
1495                        // Determine the chains and handled failure types of the
1496                        // alternatives:
1497                        List<MarkovChain> failureHandlingChains = new ArrayList<MarkovChain>();
1498                        List<List<String>> failureTypeLists = new ArrayList<List<String>>();
1499                        for (RecoveryActionBehaviour handlingAlternative : behaviour
1500                                        .getFailureHandlingAlternatives__RecoveryActionBehaviour()) {
1501                                failureTypeLists.add(getFailureTypeIds(handlingAlternative));
1502                                failureHandlingChains.add(processRecoveryActionBehaviour(
1503                                                action, handlingAlternative));
1504                        }
1505 
1506                        // Append the handling alternatives to the current chain:
1507                        markovBuilder.appendFailureHandlingMarkovChains(resultChain,
1508                                        failureHandlingChains, failureTypeLists, optimize);
1509                }
1510 
1511                // Step 3: return the result:
1512                return resultChain;
1513        }
1514 
1515        /**
1516         * Sets a resource state according to the bit pattern of an numeric value.
1517         * 
1518         * @param descriptors
1519         *            the list of resources
1520         * @param number
1521         *            the numeric value
1522         */
1523        private void setResourceState(
1524                        final List<ProcessingResourceDescriptor> descriptors,
1525                        final long number) {
1526 
1527                // Iterate over all resources:
1528                for (int i = 0; i < descriptors.size(); i++) {
1529                        MarkovResourceState state = (((number >> i) % 2) == 0) ? MarkovResourceState.OK
1530                                        : MarkovResourceState.NA;
1531                        descriptors.get(i).setCurrentState(state);
1532                }
1533        }
1534 
1535}

[all classes][de.uka.ipd.sdq.reliability.solver.pcm2markov]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov