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