From 0636411a4915a462d2cf6698ecb9c68c478f6ef5 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Thu, 16 Aug 2018 16:49:24 +0200 Subject: Fix for sonar issue Fix for some sonars. Increase code coverage. Issue-ID: CLAMP-211 Change-Id: If1b5169ff832fc94886b178226570dc0559fe3c2 Signed-off-by: Gabriel --- .../clds/client/OperationalPolicyDelegate.java | 26 +- .../OperationalPolicyAttributesConstructor.java | 158 +++++++++++ .../client/req/policy/OperationalPolicyReq.java | 316 --------------------- .../req/policy/OperationalPolicyYamlFormatter.java | 184 ++++++++++++ .../java/org/onap/clamp/clds/util/ClampTimer.java | 3 +- 5 files changed, 358 insertions(+), 329 deletions(-) create mode 100644 src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyAttributesConstructor.java delete mode 100644 src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java create mode 100644 src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyYamlFormatter.java (limited to 'src/main') diff --git a/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java b/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java index e324b2d99..ddadb55cc 100644 --- a/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java +++ b/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java @@ -17,6 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END============================================ + * Modifications copyright (c) 2018 Nokia * =================================================================== * */ @@ -31,7 +32,7 @@ import java.util.Map; import org.apache.camel.Exchange; import org.apache.camel.Handler; -import org.onap.clamp.clds.client.req.policy.OperationalPolicyReq; +import org.onap.clamp.clds.client.req.policy.OperationalPolicyAttributesConstructor; import org.onap.clamp.clds.client.req.policy.PolicyClient; import org.onap.clamp.clds.config.ClampProperties; import org.onap.clamp.clds.model.properties.ModelProperties; @@ -52,16 +53,17 @@ public class OperationalPolicyDelegate { protected static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicyDelegate.class); protected static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); - /** - * Automatically injected by Spring, define in CldsConfiguration as a bean. - */ - @Autowired - private PolicyClient policyClient; - /** - * Automatically injected by Spring, define in CldsConfiguration as a bean. - */ + private final PolicyClient policyClient; + private final ClampProperties refProp; + private final OperationalPolicyAttributesConstructor attributesConstructor; + @Autowired - private ClampProperties refProp; + public OperationalPolicyDelegate(PolicyClient policyClient, ClampProperties refProp, + OperationalPolicyAttributesConstructor attributesConstructor) { + this.policyClient = policyClient; + this.refProp = refProp; + this.attributesConstructor = attributesConstructor; + } /** * Perform activity. Send Operational Policy info to policy api. @@ -69,7 +71,7 @@ public class OperationalPolicyDelegate { * @param camelExchange * The Camel Exchange object containing the properties * @throws BuilderException - * In case of issues with OperationalPolicyReq + * In case of issues with OperationalPolicyRequestAttributesConstructor * @throws UnsupportedEncodingException * In case of issues with the Charset encoding */ @@ -80,7 +82,7 @@ public class OperationalPolicyDelegate { Policy policy = prop.getType(Policy.class); if (policy.isFound()) { for (PolicyChain policyChain : prop.getType(Policy.class).getPolicyChains()) { - Map> attributes = OperationalPolicyReq.formatAttributes(refProp, + Map> attributes = attributesConstructor.formatAttributes(refProp, prop, prop.getType(Policy.class).getId(), policyChain); responseMessage = policyClient.sendBrmsPolicy(attributes, prop, LoggingUtils.getRequestId()); } diff --git a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyAttributesConstructor.java b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyAttributesConstructor.java new file mode 100644 index 000000000..09f98f19a --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyAttributesConstructor.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * Modifications copyright (c) 2018 Nokia + * =================================================================== + * + */ + +package org.onap.clamp.clds.client.req.policy; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import org.onap.clamp.clds.config.ClampProperties; +import org.onap.clamp.clds.model.properties.ModelProperties; +import org.onap.clamp.clds.model.properties.PolicyChain; +import org.onap.clamp.clds.model.properties.PolicyItem; +import org.onap.policy.api.AttributeType; +import org.onap.policy.controlloop.policy.builder.BuilderException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +@Component +public class OperationalPolicyAttributesConstructor { + + private static final EELFLogger logger = EELFManager.getInstance() + .getLogger(OperationalPolicyAttributesConstructor.class); + static final String TEMPLATE_NAME = "templateName"; + static final String CLOSED_LOOP_CONTROL_NAME = "closedLoopControlName"; + static final String NOTIFICATION_TOPIC = "notificationTopic"; + static final String OPERATION_TOPIC = "operationTopic"; + static final String CONTROL_LOOP_YAML = "controlLoopYaml"; + static final String CONTROLLER = "controller"; + static final String RECIPE = "Recipe"; + static final String MAX_RETRIES = "MaxRetries"; + static final String RETRY_TIME_LIMIT = "RetryTimeLimit"; + static final String RESOURCE_ID = "ResourceId"; + static final String RECIPE_TOPIC = "RecipeTopic"; + private OperationalPolicyYamlFormatter policyYamlFormatter; + + @Autowired + protected OperationalPolicyAttributesConstructor(OperationalPolicyYamlFormatter policyYamlFormatter) { + this.policyYamlFormatter = policyYamlFormatter; + } + + public Map> formatAttributes(ClampProperties refProp, + ModelProperties modelProperties, + String modelElementId, PolicyChain policyChain) + throws BuilderException, UnsupportedEncodingException { + modelProperties.setCurrentModelElementId(modelElementId); + modelProperties.setPolicyUniqueId(policyChain.getPolicyId()); + + String globalService = modelProperties.getGlobal().getService(); + + Map ruleAttributes = prepareRuleAttributes(refProp, modelProperties, modelElementId, + policyChain, globalService); + Map matchingAttributes = prepareMatchingAttributes(refProp, globalService); + + return createAttributesMap(matchingAttributes, ruleAttributes); + } + + private Map prepareRuleAttributes(ClampProperties clampProperties, ModelProperties modelProperties, + String modelElementId, PolicyChain policyChain, String globalService) + throws BuilderException, UnsupportedEncodingException { + logger.info("Preparing rule attributes..."); + String templateName = clampProperties.getStringValue("op.templateName", globalService); + String operationTopic = clampProperties.getStringValue("op.operationTopic", globalService); + String notificationTopic = clampProperties.getStringValue("op.notificationTopic", globalService); + + Map ruleAttributes = new HashMap<>(); + ruleAttributes.put(TEMPLATE_NAME, templateName); + ruleAttributes.put(CLOSED_LOOP_CONTROL_NAME, modelProperties.getControlNameAndPolicyUniqueId()); + ruleAttributes.put(NOTIFICATION_TOPIC, notificationTopic); + + ImmutableMap attributes = createRuleAttributesFromPolicy(clampProperties, modelProperties, + modelElementId, policyChain, globalService, operationTopic); + ruleAttributes.putAll(attributes); + logger.info("Prepared: " + ruleAttributes); + return ruleAttributes; + } + + private Map prepareMatchingAttributes(ClampProperties refProp, String globalService) { + logger.info("Preparing matching attributes..."); + String controller = refProp.getStringValue("op.controller", globalService); + Map matchingAttributes = new HashMap<>(); + matchingAttributes.put(CONTROLLER, controller); + logger.info("Prepared: " + matchingAttributes); + return matchingAttributes; + } + + private Map> createAttributesMap(Map matchingAttributes, + Map ruleAttributes) { + Map> attributes = new HashMap<>(); + attributes.put(AttributeType.RULE, ruleAttributes); + attributes.put(AttributeType.MATCHING, matchingAttributes); + return attributes; + } + + private ImmutableMap createRuleAttributesFromPolicy(ClampProperties refProp, ModelProperties modelProperties, + String modelElementId, PolicyChain policyChain, + String globalService, String operationTopic) + throws BuilderException, UnsupportedEncodingException { + if (Strings.isNullOrEmpty(operationTopic)) { + // if no operationTopic, then don't format yaml - use first policy + String recipeTopic = refProp.getStringValue("op.recipeTopic", globalService); + return createRuleAttributesFromPolicyItem( + policyChain.getPolicyItems().get(0), recipeTopic); + } else { + return createRuleAttributesFromPolicyChain(policyChain, modelProperties, + modelElementId, operationTopic); + } + } + + private ImmutableMap createRuleAttributesFromPolicyItem(PolicyItem policyItem, String recipeTopic) { + logger.info("recipeTopic=" + recipeTopic); + return ImmutableMap.builder() + .put(RECIPE_TOPIC, recipeTopic) + .put(RECIPE, policyItem.getRecipe()) + .put(MAX_RETRIES, String.valueOf(policyItem.getMaxRetries())) + .put(RETRY_TIME_LIMIT, String.valueOf(policyItem.getRetryTimeLimit())) + .put(RESOURCE_ID, String.valueOf(policyItem.getTargetResourceId())) + .build(); + } + + private ImmutableMap createRuleAttributesFromPolicyChain(PolicyChain policyChain, + ModelProperties modelProperties, + String modelElementId, + String operationTopic) + throws BuilderException, UnsupportedEncodingException { + logger.info("operationTopic=" + operationTopic); + String yaml = policyYamlFormatter.formatYaml(modelProperties, modelElementId, policyChain); + return ImmutableMap.builder() + .put(OPERATION_TOPIC, operationTopic) + .put(CONTROL_LOOP_YAML, yaml) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java deleted file mode 100644 index f062dfca6..000000000 --- a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java +++ /dev/null @@ -1,316 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END============================================ - * Modifications copyright (c) 2018 Nokia - * =================================================================== - * - */ - -package org.onap.clamp.clds.client.req.policy; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.ws.rs.BadRequestException; - -import org.onap.clamp.clds.config.ClampProperties; -import org.onap.clamp.clds.model.properties.Global; -import org.onap.clamp.clds.model.properties.ModelProperties; -import org.onap.clamp.clds.model.properties.PolicyChain; -import org.onap.clamp.clds.model.properties.PolicyItem; -import org.onap.policy.api.AttributeType; -import org.onap.policy.controlloop.policy.Policy; -import org.onap.policy.controlloop.policy.PolicyResult; -import org.onap.policy.controlloop.policy.Target; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.controlloop.policy.builder.BuilderException; -import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder; -import org.onap.policy.controlloop.policy.builder.Message; -import org.onap.policy.controlloop.policy.builder.Results; -import org.onap.policy.sdc.Resource; -import org.onap.policy.sdc.ResourceType; -import org.onap.policy.sdc.Service; - -/** - * Construct an Operational Policy request given CLDS objects. - */ -public class OperationalPolicyReq { - - private static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicyReq.class); - - protected OperationalPolicyReq() { - } - - /** - * Format Operational Policy attributes. - * - * @param refProp - * @param prop - * @param modelElementId - * @param policyChain - * @return - * @throws BuilderException - * @throws UnsupportedEncodingException - */ - public static Map> formatAttributes(ClampProperties refProp, - ModelProperties prop, String modelElementId, PolicyChain policyChain) - throws BuilderException, UnsupportedEncodingException { - Global global = prop.getGlobal(); - prop.setCurrentModelElementId(modelElementId); - prop.setPolicyUniqueId(policyChain.getPolicyId()); - String templateName = refProp.getStringValue("op.templateName", global.getService()); - String operationTopic = refProp.getStringValue("op.operationTopic", global.getService()); - String notificationTopic = refProp.getStringValue("op.notificationTopic", global.getService()); - String controller = refProp.getStringValue("op.controller", global.getService()); - String recipeTopic = refProp.getStringValue("op.recipeTopic", global.getService()); - // ruleAttributes - logger.info("templateName=" + templateName); - logger.info("notificationTopic=" + notificationTopic); - Map ruleAttributes = new HashMap<>(); - ruleAttributes.put("templateName", templateName); - ruleAttributes.put("closedLoopControlName", prop.getControlNameAndPolicyUniqueId()); - ruleAttributes.put("notificationTopic", notificationTopic); - if (operationTopic == null || operationTopic.isEmpty()) { - logger.info("recipeTopic=" + recipeTopic); - // if no operationTopic, then don't format yaml - use first policy - // from list - PolicyItem policyItem = policyChain.getPolicyItems().get(0); - ruleAttributes.put("RecipeTopic", recipeTopic); - String recipe = policyItem.getRecipe(); - String maxRetries = String.valueOf(policyItem.getMaxRetries()); - String retryTimeLimit = String.valueOf(policyItem.getRetryTimeLimit()); - String targetResourceId = String.valueOf(policyItem.getTargetResourceId()); - logger.info("recipe=" + recipe); - logger.info("maxRetries=" + maxRetries); - logger.info("retryTimeLimit=" + retryTimeLimit); - logger.info("targetResourceId=" + targetResourceId); - ruleAttributes.put("Recipe", recipe); - ruleAttributes.put("MaxRetries", maxRetries); - ruleAttributes.put("RetryTimeLimit", retryTimeLimit); - ruleAttributes.put("ResourceId", targetResourceId); - } else { - logger.info("operationTopic=" + operationTopic); - // format yaml - String yaml = formatYaml(refProp, prop, modelElementId, policyChain); - ruleAttributes.put("operationTopic", operationTopic); - ruleAttributes.put("controlLoopYaml", yaml); - } - // matchingAttributes - Map matchingAttributes = new HashMap<>(); - matchingAttributes.put("controller", controller); - Map> attributes = new HashMap<>(); - attributes.put(AttributeType.RULE, ruleAttributes); - attributes.put(AttributeType.MATCHING, matchingAttributes); - return attributes; - } - - /** - * Format Operational OpenLoop Policy yaml. - * - * @param refProp - * @param prop - * @param modelElementId - * @param policyChain - * @return - * @throws BuilderException - * @throws UnsupportedEncodingException - */ - protected static String formatOpenLoopYaml(ClampProperties refProp, ModelProperties prop, String modelElementId, - PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException { - // get property objects - Global global = prop.getGlobal(); - prop.setCurrentModelElementId(modelElementId); - prop.setPolicyUniqueId(policyChain.getPolicyId()); - // convert values to SDC objects - Service service = new Service(global.getService()); - Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF); - // create builder - ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(), - policyChain.getTimeout(), service, vfResources); - // builder.setTriggerPolicy(refProp.getStringValue("op.openloop.policy")); - // Build the specification - Results results = builder.buildSpecification(); - validate(results); - return URLEncoder.encode(results.getSpecification(), "UTF-8"); - } - - /** - * Format Operational Policy yaml. - * - * @param refProp - * @param prop - * @param modelElementId - * @param policyChain - * @return - * @throws BuilderException - * @throws UnsupportedEncodingException - */ - protected static String formatYaml(ClampProperties refProp, ModelProperties prop, String modelElementId, - PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException { - // get property objects - Global global = prop.getGlobal(); - prop.setCurrentModelElementId(modelElementId); - prop.setPolicyUniqueId(policyChain.getPolicyId()); - // convert values to SDC objects - Service service = new Service(global.getService()); - Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF); - Resource[] vfcResources = convertToResource(global.getResourceVfc(), ResourceType.VFC); - // create builder - ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(), - policyChain.getTimeout(), service, vfResources); - builder.addResource(vfcResources); - // process each policy - Map policyObjMap = new HashMap<>(); - List policyItemList = orderParentFirst(policyChain.getPolicyItems()); - for (PolicyItem policyItem : policyItemList) { - String policyName = policyItem.getRecipe() + " Policy"; - Target target = new Target(); - target.setType(TargetType.VM); - // We can send target type as VM/VNF for most of recipes - if (policyItem.getRecipeLevel() != null && !policyItem.getRecipeLevel().isEmpty()) { - target.setType(TargetType.valueOf(policyItem.getRecipeLevel())); - } - target.setResourceID(policyItem.getTargetResourceId()); - String actor = policyItem.getActor(); - Map payloadMap = policyItem.getRecipePayload(); - Policy policyObj; - if (policyItemList.indexOf(policyItem) == 0) { - String policyDescription = policyItem.getRecipe() - + " Policy - the trigger (no parent) policy - created by CLDS"; - policyObj = builder.setTriggerPolicy(policyName, policyDescription, actor, target, - policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit()); - } else { - Policy parentPolicyObj = policyObjMap.get(policyItem.getParentPolicy()); - String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by " - + parentPolicyObj.getName() + " - created by CLDS"; - policyObj = builder.setPolicyForPolicyResult(policyName, policyDescription, actor, target, - policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit(), - parentPolicyObj.getId(), convertToPolicyResult(policyItem.getParentPolicyConditions())); - logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId()); - } - policyObjMap.put(policyItem.getId(), policyObj); - } - // Build the specification - Results results = builder.buildSpecification(); - validate(results); - return URLEncoder.encode(results.getSpecification(), "UTF-8"); - } - - protected static void validate(Results results) { - if (results.isValid()) { - logger.info("results.getSpecification()=" + results.getSpecification()); - } else { - // throw exception with error info - StringBuilder sb = new StringBuilder(); - sb.append("Operation Policy validation problem: ControlLoopPolicyBuilder failed with following messages: "); - for (Message message : results.getMessages()) { - sb.append(message.getMessage()); - sb.append("; "); - } - throw new BadRequestException(sb.toString()); - } - } - - /** - * Order list of PolicyItems so that parents come before any of their - * children - * - * @param inOrigList - * @return - */ - private static List orderParentFirst(List inOrigList) { - List inList = new ArrayList<>(); - inList.addAll(inOrigList); - List outList = new ArrayList<>(); - int prevSize = 0; - while (!inList.isEmpty()) { - // check if there's a loop in the policy chain (the inList should - // have been reduced by at least one) - if (inList.size() == prevSize) { - throw new BadRequestException("Operation Policy validation problem: loop in Operation Policy chain"); - } - prevSize = inList.size(); - // the following loop should remove at least one PolicyItem from the - // inList - Iterator inListItr = inList.iterator(); - while (inListItr.hasNext()) { - PolicyItem inItem = inListItr.next(); - // check for trigger policy (no parent) - String parent = inItem.getParentPolicy(); - if (parent == null || parent.length() == 0) { - if (!outList.isEmpty()) { - throw new BadRequestException( - "Operation Policy validation problem: more than one trigger policy"); - } else { - outList.add(inItem); - inListItr.remove(); - } - } else { - // check if this PolicyItem's parent has been processed - for (PolicyItem outItem : outList) { - if (outItem.getId().equals(parent)) { - // if the inItem parent is already in the outList, - // then add inItem to outList and remove from inList - outList.add(inItem); - inListItr.remove(); - break; - } - } - } - } - } - return outList; - } - - /** - * Convert a List of resource strings to an array of Resource objects. - * - * @param stringList - * @param resourceType - * @return - */ - protected static Resource[] convertToResource(List stringList, ResourceType resourceType) { - if (stringList == null || stringList.isEmpty()) { - return new Resource[0]; - } - return stringList.stream().map(stringElem -> new Resource(stringElem, resourceType)).toArray(Resource[]::new); - } - - /** - * Convert a List of policy result strings to an array of PolicyResult - * objects. - * - * @param prList - * @return - */ - protected static PolicyResult[] convertToPolicyResult(List prList) { - if (prList == null || prList.isEmpty()) { - return new PolicyResult[0]; - } - return prList.stream().map(PolicyResult::toResult).toArray(PolicyResult[]::new); - } -} \ No newline at end of file diff --git a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyYamlFormatter.java b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyYamlFormatter.java new file mode 100644 index 000000000..550c4dccd --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyYamlFormatter.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * Modifications copyright (c) 2018 Nokia + * =================================================================== + * + */ +package org.onap.clamp.clds.client.req.policy; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.clamp.clds.model.properties.Global; +import org.onap.clamp.clds.model.properties.ModelProperties; +import org.onap.clamp.clds.model.properties.PolicyChain; +import org.onap.clamp.clds.model.properties.PolicyItem; +import org.onap.policy.controlloop.policy.Policy; +import org.onap.policy.controlloop.policy.PolicyResult; +import org.onap.policy.controlloop.policy.Target; +import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.controlloop.policy.builder.BuilderException; +import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder; +import org.onap.policy.controlloop.policy.builder.Message; +import org.onap.policy.controlloop.policy.builder.Results; +import org.onap.policy.sdc.Resource; +import org.onap.policy.sdc.ResourceType; +import org.onap.policy.sdc.Service; +import org.springframework.stereotype.Component; + +import javax.ws.rs.BadRequestException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +@Component +class OperationalPolicyYamlFormatter { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicyYamlFormatter.class); + + + String formatYaml(ModelProperties prop, String modelElementId, + PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException { + // get property objects + Global global = prop.getGlobal(); + prop.setCurrentModelElementId(modelElementId); + prop.setPolicyUniqueId(policyChain.getPolicyId()); + // convert values to SDC objects + Service service = new Service(global.getService()); + Resource[] vfResources = convertToResources(global.getResourceVf(), ResourceType.VF); + Resource[] vfcResources = convertToResources(global.getResourceVfc(), ResourceType.VFC); + // create builder + ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(), + policyChain.getTimeout(), service, vfResources); + builder.addResource(vfcResources); + // process each policy + Map policyObjMap = new HashMap(); + List policyItemList = orderParentFirst(policyChain.getPolicyItems()); + for (PolicyItem policyItem : policyItemList) { + String policyName = policyItem.getRecipe() + " Policy"; + Target target = new Target(); + target.setType(TargetType.VM); + // We can send target type as VM/VNF for most of recipes + if (policyItem.getRecipeLevel() != null && !policyItem.getRecipeLevel().isEmpty()) { + target.setType(TargetType.valueOf(policyItem.getRecipeLevel())); + } + target.setResourceID(policyItem.getTargetResourceId()); + String actor = policyItem.getActor(); + Map payloadMap = policyItem.getRecipePayload(); + Policy policyObj; + if (policyItemList.indexOf(policyItem) == 0) { + String policyDescription = policyItem.getRecipe() + + " Policy - the trigger (no parent) policy - created by CLDS"; + policyObj = builder.setTriggerPolicy(policyName, policyDescription, actor, target, + policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit()); + } else { + Policy parentPolicyObj = policyObjMap.get(policyItem.getParentPolicy()); + String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by " + + parentPolicyObj.getName() + " - created by CLDS"; + policyObj = builder.setPolicyForPolicyResult(policyName, policyDescription, actor, target, + policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit(), + parentPolicyObj.getId(), convertToPolicyResults(policyItem.getParentPolicyConditions())); + logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId()); + } + policyObjMap.put(policyItem.getId(), policyObj); + } + // Build the specification + Results results = builder.buildSpecification(); + validate(results); + return URLEncoder.encode(results.getSpecification(), "UTF-8"); + } + + private List orderParentFirst(List inOrigList) { + List inList = new ArrayList<>(); + inList.addAll(inOrigList); + List outList = new ArrayList<>(); + int prevSize = 0; + while (!inList.isEmpty()) { + // check if there's a loop in the policy chain (the inList should + // have been reduced by at least one) + if (inList.size() == prevSize) { + throw new BadRequestException("Operation Policy validation problem: loop in Operation Policy chain"); + } + prevSize = inList.size(); + // the following loop should remove at least one PolicyItem from the + // inList + Iterator inListItr = inList.iterator(); + while (inListItr.hasNext()) { + PolicyItem inItem = inListItr.next(); + // check for trigger policy (no parent) + String parent = inItem.getParentPolicy(); + if (parent == null || parent.length() == 0) { + if (!outList.isEmpty()) { + throw new BadRequestException( + "Operation Policy validation problem: more than one trigger policy"); + } else { + outList.add(inItem); + inListItr.remove(); + } + } else { + // check if this PolicyItem's parent has been processed + for (PolicyItem outItem : outList) { + if (outItem.getId().equals(parent)) { + // if the inItem parent is already in the outList, + // then add inItem to outList and remove from inList + outList.add(inItem); + inListItr.remove(); + break; + } + } + } + } + } + return outList; + } + + private void validate(Results results) { + if (results.isValid()) { + logger.info("results.getSpecification()=" + results.getSpecification()); + } else { + // throw exception with error info + StringBuilder sb = new StringBuilder(); + sb.append("Operation Policy validation problem: ControlLoopPolicyBuilder failed with following messages: "); + for (Message message : results.getMessages()) { + sb.append(message.getMessage()); + sb.append("; "); + } + throw new BadRequestException(sb.toString()); + } + } + + + Resource[] convertToResources(List stringList, ResourceType resourceType) { + if (stringList == null || stringList.isEmpty()) { + return new Resource[0]; + } + return stringList.stream().map(stringElem -> new Resource(stringElem, resourceType)).toArray(Resource[]::new); + } + + PolicyResult[] convertToPolicyResults(List prList) { + if (prList == null || prList.isEmpty()) { + return new PolicyResult[0]; + } + return prList.stream().map(PolicyResult::toResult).toArray(PolicyResult[]::new); + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/clamp/clds/util/ClampTimer.java b/src/main/java/org/onap/clamp/clds/util/ClampTimer.java index 794e2b486..d08e73a4a 100644 --- a/src/main/java/org/onap/clamp/clds/util/ClampTimer.java +++ b/src/main/java/org/onap/clamp/clds/util/ClampTimer.java @@ -17,6 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END============================================ + * Modifications copyright (c) 2018 Nokia * =================================================================== * */ @@ -39,7 +40,7 @@ public class ClampTimer { public ClampTimer(int seconds) { timer = new Timer(); - timer.schedule(new CleanupTask(), seconds*1000); + timer.schedule(new CleanupTask(), seconds*1000L); } class CleanupTask extends TimerTask { -- cgit 1.2.3-korg