39c32fa834810410f88536189e39a3eda73d842c
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-2021 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.processor;
22
23 import java.io.Serializable;
24 import lombok.Getter;
25 import org.onap.policy.common.utils.coder.CoderException;
26 import org.onap.policy.common.utils.coder.StandardYamlCoder;
27 import org.onap.policy.controlloop.ControlLoopException;
28 import org.onap.policy.controlloop.actorserviceprovider.OperationFinalResult;
29 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
30 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
31 import org.onap.policy.drools.domain.models.operational.Operation;
32 import org.onap.policy.drools.domain.models.operational.OperationalPolicy;
33 import org.onap.policy.drools.system.PolicyEngineConstants;
34 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
35 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
36
37 public class ControlLoopProcessor implements Serializable {
38     private static final long serialVersionUID = 1L;
39
40     private static final StandardYamlCoder coder = new StandardYamlCoder();
41
42     @Getter
43     private final OperationalPolicy policy;
44     private String currentNestedPolicyId;
45
46     // not serializable, thus must be transient
47     @Getter
48     private transient ToscaPolicy toscaOpPolicy;
49
50     /**
51      * Construct an instance from yaml.
52      *
53      * @param yaml the yaml
54      * @throws ControlLoopException if an error occurs
55      */
56     public ControlLoopProcessor(String yaml) throws ControlLoopException {
57         this(decodeTosca(yaml));
58     }
59
60     /**
61      * Create an instance from a Tosca Policy.
62      */
63     public ControlLoopProcessor(ToscaPolicy toscaPolicy) throws ControlLoopException {
64         try {
65             this.policy =
66                     PolicyEngineConstants.getManager().getDomainMaker().convertTo(toscaPolicy, OperationalPolicy.class);
67             this.currentNestedPolicyId = this.policy.getProperties().getTrigger();
68             this.toscaOpPolicy = toscaPolicy;
69         } catch (RuntimeException | CoderException e) {
70             throw new ControlLoopException(e);
71         }
72     }
73
74     private static ToscaPolicy decodeTosca(String yaml) throws ControlLoopException {
75         try {
76             ToscaServiceTemplate template = coder.decode(yaml, ToscaServiceTemplate.class);
77             if (template == null || template.getToscaTopologyTemplate() == null) {
78                 throw new IllegalArgumentException("Cannot decode yaml into ToscaServiceTemplate");
79             }
80
81             return template.getToscaTopologyTemplate().getPolicies().get(0).values().iterator().next();
82
83         } catch (final Exception e) {
84             //
85             // Most likely this is a YAML Exception
86             //
87             throw new ControlLoopException(e);
88         }
89     }
90
91     /**
92      * Get ControlLoopParams.
93      */
94     public ControlLoopParams getControlLoopParams() {
95         ControlLoopParams controlLoopParams = new ControlLoopParams();
96
97         controlLoopParams.setClosedLoopControlName(this.policy.getProperties().getId());
98         controlLoopParams.setPolicyScope(policy.getType() + ":" + policy.getTypeVersion());
99         controlLoopParams.setPolicyName(policy.getName());
100         controlLoopParams.setPolicyVersion(policy.getVersion());
101         controlLoopParams.setToscaPolicy(toscaOpPolicy);
102
103         return controlLoopParams;
104     }
105
106     public OperationFinalResult checkIsCurrentPolicyFinal() {
107         return OperationFinalResult.toResult(this.currentNestedPolicyId);
108     }
109
110     /**
111      * Get the current policy.
112      *
113      * @return the current policy
114      * @throws ControlLoopException if an error occurs
115      */
116     public Operation getCurrentPolicy() throws ControlLoopException {
117         if (this.policy == null || this.policy.getProperties() == null
118                         || this.policy.getProperties().getOperations() == null
119                         || this.policy.getProperties().getOperations().isEmpty()) {
120             throw new ControlLoopException("There are no policies defined.");
121         }
122
123         for (final Operation nestedPolicy : this.policy.getProperties().getOperations()) {
124             if (nestedPolicy.getId().equals(this.currentNestedPolicyId)) {
125                 return nestedPolicy;
126             }
127         }
128         return null;
129     }
130
131     /**
132      * Get the next policy given a result of the current policy.
133      *
134      * @param result the result of the current policy
135      * @throws ControlLoopException if an error occurs
136      */
137     public void nextPolicyForResult(OperationResult result) throws ControlLoopException {
138         final Operation currentPolicy = this.getCurrentPolicy();
139         try {
140             if (currentPolicy == null) {
141                 throw new ControlLoopException("There is no current policy to determine where to go to.");
142             }
143             switch (result) {
144                 case SUCCESS:
145                     this.currentNestedPolicyId = currentPolicy.getSuccess();
146                     break;
147                 case FAILURE:
148                     this.currentNestedPolicyId = currentPolicy.getFailure();
149                     break;
150                 case FAILURE_TIMEOUT:
151                     this.currentNestedPolicyId = currentPolicy.getFailureTimeout();
152                     break;
153                 case FAILURE_RETRIES:
154                     this.currentNestedPolicyId = currentPolicy.getFailureRetries();
155                     break;
156                 case FAILURE_EXCEPTION:
157                     this.currentNestedPolicyId = currentPolicy.getFailureException();
158                     break;
159                 case FAILURE_GUARD:
160                 default:
161                     this.currentNestedPolicyId = currentPolicy.getFailureGuard();
162                     break;
163             }
164         } catch (final ControlLoopException e) {
165             this.currentNestedPolicyId = OperationFinalResult.FINAL_FAILURE_EXCEPTION.toString();
166             throw e;
167         }
168     }
169 }