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