2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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 * ===================================================================
24 package org.onap.clamp.loop;
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import com.google.gson.JsonArray;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonNull;
31 import com.google.gson.JsonObject;
32 import com.google.gson.JsonPrimitive;
34 import java.io.IOException;
35 import java.lang.reflect.Array;
36 import java.util.Collection;
37 import java.util.Iterator;
41 import org.apache.camel.Exchange;
42 import org.apache.camel.Message;
43 import org.json.simple.JSONObject;
44 import org.json.simple.parser.JSONParser;
45 import org.json.simple.parser.ParseException;
46 import org.onap.clamp.clds.config.ClampProperties;
47 import org.onap.clamp.policy.operational.OperationalPolicy;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Component;
50 import org.yaml.snakeyaml.Yaml;
53 * Closed loop operations.
56 public class LoopOperation {
58 protected static final EELFLogger logger = EELFManager.getInstance().getLogger(LoopOperation.class);
59 protected static final EELFLogger auditLogger = EELFManager.getInstance().getMetricsLogger();
60 private static final String DCAE_LINK_FIELD = "links";
61 private static final String DCAE_STATUS_FIELD = "status";
62 private static final String DCAE_DEPLOYMENT_TEMPLATE = "dcae.deployment.template";
63 private static final String DCAE_SERVICETYPE_ID = "serviceTypeId";
64 private static final String DCAE_INPUTS = "inputs";
65 private static final String DCAE_DEPLOYMENT_PREFIX = "closedLoop_";
66 private static final String DCAE_DEPLOYMENT_SUFIX = "_deploymentId";
67 private final LoopService loopService;
68 private final ClampProperties refProp;
70 public enum TempLoopState {
71 NOT_SUBMITTED, SUBMITTED, DEPLOYED, NOT_DEPLOYED, PROCESSING, IN_ERROR;
76 * @param loopService The loop service
77 * @param refProp The clamp properties
80 public LoopOperation(LoopService loopService, ClampProperties refProp) {
81 this.loopService = loopService;
82 this.refProp = refProp;
86 * Get the payload used to send the deploy closed loop request.
88 * @param loop The loop
89 * @return The payload used to send deploy closed loop request
90 * @throws IOException IOException
92 public String getDeployPayload(Loop loop) throws IOException {
93 Yaml yaml = new Yaml();
94 Map<String, Object> yamlMap = yaml.load(loop.getBlueprint());
95 JsonObject bluePrint = wrapSnakeObject(yamlMap).getAsJsonObject();
97 String serviceTypeId = loop.getDcaeBlueprintId();
99 JsonObject rootObject = refProp.getJsonTemplate(DCAE_DEPLOYMENT_TEMPLATE).getAsJsonObject();
100 rootObject.addProperty(DCAE_SERVICETYPE_ID, serviceTypeId);
101 if (bluePrint != null) {
102 rootObject.add(DCAE_INPUTS, bluePrint);
104 String apiBodyString = rootObject.toString();
105 logger.info("Dcae api Body String - " + apiBodyString);
107 return apiBodyString;
111 * Get the deployment id.
113 * @param loop The loop
114 * @return The deployment id
115 * @throws IOException IOException
117 public String getDeploymentId(Loop loop) {
118 // Set the deploymentId if not present yet
119 String deploymentId = "";
120 // If model is already deployed then pass same deployment id
121 if (loop.getDcaeDeploymentId() != null && !loop.getDcaeDeploymentId().isEmpty()) {
122 deploymentId = loop.getDcaeDeploymentId();
124 deploymentId = DCAE_DEPLOYMENT_PREFIX + loop.getName() + DCAE_DEPLOYMENT_SUFIX;
130 * Update the loop info.
132 * @param camelExchange The camel exchange
133 * @param loop The loop
134 * @param deploymentId The deployment id
135 * @throws ParseException The parse exception
137 public void updateLoopInfo(Exchange camelExchange, Loop loop, String deploymentId) throws ParseException {
138 Message in = camelExchange.getIn();
139 String msg = in.getBody(String.class);
141 JSONParser parser = new JSONParser();
142 Object obj0 = parser.parse(msg);
143 JSONObject jsonObj = (JSONObject) obj0;
145 JSONObject linksObj = (JSONObject) jsonObj.get(DCAE_LINK_FIELD);
146 String statusUrl = (String) linksObj.get(DCAE_STATUS_FIELD);
148 // use http4 instead of http, because camel http4 component is used to do the http call
149 String newStatusUrl = statusUrl.replaceAll("http:", "http4:");
151 loop.setDcaeDeploymentId(deploymentId);
152 loop.setDcaeDeploymentStatusUrl(newStatusUrl);
153 loopService.saveOrUpdateLoop(loop);
157 * Get the Closed Loop status based on the reply from Policy.
159 * @param statusCode The status code
160 * @return The state based on policy response
161 * @throws ParseException The parse exception
163 public String analysePolicyResponse(int statusCode) {
164 if (statusCode == 200) {
165 return TempLoopState.SUBMITTED.toString();
166 } else if (statusCode == 404) {
167 return TempLoopState.NOT_SUBMITTED.toString();
169 return TempLoopState.IN_ERROR.toString();
173 * Get the name of the first Operational policy.
175 * @param loop The closed loop
176 * @return The name of the first operational policy
178 public String getOperationalPolicyName(Loop loop) {
179 Set<OperationalPolicy> opSet = (Set<OperationalPolicy>)loop.getOperationalPolicies();
180 Iterator<OperationalPolicy> iterator = opSet.iterator();
181 while (iterator.hasNext()) {
182 OperationalPolicy policy = iterator.next();
183 return policy.getName();
189 * Get the Closed Loop status based on the reply from DCAE.
191 * @param camelExchange The camel exchange
192 * @return The state based on DCAE response
193 * @throws ParseException The parse exception
195 public String analyseDcaeResponse(Exchange camelExchange, Integer statusCode) throws ParseException {
196 if (statusCode == null) {
197 return TempLoopState.NOT_DEPLOYED.toString();
199 if (statusCode == 200) {
200 Message in = camelExchange.getIn();
201 String msg = in.getBody(String.class);
203 JSONParser parser = new JSONParser();
204 Object obj0 = parser.parse(msg);
205 JSONObject jsonObj = (JSONObject) obj0;
207 String opType = (String) jsonObj.get("operationType");
208 String status = (String) jsonObj.get("status");
210 // status = processing/successded/failed
211 if (status.equals("succeeded")) {
212 if (opType.equals("install")) {
213 return TempLoopState.DEPLOYED.toString();
214 } else if (opType.equals("uninstall")) {
215 return TempLoopState.NOT_DEPLOYED.toString();
217 } else if (status.equals("processing")) {
218 return TempLoopState.PROCESSING.toString();
220 } else if (statusCode == 404) {
221 return TempLoopState.NOT_DEPLOYED.toString();
223 return TempLoopState.IN_ERROR.toString();
227 * Update the status of the closed loop based on the response from Policy and DCAE.
229 * @param loop The closed loop
230 * @param policyState The state get from Policy
231 * @param dcaeState The state get from DCAE
232 * @throws ParseException The parse exception
234 public LoopState updateLoopStatus(Loop loop, TempLoopState policyState, TempLoopState dcaeState) {
235 LoopState clState = LoopState.IN_ERROR;
236 if (policyState == TempLoopState.SUBMITTED) {
237 if (dcaeState == TempLoopState.DEPLOYED) {
238 clState = LoopState.DEPLOYED;
239 } else if (dcaeState == TempLoopState.PROCESSING) {
240 clState = LoopState.WAITING;
241 } else if (dcaeState == TempLoopState.NOT_DEPLOYED) {
242 clState = LoopState.SUBMITTED;
244 } else if (policyState == TempLoopState.NOT_SUBMITTED) {
245 if (dcaeState == TempLoopState.NOT_DEPLOYED) {
246 clState = LoopState.DESIGN;
249 loop.setLastComputedState(clState);
250 loopService.saveOrUpdateLoop(loop);
254 private JsonElement wrapSnakeObject(Object obj) {
257 return JsonNull.INSTANCE;
260 // Collection => JsonArray
261 if (obj instanceof Collection) {
262 JsonArray array = new JsonArray();
263 for (Object childObj : (Collection<?>) obj) {
264 array.add(wrapSnakeObject(childObj));
269 // Array => JsonArray
270 if (obj.getClass().isArray()) {
271 JsonArray array = new JsonArray();
273 int length = Array.getLength(array);
274 for (int i = 0; i < length; i++) {
275 array.add(wrapSnakeObject(Array.get(array, i)));
281 if (obj instanceof Map) {
282 Map<?, ?> map = (Map<?, ?>) obj;
284 JsonObject jsonObject = new JsonObject();
285 for (final Map.Entry<?, ?> entry : map.entrySet()) {
286 final String name = String.valueOf(entry.getKey());
287 final Object value = entry.getValue();
288 jsonObject.add(name, wrapSnakeObject(value));
293 // otherwise take it as a string
294 return new JsonPrimitive(String.valueOf(obj));