2  * ============LICENSE_START=======================================================
 
   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
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  21 package org.onap.policy.controlloop.policy.builder.impl;
 
  23 import com.google.common.base.Strings;
 
  24 import java.util.LinkedList;
 
  26 import java.util.UUID;
 
  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.Target;
 
  39 import org.onap.policy.controlloop.policy.builder.BuilderException;
 
  40 import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
 
  41 import org.onap.policy.controlloop.policy.builder.MessageLevel;
 
  42 import org.onap.policy.controlloop.policy.builder.Results;
 
  43 import org.onap.policy.sdc.Resource;
 
  44 import org.onap.policy.sdc.Service;
 
  45 import org.slf4j.Logger;
 
  46 import org.slf4j.LoggerFactory;
 
  47 import org.yaml.snakeyaml.DumperOptions;
 
  48 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
 
  49 import org.yaml.snakeyaml.Yaml;
 
  51 public class ControlLoopPolicyBuilderImpl implements ControlLoopPolicyBuilder {
 
  52     private static final String UNKNOWN_POLICY = "Unknown policy ";
 
  53     private static Logger logger = LoggerFactory.getLogger(ControlLoopPolicyBuilderImpl.class.getName());
 
  54     private ControlLoopPolicy controlLoopPolicy;
 
  59      * @param controlLoopName control loop id
 
  60      * @param timeout timeout value
 
  62     public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout) {
 
  63         controlLoopPolicy = new ControlLoopPolicy();
 
  64         ControlLoop controlLoop = new ControlLoop();
 
  65         controlLoop.setControlLoopName(controlLoopName);
 
  66         controlLoop.setTimeout(timeout);
 
  67         controlLoopPolicy.setControlLoop(controlLoop);
 
  73      * @param controlLoopName control loop id
 
  74      * @param timeout timeout value
 
  75      * @param resource resource
 
  76      * @param services services
 
  77      * @throws BuilderException builder exception
 
  79     public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Resource resource, Service... services)
 
  80             throws BuilderException {
 
  81         this(controlLoopName, timeout);
 
  82         this.addResource(resource);
 
  83         this.addService(services);
 
  86     public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Pnf pnf) throws BuilderException {
 
  87         this(controlLoopName, timeout);
 
  94      * @param controlLoopName control loop id
 
  95      * @param timeout timeout
 
  96      * @param service service
 
  97      * @param resources resources
 
  98      * @throws BuilderException builder exception
 
 100     public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Service service, Resource[] resources)
 
 101             throws BuilderException {
 
 102         this(controlLoopName, timeout);
 
 103         this.addService(service);
 
 104         this.addResource(resources);
 
 108     public ControlLoopPolicyBuilder removePNF() throws BuilderException {
 
 109         controlLoopPolicy.getControlLoop().setPnf(null);
 
 114     public ControlLoopPolicyBuilder addService(Service... services) throws BuilderException {
 
 115         for (Service service : services) {
 
 116             if (service == null) {
 
 117                 throw new BuilderException("Service must not be null");
 
 119             if (service.getServiceUUID() == null && Strings.isNullOrEmpty(service.getServiceName())) {
 
 120                 throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
 
 122             if (controlLoopPolicy.getControlLoop().getServices() == null) {
 
 123                 controlLoopPolicy.getControlLoop().setServices(new LinkedList<>());
 
 125             controlLoopPolicy.getControlLoop().getServices().add(service);
 
 131     public ControlLoopPolicyBuilder removeService(Service... services) throws BuilderException {
 
 132         if (controlLoopPolicy.getControlLoop().getServices() == null) {
 
 133             throw new BuilderException("No existing services to remove");
 
 135         for (Service service : services) {
 
 136             if (service == null) {
 
 137                 throw new BuilderException("Service must not be null");
 
 139             if (service.getServiceUUID() == null && Strings.isNullOrEmpty(service.getServiceName())) {
 
 140                 throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
 
 142             boolean removed = controlLoopPolicy.getControlLoop().getServices().remove(service);
 
 144                 throw new BuilderException("Unknown service " + service.getServiceName());
 
 151     public ControlLoopPolicyBuilder removeAllServices() throws BuilderException {
 
 152         controlLoopPolicy.getControlLoop().getServices().clear();
 
 158     public ControlLoopPolicyBuilder addResource(Resource... resources) throws BuilderException {
 
 159         for (Resource resource : resources) {
 
 160             if (resource == null) {
 
 161                 throw new BuilderException("Resource must not be null");
 
 163             if (resource.getResourceUuid() == null && Strings.isNullOrEmpty(resource.getResourceName())) {
 
 164                 throw new BuilderException("Invalid resource - need either resourceUUID or resourceName");
 
 166             if (controlLoopPolicy.getControlLoop().getResources() == null) {
 
 167                 controlLoopPolicy.getControlLoop().setResources(new LinkedList<>());
 
 169             controlLoopPolicy.getControlLoop().getResources().add(resource);
 
 175     public ControlLoopPolicyBuilder setPNF(Pnf pnf) throws BuilderException {
 
 177             throw new BuilderException("PNF must not be null");
 
 179         if (pnf.getPnfName() == null && pnf.getPnfType() == null) {
 
 180             throw new BuilderException("Invalid PNF - need either pnfName or pnfType");
 
 182         controlLoopPolicy.getControlLoop().setPnf(pnf);
 
 187     public ControlLoopPolicyBuilder setAbatement(Boolean abatement) throws BuilderException {
 
 188         if (abatement == null) {
 
 189             throw new BuilderException("abatement must not be null");
 
 191         controlLoopPolicy.getControlLoop().setAbatement(abatement);
 
 196     public ControlLoopPolicyBuilder setTimeout(Integer timeout) {
 
 197         controlLoopPolicy.getControlLoop().setTimeout(timeout);
 
 202     public Policy setTriggerPolicy(PolicyParam policyParam)
 
 203             throws BuilderException {
 
 205         Policy trigger = new Policy(policyParam);
 
 207         controlLoopPolicy.getControlLoop().setTrigger_policy(trigger.getId());
 
 209         this.addNewPolicy(trigger);
 
 211         // Return a copy of the policy
 
 213         return new Policy(trigger);
 
 217     public ControlLoop setExistingTriggerPolicy(String id) throws BuilderException {
 
 219             throw new BuilderException("Id must not be null");
 
 221         Policy trigger = this.findPolicy(id);
 
 222         if (trigger == null) {
 
 223             throw new BuilderException(UNKNOWN_POLICY + id);
 
 225             this.controlLoopPolicy.getControlLoop().setTrigger_policy(id);
 
 227         return new ControlLoop(this.controlLoopPolicy.getControlLoop());
 
 231     public Policy setPolicyForPolicyResult(PolicyParam policyParam, PolicyResult... results)
 
 232             throws BuilderException {
 
 234         // Find the existing policy
 
 236         Policy existingPolicy = this.findPolicy(policyParam.getId());
 
 237         if (existingPolicy == null) {
 
 238             throw new BuilderException(UNKNOWN_POLICY + policyParam.getId());
 
 241         // Create the new Policy
 
 243         Policy newPolicy = new Policy(
 
 244                 PolicyParam.builder().id(UUID.randomUUID().toString())
 
 245                 .name(policyParam.getName())
 
 246                 .description(policyParam.getDescription())
 
 247                 .actor(policyParam.getActor())
 
 248                 .payload(policyParam.getPayload())
 
 249                 .target(policyParam.getTarget())
 
 250                 .recipe(policyParam.getRecipe())
 
 251                 .retries(policyParam.getRetries())
 
 252                 .timeout(policyParam.getTimeout())
 
 255         // Connect the results
 
 257         for (PolicyResult result : results) {
 
 260                     existingPolicy.setFailure(newPolicy.getId());
 
 262                 case FAILURE_EXCEPTION:
 
 263                     existingPolicy.setFailure_exception(newPolicy.getId());
 
 265                 case FAILURE_RETRIES:
 
 266                     existingPolicy.setFailure_retries(newPolicy.getId());
 
 268                 case FAILURE_TIMEOUT:
 
 269                     existingPolicy.setFailure_timeout(newPolicy.getId());
 
 272                     existingPolicy.setFailure_guard(newPolicy.getId());
 
 275                     existingPolicy.setSuccess(newPolicy.getId());
 
 278                     throw new BuilderException("Invalid PolicyResult " + result);
 
 282         // Add it to our list
 
 284         this.controlLoopPolicy.getPolicies().add(newPolicy);
 
 286         // Return a policy to them
 
 288         return new Policy(newPolicy);
 
 292     public Policy setPolicyForPolicyResult(String policyResultId, String policyId, PolicyResult... results)
 
 293             throws BuilderException {
 
 295         // Find the existing policy
 
 297         Policy existingPolicy = this.findPolicy(policyId);
 
 298         if (existingPolicy == null) {
 
 299             throw new BuilderException(policyId + " does not exist");
 
 301         if (this.findPolicy(policyResultId) == null) {
 
 302             throw new BuilderException("Operational policy " + policyResultId + " does not exist");
 
 305         // Connect the results
 
 307         for (PolicyResult result : results) {
 
 310                     existingPolicy.setFailure(policyResultId);
 
 312                 case FAILURE_EXCEPTION:
 
 313                     existingPolicy.setFailure_exception(policyResultId);
 
 315                 case FAILURE_RETRIES:
 
 316                     existingPolicy.setFailure_retries(policyResultId);
 
 318                 case FAILURE_TIMEOUT:
 
 319                     existingPolicy.setFailure_timeout(policyResultId);
 
 322                     existingPolicy.setFailure_guard(policyResultId);
 
 325                     existingPolicy.setSuccess(policyResultId);
 
 328                     throw new BuilderException("Invalid PolicyResult " + result);
 
 331         return new Policy(this.findPolicy(policyResultId));
 
 334     private class BuilderCompilerCallback implements ControlLoopCompilerCallback {
 
 336         private ResultsImpl results = new ResultsImpl();
 
 339         public boolean onWarning(String message) {
 
 340             results.addMessage(new MessageImpl(message, MessageLevel.WARNING));
 
 345         public boolean onError(String message) {
 
 346             results.addMessage(new MessageImpl(message, MessageLevel.ERROR));
 
 352     public Results buildSpecification() {
 
 354         // Dump the specification
 
 356         DumperOptions options = new DumperOptions();
 
 357         options.setDefaultFlowStyle(FlowStyle.BLOCK);
 
 358         options.setPrettyFlow(true);
 
 359         Yaml yaml = new Yaml(options);
 
 360         String dumpedYaml = yaml.dump(controlLoopPolicy);
 
 362         // This is our callback class for our compiler
 
 364         BuilderCompilerCallback callback = new BuilderCompilerCallback();
 
 369             ControlLoopCompiler.compile(controlLoopPolicy, callback);
 
 370         } catch (CompilerException e) {
 
 371             logger.error(e.getMessage() + e);
 
 372             callback.results.addMessage(new MessageImpl(e.getMessage(), MessageLevel.EXCEPTION));
 
 377         callback.results.setSpecification(dumpedYaml);
 
 378         return callback.results;
 
 381     private void addNewPolicy(Policy policy) {
 
 382         if (this.controlLoopPolicy.getPolicies() == null) {
 
 383             this.controlLoopPolicy.setPolicies(new LinkedList<>());
 
 385         this.controlLoopPolicy.getPolicies().add(policy);
 
 388     private Policy findPolicy(String id) {
 
 389         if (this.controlLoopPolicy.getPolicies() != null) {
 
 390             for (Policy policy : this.controlLoopPolicy.getPolicies()) {
 
 391                 if (policy.getId().equals(id)) {
 
 400     public ControlLoopPolicyBuilder removeResource(Resource... resources) throws BuilderException {
 
 401         if (controlLoopPolicy.getControlLoop().getResources() == null) {
 
 402             throw new BuilderException("No existing resources to remove");
 
 404         for (Resource resource : resources) {
 
 405             if (resource == null) {
 
 406                 throw new BuilderException("Resource must not be null");
 
 408             if (resource.getResourceUuid() == null && Strings.isNullOrEmpty(resource.getResourceName())) {
 
 409                 throw new BuilderException("Invalid resource - need either a resourceUUID or resourceName");
 
 411             boolean removed = controlLoopPolicy.getControlLoop().getResources().remove(resource);
 
 413                 throw new BuilderException("Unknown resource " + resource.getResourceName());
 
 420     public ControlLoopPolicyBuilder removeAllResources() throws BuilderException {
 
 421         controlLoopPolicy.getControlLoop().getResources().clear();
 
 426     public Integer calculateTimeout() {
 
 428         for (Policy policy : this.controlLoopPolicy.getPolicies()) {
 
 429             sum += policy.getTimeout().intValue();
 
 431         return Integer.valueOf(sum);
 
 435     public boolean isOpenLoop() {
 
 436         return this.controlLoopPolicy.getControlLoop().getTrigger_policy()
 
 437                 .equals(FinalResult.FINAL_OPENLOOP.toString());
 
 441     public Policy getTriggerPolicy() throws BuilderException {
 
 442         if (this.controlLoopPolicy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
 
 445             return new Policy(this.findPolicy(this.controlLoopPolicy.getControlLoop().getTrigger_policy()));
 
 450     public ControlLoop getControlLoop() {
 
 451         return new ControlLoop(this.controlLoopPolicy.getControlLoop());
 
 455     public boolean removePolicy(String policyId) throws BuilderException {
 
 456         Policy existingPolicy = this.findPolicy(policyId);
 
 457         if (existingPolicy == null) {
 
 458             throw new BuilderException(UNKNOWN_POLICY + policyId);
 
 461         // Check if the policy to remove is trigger_policy
 
 463         if (this.controlLoopPolicy.getControlLoop().getTrigger_policy().equals(policyId)) {
 
 464             this.controlLoopPolicy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
 
 466             updateChainedPoliciesForPolicyRemoval(policyId);
 
 471         return this.controlLoopPolicy.getPolicies().remove(existingPolicy);
 
 474     private void updateChainedPoliciesForPolicyRemoval(String idOfPolicyBeingRemoved) {
 
 475         for (Policy policy : this.controlLoopPolicy.getPolicies()) {
 
 476             final int index = this.controlLoopPolicy.getPolicies().indexOf(policy);
 
 477             if (policy.getSuccess().equals(idOfPolicyBeingRemoved)) {
 
 478                 policy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
 
 480             if (policy.getFailure().equals(idOfPolicyBeingRemoved)) {
 
 481                 policy.setFailure(FinalResult.FINAL_FAILURE.toString());
 
 483             if (policy.getFailure_retries().equals(idOfPolicyBeingRemoved)) {
 
 484                 policy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
 
 486             if (policy.getFailure_timeout().equals(idOfPolicyBeingRemoved)) {
 
 487                 policy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
 
 489             if (policy.getFailure_exception().equals(idOfPolicyBeingRemoved)) {
 
 490                 policy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
 
 492             if (policy.getFailure_guard().equals(idOfPolicyBeingRemoved)) {
 
 493                 policy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
 
 495             this.controlLoopPolicy.getPolicies().set(index, policy);
 
 500     public Policy resetPolicyResults(String policyId) throws BuilderException {
 
 501         Policy existingPolicy = this.findPolicy(policyId);
 
 502         if (existingPolicy == null) {
 
 503             throw new BuilderException(UNKNOWN_POLICY + policyId);
 
 506         // reset policy results
 
 508         existingPolicy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
 
 509         existingPolicy.setFailure(FinalResult.FINAL_FAILURE.toString());
 
 510         existingPolicy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
 
 511         existingPolicy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
 
 512         existingPolicy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
 
 513         existingPolicy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
 
 514         return new Policy(existingPolicy);
 
 518     public ControlLoopPolicyBuilder removeAllPolicies() {
 
 520         // Remove all existing operational policies
 
 522         this.controlLoopPolicy.getPolicies().clear();
 
 524         // Revert controlLoop back to an open loop
 
 526         this.controlLoopPolicy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
 
 531     public Policy addOperationsAccumulateParams(String policyId, OperationsAccumulateParams operationsAccumulateParams)
 
 532             throws BuilderException {
 
 533         Policy existingPolicy = this.findPolicy(policyId);
 
 534         if (existingPolicy == null) {
 
 535             throw new BuilderException(UNKNOWN_POLICY + policyId);
 
 538         // Add operationsAccumulateParams to existingPolicy
 
 540         existingPolicy.setOperationsAccumulateParams(operationsAccumulateParams);
 
 541         return new Policy(existingPolicy);