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