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