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