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