package at.ac.tuwien.dsg.sybl.syblProcessingUnit.processing; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import at.ac.tuwien.dsg.csdg.DependencyGraph; import at.ac.tuwien.dsg.csdg.Node; import at.ac.tuwien.dsg.csdg.Node.NodeType; import at.ac.tuwien.dsg.csdg.Relationship.RelationshipType; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityCapabilityInformation; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityRequirement; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Constraint; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.SYBLAnnotation; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.SYBLSpecification; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Strategy; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.InputProcessing; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.abstractModelXML.SYBLDirectiveMappingFromXML; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.primitives.ElasticityPrimitive; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.primitives.ElasticityPrimitiveDependency; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.primitives.ElasticityPrimitivesDescription; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.primitives.ServiceElasticityPrimitives; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.ActionPlanEvent; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.EventNotification; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.IEvent; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.IEvent.Stage; import at.ac.tuwien.dsg.rSybl.cloudInteractionUnit.api.EnforcementAPIInterface; import at.ac.tuwien.dsg.sybl.syblProcessingUnit.utils.SYBLDirectivesEnforcementLogger; import java.util.AbstractMap; public class ElasticityCapabilityEnforcement { EnforcementAPIInterface enforcementAPI = null; ElasticityPrimitivesDescription primitivesDescription = null; EventNotification eventNotification = EventNotification.getEventNotification(); public ElasticityCapabilityEnforcement(EnforcementAPIInterface apiInterface) { enforcementAPI = apiInterface; try { InputProcessing inputProcessing = new InputProcessing(); primitivesDescription = inputProcessing.loadElasticityPrimitivesDescriptionFromFile(); } catch (Exception e) { SYBLDirectivesEnforcementLogger.logger.error("Failed to load enabled primitives, working with default case"); } } public boolean checkECPossible(ElasticityCapabilityInformation ec) { List<String> execTargets = enforcementAPI.getPluginsExecutingActions(); for (String target : getTargetsOfPrimitives(ec)) { if (execTargets.contains(target)) { return false; } } return true; } public List<String> getTargetsOfPrimitives(ElasticityCapabilityInformation elasticityCapability) { List<String> targets = new ArrayList<String>(); String[] primitives = elasticityCapability .getPrimitiveOperations().split(";"); for (String primitive : primitives) { String actionName = primitive; if (actionName.contains(".")) { targets.add(actionName.split("\\.")[0]); actionName = actionName.split("\\.")[1]; } } return targets; } public void enforceActionGivenPrimitives( String actionName, Node target, DependencyGraph dependencyGraph, Constraint c, Strategy s) { IEvent.Stage stage = null; boolean started = false; if (!dependencyGraph.isInControlState()) { SYBLDirectivesEnforcementLogger.logger.info("Not enforcing action due to breakpoint "); return; } else { SYBLDirectivesEnforcementLogger.logger.info("Starting enforcing action" + actionName + " on target " + target + "."); } for (ElasticityCapabilityInformation elasticityCapability : target.getElasticityCapabilities()) { if (elasticityCapability.getName().trim().contains(actionName.trim()) && checkECPossible(elasticityCapability)) { if (!elasticityCapability.getName().toLowerCase().contains("scalein") || (elasticityCapability.getName().toLowerCase().contains("scalein") && target.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).size() > 1)) { ActionPlanEvent actionPlanEvent = new ActionPlanEvent(); actionPlanEvent.setServiceId(dependencyGraph.getCloudService().getId()); actionPlanEvent.addEffect(new AbstractMap.SimpleEntry<>(elasticityCapability.getName().toLowerCase(), target.getId())); if (c!=null){ actionPlanEvent.addConstraint(c);} if (s!=null){ actionPlanEvent.addStrategy(s);} actionPlanEvent.setType(IEvent.Type.ELASTICITY_CONTROL); actionPlanEvent.setStage(Stage.START); EventNotification en = EventNotification.getEventNotification(); en.sendEvent(actionPlanEvent); started = true; String[] primitives = elasticityCapability .getPrimitiveOperations().split(";"); for (int i = 0; i < primitives.length; i++) { if (!enforcePrimitive(primitivesDescription, primitives[i], target, dependencyGraph)) { SYBLDirectivesEnforcementLogger.logger.info("Failed Enforcing " + primitives[i] + ", cancelling the entire elasticity capability "); stage = IEvent.Stage.FAILED; break; } else { SYBLDirectivesEnforcementLogger.logger.info("Successfully enforced " + primitives[i] + ", continuing with capability "); } } break; } } } if (started) { if (stage == null) { stage = IEvent.Stage.FINISHED; } ActionPlanEvent actionPlanEvent = new ActionPlanEvent(); actionPlanEvent.setServiceId(dependencyGraph.getCloudService().getId()); // actionPlanEvent.addEffect(new AbstractMap.SimpleEntry<String, String>(elasticityCapability.getName().toLowerCase(), target.getId())); if (c!=null){ actionPlanEvent.addConstraint(c);} if (s!=null){ actionPlanEvent.addStrategy(s);} actionPlanEvent.setType(IEvent.Type.ELASTICITY_CONTROL); actionPlanEvent.setStage(stage); EventNotification en = EventNotification.getEventNotification(); en.sendEvent(actionPlanEvent); } } public Object parseParameter(String param, Node node, DependencyGraph dependencyGraph, String IP, String UUID) { String result = param; if (!param.contains(" ") && !param.contains(".") && !param.contains("$")) { if (param.equalsIgnoreCase("IP")) { return IP; } if (param.equalsIgnoreCase("UUID")) { return UUID; } } else { if (param.contains("{") && param.contains(".")) { result = param; String REGEX_IP = "(\\{[A-Za-z0-9]+\\}\\.IP)"; Pattern p = Pattern.compile(REGEX_IP, Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(param); // get a matcher object int nbFound = m.groupCount(); int i = 0; while (m.find()) { String value = m.group(); String nodeId = value.substring(1, value.indexOf('.') - 1); Node searchNode = null; for (Node myNode : dependencyGraph.getAllServiceUnits()) { if (myNode.getId().toLowerCase() .contains(nodeId.toLowerCase())) { searchNode = myNode; break; } } if (searchNode == null) { for (Node myNode : dependencyGraph.getAllServiceUnits()) { if (myNode.getId().toLowerCase() .contains(nodeId.toLowerCase())) { searchNode = myNode; break; } } } String newRegex = "(\\{" + nodeId + "\\}\\.IP)"; Pattern p1 = Pattern.compile(newRegex); Matcher m1 = p1.matcher(result); // get a matcher object if (searchNode.getNodeType() == NodeType.VIRTUAL_MACHINE) { String ip = (String) searchNode.getStaticInformation().get("IP"); if (ip == null || ip.equalsIgnoreCase("")) { ip = searchNode.getId(); } result = m1.replaceAll(ip); } else { Node artifact = null; Node container = null; Node accessToVM = searchNode; if (searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } Node search = accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).get(0); String ip = (String) search.getStaticInformation().get("IP"); if (ip == null || ip.equalsIgnoreCase("")) { ip = search.getId(); } result = m1.replaceAll(ip); } i++; } param = result; REGEX_IP = "(\\{[A-Za-z0-9]+\\}\\.UUID)"; p = Pattern.compile(REGEX_IP, Pattern.CASE_INSENSITIVE); m = p.matcher(param); // get a matcher object nbFound = m.groupCount(); i = 0; while (m.find()) { String value = m.group(); String nodeId = value.substring(1, value.indexOf('.') - 1); Node searchNode = null; for (Node myNode : dependencyGraph.getAllServiceUnits()) { if (myNode.getId().toLowerCase() .contains(nodeId.toLowerCase())) { searchNode = myNode; break; } } if (searchNode == null) { for (Node myNode : dependencyGraph.getAllServiceUnits()) { if (myNode.getId().toLowerCase() .contains(nodeId.toLowerCase())) { searchNode = myNode; break; } } } String newRegex = "(\\{" + nodeId + "\\}\\.UUID)"; Pattern p1 = Pattern.compile(newRegex); Matcher m1 = p1.matcher(result); // get a matcher object if (searchNode.getNodeType() == NodeType.VIRTUAL_MACHINE) { String ip = (String) searchNode.getStaticInformation().get("UUID"); if (ip == null || ip.equalsIgnoreCase("")) { ip = searchNode.getId(); } result = m1.replaceAll(ip); } else { Node artifact = null; Node container = null; Node accessToVM = searchNode; if (searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = searchNode.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } Node search = accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).get(0); String ip = (String) search.getStaticInformation().get("UUID"); if (ip == null || ip.equalsIgnoreCase("")) { ip = search.getId(); } result = m1.replaceAll(ip); } i++; } param = result; } if (param.contains("IP") || param.contains("UUID")) { String REGEX = "IP"; Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(param); // get a matcher object param = m.replaceAll(IP); REGEX = "UUID"; p = Pattern.compile(REGEX); m = p.matcher(param); // get a matcher object return m.replaceAll(UUID); } } return param; } public void scaleDiagonally(Node currentEntity,Strategy s){ enforcementAPI.diagonallyScale(currentEntity, s); } public boolean enforcePrimitive( ElasticityPrimitivesDescription primitivesDescription, String primitive, Node node, DependencyGraph dependencyGraph) { String target = ""; String actionName = primitive; SYBLDirectivesEnforcementLogger.logger.info("Trying to enforce primitive " + actionName); if (actionName.contains(".")) { target = actionName.split("\\.")[0]; actionName = actionName.split("\\.")[1]; } if (target.equalsIgnoreCase("")) { for (ElasticityCapabilityInformation capability : node .getElasticityCapabilities()) { if (capability.getName().toLowerCase().contains(actionName)) { if (capability.getName().toLowerCase().contains(".")) { target = capability.getName().split("\\.")[0].toLowerCase(); } } } } if (target.equalsIgnoreCase("")) { switch (actionName.toLowerCase()) { case "scaleout": SYBLDirectivesEnforcementLogger.logger.info("Calling Scale out from sybl parser "); return enforcementAPI.scaleout(node); case "scalein": SYBLDirectivesEnforcementLogger.logger.info("Calling Scale in from sybl parser "); return enforcementAPI.scalein(node); default: return enforcementAPI.enforceAction(actionName, node); } } else { boolean res = true; for (ServiceElasticityPrimitives serviceElasticityPrimitives : primitivesDescription .getElasticityPrimitives()) { if (serviceElasticityPrimitives.getId() .equalsIgnoreCase(target)) { for (ElasticityPrimitive elasticityPrimitive : serviceElasticityPrimitives .getElasticityPrimitives()) { if (elasticityPrimitive.getId().equalsIgnoreCase( actionName)) { if (elasticityPrimitive.getParameters() .equalsIgnoreCase("")) { boolean x = enforcementAPI.enforceAction(target, actionName, node); if (x == false) { res = false; } } else { List<ElasticityPrimitiveDependency> elasticityPrimitiveDependencies = elasticityPrimitive .getPrimitiveDependencies(); List<ElasticityPrimitiveDependency> beforePrimitives = new ArrayList<ElasticityPrimitiveDependency>(); List<ElasticityPrimitiveDependency> afterPrimitives = new ArrayList<ElasticityPrimitiveDependency>(); for (ElasticityPrimitiveDependency dependency : elasticityPrimitiveDependencies) { if (dependency.getDependencyType().equalsIgnoreCase("BEFORE")) { beforePrimitives.add(dependency); } else { afterPrimitives.add(dependency); } //TODO: } Object[] parameters = new Object[elasticityPrimitive .getParameters().split(",").length]; Object transferredParameters; String ip = ""; String uuid = ""; if (node.getNodeType() == NodeType.VIRTUAL_MACHINE) { ip = (String) node.getStaticInformation() .get("IP"); if (ip == null || ip.equalsIgnoreCase("")) { ip = node.getId(); } uuid = (String) node.getStaticInformation() .get("UUID"); if (uuid == null || uuid.equalsIgnoreCase("")) { uuid = node.getId(); } } else { if (node.getNodeType() == NodeType.SERVICE_UNIT) { Node artifact = null; Node container = null; Node accessToVM = node; if (node.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && node.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = node.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } Node newNode = accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).get(0); ip = (String) newNode.getStaticInformation() .get("IP"); if (ip == null || ip.equalsIgnoreCase("")) { ip = newNode.getId(); } uuid = (String) newNode.getStaticInformation() .get("UUID"); if (uuid == null || uuid.equalsIgnoreCase("")) { uuid = newNode.getId(); } } } int i = 0; for (String parameter : elasticityPrimitive .getParameters().split(",")) { parameter.trim(); parameters[i] = parseParameter(parameter, node, dependencyGraph, ip, uuid); i += 1; } for (ElasticityPrimitiveDependency elasticityPrimitiveDependency : beforePrimitives) { // check before primitives boolean x = enforcePrimitive(primitivesDescription, elasticityPrimitiveDependency .getPrimitiveID(), node, dependencyGraph); if (!x) { res = false; } } String methodName = elasticityPrimitive .getMethodName(); if (methodName.equalsIgnoreCase("")) { if (!target.equalsIgnoreCase("")) { boolean x = enforcementAPI.enforceAction(target, actionName, node, parameters); if (!x) { res = false; } } else { boolean x = enforcementAPI.enforceAction( actionName, node, parameters); if (!x) { res = false; } } } else { if (!target.equalsIgnoreCase("")) { boolean x = enforcementAPI.enforceAction(target, methodName, node, parameters); if (!x) { res = false; } } else { boolean x = enforcementAPI.enforceAction( methodName, node, parameters); if (!x) { res = false; } } } for (ElasticityPrimitiveDependency elasticityPrimitiveDependency : afterPrimitives) { // check before primitives boolean x = enforcePrimitive(primitivesDescription, elasticityPrimitiveDependency .getPrimitiveID(), node, dependencyGraph); if (!x) { res = false; } } } break; } } break; } } //SYBLDirectivesEnforcementLogger.logger.info("Enforcing primitive success="+res); return res; // switch (actionName) { // case "scaleout": // SYBLDirectivesEnforcementLogger.logger.info("Calling Scale out from planning "); // // enforcementAPI.scaleout(target, node); // break; // case "scalein": // SYBLDirectivesEnforcementLogger.logger.info("Calling Scale in from planning "); // // enforcementAPI.scalein(target, node); // break; // default: // if (target.equalsIgnoreCase("")) { // enforcementAPI.enforceAction(target, actionName, node); // } // // break; // } } } }