| 1 | package de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.impl; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.Collection; |
| 5 | import java.util.Collections; |
| 6 | import java.util.List; |
| 7 | |
| 8 | import org.apache.log4j.Logger; |
| 9 | import org.opt4j.core.Objective; |
| 10 | import org.opt4j.core.problem.Genotype; |
| 11 | import org.opt4j.operator.copy.Copy; |
| 12 | |
| 13 | import de.uka.ipd.sdq.context.aggregatedUsageContext.AggregatedCommunication; |
| 14 | import de.uka.ipd.sdq.context.aggregatedUsageContext.AggregatedResourceDemand; |
| 15 | import de.uka.ipd.sdq.context.aggregatedUsageContext.ComputedAggregatedUsage; |
| 16 | import de.uka.ipd.sdq.context.aggregatedUsageContext.ServiceExecutionContext; |
| 17 | import de.uka.ipd.sdq.dsexplore.helper.EMFHelper; |
| 18 | import de.uka.ipd.sdq.dsexplore.helper.Pair; |
| 19 | import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration; |
| 20 | import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.AbstractTactic; |
| 21 | import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.TacticsResultCandidate; |
| 22 | import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.UtilisationResultCacheAndHelper; |
| 23 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual; |
| 24 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividualBuilder; |
| 25 | import de.uka.ipd.sdq.dsexplore.opt4j.start.Opt4JStarter; |
| 26 | import de.uka.ipd.sdq.dsexplore.qml.handling.QMLConstantsContainer; |
| 27 | import de.uka.ipd.sdq.dsexplore.qml.reader.QMLDimensionReader; |
| 28 | import de.uka.ipd.sdq.pcm.allocation.AllocationContext; |
| 29 | import de.uka.ipd.sdq.pcm.designdecision.AllocationDegree; |
| 30 | import de.uka.ipd.sdq.pcm.designdecision.CapacityDegree; |
| 31 | import de.uka.ipd.sdq.pcm.designdecision.Choice; |
| 32 | import de.uka.ipd.sdq.pcm.designdecision.DiscreteRangeChoice; |
| 33 | import de.uka.ipd.sdq.pcm.designdecision.ClassChoice; |
| 34 | import de.uka.ipd.sdq.pcm.designdecision.ClassDegree; |
| 35 | import de.uka.ipd.sdq.pcm.designdecision.SchedulingPolicyChoice; |
| 36 | import de.uka.ipd.sdq.pcm.designdecision.SchedulingPolicyDegree; |
| 37 | import de.uka.ipd.sdq.pcm.repository.BasicComponent; |
| 38 | import de.uka.ipd.sdq.pcm.repository.PassiveResource; |
| 39 | import de.uka.ipd.sdq.pcm.repository.Repository; |
| 40 | import de.uka.ipd.sdq.pcm.repository.RepositoryComponent; |
| 41 | import de.uka.ipd.sdq.pcm.resourceenvironment.CommunicationLinkResourceSpecification; |
| 42 | import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification; |
| 43 | import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer; |
| 44 | import de.uka.ipd.sdq.pcm.resourceenvironment.SchedulingPolicy; |
| 45 | import de.uka.ipd.sdq.pcm.resourcetype.ResourceType; |
| 46 | import de.uka.ipd.sdq.pcm.resultdecorator.ResultDecoratorRepository; |
| 47 | import de.uka.ipd.sdq.pcm.resultdecorator.repositorydecorator.ServiceResult; |
| 48 | import de.uka.ipd.sdq.pcm.resultdecorator.resourceenvironmentdecorator.PassiveResourceResult; |
| 49 | import de.uka.ipd.sdq.pcm.resultdecorator.resourceenvironmentdecorator.ProcessingResourceSpecificationResult; |
| 50 | import de.uka.ipd.sdq.pcm.resultdecorator.resourceenvironmentdecorator.UtilisationResult; |
| 51 | import de.uka.ipd.sdq.pcm.usagemodel.UsageScenario; |
| 52 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
| 53 | |
| 54 | public class ConcurrentProcessingSystemImplCatia extends AbstractTactic { |
| 55 | |
| 56 | private Objective performance; |
| 57 | |
| 58 | |
| 59 | protected static Logger logger = Logger |
| 60 | .getLogger(ConcurrentProcessingSystemImplCatia.class.getName()); |
| 61 | |
| 62 | public ConcurrentProcessingSystemImplCatia(Copy<Genotype> copy, |
| 63 | DSEIndividualBuilder individualBuilder, |
| 64 | DSEWorkflowConfiguration configuration) { |
| 65 | super(copy, individualBuilder, configuration, new String[] {QMLConstantsContainer.QUALITY_ATTRIBUTE_DIMENSION_RESPONSETIME_DEFINITION_PATH, |
| 66 | QMLConstantsContainer.QUALITY_ATTRIBUTE_DIMENSION_THROUGHPUT_DEFINITION_PATH}); |
| 67 | try { |
| 68 | Collection<Objective> objectives = Opt4JStarter.getDSEEvaluator() |
| 69 | .getObjectives(); |
| 70 | for (Objective objective : objectives) { |
| 71 | //XXX: Read the dimension name from definition rather than the constants container |
| 72 | if (objective.getName().contains( |
| 73 | new QMLDimensionReader().getDimension(QMLConstantsContainer.QUALITY_ATTRIBUTE_DIMENSION_RESPONSETIME_DEFINITION_PATH).getEntityName()) |
| 74 | || objective.getName().contains( |
| 75 | new QMLDimensionReader().getDimension(QMLConstantsContainer.QUALITY_ATTRIBUTE_DIMENSION_THROUGHPUT_DEFINITION_PATH).getEntityName())) { |
| 76 | //DSEConstantsContainer.MEAN_RESPONSE_TIME_QUALITY)) { |
| 77 | this.performance = objective; |
| 78 | break; |
| 79 | } |
| 80 | } |
| 81 | } catch (Exception e) { |
| 82 | // TODO: handle exception |
| 83 | } |
| 84 | |
| 85 | } |
| 86 | |
| 87 | //@author catia: find the max utilised cpu |
| 88 | public int getMaxUtilisedCpu(List<ActiveResInfo> list) { |
| 89 | int position = 0; |
| 90 | int temp = 0; |
| 91 | for (ActiveResInfo el : list) { |
| 92 | if (el.type.getEntityName().equals("CPU") && (el.utilisation > list.get(position).utilisation)) { |
| 93 | position = temp; |
| 94 | } |
| 95 | temp++; |
| 96 | } |
| 97 | return position; |
| 98 | } |
| 99 | |
| 100 | //@author catia: find the max utilised hdd |
| 101 | public int getMaxUtilisedHdd(List<ActiveResInfo> list) { |
| 102 | int position = 0; |
| 103 | int temp = 0; |
| 104 | for (ActiveResInfo el : list) { |
| 105 | if (el.type.getEntityName().equals("HDD") && (el.utilisation > list.get(position).utilisation)) { |
| 106 | position = temp; |
| 107 | } |
| 108 | temp++; |
| 109 | } |
| 110 | return position; |
| 111 | } |
| 112 | |
| 113 | //@author catia: find the max utilised active resource |
| 114 | public int getMaxUtilisedActiveRes(List<ActiveResInfo> list) { |
| 115 | int position = 0; |
| 116 | int temp = 0; |
| 117 | for (ActiveResInfo el : list) { |
| 118 | if (el.utilisation > list.get(position).utilisation) { |
| 119 | position = temp; |
| 120 | } |
| 121 | temp++; |
| 122 | } |
| 123 | return position; |
| 124 | } |
| 125 | |
| 126 | //@author catia: get over used CPU resources whose queue length exceeds a threshold |
| 127 | public List<ActiveResInfo> getOverUsedCpu(List<ActiveResInfo> list){ |
| 128 | List<ActiveResInfo> result = new ArrayList<ActiveResInfo>(0); |
| 129 | |
| 130 | //@author catia: threshold value for max CPU utilisation |
| 131 | double thresholdMaxCpu = new Thresholds().thresholdMaxCpu; |
| 132 | |
| 133 | // @author catia: threshold value for max queue length |
| 134 | double thresholdCpuQL = new Thresholds().thresholdCpuQL; |
| 135 | |
| 136 | for (ActiveResInfo el : list) { |
| 137 | if((el.type.getEntityName().equals("CPU")) && (el.utilisation > thresholdMaxCpu) && (el.queueLength > thresholdCpuQL)){ |
| 138 | result.add(el); |
| 139 | } |
| 140 | } |
| 141 | return result; |
| 142 | } |
| 143 | |
| 144 | //@author catia: get under used CPU resources |
| 145 | public List<ActiveResInfo> getUnderUsedCpu(List<ActiveResInfo> list){ |
| 146 | List<ActiveResInfo> result = new ArrayList<ActiveResInfo>(0); |
| 147 | |
| 148 | //@author catia: threshold value for min CPU utilisation |
| 149 | double thresholdMinCpu = new Thresholds().thresholdMinCpu; |
| 150 | |
| 151 | for (ActiveResInfo el : list) { |
| 152 | if((el.type.getEntityName().equals("CPU")) && (el.utilisation < thresholdMinCpu)){ |
| 153 | result.add(el); |
| 154 | } |
| 155 | } |
| 156 | return result; |
| 157 | } |
| 158 | |
| 159 | //@author catia: get over used HDD resources whose queue length exceeds a threshold |
| 160 | public List<ActiveResInfo> getOverUsedHDD(List<ActiveResInfo> list){ |
| 161 | List<ActiveResInfo> result = new ArrayList<ActiveResInfo>(0); |
| 162 | |
| 163 | //@author catia: threshold value for max HDD utilisation |
| 164 | double thresholdMaxHdd = new Thresholds().thresholdMaxHdd; |
| 165 | |
| 166 | // @author catia: threshold value for max queue length |
| 167 | double thresholdHddQL = new Thresholds().thresholdHddQL; |
| 168 | |
| 169 | for (ActiveResInfo el : list) { |
| 170 | if((el.type.getEntityName().equals("HDD")) && (el.utilisation > thresholdMaxHdd) && (el.queueLength > thresholdHddQL)){ |
| 171 | result.add(el); |
| 172 | } |
| 173 | } |
| 174 | return result; |
| 175 | } |
| 176 | |
| 177 | //@author catia: get under used HDD resources |
| 178 | public List<ActiveResInfo> getUnderUsedHDD(List<ActiveResInfo> list){ |
| 179 | List<ActiveResInfo> result = new ArrayList<ActiveResInfo>(0); |
| 180 | |
| 181 | //@author catia: threshold value for min CPU utilisation |
| 182 | double thresholdMinHdd = new Thresholds().thresholdMinHdd; |
| 183 | |
| 184 | for (ActiveResInfo el : list) { |
| 185 | if((el.type.getEntityName().equals("HDD")) && (el.utilisation < thresholdMinHdd)){ |
| 186 | result.add(el); |
| 187 | } |
| 188 | } |
| 189 | return result; |
| 190 | } |
| 191 | |
| 192 | //@author catia: get critical passive resources |
| 193 | //Assumption: a passive resource is considered "critical" if its queue length exceeds a threshold value |
| 194 | //and the waiting time is more than the double of the holding time |
| 195 | public List<PassiveResInfo> getCriticalPassiveRes(List<PassiveResInfo> list){ |
| 196 | List<PassiveResInfo> result = new ArrayList<PassiveResInfo>(0); |
| 197 | |
| 198 | //@author catia: threshold value for max queue length of passive resources |
| 199 | double thresholdPrQL = new Thresholds().thresholdPrQL; |
| 200 | |
| 201 | for (PassiveResInfo el : list) { |
| 202 | if((el.queueLength > thresholdPrQL) && (el.waitingTime > (el.holdingTime * 2))){ |
| 203 | result.add(el); |
| 204 | } |
| 205 | } |
| 206 | return result; |
| 207 | } |
| 208 | |
| 209 | //@author catia: check if a component is already stored for its resource demand (cpu, hdd) |
| 210 | public boolean compOccurrence(List<CompInfoResDemand> list, AllocationContext a) { |
| 211 | boolean value = false; |
| 212 | for (CompInfoResDemand compInfoResDemand : list) { |
| 213 | if (compInfoResDemand.ac == a) { |
| 214 | value = true; |
| 215 | } |
| 216 | } |
| 217 | return value; |
| 218 | } |
| 219 | |
| 220 | //@author catia: increment the computation (cpu demand) of a component |
| 221 | public void incrementComputation(List<CompInfoResDemand> list, |
| 222 | AllocationContext b, double value) { |
| 223 | for (CompInfoResDemand compInfoResDemand : list) { |
| 224 | if (compInfoResDemand.ac == b) { |
| 225 | compInfoResDemand.computation = compInfoResDemand.computation |
| 226 | + value; |
| 227 | } |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | //@author catia: increment the storage (hdd demand) of a component |
| 232 | public void incrementStorage(List<CompInfoResDemand> list, |
| 233 | AllocationContext b, double value) { |
| 234 | for (CompInfoResDemand compInfoResDemand : list) { |
| 235 | if (compInfoResDemand.ac == b) { |
| 236 | compInfoResDemand.storage = compInfoResDemand.storage + value; |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | //@author catia: update the frequency of a seff |
| 242 | public void updateFrequency (List<ServiceInfo> list, String seffName, String compName, double f){ |
| 243 | for (ServiceInfo el: list){ |
| 244 | if (el.serviceName.equals(seffName) && el.compName.equals(compName)){ |
| 245 | el.frequency = f; |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | //@author catia: check if the list of seffs is unbalanced |
| 251 | //Assumption - a list of seffs is considered "unbalanced" if the maximum and |
| 252 | //the minimum response time among them is higher than a threshold value |
| 253 | public boolean unbalancedSeffs(List<ServiceInfo> list){ |
| 254 | boolean result = false; |
| 255 | // threshold value, i.e. the allowed gap between the maximum and the minimum response time of seffs |
| 256 | double gapRT = 0.5; |
| 257 | |
| 258 | if ( (getMaxRT(list) - getMinRT(list)) > gapRT ){ |
| 259 | result = true; |
| 260 | logger.info("The list of seffs is unbalanced, the maximum resp. time is " |
| 261 | + getMaxRT(list) + " and the minimum one is " + getMinRT(list)); |
| 262 | } |
| 263 | return result; |
| 264 | } |
| 265 | |
| 266 | //@author catia: detection of the antipattern CPS (Concurrent Processing Systems) |
| 267 | public boolean cps(List<ActiveResInfo> list) { |
| 268 | boolean result = false; |
| 269 | if ((getOverUsedCpu(list).size() != 0 && getUnderUsedCpu(list).size() != 0) |
| 270 | || (getOverUsedHDD(list).size() != 0 && getUnderUsedHDD(list).size() != 0)) { |
| 271 | logger.info("The antipattern CONCURRENT PROCESSING SYSTEMS has been detected"); |
| 272 | result = true; |
| 273 | } |
| 274 | return result; |
| 275 | } |
| 276 | |
| 277 | //@author catia: detection of the antipattern OLB (One-Lane Bridge) |
| 278 | public boolean olb(List<ServiceInfo> list, PassiveResInfo criticPassiveRes) { |
| 279 | boolean result = false; |
| 280 | for (ServiceInfo el : list) { |
| 281 | if (el.compName.equals(criticPassiveRes.component)) { |
| 282 | if (el.respT > el.userReq) { |
| 283 | result = true; |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | if (result) { |
| 288 | logger.info("The antipattern ONE-LANE BRIDGE has been detected"); |
| 289 | } |
| 290 | return result; |
| 291 | } |
| 292 | |
| 293 | //@author catia: detection of the antipattern EP (Extensive Processing) |
| 294 | public boolean ep(ActiveResInfo activeRes, List<ServiceInfo> list) { |
| 295 | boolean result = false; |
| 296 | if ( (activeRes.schedulingPolicy.equals("FCFS")) && (unbalancedSeffs(list))) { |
| 297 | result = true; |
| 298 | logger.info("The antipattern EXTENSIVE PROCESSING has been detected"); |
| 299 | } |
| 300 | return result; |
| 301 | } |
| 302 | |
| 303 | //@author catia: find the component that requires the most high cpu demand |
| 304 | public int getCompMaxCPUdemand(List<CompInfoResDemand> list) { |
| 305 | int position = 0; |
| 306 | int temp = 0; |
| 307 | for (CompInfoResDemand compInfoResDemand : list) { |
| 308 | if (compInfoResDemand != null) { |
| 309 | if (list.get(position).computation < compInfoResDemand.computation) { |
| 310 | position = temp; |
| 311 | } |
| 312 | } |
| 313 | temp++; |
| 314 | } |
| 315 | return position; |
| 316 | } |
| 317 | |
| 318 | //@author catia: find the component that requires the most high hdd demand |
| 319 | public int getCompMaxHDDdemand(List<CompInfoResDemand> list) { |
| 320 | int position = 0; |
| 321 | int temp = 0; |
| 322 | for (CompInfoResDemand compInfoResDemand : list) { |
| 323 | if (compInfoResDemand != null) { |
| 324 | if (list.get(position).storage < compInfoResDemand.storage) { |
| 325 | position = temp; |
| 326 | } |
| 327 | } |
| 328 | temp++; |
| 329 | } |
| 330 | return position; |
| 331 | } |
| 332 | |
| 333 | //@author catia: give the components deployed on a node |
| 334 | public List<CompInfoResDemand> deployedComponents(List<CompInfoResDemand> comp, ResourceContainer node) { |
| 335 | List<CompInfoResDemand> result = new ArrayList<CompInfoResDemand>(0); |
| 336 | for (CompInfoResDemand compInfoResDemand : comp) { |
| 337 | if (compInfoResDemand.rc == node) { |
| 338 | result.add(compInfoResDemand); |
| 339 | } |
| 340 | } |
| 341 | return result; |
| 342 | } |
| 343 | |
| 344 | //@author catia: give the seffs provided by a basic component |
| 345 | public List<ServiceInfo> getSeffsOfComp(List<ServiceInfo> list, String comp) { |
| 346 | List<ServiceInfo> result = new ArrayList<ServiceInfo>(0); |
| 347 | for (ServiceInfo el : list) { |
| 348 | if (el.compName.equals(comp)) { |
| 349 | result.add(el); |
| 350 | } |
| 351 | } |
| 352 | return result; |
| 353 | } |
| 354 | |
| 355 | //@author catia: provide the maximum response time among a list of seffs |
| 356 | public double getMaxRT(List<ServiceInfo> list) { |
| 357 | double temp = 0.0; |
| 358 | for (ServiceInfo el : list) { |
| 359 | if (el.respT > temp) { |
| 360 | temp = el.respT; |
| 361 | } |
| 362 | } |
| 363 | return temp; |
| 364 | } |
| 365 | |
| 366 | //@author catia: provide the minimum response time among a list of seffs |
| 367 | public double getMinRT(List<ServiceInfo> list) { |
| 368 | double temp = getMaxRT(list); |
| 369 | for (ServiceInfo el : list) { |
| 370 | if (el.respT < temp) { |
| 371 | temp = el.respT; |
| 372 | } |
| 373 | } |
| 374 | return temp; |
| 375 | } |
| 376 | |
| 377 | |
| 378 | /* |
| 379 | * (non-Javadoc) |
| 380 | * |
| 381 | * @see |
| 382 | * de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.ITactic# |
| 383 | * doesMatchPrecondition |
| 384 | * (de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual) |
| 385 | */ |
| 386 | public boolean doesMatchPrecondition(DSEIndividual i) { |
| 387 | return getSolution(i) != null; |
| 388 | } |
| 389 | |
| 390 | public List<TacticsResultCandidate> getSolution(DSEIndividual i) { |
| 391 | // check that performance is optimised |
| 392 | if (performance != null |
| 393 | && i.getObjectives().getResultDecoratorFor(this.performance) != null) { |
| 394 | |
| 395 | ResultDecoratorRepository resultRepo = i.getObjectives().getResultDecoratorFor(this.performance); |
| 396 | |
| 397 | logger.info("---------------------------------------------------------------------"); |
| 398 | logger.info("System response time: " + i.getObjectives().get(performance).getDouble()); |
| 399 | logger.info("---------------------------------------------------------------------"); |
| 400 | |
| 401 | // AM: response time of SEFFs |
| 402 | List<ServiceResult> serviceResultList = resultRepo.getServiceResult_ResultDecoratorRepository(); |
| 403 | |
| 404 | //@author catia: the list of SEFFs is stored in the ServiceInfo data structure |
| 405 | List<ServiceInfo> serviceInfoList = new ArrayList<ServiceInfo>(serviceResultList.size()); |
| 406 | |
| 407 | //@author catia: user requirements for all services are currently set to 0.001 |
| 408 | |
| 409 | for (ServiceResult serviceResult : serviceResultList) { |
| 410 | |
| 411 | serviceInfoList.add(new ServiceInfo(serviceResult.getServiceEffectSpecification_ServiceResult().getDescribedService__SEFF().getEntityName(), |
| 412 | serviceResult.getServiceEffectSpecification_ServiceResult().getBasicComponent_ServiceEffectSpecification().getEntityName(), |
| 413 | 0.001, serviceResult.getMeanResponseTime(), 0.0)); |
| 414 | } |
| 415 | |
| 416 | |
| 417 | |
| 418 | //@author catia: the list of services is printed when the frequency is set (according to the usage model) |
| 419 | |
| 420 | // select the results of active resources (CPU, HDD, ...), and passive resources |
| 421 | // not network yet. |
| 422 | List<UtilisationResult> allUtilResults = resultRepo.getUtilisationResults_ResultDecoratorRepository(); |
| 423 | |
| 424 | // List to contain all active resource results |
| 425 | List<ProcessingResourceSpecificationResult> utilResults = new ArrayList<ProcessingResourceSpecificationResult>(allUtilResults.size()); |
| 426 | |
| 427 | // list to contain all passive resource results |
| 428 | List<PassiveResourceResult> passiveResourceUtilResults = new ArrayList<PassiveResourceResult>(5); |
| 429 | |
| 430 | //iterate through utilisation results and add them to the right list. |
| 431 | for (UtilisationResult anyUtilResult : allUtilResults) { |
| 432 | if (anyUtilResult instanceof ProcessingResourceSpecificationResult) { |
| 433 | utilResults.add((ProcessingResourceSpecificationResult) anyUtilResult); |
| 434 | } else if (anyUtilResult instanceof PassiveResourceResult ){ |
| 435 | passiveResourceUtilResults.add((PassiveResourceResult)anyUtilResult); |
| 436 | ((PassiveResourceResult)anyUtilResult).getAverageQueueLength(); |
| 437 | ((PassiveResourceResult)anyUtilResult).getAverageWaitTime(); |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | // util results can be network util (not yet filled with values) or active resource utils |
| 442 | |
| 443 | //@author catia: the list of active resources is stored in the ActiveResInfo data structure |
| 444 | List<ActiveResInfo> activeResInfoList = new ArrayList<ActiveResInfo>(utilResults.size()); |
| 445 | |
| 446 | for (UtilisationResult utilisationResult : utilResults) { |
| 447 | if (utilisationResult instanceof ProcessingResourceSpecificationResult) { |
| 448 | ProcessingResourceSpecificationResult activeProcUtilResult = (ProcessingResourceSpecificationResult) utilisationResult; |
| 449 | // retrieve the processor for which this is the result |
| 450 | ProcessingResourceSpecification resource = activeProcUtilResult.getProcessingResourceSpecification_ProcessingResourceSpecificationResult(); |
| 451 | // You can retrieve the utilisation value |
| 452 | // double util = activeProcUtilResult.getResourceUtilisation(); |
| 453 | // double averageQueueLength = activeProcUtilResult.getAverageQueueLength(); |
| 454 | // does not work with the LQN solver, and is not tested yet for SimuCom. |
| 455 | // int maxQueueLength = activeProcUtilResult.getMaxQueueLength(); |
| 456 | |
| 457 | // AM: added queue length and scheduling here |
| 458 | activeResInfoList.add(new ActiveResInfo(resource.getResourceContainer_ProcessingResourceSpecification(), |
| 459 | resource.getActiveResourceType_ActiveResourceSpecification(), |
| 460 | activeProcUtilResult.getResourceUtilisation(), |
| 461 | activeProcUtilResult.getAverageQueueLength(), resource.getSchedulingPolicy().getName())); |
| 462 | |
| 463 | } |
| 464 | // Other possible results are for network: |
| 465 | // LinkingResourceResults or for the whole resource container: |
| 466 | // ResourceContainerResult, both are not yet filled with values. |
| 467 | } |
| 468 | |
| 469 | logger.info("List of Active Resources: "); |
| 470 | |
| 471 | for (ActiveResInfo el : activeResInfoList) { |
| 472 | el.print(); |
| 473 | } |
| 474 | |
| 475 | logger.info("---------------------------------------------------------------------"); |
| 476 | logger.info("Max utilised hardware resources: "); |
| 477 | |
| 478 | //@author catia: select the active resource maximum utilised |
| 479 | logger.info("Max utilised active resource: "); |
| 480 | ActiveResInfo maxUtilised = new ActiveResInfo(activeResInfoList.get(getMaxUtilisedActiveRes(activeResInfoList))); |
| 481 | maxUtilised.print(); |
| 482 | |
| 483 | //@author catia: select the cpu maximum utilised |
| 484 | logger.info("Max utilised cpu resource: "); |
| 485 | ActiveResInfo maxUtilisedCpu = new ActiveResInfo(activeResInfoList.get(getMaxUtilisedCpu(activeResInfoList))); |
| 486 | maxUtilisedCpu.print(); |
| 487 | |
| 488 | //@author catia: select the hdd maximum utilised |
| 489 | logger.info("Max utilised hdd resource: "); |
| 490 | ActiveResInfo maxUtilisedHdd = new ActiveResInfo(activeResInfoList.get(getMaxUtilisedHdd(activeResInfoList))); |
| 491 | maxUtilisedHdd.print(); |
| 492 | |
| 493 | logger.info("---------------------------------------------------------------------"); |
| 494 | |
| 495 | // results for the services |
| 496 | ComputedAggregatedUsage computedUsage = i.getObjectives().getComputedAggregatedUsageFor(this.performance); |
| 497 | List<ServiceExecutionContext> serviceContexts = computedUsage.getServiceExecutionContexts_ComputedAggregatedUsage(); |
| 498 | |
| 499 | //@author catia: store the components and their resource demands according to the usage model |
| 500 | List<CompInfoResDemand> listCompIDs = new ArrayList<CompInfoResDemand>(serviceContexts.size()); |
| 501 | |
| 502 | for (ServiceExecutionContext serviceExecutionContext : serviceContexts) { |
| 503 | |
| 504 | // the global frequency of calling this service if its usage |
| 505 | // scenario is called once. |
| 506 | // Note that there may be several ServiceExecutionContext for |
| 507 | // one service in this list because |
| 508 | // there is up to one ServiceExecutionContext for each |
| 509 | // AssemblyContext (= component instance) |
| 510 | // and each UsageScenario. |
| 511 | // We cannot combine the frequencies of |
| 512 | // usage scenarios on the dependency solver level for closed |
| 513 | // workloads, because the throughput is depending |
| 514 | // on the performance prediction. |
| 515 | |
| 516 | UsageScenario usageScenario = serviceExecutionContext.getUsageScenario_ServiceExecutionContext(); |
| 517 | |
| 518 | AllocationContext allocationContext = serviceExecutionContext.getAllocationContext_ServiceExecutionContext(); |
| 519 | |
| 520 | // AM: this is the execution probability for a SEFF (see above, |
| 521 | // for one execution of the usage scenario!) |
| 522 | double frequency = serviceExecutionContext |
| 523 | .getGlobalExecutionFrequency(); |
| 524 | |
| 525 | //@author catia: store the current basic component the "serviceExecutionContext" refers to. |
| 526 | BasicComponent currentBasicComp = serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext().getBasicComponent_ServiceEffectSpecification(); |
| 527 | |
| 528 | //@author catia: store the current allocation context the "serviceExecutionContext" refers to. |
| 529 | AllocationContext currentCompAllCont = serviceExecutionContext.getAllocationContext_ServiceExecutionContext(); |
| 530 | |
| 531 | if (!compOccurrence(listCompIDs, currentCompAllCont)) { |
| 532 | listCompIDs.add(new CompInfoResDemand(currentBasicComp, currentCompAllCont, |
| 533 | allocationContext.getResourceContainer_AllocationContext(), 0.0, 0.0)); |
| 534 | } |
| 535 | |
| 536 | //logger.info("TEST seff " + serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext().getDescribedService__SEFF().getEntityName() + " frequency: " + frequency); |
| 537 | |
| 538 | String seffName = serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext().getDescribedService__SEFF().getEntityName(); |
| 539 | |
| 540 | //@author catia: update the frequency of the seff - to be checked |
| 541 | updateFrequency (serviceInfoList, seffName, currentBasicComp.getEntityName(), frequency ); |
| 542 | |
| 543 | logger.info(" "); |
| 544 | logger.info("Service "+serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext().getDescribedService__SEFF().getEntityName() |
| 545 | + " of component " + |
| 546 | serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext().getBasicComponent_ServiceEffectSpecification().getEntityName() |
| 547 | + " in allocation context "+ |
| 548 | allocationContext.getEntityName() |
| 549 | + " on server "+ |
| 550 | allocationContext.getResourceContainer_AllocationContext().getEntityName() |
| 551 | + " has frequency "+frequency |
| 552 | + " in usage scenario "+usageScenario.getEntityName()); |
| 553 | // + " The resource demands are the following: "); |
| 554 | |
| 555 | // the weighted average resource demands per resource type as a list |
| 556 | List<AggregatedResourceDemand> aggregatedResourceDemandList = serviceExecutionContext |
| 557 | .getAggregatedResourceDemands_ServiceExecutionContext(); |
| 558 | for (AggregatedResourceDemand aggregatedResourceDemand : aggregatedResourceDemandList) { |
| 559 | // the resource type of this resource demand |
| 560 | ResourceType resourceType = aggregatedResourceDemand |
| 561 | .getResourceType_AggregatedResourceDemand(); |
| 562 | |
| 563 | // the weighted average resource demand for this resource type |
| 564 | double demand = aggregatedResourceDemand |
| 565 | .getAggregatedResourceDemand(); |
| 566 | |
| 567 | // logger.info("Demand "+demand+" on the "+resourceType.getEntityName()); |
| 568 | |
| 569 | // @author catia: if the "resourceType" is a CPU then increment computation demand |
| 570 | if (resourceType.getEntityName().equals("CPU")) { |
| 571 | incrementComputation(listCompIDs, currentCompAllCont, demand); |
| 572 | } |
| 573 | // @author catia: if the "resourceType" is a HDD then increment storage demand |
| 574 | if (resourceType.getEntityName().equals("HDD")) { |
| 575 | incrementStorage(listCompIDs, currentCompAllCont, demand); |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | // logger.info("The service sends the following messages: "); |
| 580 | // the message information |
| 581 | List<AggregatedCommunication> communicationInfoList = serviceExecutionContext |
| 582 | .getSentAggregatedCommunications_ServiceExecutionContext(); |
| 583 | // The list contains one AggregatedCommunication per |
| 584 | // communication betwen two ServiceExcecutionContexts. |
| 585 | for (AggregatedCommunication aggregatedCommunication : communicationInfoList) { |
| 586 | |
| 587 | // the message frequency is relative to the probability of |
| 588 | // the caller being executed |
| 589 | // That means, if the caller has just a probability of 0.5 |
| 590 | // of being executed in a usage scenario, and |
| 591 | // the relativeMessageFrequency here has a frequency of 0.3, |
| 592 | // then the overall probability |
| 593 | // that this message is sent in this UsageScenario is 0.15. |
| 594 | //double relativeMessageFrequency = aggregatedCommunication |
| 595 | // .getAverageMessageFrequency(); |
| 596 | |
| 597 | // the communication link resource that is used. Is null if |
| 598 | // this is a local call. |
| 599 | CommunicationLinkResourceSpecification link = aggregatedCommunication |
| 600 | .getUsedCommunicationLinkResourceSpecification_AggregatedCommunication(); |
| 601 | |
| 602 | // not yet implemented |
| 603 | //double averageMessageSize = aggregatedCommunication |
| 604 | // .getAverageMessageSize(); |
| 605 | |
| 606 | // logger.info(relativeMessageFrequency |
| 607 | // + |
| 608 | // " messages to service "+aggregatedCommunication.getCommunicationPartner_AggregatedCommunication().getDescribedSEFF_ServiceExecutionContext().getDescribedService__SEFF().getEntityName() |
| 609 | // + " of component " + |
| 610 | // aggregatedCommunication.getCommunicationPartner_AggregatedCommunication().getDescribedSEFF_ServiceExecutionContext().getBasicComponent_ServiceEffectSpecification().getEntityName() |
| 611 | // + " in allocation context "+ |
| 612 | // aggregatedCommunication.getCommunicationPartner_AggregatedCommunication().getAllocationContext_ServiceExecutionContext().getEntityName() |
| 613 | // + ". The average message size is "+averageMessageSize); |
| 614 | if (link != null) { |
| 615 | // logger.info("The communication is remote over link "+link.getId() |
| 616 | // + |
| 617 | // " of type "+link.getCommunicationLinkResourceType_CommunicationLinkResourceSpecification().getEntityName()); |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | } |
| 622 | |
| 623 | logger.info("List of all SEFFs with the frequency value: "); |
| 624 | for (ServiceInfo el : serviceInfoList) { |
| 625 | el.print(); |
| 626 | } |
| 627 | logger.info("---------------------------------------------------------------------"); |
| 628 | |
| 629 | List<TacticsResultCandidate> listPairs = new ArrayList<TacticsResultCandidate>(); |
| 630 | |
| 631 | // AM: Example how to reach the initial PCM model |
| 632 | PCMInstance pcm = Opt4JStarter.getProblem().getInitialInstance(); |
| 633 | |
| 634 | // AM: Example for getting a passive resource capacity. Note that |
| 635 | // the passive resource belongs to a component, not to a service |
| 636 | List<Repository> repositoryList = pcm.getRepositories(); |
| 637 | |
| 638 | //@author catia: the list of passive resources is stored in the PassiveResInfo data structure |
| 639 | List<PassiveResInfo> passiveResInfoList = new ArrayList<PassiveResInfo>(repositoryList.size()); |
| 640 | |
| 641 | for (Repository repository : repositoryList) { |
| 642 | List<RepositoryComponent> repoComponents = repository |
| 643 | .getComponents__Repository(); |
| 644 | for (RepositoryComponent repositoryComponent : repoComponents) { |
| 645 | if (repositoryComponent instanceof BasicComponent) { |
| 646 | BasicComponent basicComponent = (BasicComponent) repositoryComponent; |
| 647 | List<PassiveResource> passiveResourceList = basicComponent |
| 648 | .getPassiveResource_BasicComponent(); |
| 649 | for (PassiveResource passiveResource : passiveResourceList) { |
| 650 | |
| 651 | //@author catia: (1) queue length, (2) waiting and (3) holding time of passive resources are currently set to pre-defined values |
| 652 | passiveResInfoList.add(new PassiveResInfo(passiveResource, basicComponent |
| 653 | .getEntityName(), Integer.parseInt(passiveResource |
| 654 | .getCapacity_PassiveResource().getSpecification()), 0.8, 1.0, 0.4)); |
| 655 | } |
| 656 | |
| 657 | } |
| 658 | } |
| 659 | } |
| 660 | |
| 661 | logger.info("List of Passive Resources: "); |
| 662 | for (PassiveResInfo el : passiveResInfoList) { |
| 663 | el.print(); |
| 664 | } |
| 665 | logger.info("---------------------------------------------------------------------"); |
| 666 | |
| 667 | //@author catia: select the critical passive resources |
| 668 | List<PassiveResInfo> criticalPassiveResInfoList = getCriticalPassiveRes(passiveResInfoList); |
| 669 | |
| 670 | if(criticalPassiveResInfoList.size()!= 0){ |
| 671 | for (PassiveResInfo criticalPassiveResInfo: criticalPassiveResInfoList){ |
| 672 | |
| 673 | //@author catia: detection of the antipattern OLB - the rules are verified for each critical passive resource |
| 674 | if (olb(serviceInfoList, criticalPassiveResInfo)) { |
| 675 | |
| 676 | //@author catia: solution of the antipattern OLB - "IncreaseCapacity" action |
| 677 | |
| 678 | //criticalPassiveResInfo.pr.getCapacity_PassiveResource().setSpecification("5"); |
| 679 | //Note that the capacity is increased by adding 5 units to the current one |
| 680 | TacticsResultCandidate candidate = createIncreasedCapacityCandidate(i,criticalPassiveResInfo.pr, criticalPassiveResInfo.capacity + 5); |
| 681 | listPairs.add(candidate); |
| 682 | |
| 683 | logger.info("The capacity of the passive resource " + criticalPassiveResInfo.pr.getEntityName() + " must be increased"); |
| 684 | |
| 685 | } |
| 686 | } |
| 687 | } |
| 688 | |
| 689 | //@author catia: print the resource demand (cpu, hdd) of the components involved in services specified in the usage model |
| 690 | logger.info("---------------------------------------------------------------------"); |
| 691 | logger.info("List of components involved in services specified in the usage model: "); |
| 692 | for (CompInfoResDemand el : listCompIDs) { |
| 693 | el.print(); |
| 694 | } |
| 695 | |
| 696 | //@author catia: list of components deployed on the max utilised CPU |
| 697 | List<CompInfoResDemand> depCompCpu = deployedComponents(listCompIDs, maxUtilisedCpu.rc); |
| 698 | |
| 699 | //@author catia: list of components deployed on the max utilised HDD |
| 700 | List<CompInfoResDemand> depCompHdd = deployedComponents(listCompIDs, maxUtilisedHdd.rc); |
| 701 | |
| 702 | |
| 703 | //@author catia: list of components deployed on the max utilised active resource |
| 704 | List<CompInfoResDemand> depComp = deployedComponents(listCompIDs, maxUtilised.rc); |
| 705 | |
| 706 | logger.info("---------------------------------------------------------------------"); |
| 707 | logger.info("List of seffs provided in the max utilised Active Resource : " + maxUtilised.rc.getEntityName()); |
| 708 | |
| 709 | //@author catia: list of seffs executed on the max utilised active resource |
| 710 | List<ServiceInfo> seffsOfMaxUtilised = new ArrayList<ServiceInfo>(0); |
| 711 | |
| 712 | for (CompInfoResDemand el: depComp){ |
| 713 | //@author catia: list of seffs provided by a basic component |
| 714 | List<ServiceInfo> seffsTempList = getSeffsOfComp(serviceInfoList, el.bc.getEntityName()); |
| 715 | |
| 716 | for (ServiceInfo elseff: seffsTempList){ |
| 717 | seffsOfMaxUtilised.add(elseff); |
| 718 | } |
| 719 | } |
| 720 | |
| 721 | for (ServiceInfo el : seffsOfMaxUtilised) { |
| 722 | el.print(); |
| 723 | } |
| 724 | logger.info("---------------------------------------------------------------------"); |
| 725 | |
| 726 | //@author catia: detection of the antipattern EP - the rules are verified for the active resorce maximum utilised (to be checked) |
| 727 | if (ep(maxUtilised, seffsOfMaxUtilised)) { |
| 728 | |
| 729 | // AM: example how to change the scheduling policy. Values are |
| 730 | // SchedulingPolicy.FCFS for first come first serve |
| 731 | // SchedulingPolicy.PROCESSOR_SHARING for processor sharing |
| 732 | // resource.setSchedulingPolicy(SchedulingPolicy.PROCESSOR_SHARING); |
| 733 | |
| 734 | // @author catia: solution of the antipattern EP - "UnblockExecution" action |
| 735 | //maxUtilised.setSchedulingPolicy(SchedulingPolicy.PROCESSOR_SHARING); |
| 736 | listPairs.add(createUpdatedSchedulingCandidate(i,maxUtilised,SchedulingPolicy.PROCESSOR_SHARING)); |
| 737 | |
| 738 | //listPairs.add(createUpdatedSchedulingCandidate(i,maxUtilised,SchedulingPolicy.DELAY)); |
| 739 | //listPairs.add(createUpdatedSchedulingCandidate(i,maxUtilised,SchedulingPolicy.EXACT)); |
| 740 | |
| 741 | logger.info("The scheduling policy of the active resource " + maxUtilised.rc.getEntityName() + " must be changed"); |
| 742 | } |
| 743 | |
| 744 | logger.info("---------------------------------------------------------------------"); |
| 745 | // @author catia: print the most critical components |
| 746 | logger.info("List of the most critical components: "); |
| 747 | |
| 748 | if (depCompCpu.size() !=0){ |
| 749 | CompInfoResDemand mostCriticalCpu = depCompCpu.get(getCompMaxCPUdemand(depCompCpu)); |
| 750 | logger.info("Most CPU critical"); |
| 751 | mostCriticalCpu.print(); |
| 752 | } |
| 753 | |
| 754 | if(depCompHdd.size() !=0){ |
| 755 | |
| 756 | CompInfoResDemand mostCriticalHdd = depCompHdd.get(getCompMaxHDDdemand(depCompCpu)); |
| 757 | logger.info("Most HDD critical"); |
| 758 | mostCriticalHdd.print(); |
| 759 | } |
| 760 | |
| 761 | logger.info("---------------------------------------------------------------------"); |
| 762 | |
| 763 | //@author catia: detection of the antipattern CPS |
| 764 | if (cps(activeResInfoList)) { |
| 765 | |
| 766 | //@author catia: solution of the antipattern CPS (Concurrent Processing Systems) |
| 767 | |
| 768 | List<ActiveResInfo> getUnderUsedCPUList = getUnderUsedCpu(activeResInfoList); |
| 769 | List<ActiveResInfo> getUnderUsedHDDList = getUnderUsedHDD(activeResInfoList); |
| 770 | |
| 771 | // @author catia: solution of the antipattern CPS - "Redeploy Action" with feature F1 : check the computation resource demand of the PCM components |
| 772 | // It means that the most cpu critical component is re-deployed on all under used cpu(s) available in the system, each redeployment action provides a new candidate (i.e. a pair p) |
| 773 | // Es: Redeploy component Cx in one of the following servers: S1, S2 |
| 774 | // Two candidates are evaluated: the first one in which Cx is redeployed on S1, and the second one in which Cx is redeployed on S2 |
| 775 | |
| 776 | if ((getUnderUsedCPUList.size() != 0) && (depCompCpu.size() !=0)) { |
| 777 | logger.info("Redeploy component " |
| 778 | + depCompCpu.get(getCompMaxCPUdemand(depCompCpu)).bc.getEntityName() |
| 779 | + " in the following servers: "); |
| 780 | for (ActiveResInfo el : getUnderUsedCPUList) { |
| 781 | //if (utilisationResult instanceof ProcessingResourceSpecificationResult) { |
| 782 | //ProcessingResourceSpecificationResult activeProcUtilResult = (ProcessingResourceSpecificationResult) utilisationResult; |
| 783 | // retrieve the processor for which this is the result |
| 784 | //ProcessingResourceSpecification resource = activeProcUtilResult.getProcessingresourcespecification(); |
| 785 | logger |
| 786 | .info(//resource.getResourceContainer_ProcessingResourceSpecification() |
| 787 | el.rc.getEntityName()); |
| 788 | Pair<CompInfoResDemand, ResourceContainer> p = new Pair<CompInfoResDemand, ResourceContainer>( |
| 789 | depCompCpu.get(getCompMaxCPUdemand(depCompCpu)), el.rc); |
| 790 | //resource.getResourceContainer_ProcessingResourceSpecification()); |
| 791 | listPairs.add(createCPSCandidate(i, p)); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | // @author catia: solution of the antipattern CPS - "Redeploy Action" with feature F1 : check the storage resource demand of the PCM components |
| 796 | // It means that the most hdd critical component is re-deployed on all under used hdd(s) available in the system, each redeployment action provides a new candidate (i.e. a pair p) |
| 797 | |
| 798 | if ((getUnderUsedHDDList.size() != 0) && (depCompHdd.size() !=0)) { |
| 799 | logger.info("Redeploy component " |
| 800 | + depCompHdd.get(getCompMaxHDDdemand(depCompHdd)).bc.getEntityName() |
| 801 | + " in the following servers: "); |
| 802 | for (ActiveResInfo el : getUnderUsedHDDList) { |
| 803 | //if (utilisationResult instanceof ProcessingResourceSpecificationResult) { |
| 804 | //ProcessingResourceSpecificationResult activeProcUtilResult = (ProcessingResourceSpecificationResult) utilisationResult; |
| 805 | // retrieve the processor for which this is the result |
| 806 | //ProcessingResourceSpecification resource = activeProcUtilResult.getProcessingresourcespecification(); |
| 807 | logger |
| 808 | .info(//resource.getResourceContainer_ProcessingResourceSpecification() |
| 809 | el.rc.getEntityName()); |
| 810 | Pair<CompInfoResDemand, ResourceContainer> p = new Pair<CompInfoResDemand, ResourceContainer>( |
| 811 | depCompHdd.get(getCompMaxHDDdemand(depCompHdd)), el.rc); |
| 812 | //resource.getResourceContainer_ProcessingResourceSpecification()); |
| 813 | listPairs.add(createCPSCandidate(i, p)); |
| 814 | } |
| 815 | } |
| 816 | |
| 817 | } |
| 818 | logger.info("---------------------------------------------------------------------"); |
| 819 | return listPairs; |
| 820 | } else { |
| 821 | logger |
| 822 | .warn("No performance objective or no result decorator for it found. Skipping " |
| 823 | + this.getClass().getName()); |
| 824 | } |
| 825 | return null; |
| 826 | } |
| 827 | |
| 828 | |
| 829 | @Override |
| 830 | public List<TacticsResultCandidate> getHeuristicCandidates(DSEIndividual i, |
| 831 | UtilisationResultCacheAndHelper resultsCache) { |
| 832 | |
| 833 | if (performance != null) { |
| 834 | List<TacticsResultCandidate> resultsTRC = getSolution(i); |
| 835 | |
| 836 | if (resultsTRC != null){ |
| 837 | return resultsTRC; |
| 838 | } |
| 839 | } |
| 840 | return Collections.emptyList(); |
| 841 | |
| 842 | } |
| 843 | |
| 844 | private TacticsResultCandidate createCPSCandidate(DSEIndividual i, |
| 845 | Pair<CompInfoResDemand, ResourceContainer> result) { |
| 846 | TacticsResultCandidate candidate = individualBuilder |
| 847 | .buildCandidate(copy.copy(i.getGenotype()), i); |
| 848 | |
| 849 | // apply change |
| 850 | for (Choice choice : candidate.getGenotype()) { |
| 851 | if (choice instanceof ClassChoice) { |
| 852 | ClassChoice classChoice = (ClassChoice) choice; |
| 853 | if (classChoice.getDegreeOfFreedomInstance() instanceof AllocationDegree) { |
| 854 | |
| 855 | if (EMFHelper.checkIdentity( |
| 856 | classChoice.getDegreeOfFreedomInstance().getPrimaryChanged(), |
| 857 | result.getFirst().ac)) { |
| 858 | |
| 859 | // if (ClassChoice.getDegreeOfFreedomInstance().g) |
| 860 | |
| 861 | classChoice.setChosenValue(EMFHelper.retrieveEntityByID( |
| 862 | ((ClassDegree)classChoice.getDegreeOfFreedomInstance()).getClassDesignOptions(), |
| 863 | result.getSecond())); |
| 864 | |
| 865 | // set weight to one for now, maybe later find a better value. |
| 866 | candidate.setCandidateWeight(1); |
| 867 | candidate.setHeuristic(this); |
| 868 | increaseCounterOfGeneratedCandidates(); |
| 869 | |
| 870 | logger.info("Applied CPS solution"); |
| 871 | return candidate; |
| 872 | |
| 873 | } |
| 874 | } |
| 875 | } |
| 876 | } |
| 877 | throw new RuntimeException("Changing the allocation of "+result.getFirst().ac.getEntityName()+" is not allowed with the current designdecision model."); |
| 878 | } |
| 879 | |
| 880 | private TacticsResultCandidate createIncreasedCapacityCandidate( |
| 881 | DSEIndividual i, PassiveResource pr, int newCapacity) { |
| 882 | TacticsResultCandidate candidate = individualBuilder |
| 883 | .buildCandidate(copy.copy(i.getGenotype()), i); |
| 884 | |
| 885 | // apply change |
| 886 | for (Choice choice : candidate.getGenotype()) { |
| 887 | if (choice instanceof DiscreteRangeChoice) { |
| 888 | DiscreteRangeChoice schedChoice = (DiscreteRangeChoice) choice; |
| 889 | if (schedChoice.getDegreeOfFreedomInstance() instanceof CapacityDegree) { |
| 890 | |
| 891 | if (EMFHelper.checkIdentity(schedChoice |
| 892 | .getDegreeOfFreedomInstance().getPrimaryChanged(), pr)) { |
| 893 | |
| 894 | // if (ClassChoice.getDegreeOfFreedomInstance().g) |
| 895 | |
| 896 | schedChoice.setChosenValue(newCapacity); |
| 897 | |
| 898 | // set weight to one for now, maybe later find a better value. |
| 899 | candidate.setCandidateWeight(1); |
| 900 | candidate.setHeuristic(this); |
| 901 | increaseCounterOfGeneratedCandidates(); |
| 902 | |
| 903 | logger.info("Increased capacity of "+pr.getEntityName()+" to "+newCapacity); |
| 904 | return candidate; |
| 905 | |
| 906 | } |
| 907 | } |
| 908 | } |
| 909 | } |
| 910 | throw new RuntimeException("Increasing the capacity of passive resource "+pr.getEntityName()+" is not allowed with the current designdecision model."); |
| 911 | } |
| 912 | |
| 913 | |
| 914 | private TacticsResultCandidate createUpdatedSchedulingCandidate( |
| 915 | DSEIndividual i, ActiveResInfo resourceToChange, |
| 916 | SchedulingPolicy schedulingPolicy) { |
| 917 | TacticsResultCandidate candidate = individualBuilder.buildCandidate( |
| 918 | copy.copy(i.getGenotype()), i); |
| 919 | |
| 920 | // apply change |
| 921 | for (Choice choice : candidate.getGenotype()) { |
| 922 | if (choice instanceof SchedulingPolicyChoice) { |
| 923 | SchedulingPolicyChoice ClassChoice = (SchedulingPolicyChoice) choice; |
| 924 | if (ClassChoice.getDegreeOfFreedomInstance() instanceof SchedulingPolicyDegree) { |
| 925 | |
| 926 | SchedulingPolicyDegree schedDegree = (SchedulingPolicyDegree)ClassChoice.getDegreeOfFreedomInstance(); |
| 927 | if (EMFHelper.checkIdentity(schedDegree.getPrimaryChanged(),resourceToChange.rc) |
| 928 | && EMFHelper.checkIdentity(schedDegree.getProcessingresourcetype(),resourceToChange.type)) { |
| 929 | |
| 930 | // if (ClassChoice.getDegreeOfFreedomInstance().g) |
| 931 | |
| 932 | ClassChoice.setChosenValue(schedulingPolicy); |
| 933 | |
| 934 | // set weight to one for now, maybe later find a better |
| 935 | // value. |
| 936 | candidate.setCandidateWeight(1); |
| 937 | candidate.setHeuristic(this); |
| 938 | increaseCounterOfGeneratedCandidates(); |
| 939 | |
| 940 | logger.info("Changed scheduling policy of "+resourceToChange.type.getEntityName()+" of " |
| 941 | + resourceToChange.rc.getEntityName() + " to " + schedulingPolicy.getLiteral()); |
| 942 | return candidate; |
| 943 | |
| 944 | } |
| 945 | } |
| 946 | } |
| 947 | } |
| 948 | throw new RuntimeException( |
| 949 | "Changing the scheduling of "+resourceToChange.type.getEntityName()+" of " |
| 950 | + resourceToChange.rc.getEntityName()+ " is not allowed with the current designdecision model."); |
| 951 | |
| 952 | } |
| 953 | |
| 954 | |
| 955 | |
| 956 | } |