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