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