remove dependency of drool-application/yaml in actors
[policy/models.git] / models-interactions / model-yaml / src / main / java / org / onap / policy / controlloop / policy / builder / impl / ControlLoopPolicyBuilderImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * policy-yaml
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.controlloop.policy.builder.impl;
23
24 import com.google.common.base.Strings;
25 import java.util.LinkedList;
26 import java.util.UUID;
27
28 import org.onap.policy.aai.Pnf;
29 import org.onap.policy.controlloop.compiler.CompilerException;
30 import org.onap.policy.controlloop.compiler.ControlLoopCompiler;
31 import org.onap.policy.controlloop.compiler.ControlLoopCompilerCallback;
32 import org.onap.policy.controlloop.policy.ControlLoop;
33 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
34 import org.onap.policy.controlloop.policy.FinalResult;
35 import org.onap.policy.controlloop.policy.OperationsAccumulateParams;
36 import org.onap.policy.controlloop.policy.Policy;
37 import org.onap.policy.controlloop.policy.PolicyParam;
38 import org.onap.policy.controlloop.policy.PolicyResult;
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(PolicyParam policyParam, PolicyResult... results)
232             throws BuilderException {
233         //
234         // Find the existing policy
235         //
236         Policy existingPolicy = this.findPolicy(policyParam.getId());
237         if (existingPolicy == null) {
238             throw new BuilderException(UNKNOWN_POLICY + policyParam.getId());
239         }
240         //
241         // Create the new Policy
242         //
243         Policy newPolicy = new Policy(
244                 PolicyParam.builder().id(UUID.randomUUID().toString())
245                 .name(policyParam.getName())
246                 .description(policyParam.getDescription())
247                 .actor(policyParam.getActor())
248                 .payload(policyParam.getPayload())
249                 .target(policyParam.getTarget())
250                 .recipe(policyParam.getRecipe())
251                 .retries(policyParam.getRetries())
252                 .timeout(policyParam.getTimeout())
253                 .build());
254         //
255         // Connect the results
256         //
257         for (PolicyResult result : results) {
258             switch (result) {
259                 case FAILURE:
260                     existingPolicy.setFailure(newPolicy.getId());
261                     break;
262                 case FAILURE_EXCEPTION:
263                     existingPolicy.setFailure_exception(newPolicy.getId());
264                     break;
265                 case FAILURE_RETRIES:
266                     existingPolicy.setFailure_retries(newPolicy.getId());
267                     break;
268                 case FAILURE_TIMEOUT:
269                     existingPolicy.setFailure_timeout(newPolicy.getId());
270                     break;
271                 case FAILURE_GUARD:
272                     existingPolicy.setFailure_guard(newPolicy.getId());
273                     break;
274                 case SUCCESS:
275                     existingPolicy.setSuccess(newPolicy.getId());
276                     break;
277                 default:
278                     throw new BuilderException("Invalid PolicyResult " + result);
279             }
280         }
281         //
282         // Add it to our list
283         //
284         this.controlLoopPolicy.getPolicies().add(newPolicy);
285         //
286         // Return a policy to them
287         //
288         return new Policy(newPolicy);
289     }
290
291     @Override
292     public Policy setPolicyForPolicyResult(String policyResultId, String policyId, PolicyResult... results)
293             throws BuilderException {
294         //
295         // Find the existing policy
296         //
297         Policy existingPolicy = this.findPolicy(policyId);
298         if (existingPolicy == null) {
299             throw new BuilderException(policyId + " does not exist");
300         }
301         if (this.findPolicy(policyResultId) == null) {
302             throw new BuilderException("Operational policy " + policyResultId + " does not exist");
303         }
304         //
305         // Connect the results
306         //
307         for (PolicyResult result : results) {
308             switch (result) {
309                 case FAILURE:
310                     existingPolicy.setFailure(policyResultId);
311                     break;
312                 case FAILURE_EXCEPTION:
313                     existingPolicy.setFailure_exception(policyResultId);
314                     break;
315                 case FAILURE_RETRIES:
316                     existingPolicy.setFailure_retries(policyResultId);
317                     break;
318                 case FAILURE_TIMEOUT:
319                     existingPolicy.setFailure_timeout(policyResultId);
320                     break;
321                 case FAILURE_GUARD:
322                     existingPolicy.setFailure_guard(policyResultId);
323                     break;
324                 case SUCCESS:
325                     existingPolicy.setSuccess(policyResultId);
326                     break;
327                 default:
328                     throw new BuilderException("Invalid PolicyResult " + result);
329             }
330         }
331         return new Policy(this.findPolicy(policyResultId));
332     }
333
334     private class BuilderCompilerCallback implements ControlLoopCompilerCallback {
335
336         private ResultsImpl results = new ResultsImpl();
337
338         @Override
339         public boolean onWarning(String message) {
340             results.addMessage(new MessageImpl(message, MessageLevel.WARNING));
341             return false;
342         }
343
344         @Override
345         public boolean onError(String message) {
346             results.addMessage(new MessageImpl(message, MessageLevel.ERROR));
347             return false;
348         }
349     }
350
351     @Override
352     public Results buildSpecification() {
353         //
354         // Dump the specification
355         //
356         DumperOptions options = new DumperOptions();
357         options.setDefaultFlowStyle(FlowStyle.BLOCK);
358         options.setPrettyFlow(true);
359         Yaml yaml = new Yaml(options);
360         String dumpedYaml = yaml.dump(controlLoopPolicy);
361         //
362         // This is our callback class for our compiler
363         //
364         BuilderCompilerCallback callback = new BuilderCompilerCallback();
365         //
366         // Compile it
367         //
368         try {
369             ControlLoopCompiler.compile(controlLoopPolicy, callback);
370         } catch (CompilerException e) {
371             logger.error(e.getMessage() + e);
372             callback.results.addMessage(new MessageImpl(e.getMessage(), MessageLevel.EXCEPTION));
373         }
374         //
375         // Save the spec
376         //
377         callback.results.setSpecification(dumpedYaml);
378         return callback.results;
379     }
380
381     private void addNewPolicy(Policy policy) {
382         if (this.controlLoopPolicy.getPolicies() == null) {
383             this.controlLoopPolicy.setPolicies(new LinkedList<>());
384         }
385         this.controlLoopPolicy.getPolicies().add(policy);
386     }
387
388     private Policy findPolicy(String id) {
389         if (this.controlLoopPolicy.getPolicies() != null) {
390             for (Policy policy : this.controlLoopPolicy.getPolicies()) {
391                 if (policy.getId().equals(id)) {
392                     return policy;
393                 }
394             }
395         }
396         return null;
397     }
398
399     @Override
400     public ControlLoopPolicyBuilder removeResource(Resource... resources) throws BuilderException {
401         if (controlLoopPolicy.getControlLoop().getResources() == null) {
402             throw new BuilderException("No existing resources to remove");
403         }
404         for (Resource resource : resources) {
405             if (resource == null) {
406                 throw new BuilderException("Resource must not be null");
407             }
408             if (resource.getResourceUuid() == null && Strings.isNullOrEmpty(resource.getResourceName())) {
409                 throw new BuilderException("Invalid resource - need either a resourceUUID or resourceName");
410             }
411             boolean removed = controlLoopPolicy.getControlLoop().getResources().remove(resource);
412             if (!removed) {
413                 throw new BuilderException("Unknown resource " + resource.getResourceName());
414             }
415         }
416         return this;
417     }
418
419     @Override
420     public ControlLoopPolicyBuilder removeAllResources() throws BuilderException {
421         controlLoopPolicy.getControlLoop().getResources().clear();
422         return this;
423     }
424
425     @Override
426     public Integer calculateTimeout() {
427         int sum = 0;
428         for (Policy policy : this.controlLoopPolicy.getPolicies()) {
429             sum += policy.getTimeout().intValue();
430         }
431         return Integer.valueOf(sum);
432     }
433
434     @Override
435     public boolean isOpenLoop() {
436         return this.controlLoopPolicy.getControlLoop().getTrigger_policy()
437                 .equals(FinalResult.FINAL_OPENLOOP.toString());
438     }
439
440     @Override
441     public Policy getTriggerPolicy() throws BuilderException {
442         if (this.controlLoopPolicy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
443             return null;
444         } else {
445             return new Policy(this.findPolicy(this.controlLoopPolicy.getControlLoop().getTrigger_policy()));
446         }
447     }
448
449     @Override
450     public ControlLoop getControlLoop() {
451         return new ControlLoop(this.controlLoopPolicy.getControlLoop());
452     }
453
454     @Override
455     public boolean removePolicy(String policyId) throws BuilderException {
456         Policy existingPolicy = this.findPolicy(policyId);
457         if (existingPolicy == null) {
458             throw new BuilderException(UNKNOWN_POLICY + policyId);
459         }
460         //
461         // Check if the policy to remove is trigger_policy
462         //
463         if (this.controlLoopPolicy.getControlLoop().getTrigger_policy().equals(policyId)) {
464             this.controlLoopPolicy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
465         } else {
466             updateChainedPoliciesForPolicyRemoval(policyId);
467         }
468         //
469         // remove the policy
470         //
471         return this.controlLoopPolicy.getPolicies().remove(existingPolicy);
472     }
473
474     private void updateChainedPoliciesForPolicyRemoval(String idOfPolicyBeingRemoved) {
475         for (Policy policy : this.controlLoopPolicy.getPolicies()) {
476             final int index = this.controlLoopPolicy.getPolicies().indexOf(policy);
477             if (policy.getSuccess().equals(idOfPolicyBeingRemoved)) {
478                 policy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
479             }
480             if (policy.getFailure().equals(idOfPolicyBeingRemoved)) {
481                 policy.setFailure(FinalResult.FINAL_FAILURE.toString());
482             }
483             if (policy.getFailure_retries().equals(idOfPolicyBeingRemoved)) {
484                 policy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
485             }
486             if (policy.getFailure_timeout().equals(idOfPolicyBeingRemoved)) {
487                 policy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
488             }
489             if (policy.getFailure_exception().equals(idOfPolicyBeingRemoved)) {
490                 policy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
491             }
492             if (policy.getFailure_guard().equals(idOfPolicyBeingRemoved)) {
493                 policy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
494             }
495             this.controlLoopPolicy.getPolicies().set(index, policy);
496         }
497     }
498
499     @Override
500     public Policy resetPolicyResults(String policyId) throws BuilderException {
501         Policy existingPolicy = this.findPolicy(policyId);
502         if (existingPolicy == null) {
503             throw new BuilderException(UNKNOWN_POLICY + policyId);
504         }
505         //
506         // reset policy results
507         //
508         existingPolicy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
509         existingPolicy.setFailure(FinalResult.FINAL_FAILURE.toString());
510         existingPolicy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
511         existingPolicy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
512         existingPolicy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
513         existingPolicy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
514         return new Policy(existingPolicy);
515     }
516
517     @Override
518     public ControlLoopPolicyBuilder removeAllPolicies() {
519         //
520         // Remove all existing operational policies
521         //
522         this.controlLoopPolicy.getPolicies().clear();
523         //
524         // Revert controlLoop back to an open loop
525         //
526         this.controlLoopPolicy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
527         return this;
528     }
529
530     @Override
531     public Policy addOperationsAccumulateParams(String policyId, OperationsAccumulateParams operationsAccumulateParams)
532             throws BuilderException {
533         Policy existingPolicy = this.findPolicy(policyId);
534         if (existingPolicy == null) {
535             throw new BuilderException(UNKNOWN_POLICY + policyId);
536         }
537         //
538         // Add operationsAccumulateParams to existingPolicy
539         //
540         existingPolicy.setOperationsAccumulateParams(operationsAccumulateParams);
541         return new Policy(existingPolicy);
542     }
543
544 }