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