00cc9159b9c59e8d1645314b38b120af5be4d7ac
[appc.git] / appc-provider / appc-provider-bundle / src / main / java / org / onap / appc / provider / topology / TopologyService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.appc.provider.topology;
25
26 import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
27 import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
28 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
29 import static com.att.eelf.configuration.Configuration.MDC_REMOTE_HOST;
30 import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
31 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
32 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
33 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
34
35 import com.att.eelf.configuration.EELFLogger;
36 import com.att.eelf.configuration.EELFManager;
37 import com.att.eelf.i18n.EELFResourceManager;
38 import java.net.InetAddress;
39 import java.text.DateFormat;
40 import java.text.SimpleDateFormat;
41 import java.util.Date;
42 import java.util.Properties;
43 import java.util.TimeZone;
44 import org.onap.appc.Constants;
45 import org.onap.appc.configuration.Configuration;
46 import org.onap.appc.configuration.ConfigurationFactory;
47 import org.onap.appc.i18n.Msg;
48 import org.onap.appc.provider.AppcProvider;
49 import org.onap.appc.provider.AppcProviderClient;
50 import org.onap.appc.provider.ResponseHeaderBuilder;
51 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.MigrateOutput;
52 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.MigrateOutputBuilder;
53 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.ModifyConfigOutput;
54 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.ModifyConfigOutputBuilder;
55 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.RebuildOutput;
56 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.RebuildOutputBuilder;
57 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.RestartOutput;
58 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.RestartOutputBuilder;
59 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.SnapshotOutput;
60 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.SnapshotOutputBuilder;
61 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.UUID;
62 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.VmstatuscheckOutput;
63 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.VmstatuscheckOutputBuilder;
64 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.common.request.header.CommonRequestHeader;
65 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.config.payload.ConfigPayload;
66 import org.opendaylight.yang.gen.v1.org.onap.appc.rev160104.vnf.resource.VnfResource;
67 import org.opendaylight.yangtools.yang.common.RpcResult;
68 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
69 import org.slf4j.MDC;
70
71 /**
72  * This class is used to implement the topology services API and invoke the appropriate directed graphs based on the
73  * service being requested.
74  */
75 public class TopologyService {
76
77     /**
78      * The loggers we are using
79      */
80     private final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
81     private final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
82     private final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
83     private final EELFLogger performanceLogger = EELFManager.getInstance().getPerformanceLogger();
84     private final static String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssX";
85     private final static String START_TIME_PARAM = "startTime";
86     private final static String RESTART_INITIATED_STR = "Metrics Logger: App-C Restart initiated. Start Time: [%s]. Request ID: [%s]";
87     private final static String TARGET_PARAM = "target";
88     private final static String SUCCESS_PARAM = "SUCCESS";
89     private final static String FAILURE_PARAM = "FAILURE";
90     private final static String END_TIME_PARAM = "endTime";
91     private final static String DURATION_PARAM = "duration";
92     private final static String ERROR_STR = "An error occurred";
93
94     /**
95      * The provider we are servicing
96      */
97     private AppcProvider provider;
98
99     /**
100      * The reason associated with the last DG call
101      */
102     private String reason;
103
104     /**
105      * The APPC configuration properties
106      */
107     private Configuration configuration = ConfigurationFactory.getConfiguration();
108
109     /**
110      * Create the topology services implementation for the specific appc provider (api) implementation
111      *
112      * @param provider The provider we are servicing
113      */
114     public TopologyService(AppcProvider provider) {
115         this.provider = provider;
116     }
117
118     /**
119      * Modify configuration
120      *
121      * @param hdr The common request header
122      * @param data The payload of the configuration
123      * @return The rpc result of the operation
124      */
125     public RpcResult<ModifyConfigOutput> modifyConfig(CommonRequestHeader hdr, ConfigPayload data) {
126         long startTime = System.currentTimeMillis();
127         TimeZone tz = TimeZone.getTimeZone("UTC");
128         DateFormat df = new SimpleDateFormat(DATE_FORMAT);
129         df.setTimeZone(tz);
130         String requestId = hdr.getServiceRequestId();
131
132         MDC.put(MDC_REMOTE_HOST, "");
133         MDC.put(MDC_KEY_REQUEST_ID, requestId);
134         MDC.put(MDC_SERVICE_NAME, "App-C Provider:Restart");
135         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
136         try {
137             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
138             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
139         } catch (Exception e) {
140             logger.error(ERROR_STR, e);
141         }
142         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
143         MDC.put(MDC_ALERT_SEVERITY, "0");
144         MDC.put(START_TIME_PARAM, Long.toString(startTime));
145         MDC.put(TARGET_PARAM, "appc");
146         logger.info(String.format("Starting RESTART for request with id [%s]", requestId));
147         metricsLogger.info(String.format(RESTART_INITIATED_STR,
148             startTime, requestId));
149
150         /*
151          * Copy any needed inputs or other values into the properties to be passed to the DG model
152          */
153         Properties properties = new Properties();
154         properties.put(Constants.CONTEXT_ACTION, "modifyConfig");
155         properties.put(Constants.CONTEXT_REQID, requestId);
156         String url = configuration.getProperty("appc.provider.vfodl.url");
157         try {
158             if (url.contains("NODE_NAME")) {
159                 url = url.replace("NODE_NAME", data.getConfigUrl());
160             }
161         } catch (Exception e) {
162             logger.error("An error occurred when replacing node name", e);
163             url = configuration.getProperty("appc.provider.vfodl.url");
164         }
165         logger.trace("Final URL to VF ODL: " + url);
166         properties.put("org.onap.appc.configURL", url);
167         properties.put("org.onap.appc.configJson", data.getConfigJson());
168
169         /*
170          * Attempt to call the DG with the appropriate properties
171          */
172         boolean success = callGraph(properties);
173
174         MDC.put(TARGET_PARAM, "appc");
175         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
176         String infomsg =
177             String.format("APPC0119I ModifyConfig '%s' finished with status %s. Reason: %s", requestId, statusStr,
178                 reason);
179         logger.info(infomsg);
180
181         ModifyConfigOutputBuilder rob = new ModifyConfigOutputBuilder();
182         long endTime = System.currentTimeMillis();
183         long duration = endTime - startTime;
184         String endTimeStr = String.valueOf(endTime);
185         String durationStr = String.valueOf(duration);
186         MDC.put(END_TIME_PARAM, endTimeStr);
187         MDC.put(DURATION_PARAM, durationStr);
188         rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
189
190         auditLogger.info(String.format(
191             "Audit Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
192             requestId, statusStr, startTime, endTime, duration, requestId, reason));
193         metricsLogger.info(String.format(
194             "Metrics Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
195             requestId, statusStr, startTime, endTime, duration, requestId, reason));
196
197         // Status must be set to true to indicate that our return is expected
198         return RpcResultBuilder.<ModifyConfigOutput>status(true).withResult(rob.build()).build();
199
200     }
201
202
203     /**
204      * Restart a VM
205      *
206      * @param hdr The common request header
207      * @param vnf The identification of the VNF resource to be operated upon
208      * @return The rpc result of the restart operation
209      */
210     public RpcResult<MigrateOutput> migrate(CommonRequestHeader hdr, VnfResource vnf) {
211         long startTime = System.currentTimeMillis();
212         TimeZone tz = TimeZone.getTimeZone("UTC");
213         DateFormat df = new SimpleDateFormat(DATE_FORMAT);
214         df.setTimeZone(tz);
215         String startTimeStr = df.format(new Date());
216         String requestId = hdr.getServiceRequestId();
217
218         MDC.put(MDC_REMOTE_HOST, "");
219         MDC.put(MDC_KEY_REQUEST_ID, requestId);
220         MDC.put(MDC_SERVICE_NAME, "App-C Provider:Migrate");
221         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
222         try {
223             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
224             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
225         } catch (Exception e) {
226             logger.error(ERROR_STR, e);
227         }
228         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
229         MDC.put(MDC_ALERT_SEVERITY, "0");
230         MDC.put(START_TIME_PARAM, startTimeStr);
231         MDC.put(TARGET_PARAM, "appc");
232         logger.info(String.format("Starting ANY for request with id [%s]", requestId));
233         metricsLogger.info(String.format(RESTART_INITIATED_STR,
234             startTime, requestId));
235
236         /*
237          * Copy any needed inputs or other values into the properties to be passed to the DG model
238          */
239         UUID vmId = vnf.getVmId();
240         Properties properties = new Properties();
241         properties.put(Constants.CONTEXT_ACTION, "migrate");
242         properties.put(Constants.CONTEXT_REQID, requestId);
243         properties.put(Constants.CONTEXT_VMID, vmId.getValue());
244
245         UUID identityUrl = vnf.getIdentityUrl();
246         if (identityUrl != null) {
247             properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue());
248         }
249
250         /*
251          * Attempt to call the DG with the appropriate properties
252          */
253         boolean success = callGraph(properties);
254
255         /*
256          * Generate the appropriate response
257          */
258         MDC.put(TARGET_PARAM, "appc");
259         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
260         String infomsg =
261             String.format("APPC0118I Migrate '%s' finished with status %s. Reason: %s", requestId, statusStr, reason);
262         logger.info(infomsg);
263
264         MigrateOutputBuilder mob = new MigrateOutputBuilder();
265
266         long endTime = System.currentTimeMillis();
267         long duration = endTime - startTime;
268         String endTimeStr = String.valueOf(endTime);
269         String durationStr = String.valueOf(duration);
270         MDC.put(END_TIME_PARAM, endTimeStr);
271         MDC.put(DURATION_PARAM, durationStr);
272         mob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
273         mob.setVmId(new UUID(vmId));
274
275         auditLogger.info(String.format(
276             "Audit Logger: APPC0118I Migrate '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
277             requestId, statusStr, startTime, endTime, duration, requestId, reason));
278         metricsLogger.info(String.format(
279             "Metrics Logger: APPC0118I Migrate '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
280             requestId, statusStr, startTime, endTime, duration, requestId, reason));
281
282         // Status must be set to true to indicate that our return is expected
283         return RpcResultBuilder.<MigrateOutput>status(true).withResult(mob.build()).build();
284     }
285
286     /**
287      * Restart a VM
288      *
289      * @param hdr The common request header
290      * @param vnf The identification of the VNF resource to be operated upon
291      * @return The rpc result of the restart operation
292      */
293     public RpcResult<RestartOutput> restart(CommonRequestHeader hdr, VnfResource vnf) {
294         long startTime = System.currentTimeMillis();
295         TimeZone tz = TimeZone.getTimeZone("UTC");
296         DateFormat df = new SimpleDateFormat(DATE_FORMAT);
297         df.setTimeZone(tz);
298         String requestId = hdr.getServiceRequestId();
299
300         MDC.put(MDC_REMOTE_HOST, "");
301         MDC.put(MDC_KEY_REQUEST_ID, requestId);
302         MDC.put(MDC_SERVICE_NAME, "App-C Provider:Restart");
303         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
304         try {
305             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
306             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
307         } catch (Exception e) {
308             logger.error(ERROR_STR, e);
309         }
310         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
311         MDC.put(MDC_ALERT_SEVERITY, "0");
312         MDC.put(START_TIME_PARAM, Long.toString(startTime));
313         MDC.put(TARGET_PARAM, "appc");
314         logger.info(String.format("Starting RESTART for request with id [%s]", requestId));
315         metricsLogger.info(String.format(RESTART_INITIATED_STR,
316             startTime, requestId));
317
318         /*
319          * Copy any needed inputs or other values into the properties to be passed to the DG model
320          */
321         UUID vmId = vnf.getVmId();
322         Properties properties = new Properties();
323         properties.put(Constants.CONTEXT_ACTION, "restart");
324         properties.put(Constants.CONTEXT_REQID, requestId);
325         properties.put(Constants.CONTEXT_VMID, vmId.getValue());
326
327         UUID identityUrl = vnf.getIdentityUrl();
328         if (identityUrl != null) {
329             properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue());
330         }
331         /*
332          * Attempt to call the DG with the appropriate properties
333          */
334         boolean success = callGraph(properties);
335
336         /*
337          * Generate the appropriate response
338          */
339         MDC.put(TARGET_PARAM, "appc");
340         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
341         String infomsg =
342             String.format("APPC0119I Restart '%s' finished with status %s. Reason: %s", requestId, statusStr, reason);
343         logger.info(infomsg);
344
345         RestartOutputBuilder rob = new RestartOutputBuilder();
346         long endTime = System.currentTimeMillis();
347         long duration = endTime - startTime;
348         String endTimeStr = String.valueOf(endTime);
349         String durationStr = String.valueOf(duration);
350         MDC.put(END_TIME_PARAM, endTimeStr);
351         MDC.put(DURATION_PARAM, durationStr);
352         rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
353         rob.setVmId(new UUID(vmId));
354
355         auditLogger.info(String.format(
356             "Audit Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
357             requestId, statusStr, startTime, endTime, duration, requestId, reason));
358         metricsLogger.info(String.format(
359             "Metrics Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
360             requestId, statusStr, startTime, endTime, duration, requestId, reason));
361
362         // Status must be set to true to indicate that our return is expected
363         return RpcResultBuilder.<RestartOutput>status(true).withResult(rob.build()).build();
364     }
365
366     /**
367      * Rebuild a VM
368      *
369      * @param hdr The common request header
370      * @param vnf The identification of the VNF resource to be operated upon
371      * @return The rpc result of the rebuild operation
372      */
373     public RpcResult<RebuildOutput> rebuild(CommonRequestHeader hdr, VnfResource vnf) {
374         long startTime = System.currentTimeMillis();
375         TimeZone tz = TimeZone.getTimeZone("UTC");
376         DateFormat df = new SimpleDateFormat(DATE_FORMAT);
377         df.setTimeZone(tz);
378         String startTimeStr = df.format(new Date());
379         String requestId = hdr.getServiceRequestId();
380
381         MDC.put(MDC_REMOTE_HOST, "");
382         MDC.put(MDC_KEY_REQUEST_ID, requestId);
383         MDC.put(MDC_SERVICE_NAME, "App-C Provider:Rebuild");
384         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
385         try {
386             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
387             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
388         } catch (Exception e) {
389             logger.error(ERROR_STR, e);
390         }
391         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
392         MDC.put(MDC_ALERT_SEVERITY, "0");
393         MDC.put(START_TIME_PARAM, startTimeStr);
394         MDC.put(TARGET_PARAM, "appc");
395         logger.info(String.format("Starting REBUILD for request with id [%s]", requestId));
396         metricsLogger.info(String.format(RESTART_INITIATED_STR,
397             startTime, requestId));
398
399         /*
400          * Copy any needed inputs or other values into the properties to be passed to the DG model
401          */
402         UUID vmId = vnf.getVmId();
403         Properties properties = new Properties();
404         properties.put(Constants.CONTEXT_ACTION, "rebuild");
405         properties.put(Constants.CONTEXT_REQID, requestId);
406         properties.put(Constants.CONTEXT_VMID, vmId.getValue());
407
408         UUID identityUrl = vnf.getIdentityUrl();
409         if (identityUrl != null) {
410             properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue());
411         }
412
413         /*
414          * Attempt to call the DG with the appropriate properties
415          */
416         boolean success = callGraph(properties);
417
418         /*
419          * Generate the appropriate response
420          */
421         MDC.put(TARGET_PARAM, "appc");
422         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
423         String infomsg =
424             String.format("APPC0120I Rebuild '%s' finished with status %s. Reason: %s", requestId, statusStr, reason);
425         logger.info(infomsg);
426
427         RebuildOutputBuilder rob = new RebuildOutputBuilder();
428         long endTime = System.currentTimeMillis();
429         long duration = endTime - startTime;
430         String endTimeStr = String.valueOf(endTime);
431         String durationStr = String.valueOf(duration);
432         MDC.put(END_TIME_PARAM, endTimeStr);
433         MDC.put(DURATION_PARAM, durationStr);
434         rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
435         rob.setOriginalVmId(new UUID(vmId));
436         rob.setNewVmId(new UUID(vmId));
437
438         auditLogger.info(String.format(
439             "Audit Logger: APPC0120I Rebuild '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
440             requestId, statusStr, startTime, endTime, duration, requestId, reason));
441         metricsLogger.info(String.format(
442             "Metrics Logger: APPC0120I Rebuild '%s' finished with status %s. Start Time: [%s]. End Time: [%s].  Duration: [%s]. Request ID: [%s]. Reason:%s",
443             requestId, statusStr, startTime, endTime, duration, requestId, reason));
444
445         // Status must be set to true to indicate that our return is expected
446         return RpcResultBuilder.<RebuildOutput>status(true).withResult(rob.build()).build();
447     }
448
449     /**
450      * Snapshot a VM
451      *
452      * @param hdr The common request header
453      * @param vnf The identification of the VNF resource to be operated upon
454      * @return The rpc result of the restart operation
455      */
456     public RpcResult<SnapshotOutput> snapshot(CommonRequestHeader hdr, VnfResource vnf) {
457         long startTime = System.currentTimeMillis();
458         TimeZone tz = TimeZone.getTimeZone("UTC");
459         DateFormat df = new SimpleDateFormat(DATE_FORMAT);
460         df.setTimeZone(tz);
461         String requestId = hdr.getServiceRequestId();
462         MDC.put(MDC_REMOTE_HOST, "");
463         MDC.put(MDC_KEY_REQUEST_ID, requestId);
464         MDC.put(MDC_SERVICE_NAME, "App-C Provider:Snapshot");
465         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
466         try {
467             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
468             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
469         } catch (Exception e) {
470             logger.error(ERROR_STR, e);
471         }
472         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
473         MDC.put(MDC_ALERT_SEVERITY, "0");
474         MDC.put(START_TIME_PARAM, Long.toString(startTime));
475         MDC.put(TARGET_PARAM, "appc");
476         logger.info(String.format("Starting SNAPSHOT for request with id [%s]", requestId));
477         metricsLogger.info(String.format("Metrics Logger: App-C Snapshot initiated. Start Time: [%s]. Request ID: [%s]",
478             startTime, requestId));
479
480         /*
481          * Copy any needed inputs or other values into the properties to be passed to the DG model
482          */
483         UUID vmId = vnf.getVmId();
484         Properties properties = new Properties();
485         properties.put(Constants.CONTEXT_ACTION, "snapshot");
486         properties.put(Constants.CONTEXT_REQID, requestId);
487         properties.put(Constants.CONTEXT_VMID, vmId.getValue());
488
489         UUID identityUrl = vnf.getIdentityUrl();
490         if (identityUrl != null) {
491             properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue());
492         }
493         /*
494          * Attempt to call the DG with the appropriate properties
495          */
496         boolean success = callGraph(properties);
497
498         /*
499          * Generate the appropriate response
500          */
501         MDC.put(TARGET_PARAM, "appc");
502         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
503         String infomsg =
504             String.format("APPC0119I Snapshot '%s' finished with status %s. Reason: %s", requestId, statusStr, reason);
505         logger.info(infomsg);
506
507         SnapshotOutputBuilder sob = new SnapshotOutputBuilder();
508         long endTime = System.currentTimeMillis();
509         long duration = endTime - startTime;
510         String endTimeStr = String.valueOf(endTime);
511         String durationStr = String.valueOf(duration);
512         MDC.put(END_TIME_PARAM, endTimeStr);
513         MDC.put(DURATION_PARAM, durationStr);
514         sob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
515         sob.setVmId(new UUID(vmId));
516
517         auditLogger.info(String.format(
518             "Audit Logger: APPC0119I Snapshot '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
519             requestId, statusStr, startTime, endTime, duration, requestId, reason));
520         metricsLogger.info(String.format(
521             "Metrics Logger: APPC0119I Snapshot '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s",
522             requestId, statusStr, startTime, endTime, duration, requestId, reason));
523
524         // Status must be set to true to indicate that our return is expected
525         return RpcResultBuilder.<SnapshotOutput>status(true).withResult(sob.build()).build();
526     }
527
528     /**************************************************/
529
530     public RpcResult<VmstatuscheckOutput> vmstatuscheck(CommonRequestHeader hdr, VnfResource vnf) {
531         long startTime = System.currentTimeMillis();
532         String requestId = hdr.getServiceRequestId();
533
534         MDC.clear();
535         MDC.put(MDC_REMOTE_HOST, "");
536         MDC.put(MDC_KEY_REQUEST_ID, requestId);
537         MDC.put(MDC_SERVICE_NAME, "App-C Provider:vmstatuscheck");
538         MDC.put(MDC_SERVICE_INSTANCE_ID, "");
539         try {
540             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
541             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
542         } catch (Exception e) {
543             logger.error(ERROR_STR, e);
544         }
545         MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString());
546         MDC.put(MDC_ALERT_SEVERITY, "0");
547         logger.info(String.format("Starting VMSTATUSCHECK for request with id [%s]", requestId));
548
549         performanceLogger.info(String
550             .format("Performance Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime,
551                 requestId));
552         auditLogger.info(String
553             .format("Audit Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime,
554                 requestId));
555         metricsLogger.info(String
556             .format("Metrics Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime,
557                 requestId));
558
559         /*
560          * Copy any needed inputs or other values into the properties to be passed to the DG model
561          */
562         UUID vmId = vnf.getVmId();
563         Properties properties = new Properties();
564         properties.put(Constants.CONTEXT_ACTION, "vmstatuschecking");
565         properties.put(Constants.CONTEXT_REQID, requestId);
566         properties.put(Constants.CONTEXT_VMID, vmId.getValue());
567         properties.put(Constants.STATUS_GETTER, "checking");
568
569         UUID identityUrl = vnf.getIdentityUrl();
570         if (identityUrl != null) {
571             properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue());
572         }
573         /*
574          * Attempt to call the DG with the appropriate properties
575          */
576         boolean success = callGraph(properties);
577
578         /*
579          * Generate the appropriate response
580          */
581         String statusStr = success ? SUCCESS_PARAM : FAILURE_PARAM;
582         String infomsg =
583             String.format("VMSTATUSCHECK '%s' finished with status %s. Reason: %s", requestId, statusStr, reason);
584         logger.info(infomsg);
585         long endTime = System.currentTimeMillis();
586         auditLogger.info(String.format(
587             "Audit Logger: VMSTATUSCHECK '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Request ID: [%s]. Reason:%s",
588             requestId, statusStr, startTime, endTime, requestId, reason));
589         metricsLogger.info(String.format(
590             "Metrics Logger: VMSTATUSCHECK '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Request ID: [%s]. Reason:%s",
591             requestId, statusStr, startTime, endTime, requestId, reason));
592         String tempstring2 = properties.getProperty(Constants.STATUS_GETTER).trim();
593
594         VmstatuscheckOutputBuilder vob = new VmstatuscheckOutputBuilder();
595         long duration = System.currentTimeMillis() - startTime;
596         vob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration));
597         vob.setStatMsg(tempstring2);
598
599         // Status must be set to true to indicate that our return is expected
600         return RpcResultBuilder.<VmstatuscheckOutput>status(true).withResult(vob.build()).build();
601     }
602
603     /*************************************************/
604
605
606     private boolean callGraph(Properties props) {
607         String moduleName = configuration.getProperty(Constants.PROPERTY_MODULE_NAME);
608         String methodName = configuration.getProperty(Constants.PROPERTY_TOPOLOGY_METHOD);
609         String version = configuration.getProperty(Constants.PROPERTY_TOPOLOGY_VERSION);
610         String mode = Constants.SYNC_MODE;
611         return callGraph(moduleName, methodName, version, mode, props);
612     }
613
614     /**
615      * Calls a specified directed graph with the specified properties and returns the response
616      *
617      * @param module The module name to be used to locate the graph
618      * @param method The method name to be executed (rpc)
619      * @param version The version of the graph to be used, or null for the latest
620      * @param mode the execution mode of the graph, sync or async
621      * @param props A set of name-value properties to be passed to the graph for context variables.
622      */
623     private boolean callGraph(String module, String method, String version, String mode, Properties props) {
624         String graphName = String.format(("%s:%s:%s"), module, method, version);
625         logger.debug(String.format("Calling Graph %s", graphName));
626         metricsLogger.info(String.format("Calling Graph %s", graphName));
627
628         boolean success;
629         String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
630         AppcProviderClient svcLogicClient = new AppcProviderClient();
631         try {
632             if (svcLogicClient.hasGraph(module, method, version, mode)) {
633                 try {
634                     Properties respProps = svcLogicClient.execute(module, method, version, mode, props);
635                     reason = "Failed";      // Assume it failed unless proven otherwise
636                     logger.debug(EELFResourceManager.format(Msg.DEBUG_GRAPH_RESPONSE_HEADER, appName, graphName,
637                         Integer.toString(respProps.size())));
638                     logKeys(graphName, appName, respProps);
639                     success = resolveSuccess(graphName, appName, respProps);
640                 } catch (Exception e) {
641                     success = false;
642                     reason = EELFResourceManager.format(Msg.EXCEPTION_CALLING_DG, e, appName,
643                         e.getClass().getSimpleName(), graphName, e.getMessage());
644                     logger.error(reason);
645                 }
646             } else {
647                 success = false;
648                 reason = EELFResourceManager.format(Msg.GRAPH_NOT_FOUND, appName, graphName);
649                 logger.error(reason);
650             }
651         } catch (Exception e) {
652             success = false;
653             reason = EELFResourceManager.format(Msg.EXCEPTION_CALLING_DG, e, appName, e.getClass().getSimpleName(),
654                 graphName, e.getMessage());
655             logger.error(reason);
656         }
657
658         return success;
659     }
660
661     private boolean resolveSuccess(String graphName, String appName, Properties respProps) {
662         // TODO - Find docs and see if there is a better way to handle this
663         // Bad requests have errors
664         if (respProps.containsKey(Constants.ATTRIBUTE_ERROR_CODE)) {
665             String errorCodeProperty = respProps.getProperty(Constants.ATTRIBUTE_ERROR_CODE).trim();
666             return doResolveSuccess(graphName, appName, respProps, errorCodeProperty);
667         } else {
668             /*
669              * Added code that requires error code to now be defined in ALL cases. If not, it is an error
670              * and the response will be set to failed regardless if the DG worked or not.
671              */
672             reason = EELFResourceManager.format(Msg.PARAMETER_IS_MISSING, appName, graphName,
673                 Constants.ATTRIBUTE_ERROR_CODE);
674             logger.error(reason);
675             return false;
676         }
677     }
678
679     private boolean doResolveSuccess(String graphName, String appName, Properties respProps, String errorCodeProperty) {
680
681         try {
682             int errorCode = Integer.parseInt(errorCodeProperty);
683             if (errorCode >= 300) {
684                 reason = EELFResourceManager.format(Msg.DG_FAILED_RESPONSE, appName, graphName,
685                     errorCodeProperty, respProps.getProperty(Constants.ATTRIBUTE_ERROR_MESSAGE));
686                 logger.error(reason);
687                 return false;
688             } else {
689
690                 reason = "Success";
691                 return true;
692             }
693         } catch (NumberFormatException e) {
694             reason = EELFResourceManager.format(Msg.PARAMETER_NOT_NUMERIC, appName, graphName,
695                 Constants.ATTRIBUTE_ERROR_CODE, errorCodeProperty);
696             logger.error(reason);
697             return false;
698         }
699     }
700
701     private void logKeys(String graphName, String appName, Properties respProps) {
702         for (String key : respProps.stringPropertyNames()) {
703             logger.debug(EELFResourceManager.format(
704                 Msg.DEBUG_GRAPH_RESPONSE_DETAIL, appName, graphName, key, (String) respProps.get(key)));
705         }
706     }
707
708 }