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