2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END============================================
20 * ===================================================================
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
24 package org.onap.clamp.clds.client.req;
26 import java.io.UnsupportedEncodingException;
27 import java.net.URLEncoder;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
34 import org.jboss.resteasy.spi.BadRequestException;
35 import org.onap.clamp.clds.model.prop.Global;
36 import org.onap.clamp.clds.model.prop.ModelProperties;
37 import org.onap.clamp.clds.model.prop.PolicyChain;
38 import org.onap.clamp.clds.model.prop.PolicyItem;
39 import org.onap.clamp.clds.model.prop.Tca;
40 import org.onap.clamp.clds.model.refprop.RefProp;
41 import org.onap.policy.controlloop.policy.OperationsAccumulateParams;
42 import org.onap.policy.api.AttributeType;
43 import org.onap.policy.asdc.Resource;
44 import org.onap.policy.asdc.ResourceType;
45 import org.onap.policy.asdc.Service;
46 import org.onap.policy.controlloop.policy.Policy;
47 import org.onap.policy.controlloop.policy.PolicyResult;
48 import org.onap.policy.controlloop.policy.Target;
49 import org.onap.policy.controlloop.policy.TargetType;
50 import org.onap.policy.controlloop.policy.builder.BuilderException;
51 import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
52 import org.onap.policy.controlloop.policy.builder.Message;
53 import org.onap.policy.controlloop.policy.builder.Results;
55 import com.att.eelf.configuration.EELFLogger;
56 import com.att.eelf.configuration.EELFLogger.Level;
57 import com.att.eelf.configuration.EELFManager;
58 import com.fasterxml.jackson.databind.JsonNode;
59 import com.fasterxml.jackson.databind.node.ObjectNode;
62 * Construct an Operational Policy request given CLDS objects.
64 public class OperationalPolicyReq {
65 protected static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicyReq.class);
66 protected static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
69 * Format Operational Policy attributes.
74 * @throws BuilderException
75 * @throws UnsupportedEncodingException
77 public static Map<AttributeType, Map<String, String>> formatAttributes(RefProp refProp, ModelProperties prop,
78 String modelElementId, PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
79 Global global = prop.getGlobal();
80 prop.setCurrentModelElementId(modelElementId);
81 prop.setPolicyUniqueId(policyChain.getPolicyId());
83 String templateName = "";
84 String operationTopic = "";
85 String notificationTopic = "";
86 String controller = "";
87 Tca tca = prop.getTca();
89 if (!global.getActionSet().equalsIgnoreCase("enbRecipe")) {
90 throw new BadRequestException(
91 "Operation Policy validation problem: action set is not selected properly.");
93 templateName = refProp.getStringValue("op.eNodeB.templateName", global.getService());
94 operationTopic = refProp.getStringValue("op.eNodeB.operationTopic", global.getService());
95 notificationTopic = refProp.getStringValue("op.eNodeB.notificationTopic", global.getService());
96 controller = refProp.getStringValue("op.eNodeB.controller", global.getService());
98 if (!global.getActionSet().equalsIgnoreCase("vnfRecipe")) {
99 throw new BadRequestException(
100 "Operation Policy validation problem: Action set is not selected properly.");
102 templateName = refProp.getStringValue("op.templateName", global.getService());
103 operationTopic = refProp.getStringValue("op.operationTopic", global.getService());
104 notificationTopic = refProp.getStringValue("op.notificationTopic", global.getService());
105 controller = refProp.getStringValue("op.controller", global.getService());
107 String recipeTopic = refProp.getStringValue("op.recipeTopic", global.getService());
110 Map<String, String> ruleAttributes = new HashMap<String, String>();
112 if (operationTopic == null || operationTopic.length() == 0) {
113 logger.info("templateName=" + templateName);
114 logger.info("recipeTopic=" + recipeTopic);
115 logger.info("notificationTopic=" + notificationTopic);
117 // if no operationTopic, then don't format yaml - use first policy
119 PolicyItem policyItem = policyChain.getPolicyItems().get(0);
121 ruleAttributes.put("templateName", templateName);
122 ruleAttributes.put("ClosedLoopControlName", prop.getControlNameAndPolicyUniqueId());
123 ruleAttributes.put("RecipeTopic", recipeTopic);
124 ruleAttributes.put("NotificationTopic", notificationTopic);
126 String recipe = policyItem.getRecipe();
127 String maxRetries = String.valueOf(policyItem.getMaxRetries());
128 String retryTimeLimit = String.valueOf(policyItem.getRetryTimeLimit());
129 logger.info("recipe=" + recipe);
130 logger.info("maxRetries=" + maxRetries);
131 logger.info("retryTimeLimit=" + retryTimeLimit);
132 ruleAttributes.put("Recipe", recipe);
133 ruleAttributes.put("MaxRetries", maxRetries);
134 ruleAttributes.put("RetryTimeLimit", retryTimeLimit);
136 logger.info("templateName=" + templateName);
137 logger.info("operationTopic=" + operationTopic);
138 logger.info("notificationTopic=" + notificationTopic);
141 String yaml = tca.isFound() ? formateNodeBYaml(refProp, prop, modelElementId, policyChain)
142 : formatYaml(refProp, prop, modelElementId, policyChain);
144 ruleAttributes.put("templateName", templateName);
145 ruleAttributes.put("ClosedLoopControlName", prop.getControlNameAndPolicyUniqueId());
146 ruleAttributes.put("OperationTopic", operationTopic);
147 ruleAttributes.put("NotificationTopic", notificationTopic);
149 ruleAttributes.put("ControlLoopYaml", yaml);
152 // matchingAttributes
153 Map<String, String> matchingAttributes = new HashMap<String, String>();
154 matchingAttributes.put("controller", controller);
156 Map<AttributeType, Map<String, String>> attributes = new HashMap<AttributeType, Map<String, String>>();
157 attributes.put(AttributeType.RULE, ruleAttributes);
158 attributes.put(AttributeType.MATCHING, matchingAttributes);
164 * Format Operational Policy yaml.
169 * @throws BuilderException
170 * @throws UnsupportedEncodingException
172 private static String formatYaml(RefProp refProp, ModelProperties prop, String modelElementId,
173 PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
175 // get property objects
176 Global global = prop.getGlobal();
177 prop.setCurrentModelElementId(modelElementId);
178 prop.setPolicyUniqueId(policyChain.getPolicyId());
180 // convert values to SDC objects
181 Service service = new Service(global.getService());
182 Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF);
183 Resource[] vfcResources = convertToResource(global.getResourceVfc(), ResourceType.VFC);
186 ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(),
187 policyChain.getTimeout(), service, vfResources);
188 builder.addResource(vfcResources);
190 // process each policy
191 HashMap<String, org.onap.policy.controlloop.policy.Policy> policyObjMap = new HashMap<String, org.onap.policy.controlloop.policy.Policy>();
192 List<PolicyItem> policyItemList = orderParentFirst(policyChain.getPolicyItems());
193 Target target = new Target();
194 target.setType(TargetType.VM);
195 for (int i = 0; i < policyItemList.size(); i++) {
197 org.onap.policy.controlloop.policy.Policy policyObj;
198 PolicyItem policyItem = policyItemList.get(i);
199 String policyName = policyItem.getRecipe() + " Policy";
201 String policyDescription = policyItem.getRecipe()
202 + " Policy - the trigger (no parent) policy - created by CLDS";
203 policyObj = builder.setTriggerPolicy(policyName, policyDescription,
204 refProp.getStringValue("op.policy.appc"), target, policyItem.getRecipe(), null,
205 policyItem.getMaxRetries(), policyItem.getRetryTimeLimit());
207 org.onap.policy.controlloop.policy.Policy parentPolicyObj = policyObjMap
208 .get(policyItem.getParentPolicy());
209 String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by "
210 + parentPolicyObj.getName() + " - created by CLDS";
211 policyObj = builder.setPolicyForPolicyResult(policyName, policyDescription,
212 refProp.getStringValue("op.policy.appc"), target, policyItem.getRecipe(), null,
213 policyItem.getMaxRetries(), policyItem.getRetryTimeLimit(), parentPolicyObj.getId(),
214 convertToPolicyResult(policyItem.getParentPolicyConditions()));
216 logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId());
218 policyObjMap.put(policyItem.getId(), policyObj);
222 // Build the specification
224 Results results = builder.buildSpecification();
225 if (results.isValid()) {
226 logger.info("results.getSpecification()=" + results.getSpecification());
228 // throw exception with error info
229 StringBuffer sb = new StringBuffer();
230 sb.append("Operation Policy validation problem: ControlLoopPolicyBuilder failed with following messages: ");
231 for (Message message : results.getMessages()) {
232 sb.append(message.getMessage());
235 throw new BadRequestException(sb.toString());
238 String encodedYaml = URLEncoder.encode(results.getSpecification(), "UTF-8");
244 * Format Operational Policy yaml.
249 * @throws BuilderException
250 * @throws UnsupportedEncodingException
252 private static String formateNodeBYaml(RefProp refProp, ModelProperties prop, String modelElementId,
253 PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
255 // get property objects
256 Global global = prop.getGlobal();
257 prop.setCurrentModelElementId(modelElementId);
258 prop.setPolicyUniqueId(policyChain.getPolicyId());
260 // convert values to SDC objects
261 Service service = new Service(global.getService());
262 Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF);
263 Resource[] vfcResources = convertToResource(global.getResourceVfc(), ResourceType.VFC);
266 ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(),
267 policyChain.getTimeout(), service, vfResources);
268 builder.addResource(vfcResources);
270 // process each policy
271 HashMap<String, Policy> policyObjMap = new HashMap<String, Policy>();
272 List<PolicyItem> policyItemList = addAOTSActorRecipe(refProp, global.getService(),
273 policyChain.getPolicyItems());
274 Target target = new Target();
275 target.setType(TargetType.VM);
276 Policy lastPolicyObj = new Policy();
277 for (int i = 0; i < policyItemList.size(); i++) {
278 org.onap.policy.controlloop.policy.Policy policyObj;
279 PolicyItem policyItem = policyItemList.get(i);
280 String policyName = policyItem.getRecipe() + " Policy";
282 //To set up time window payload for trigger policy
283 Map<String, String> payloadMap = new HashMap<String, String>();
284 payloadMap.put("timeWindow", refProp.getStringValue("op.eNodeB.timeWindow"));
285 String policyDescription = policyItem.getRecipe()
286 + " Policy - the trigger (no parent) policy - created by CLDS";
287 policyObj = builder.setTriggerPolicy(policyName, policyDescription, policyItem.getActor(), target,
288 policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit());
290 Policy parentPolicyObj = policyObjMap
291 .get(policyItem.getParentPolicy());
292 String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by "
293 + parentPolicyObj.getName() + " - created by CLDS";
294 policyObj = builder.setPolicyForPolicyResult(policyName, policyDescription, policyItem.getActor(),
295 target, policyItem.getRecipe(), null, policyItem.getMaxRetries(),
296 policyItem.getRetryTimeLimit(), parentPolicyObj.getId(),
297 convertToPolicyResult(policyItem.getParentPolicyConditions()));
298 lastPolicyObj = policyObj;
299 logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId());
301 policyObjMap.put(policyItem.getId(), policyObj);
303 //To set up operations accumulate params
304 OperationsAccumulateParams operationsAccumulateParams = new OperationsAccumulateParams();
305 operationsAccumulateParams.setLimit(Integer.valueOf(refProp.getStringValue("op.eNodeB.limit")));
306 operationsAccumulateParams.setPeriod(refProp.getStringValue("op.eNodeB.period"));
307 builder.addOperationsAccumulateParams(lastPolicyObj.getId(), operationsAccumulateParams);
310 // Build the specification
312 Results results = builder.buildSpecification();
313 if (results.isValid()) {
314 logger.info("results.getSpecification()=" + results.getSpecification());
316 // throw exception with error info
317 StringBuffer sb = new StringBuffer();
318 sb.append("Operation Policy validation problem: ControlLoopPolicyBuilder failed with following messages: ");
319 for (Message message : results.getMessages()) {
320 sb.append(message.getMessage());
323 throw new BadRequestException(sb.toString());
326 String encodedYaml = URLEncoder.encode(results.getSpecification(), "UTF-8");
332 * Adding AOTS actor and other recipe for yaml
337 private static List<PolicyItem> addAOTSActorRecipe(RefProp refProp, String service, List<PolicyItem> inOrigList) {
338 List<PolicyItem> outList = new ArrayList<PolicyItem>();
340 PolicyItem policyItem = inOrigList.get(0);
341 ObjectNode rootNode = (ObjectNode) refProp.getJsonTemplate("op.eNodeB.recipe", service);
342 Iterator<JsonNode> itr = rootNode.get("eNodeBRecipes").elements();
343 while (itr.hasNext()) {
344 PolicyItem policyItemObj = (PolicyItem) policyItem.clone();
345 JsonNode recipeNode = itr.next();
346 policyItemObj.setId(recipeNode.path("Recipe").asText());
347 policyItemObj.setActor(recipeNode.path("Actor").asText());
348 policyItemObj.setRecipe(recipeNode.path("Recipe").asText());
349 policyItemObj.setParentPolicy(recipeNode.path("ParentPolicy").asText());
350 if (!recipeNode.path("Retry").asText().isEmpty()) {
351 policyItemObj.setMaxRetries(Integer.parseInt(recipeNode.path("Retry").asText()));
353 if (!recipeNode.path("TimeLimit").asText().isEmpty()) {
354 policyItemObj.setRetryTimeLimit(Integer.parseInt(recipeNode.path("TimeLimit").asText()));
356 if (!recipeNode.path("PPConditions").asText().isEmpty()) {
357 List<String> parentPolicyConditions = new ArrayList<String>();
358 for (String ppCondition : recipeNode.path("PPConditions").asText().split(",")) {
359 parentPolicyConditions.add(ppCondition);
361 policyItemObj.setParentPolicyConditions(parentPolicyConditions);
363 outList.add(policyItemObj);
365 } catch (Exception e) {
366 logger.log(Level.ERROR, "Error", e);
372 * Order list of PolicyItems so that parents come before any of their
378 private static List<PolicyItem> orderParentFirst(List<PolicyItem> inOrigList) {
379 List<PolicyItem> inList = new ArrayList<>();
380 inList.addAll(inOrigList);
381 List<PolicyItem> outList = new ArrayList<>();
383 while (!inList.isEmpty()) {
384 // check if there's a loop in the policy chain (the inList should
385 // have been reduced by at least one)
386 if (inList.size() == prevSize) {
387 throw new BadRequestException("Operation Policy validation problem: loop in Operation Policy chain");
389 prevSize = inList.size();
390 // the following loop should remove at least one PolicyItem from the
392 Iterator<PolicyItem> inListItr = inList.iterator();
393 while (inListItr.hasNext()) {
394 PolicyItem inItem = inListItr.next();
395 // check for trigger policy (no parent)
396 String parent = inItem.getParentPolicy();
397 if (parent == null || parent.length() == 0) {
398 if (outList.size() > 0) {
399 throw new BadRequestException(
400 "Operation Policy validation problem: more than one trigger policy");
406 // check if this PolicyItem's parent has been processed
407 for (PolicyItem outItem : outList) {
408 if (outItem.getId().equals(parent)) {
409 // if the inItem parent is already in the outList,
410 // then add inItem to outList and remove from inList
423 * Convert a List of resource strings to an array of Resource objects.
426 * @param resourceType
429 private static Resource[] convertToResource(List<String> stringList, ResourceType resourceType) {
431 if (stringList != null) {
432 size = stringList.size();
434 Resource[] resourceArray = new Resource[size];
435 for (int i = 0; i < size; i++) {
436 String rString = stringList.get(i);
437 resourceArray[i] = new Resource(rString, resourceType);
439 return resourceArray;
443 * Convert a List of policy result strings to an array of PolicyResult
449 private static PolicyResult[] convertToPolicyResult(List<String> prList) {
451 if (prList != null) {
452 size = prList.size();
454 PolicyResult[] prArray = new PolicyResult[size];
455 for (int i = 0; i < size; i++) {
456 String prString = prList.get(i);
457 prArray[i] = PolicyResult.toResult(prString);