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