Code changes for OOF SON Use Case
[policy/models.git] / models-interactions / model-actors / actor.sdnr / src / main / java / org / onap / policy / controlloop / actor / sdnr / SdnrActorServiceProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SdnrActorServiceProvider
4  * ================================================================================
5  * Copyright (C) 2018 Wipro Limited Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.controlloop.actor.sdnr;
23
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.ImmutableMap;
26
27 import java.util.Collections;
28 import java.util.List;
29
30 import org.onap.policy.controlloop.ControlLoopOperation;
31 import org.onap.policy.controlloop.ControlLoopResponse;
32 import org.onap.policy.controlloop.VirtualControlLoopEvent;
33 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
34 import org.onap.policy.controlloop.policy.Policy;
35 import org.onap.policy.controlloop.policy.PolicyResult;
36 import org.onap.policy.sdnr.PciCommonHeader;
37 import org.onap.policy.sdnr.PciRequest;
38 import org.onap.policy.sdnr.PciRequestWrapper;
39 import org.onap.policy.sdnr.PciResponse;
40 import org.onap.policy.sdnr.PciResponseCode;
41 import org.onap.policy.sdnr.PciResponseWrapper;
42
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public class SdnrActorServiceProvider implements Actor {
47
48     public static class Pair<A, B> {
49         public final A result;
50         public final B message;
51
52         public Pair(A result, B message) {
53             this.result = result;
54             this.message = message;
55         }
56
57         public A getResult() {
58             return this.result;
59         }
60
61         public B getMessage() {
62             return this.message;
63         }
64     }
65
66     private static final Logger logger = LoggerFactory.getLogger(SdnrActorServiceProvider.class);
67
68     // Strings for targets
69     private static final String TARGET_VNF = "VNF";
70
71     // Strings for recipes
72     private static final String RECIPE_MODIFY = "ModifyConfig";
73     private static final String RECIPE_MODIFY_ANR = "ModifyConfigANR";
74
75     /* To be used in future releases when pci ModifyConfig is used */
76     private static final String SDNR_REQUEST_PARAMS = "request-parameters";
77     private static final String SDNR_CONFIG_PARAMS = "configuration-parameters";
78
79     private static final ImmutableList<String> recipes = ImmutableList.of(RECIPE_MODIFY);
80     private static final ImmutableMap<String, List<String>> targets = new ImmutableMap.Builder<String, List<String>>()
81             .put(RECIPE_MODIFY, ImmutableList.of(TARGET_VNF)).build();
82     private static final ImmutableMap<String, List<String>> payloads = new ImmutableMap.Builder<String, List<String>>()
83             .put(RECIPE_MODIFY, ImmutableList.of(SDNR_REQUEST_PARAMS, SDNR_CONFIG_PARAMS)).build();
84
85     @Override
86     public String actor() {
87         return "SDNR";
88     }
89
90     @Override
91     public List<String> recipes() {
92         return ImmutableList.copyOf(recipes);
93     }
94
95     @Override
96     public List<String> recipeTargets(String recipe) {
97         return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
98     }
99
100     @Override
101     public List<String> recipePayloads(String recipe) {
102         return ImmutableList.copyOf(payloads.getOrDefault(recipe, Collections.emptyList()));
103     }
104
105     /**
106      * Constructs an SDNR request conforming to the pci API. The actual request is
107      * constructed and then placed in a wrapper object used to send through DMAAP.
108      *
109      * @param onset
110      *            the event that is reporting the alert for policy to perform an
111      *            action
112      * @param operation
113      *            the control loop operation specifying the actor, operation,
114      *            target, etc.
115      * @param policy
116      *            the policy the was specified from the yaml generated by CLAMP or
117      *            through the Policy GUI/API
118      * @return an SDNR request conforming to the pci API using the DMAAP wrapper
119      */
120
121     public static PciRequestWrapper constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation,
122             Policy policy) {
123
124         /* Construct an SDNR request using pci Model */
125
126         /*
127          * The actual pci request is placed in a wrapper used to send through dmaap. The
128          * current version is 2.0 as of R1.
129          */
130         PciRequestWrapper dmaapRequest = new PciRequestWrapper();
131         dmaapRequest.setVersion("1.0");
132         dmaapRequest.setCorrelationId(onset.getRequestId() + "-" + operation.getSubRequestId());
133         dmaapRequest.setRpcName(policy.getRecipe().toLowerCase());
134         dmaapRequest.setType("request");
135
136         /* This is the actual request that is placed in the dmaap wrapper. */
137         final PciRequest sdnrRequest = new PciRequest();
138
139         /* The common header is a required field for all SDNR requests. */
140         PciCommonHeader requestCommonHeader = new PciCommonHeader();
141         requestCommonHeader.setRequestId(onset.getRequestId());
142         requestCommonHeader.setSubRequestId(operation.getSubRequestId());
143
144         sdnrRequest.setCommonHeader(requestCommonHeader);
145         sdnrRequest.setPayload(onset.getPayload());
146
147         /*
148          * An action is required for all SDNR requests, this will be the recipe
149          * specified in the policy.
150          */
151         sdnrRequest.setAction(policy.getRecipe());
152
153         /*
154          * Once the pci request is constructed, add it into the body of the dmaap
155          * wrapper.
156          */
157         dmaapRequest.setBody(sdnrRequest);
158         logger.info("SDNR Request to be sent is {}", dmaapRequest);
159
160         /* Return the request to be sent through dmaap. */
161         return dmaapRequest;
162     }
163
164     /**
165      * Parses the operation attempt using the subRequestId of SDNR response.
166      *
167      * @param subRequestId
168      *            the sub id used to send to SDNR, Policy sets this using the
169      *            operation attempt
170      *
171      * @return the current operation attempt
172      */
173     public static Integer parseOperationAttempt(String subRequestId) {
174         Integer operationAttempt;
175         try {
176             operationAttempt = Integer.parseInt(subRequestId);
177         } catch (NumberFormatException e) {
178             logger.debug("A NumberFormatException was thrown in parsing the operation attempt {}", subRequestId);
179             return null;
180         }
181         return operationAttempt;
182     }
183
184     /**
185      * Processes the SDNR pci response sent from SDNR. Determines if the SDNR
186      * operation was successful/unsuccessful and maps this to the corresponding
187      * Policy result.
188      *
189      * @param dmaapResponse
190      *            the dmaap wrapper message that contains the actual SDNR reponse
191      *            inside the body field
192      *
193      * @return an key-value pair that contains the Policy result and SDNR response
194      *         message
195      */
196     public static SdnrActorServiceProvider.Pair<PolicyResult, String> processResponse(
197             PciResponseWrapper dmaapResponse) {
198
199         logger.info("SDNR processResponse called : {}", dmaapResponse);
200
201         /* The actual SDNR response is inside the wrapper's body field. */
202         PciResponse sdnrResponse = dmaapResponse.getBody();
203
204         /* The message returned in the SDNR response. */
205         String message;
206
207         /* The Policy result determined from the SDNR Response. */
208         PolicyResult result;
209
210         /*
211          * If there is no status, Policy cannot determine if the request was successful.
212          */
213         if (sdnrResponse.getStatus() == null) {
214             message = "Policy was unable to parse SDN-R response status field (it was null).";
215             return new SdnrActorServiceProvider.Pair<>(PolicyResult.FAILURE_EXCEPTION, message);
216         }
217
218         /*
219          * If there is no code, Policy cannot determine if the request was successful.
220          */
221         String responseValue = PciResponseCode.toResponseValue(sdnrResponse.getStatus().getCode());
222         if (responseValue == null) {
223             message = "Policy was unable to parse SDN-R response status code field.";
224             return new SdnrActorServiceProvider.Pair<>(PolicyResult.FAILURE_EXCEPTION, message);
225         }
226         logger.info("SDNR Response Code is {}", responseValue);
227
228         /* Save the SDNR response's message for Policy notification message. */
229         message = sdnrResponse.getStatus().getValue();
230         logger.info("SDNR Response Message is {}", message);
231
232         /*
233          * Response and Payload are just printed and no further action needed in
234          * casablanca release
235          */
236         String rspPayload = sdnrResponse.getPayload();
237         logger.info("SDNR Response Payload is {}", rspPayload);
238
239         /* Maps the SDNR response result to a Policy result. */
240         switch (responseValue) {
241             case PciResponseCode.ACCEPTED:
242                 /* Nothing to do if code is accept, continue processing */
243                 result = null;
244                 break;
245             case PciResponseCode.SUCCESS:
246                 result = PolicyResult.SUCCESS;
247                 break;
248             case PciResponseCode.FAILURE:
249                 result = PolicyResult.FAILURE;
250                 break;
251             case PciResponseCode.REJECT:
252             case PciResponseCode.ERROR:
253             default:
254                 result = PolicyResult.FAILURE_EXCEPTION;
255         }
256         return new SdnrActorServiceProvider.Pair<>(result, message);
257     }
258
259     /**
260      * Converts the SDNR response to ControlLoopResponse object.
261      *
262      * @param dmaapResponse
263      *            the dmaap wrapper message that contains the actual SDNR reponse
264      *            inside the body field
265      *
266      * @return a ControlLoopResponse object to send to DCAE_CL_RSP topic
267      */
268     public static ControlLoopResponse getControlLoopResponse(PciResponseWrapper dmaapResponse,
269             VirtualControlLoopEvent event) {
270
271         logger.info("SDNR getClosedLoopResponse called : {} {}", dmaapResponse, event);
272
273         /* The actual SDNR response is inside the wrapper's body field. */
274         PciResponse sdnrResponse = dmaapResponse.getBody();
275
276         /* The ControlLoop response determined from the SDNR Response and input event. */
277         ControlLoopResponse clRsp = new ControlLoopResponse();
278         clRsp.setPayload(sdnrResponse.getPayload());
279         clRsp.setFrom("SDNR");
280         clRsp.setTarget("DCAE");
281         clRsp.setClosedLoopControlName(event.getClosedLoopControlName());
282         clRsp.setPolicyName(event.getPolicyName());
283         clRsp.setPolicyVersion(event.getPolicyVersion());
284         clRsp.setRequestId(event.getRequestId());
285         clRsp.setVersion(event.getVersion());
286         logger.info("SDNR getClosedLoopResponse clRsp : {}", clRsp);
287
288         return clRsp;
289     }
290
291 }