[POLICY-117] Resolve the Policy Critical issues
[policy/engine.git] / ECOMP-ControlloopPolicy / src / main / java / org / openecomp / policy / controlloop / policy / builder / impl / ControlLoopPolicyBuilderImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.policy.controlloop.policy.builder.impl;
22
23 import java.util.LinkedList;
24 import java.util.Map;
25 import java.util.UUID;
26
27 import org.openecomp.policy.asdc.Resource;
28 import org.openecomp.policy.asdc.Service;
29 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
30 import org.openecomp.policy.common.logging.flexlogger.Logger;
31 import org.openecomp.policy.controlloop.compiler.CompilerException;
32 import org.openecomp.policy.controlloop.compiler.ControlLoopCompiler;
33 import org.openecomp.policy.controlloop.compiler.ControlLoopCompilerCallback;
34 import org.openecomp.policy.controlloop.policy.ControlLoop;
35 import org.openecomp.policy.controlloop.policy.ControlLoopPolicy;
36 import org.openecomp.policy.controlloop.policy.FinalResult;
37 import org.openecomp.policy.controlloop.policy.OperationsAccumulateParams;
38 import org.openecomp.policy.controlloop.policy.Policy;
39 import org.openecomp.policy.controlloop.policy.PolicyResult;
40 import org.openecomp.policy.controlloop.policy.Target;
41 import org.openecomp.policy.controlloop.policy.builder.BuilderException;
42 import org.openecomp.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
43 import org.openecomp.policy.controlloop.policy.builder.MessageLevel;
44 import org.openecomp.policy.controlloop.policy.builder.Results;
45 import org.yaml.snakeyaml.DumperOptions;
46 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
47 import org.yaml.snakeyaml.Yaml;
48
49 public class ControlLoopPolicyBuilderImpl implements ControlLoopPolicyBuilder {
50         private static Logger logger = FlexLogger.getLogger(ControlLoopPolicyBuilderImpl.class.getName());
51         private ControlLoopPolicy policy;
52         
53         public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout) throws BuilderException {
54                 policy = new ControlLoopPolicy();
55                 ControlLoop controlLoop = new ControlLoop();
56                 controlLoop.setControlLoopName(controlLoopName);
57                 controlLoop.setTimeout(timeout);
58                 policy.setControlLoop(controlLoop);
59         }
60         
61         public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Resource resource, Service... services) throws BuilderException {
62                 this(controlLoopName, timeout);
63                 this.addResource(resource);
64                 this.addService(services);
65         }
66         
67         public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Service service, Resource[] resources) throws BuilderException {
68                 this(controlLoopName, timeout);
69                 this.addService(service);
70                 this.addResource(resources);
71         }
72
73         @Override
74         public ControlLoopPolicyBuilder addService(Service... services) throws BuilderException {
75                 if (services == null) {
76                         throw new BuilderException("Service must not be null");
77                 }
78                 for (Service service : services) {
79                         if (service.getServiceUUID() == null) {
80                                 if (service.getServiceName() == null || service.getServiceName().length() < 1) {
81                                         throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
82                                 }
83                                 if(policy.getControlLoop().getServices()==null){
84                                         policy.getControlLoop().setServices(new LinkedList<>());
85                                 }
86                                 policy.getControlLoop().getServices().add(service);
87                         }
88                 }
89                 return this;
90         }
91         
92         @Override
93         public ControlLoopPolicyBuilder removeService(Service... services) throws BuilderException {
94                 if (services == null) {
95             throw new BuilderException("Service must not be null");
96         }
97         if (policy.getControlLoop().getServices() == null) {
98             throw new BuilderException("No existing services to remove");
99         }
100         for (Service service : services) {
101             if (service.getServiceUUID() == null) {
102                 if (service.getServiceName() == null || service.getServiceName().length() < 1) {
103                     throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
104                 }
105             }
106             boolean removed = policy.getControlLoop().getServices().remove(service);
107             if (!removed) {
108                 throw new BuilderException("Unknown service " + service.getServiceName());
109             }
110         }
111         return this;
112         }
113
114         @Override
115         public ControlLoopPolicyBuilder removeAllServices() throws BuilderException {
116                 policy.getControlLoop().getServices().clear();
117         return this;
118         }
119
120         
121         @Override
122         public ControlLoopPolicyBuilder addResource(Resource... resources) throws BuilderException {
123                 if (resources == null) {
124                         throw new BuilderException("resources must not be null");
125                 }
126                 for (Resource resource : resources) {
127                         if (resource.getResourceUUID() == null) {
128                                 if (resource.getResourceName() == null || resource.getResourceName().length() <= 0) {
129                                         throw new BuilderException("Invalid resource - need either resourceUUID or resourceName");
130                                 }
131                         }
132                         if(policy.getControlLoop().getResources()==null){
133                                 policy.getControlLoop().setResources(new LinkedList<>());
134                         }
135                         policy.getControlLoop().getResources().add(resource);
136                 }
137                 return this;
138         }
139         
140         @Override
141         public ControlLoopPolicyBuilder setAbatement(Boolean abatement) throws BuilderException{
142                 if (abatement == null) {
143                         throw new BuilderException("abatement must not be null");
144                 }
145                 policy.getControlLoop().setAbatement(abatement);
146                 return this;
147         }
148         
149         @Override
150         public ControlLoopPolicyBuilder setTimeout(Integer timeout) {
151                 policy.getControlLoop().setTimeout(timeout);
152                 return this;
153         }
154         
155         @Override
156         public Policy setTriggerPolicy(String name, String description, String actor, Target target, String recipe,
157                         Map<String, String> payload, Integer retries, Integer timeout) throws BuilderException {
158                 
159                 Policy trigger = new Policy(UUID.randomUUID().toString(), name, description, actor, payload, target, recipe, retries, timeout);
160                 
161                 policy.getControlLoop().setTrigger_policy(trigger.getId());
162                 
163                 this.addNewPolicy(trigger);
164                 //
165                 // Return a copy of the policy
166                 //
167                 return new Policy(trigger);
168         }
169
170         @Override
171         public Policy setPolicyForPolicyResult(String name, String description, String actor,
172                         Target target, String recipe, Map<String, String> payload, Integer retries, Integer timeout, String policyID, PolicyResult... results) throws BuilderException {
173                 //
174                 // Find the existing policy
175                 //
176                 Policy existingPolicy = this.findPolicy(policyID);
177                 if (existingPolicy == null) {
178                         throw new BuilderException("Unknown policy " + policyID);
179                 }
180                 //
181                 // Create the new Policy
182                 //
183                 Policy newPolicy = new Policy(UUID.randomUUID().toString(), name, description, actor, payload, target, recipe, retries, timeout);
184                 //
185                 // Connect the results
186                 //
187                 for (PolicyResult result : results) {
188                         switch (result) {
189                         case FAILURE:
190                                 existingPolicy.setFailure(newPolicy.getId());
191                                 break;
192                         case FAILURE_EXCEPTION:
193                                 existingPolicy.setFailure_exception(newPolicy.getId());
194                                 break;
195                         case FAILURE_RETRIES:
196                                 existingPolicy.setFailure_retries(newPolicy.getId());
197                                 break;
198                         case FAILURE_TIMEOUT:
199                                 existingPolicy.setFailure_timeout(newPolicy.getId());
200                                 break;
201                         case FAILURE_GUARD:
202                                 existingPolicy.setFailure_guard(newPolicy.getId());
203                                 break;
204                         case SUCCESS:
205                                 existingPolicy.setSuccess(newPolicy.getId());
206                                 break;
207                         default:
208                                 throw new BuilderException("Invalid PolicyResult " + result);
209                         }
210                 }
211                 //
212                 // Add it to our list
213                 //
214                 this.policy.getPolicies().add(newPolicy);
215                 //
216                 // Return a policy to them
217                 //
218                 return new Policy(newPolicy);
219         }
220         
221         private class BuilderCompilerCallback implements ControlLoopCompilerCallback {
222
223                 private ResultsImpl results = new ResultsImpl();
224                 
225                 @Override
226                 public boolean onWarning(String message) {
227                         results.addMessage(new MessageImpl(message, MessageLevel.WARNING));
228                         return false;
229                 }
230
231                 @Override
232                 public boolean onError(String message) {
233                         results.addMessage(new MessageImpl(message, MessageLevel.ERROR));
234                         return false;
235                 }
236         }
237
238         @Override
239         public Results  buildSpecification() {
240                 //
241                 // Dump the specification
242                 //
243                 DumperOptions options = new DumperOptions();
244                 options.setDefaultFlowStyle(FlowStyle.BLOCK);
245                 options.setPrettyFlow(true);
246                 Yaml yaml = new Yaml(options);
247                 String dumpedYaml = yaml.dump(policy);
248                 //
249                 // This is our callback class for our compiler
250                 //
251                 BuilderCompilerCallback callback = new BuilderCompilerCallback();
252                 //
253                 // Compile it
254                 //
255                 try {
256                         ControlLoopCompiler.compile(policy, callback);
257                 } catch (CompilerException e) {
258                         logger.error(e.getMessage() + e);
259                         callback.results.addMessage(new MessageImpl(e.getMessage(), MessageLevel.EXCEPTION));
260                 }
261                 //
262                 // Save the spec
263                 //
264                 callback.results.setSpecification(dumpedYaml);
265                 return callback.results;
266         }
267
268         private void addNewPolicy(Policy policy) {
269                 if (this.policy.getPolicies() == null) {
270                         this.policy.setPolicies(new LinkedList<>());
271                 }
272                 this.policy.getPolicies().add(policy);
273         }
274         
275         private Policy findPolicy(String id) {
276                 for (Policy policy : this.policy.getPolicies()) {
277                         if (policy.getId().equals(id)) {
278                                 return policy;
279                         }
280                 }
281                 return null;
282         }
283
284         @Override
285         public ControlLoopPolicyBuilder removeResource(Resource... resources) throws BuilderException {
286             if (resources == null) {
287             throw new BuilderException("Resource must not be null");
288         }
289         if (policy.getControlLoop().getResources() == null) {
290             throw new BuilderException("No existing resources to remove");
291         }
292         for (Resource resource : resources) {
293             if (resource.getResourceUUID() == null) {
294                 if (resource.getResourceName() == null || resource.getResourceName().length() < 1) {
295                     throw new BuilderException("Invalid resource - need either a resourceUUID or resourceName");
296                 }
297             }
298             boolean removed = policy.getControlLoop().getResources().remove(resource); 
299             if (!removed) {
300                 throw new BuilderException("Unknown resource " + resource.getResourceName());
301             }
302         }
303         return this; 
304     }
305
306         @Override
307         public ControlLoopPolicyBuilder removeAllResources() throws BuilderException {
308             policy.getControlLoop().getResources().clear();
309         return this;
310     }
311
312         @Override
313         public Integer calculateTimeout() {
314                 int sum = 0;
315         for (Policy policy : this.policy.getPolicies()) {
316             sum += policy.getTimeout().intValue();
317         }
318         return new Integer(sum);
319         }
320
321         @Override
322         public ControlLoop setTriggerPolicy(String id) throws BuilderException {
323                 if (id == null) {
324             throw new BuilderException("Id must not be null");
325         }
326             Policy trigger = this.findPolicy(id);
327         if (trigger == null) {
328             throw new BuilderException("Unknown policy " + id);
329         }
330         else {
331             this.policy.getControlLoop().setTrigger_policy(id);
332         }
333         return new ControlLoop(this.policy.getControlLoop());
334     }
335
336         @Override
337         public boolean isOpenLoop() {
338         if (this.policy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
339             return true;
340         }       
341         else {
342             return false;
343         }
344         }
345
346         @Override
347         public Policy getTriggerPolicy() throws BuilderException {
348             if (this.policy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
349             return null;
350         }
351         else {
352             Policy trigger = new Policy(this.findPolicy(this.policy.getControlLoop().getTrigger_policy()));
353             return trigger;
354         }
355     }
356
357         @Override
358         public ControlLoop getControlLoop() {
359                 ControlLoop loop = new ControlLoop(this.policy.getControlLoop());
360                 return loop;
361         }
362
363         @Override
364         public Policy setPolicyForPolicyResult(String policyResultID, String policyID, PolicyResult... results)
365                         throws BuilderException {
366                 //
367         // Find the existing policy
368         //
369         Policy existingPolicy = this.findPolicy(policyID);
370         if (existingPolicy == null) {
371             throw new BuilderException(policyID + " does not exist");
372         }
373         if (this.findPolicy(policyResultID) == null) {
374             throw new BuilderException("Operational policy " + policyResultID + " does not exist");
375         }
376         //
377         // Connect the results
378         //
379         for (PolicyResult result : results) {
380             switch (result) {
381             case FAILURE:
382                 existingPolicy.setFailure(policyResultID);
383                 break;
384             case FAILURE_EXCEPTION:
385                 existingPolicy.setFailure_exception(policyResultID);
386                 break;
387             case FAILURE_RETRIES:
388                 existingPolicy.setFailure_retries(policyResultID);
389                 break;
390             case FAILURE_TIMEOUT:
391                 existingPolicy.setFailure_timeout(policyResultID);
392                 break;
393             case FAILURE_GUARD:
394                 existingPolicy.setFailure_guard(policyResultID);
395                 break;
396             case SUCCESS:
397                 existingPolicy.setSuccess(policyResultID);
398                 break;
399             default:
400                 throw new BuilderException("Invalid PolicyResult " + result);
401             }
402         }
403         return new Policy(this.findPolicy(policyResultID));
404         }
405
406         @Override
407         public boolean removePolicy(String policyID) throws BuilderException {
408                 Policy existingPolicy = this.findPolicy(policyID);
409         if (existingPolicy == null) {
410             throw new BuilderException("Unknown policy " + policyID);
411         }
412         //
413         // Check if the policy to remove is trigger_policy
414         //
415         if (this.policy.getControlLoop().getTrigger_policy().equals(policyID)) {
416             this.policy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
417         }
418         else {
419             //
420             // Update policies
421             //
422             for (Policy policy : this.policy.getPolicies()) {
423                 int index = this.policy.getPolicies().indexOf(policy);
424                 if (policy.getSuccess().equals(policyID)) {
425                     policy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
426                 }
427                 if (policy.getFailure().equals(policyID)) {
428                     policy.setFailure(FinalResult.FINAL_FAILURE.toString());
429                 }
430                 if (policy.getFailure_retries().equals(policyID)) {
431                     policy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
432                 }
433                 if (policy.getFailure_timeout().equals(policyID)) {
434                     policy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
435                 }
436                 if (policy.getFailure_exception().equals(policyID)) {
437                     policy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
438                 }
439                 if (policy.getFailure_guard().equals(policyID)) {
440                     policy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
441                 }
442                 this.policy.getPolicies().set(index, policy);
443             }
444         }
445         //
446         // remove the policy
447         //
448         boolean removed = this.policy.getPolicies().remove(existingPolicy);
449         return removed;
450         }
451
452         @Override
453         public Policy resetPolicyResults(String policyID) throws BuilderException {
454         Policy existingPolicy = this.findPolicy(policyID);
455         if (existingPolicy == null) {
456             throw new BuilderException("Unknown policy " + policyID);
457         }
458         //
459         // reset policy results
460         //
461         existingPolicy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
462         existingPolicy.setFailure(FinalResult.FINAL_FAILURE.toString());
463         existingPolicy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
464         existingPolicy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
465         existingPolicy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
466         existingPolicy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
467         return new Policy(existingPolicy);
468         }
469
470         @Override
471         public ControlLoopPolicyBuilder removeAllPolicies() {
472                 //
473         // Remove all existing operational policies
474         //
475         this.policy.getPolicies().clear();
476         //
477         // Revert controlLoop back to an open loop
478         //
479         this.policy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
480         return this;
481         }
482         
483         @Override
484         public Policy addOperationsAccumulateParams(String policyID, OperationsAccumulateParams operationsAccumulateParams) throws BuilderException {
485                 Policy existingPolicy = this.findPolicy(policyID);
486         if (existingPolicy == null) {
487             throw new BuilderException("Unknown policy " + policyID);
488         }
489         //
490         // Add operationsAccumulateParams to existingPolicy
491         //
492         existingPolicy.setOperationsAccumulateParams(operationsAccumulateParams);
493         return new Policy(existingPolicy);
494         }
495
496 }