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