1 | package de.uka.ipd.sdq.reliability.solver.sensitivity; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.List; |
5 | |
6 | import org.eclipse.emf.common.util.BasicEList; |
7 | import org.eclipse.emf.common.util.EList; |
8 | import org.eclipse.emf.ecore.EObject; |
9 | |
10 | import de.uka.ipd.sdq.pcm.reliability.InternalFailureOccurrenceDescription; |
11 | import de.uka.ipd.sdq.pcm.repository.BasicComponent; |
12 | import de.uka.ipd.sdq.pcm.repository.Repository; |
13 | import de.uka.ipd.sdq.pcm.repository.RepositoryFactory; |
14 | import de.uka.ipd.sdq.pcm.seff.AbstractAction; |
15 | import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition; |
16 | import de.uka.ipd.sdq.pcm.seff.AbstractLoopAction; |
17 | import de.uka.ipd.sdq.pcm.seff.BranchAction; |
18 | import de.uka.ipd.sdq.pcm.seff.ForkAction; |
19 | import de.uka.ipd.sdq.pcm.seff.ForkedBehaviour; |
20 | import de.uka.ipd.sdq.pcm.seff.InternalAction; |
21 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour; |
22 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF; |
23 | import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification; |
24 | import de.uka.ipd.sdq.pcm.seff.seff_reliability.RecoveryAction; |
25 | import de.uka.ipd.sdq.pcm.seff.seff_reliability.RecoveryActionBehaviour; |
26 | import de.uka.ipd.sdq.sensitivity.DoubleParameterVariation; |
27 | |
28 | /** |
29 | * Provides sensitivity support to alter the failure probabilities of all |
30 | * internal actions within one component. |
31 | * |
32 | * @author brosch |
33 | * |
34 | */ |
35 | public class ComponentSensitivity extends MarkovSensitivity { |
36 | |
37 | /** |
38 | * The list of base values of this sensitivity. |
39 | */ |
40 | private List<Double> baseValues = null; |
41 | |
42 | /** |
43 | * The ID of the component to alter. |
44 | */ |
45 | private String componentId = null; |
46 | |
47 | /** |
48 | * The name of the component to alter. |
49 | */ |
50 | private String componentName = null; |
51 | |
52 | /** |
53 | * The list of affected internal failure occurrence descriptions. |
54 | */ |
55 | private List<InternalFailureOccurrenceDescription> descriptions = null; |
56 | |
57 | /** |
58 | * The constructor. |
59 | * |
60 | * @param name |
61 | * the name of the sensitivity analysis |
62 | * @param componentId |
63 | * the ID of the component to alter |
64 | * @param variation |
65 | * the parameter variation |
66 | */ |
67 | public ComponentSensitivity(final String name, final String componentId, |
68 | final DoubleParameterVariation variation) { |
69 | |
70 | // Initialize base variables: |
71 | super(name, variation); |
72 | |
73 | // Further initialization: |
74 | this.componentId = componentId; |
75 | } |
76 | |
77 | /** |
78 | * Alters the model according to the next sensitivity analysis step. |
79 | * |
80 | * @return indicates if the model could be successfully altered |
81 | */ |
82 | protected boolean alterModel() { |
83 | |
84 | // Determine the current failure probability: |
85 | for (int i = 0; i < descriptions.size(); i++) { |
86 | descriptions.get(i).setFailureProbability( |
87 | calculator.calculateCurrentDoubleValue( |
88 | getDoubleVariation(), getCurrentStepNumber(), |
89 | baseValues.get(i))); |
90 | } |
91 | |
92 | // Everything ok: |
93 | return true; |
94 | } |
95 | |
96 | /** |
97 | * Extracts the relevant sensitivity information from the given model. |
98 | */ |
99 | protected void extractSensitivityInformation() { |
100 | |
101 | // Declare the result variables: |
102 | descriptions = new BasicEList<InternalFailureOccurrenceDescription>(); |
103 | baseValues = new ArrayList<Double>(); |
104 | |
105 | // Retrieve the involved internal actions: |
106 | List<InternalAction> internalActions = getInternalActions(); |
107 | if (internalActions == null) { |
108 | logger |
109 | .error("Did not find any InternalActions for BasicComponent \"" |
110 | + componentName + "\" <ID=" + componentId + ">"); |
111 | return; |
112 | } |
113 | |
114 | // Build the list of internal failure occurrence descriptions: |
115 | for (InternalAction action : internalActions) { |
116 | for (InternalFailureOccurrenceDescription description : action |
117 | .getInternalFailureOccurrenceDescriptions__InternalAction()) { |
118 | descriptions.add(description); |
119 | baseValues.add(description.getFailureProbability()); |
120 | } |
121 | } |
122 | } |
123 | |
124 | /** |
125 | * Retrieves the relevant basic component. |
126 | * |
127 | * @return the basic component |
128 | */ |
129 | private BasicComponent getBasicComponent() { |
130 | |
131 | // Retrieve all BasicComponents in the PCM Repository: |
132 | List<Repository> repositories = getModel().getRepositories(); |
133 | if (repositories.size() == 0) { |
134 | // No repository found! |
135 | logger.error("No PCM Repositories found."); |
136 | return null; |
137 | } |
138 | |
139 | // Search for the relevant BasicComponent: |
140 | for (Repository repository : repositories) { |
141 | EList<EObject> components = helper |
142 | .getElements(repository, RepositoryFactory.eINSTANCE |
143 | .createBasicComponent().eClass()); |
144 | for (EObject object : components) { |
145 | if (((BasicComponent) object).getId().equals(componentId)) { |
146 | componentName = ((BasicComponent) object).getEntityName(); |
147 | return (BasicComponent) object; |
148 | } |
149 | } |
150 | } |
151 | |
152 | // Nothing found: |
153 | logger.error("BasicComponent \"" + componentName + "\" <ID=" |
154 | + componentId + "> not found."); |
155 | return null; |
156 | } |
157 | |
158 | /** |
159 | * Retrieves the list of involved internal actions. |
160 | * |
161 | * @return the list of internal actions |
162 | */ |
163 | private List<InternalAction> getInternalActions() { |
164 | |
165 | // Retrieve the relevant BasicComponent: |
166 | BasicComponent component = getBasicComponent(); |
167 | if (component == null) { |
168 | return null; |
169 | } |
170 | |
171 | // Build the list of internal actions over all SEFFs of the component: |
172 | List<InternalAction> resultList = new BasicEList<InternalAction>(); |
173 | for (ServiceEffectSpecification specifiction : component |
174 | .getServiceEffectSpecifications__BasicComponent()) { |
175 | if (specifiction instanceof ResourceDemandingSEFF) { |
176 | resultList |
177 | .addAll(getInternalActionsForBehaviour((ResourceDemandingSEFF) specifiction)); |
178 | } |
179 | } |
180 | |
181 | // Return the result: |
182 | return resultList; |
183 | } |
184 | |
185 | /** |
186 | * Retrieves the list of internal actions within the given behaviour. |
187 | * |
188 | * @param behaviour |
189 | * the behaviour |
190 | * @return the list of contained internal actions |
191 | */ |
192 | private List<InternalAction> getInternalActionsForBehaviour( |
193 | final ResourceDemandingBehaviour behaviour) { |
194 | |
195 | // Build the list of internal actions over all steps in the behaviour: |
196 | List<InternalAction> resultList = new BasicEList<InternalAction>(); |
197 | for (AbstractAction action : behaviour.getSteps_Behaviour()) { |
198 | if (action instanceof InternalAction) { |
199 | resultList.add((InternalAction) action); |
200 | } else if (action instanceof AbstractLoopAction) { |
201 | resultList |
202 | .addAll(getInternalActionsForBehaviour(((AbstractLoopAction) action) |
203 | .getBodyBehaviour_Loop())); |
204 | } else if (action instanceof BranchAction) { |
205 | for (AbstractBranchTransition transition : ((BranchAction) action) |
206 | .getBranches_Branch()) { |
207 | resultList.addAll(getInternalActionsForBehaviour(transition |
208 | .getBranchBehaviour_BranchTransition())); |
209 | } |
210 | } else if (action instanceof RecoveryAction) { |
211 | for (RecoveryActionBehaviour recoveryBehaviour : ((RecoveryAction) action) |
212 | .getRecoveryActionBehaviours__RecoveryAction()) { |
213 | resultList |
214 | .addAll(getInternalActionsForBehaviour(recoveryBehaviour)); |
215 | } |
216 | } else if (action instanceof ForkAction) { |
217 | if (((ForkAction) action) |
218 | .getAsynchronousForkedBehaviours_ForkAction() != null) { |
219 | for (ForkedBehaviour forkedBehaviour : ((ForkAction) action) |
220 | .getAsynchronousForkedBehaviours_ForkAction()) { |
221 | resultList |
222 | .addAll(getInternalActionsForBehaviour(forkedBehaviour)); |
223 | } |
224 | } |
225 | if (((ForkAction) action) |
226 | .getSynchronisingBehaviours_ForkAction() != null) { |
227 | for (ForkedBehaviour forkedBehaviour : ((ForkAction) action) |
228 | .getSynchronisingBehaviours_ForkAction() |
229 | .getSynchronousForkedBehaviours_SynchronisationPoint()) { |
230 | resultList |
231 | .addAll(getInternalActionsForBehaviour(forkedBehaviour)); |
232 | } |
233 | } |
234 | } |
235 | } |
236 | |
237 | // Return the result: |
238 | return resultList; |
239 | } |
240 | |
241 | /** |
242 | * Builds the headings strings for logging. |
243 | * |
244 | * @return the log headings strings |
245 | */ |
246 | protected List<List<String>> getLogHeadingsMulti() { |
247 | |
248 | // Create a result list: |
249 | List<List<String>> resultList = new ArrayList<List<String>>(); |
250 | |
251 | // Create the headings: |
252 | ArrayList<String> headings = new ArrayList<String>(); |
253 | headings.add("Component Name"); |
254 | headings.add("Component ID"); |
255 | headings.add("Failure Probability"); |
256 | resultList.add(headings); |
257 | |
258 | // Return the result: |
259 | return resultList; |
260 | } |
261 | |
262 | /** |
263 | * Builds the results strings for sensitivity logging. |
264 | * |
265 | * @return the results strings |
266 | */ |
267 | protected List<String> getLogSingleResultsMulti() { |
268 | |
269 | // Create a result list: |
270 | List<String> resultList = new ArrayList<String>(); |
271 | |
272 | // Create the result strings: |
273 | resultList.add(componentName); |
274 | resultList.add(componentId); |
275 | resultList.add(calculator.getCurrentLogEntry(getDoubleVariation(), |
276 | getCurrentStepNumber())); |
277 | |
278 | // Return the result: |
279 | return resultList; |
280 | } |
281 | } |