Initial commit for OpenECOMP SDN-C northbound
[sdnc/northbound.git] / ueb-listener / src / main / java / org / openecomp / sdnc / uebclient / SdncUebCallback.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-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.sdnc.uebclient;
23
24 import java.io.BufferedReader;
25 import java.io.ByteArrayInputStream;
26 import java.io.DataOutputStream;
27 import java.io.File;
28 import java.io.FileReader;
29 import java.io.FileWriter;
30 import java.io.IOException;
31 import java.io.InputStreamReader;
32 import java.net.Authenticator;
33 import java.net.HttpURLConnection;
34 import java.net.PasswordAuthentication;
35 import java.net.URL;
36 import java.nio.file.DirectoryStream;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.StandardCopyOption;
40 import java.text.SimpleDateFormat;
41 import java.util.Date;
42 import java.util.LinkedList;
43 import java.util.List;
44
45 import javax.net.ssl.HostnameVerifier;
46 import javax.net.ssl.HttpsURLConnection;
47 import javax.net.ssl.SSLSession;
48 import javax.xml.parsers.DocumentBuilder;
49 import javax.xml.parsers.DocumentBuilderFactory;
50 import javax.xml.transform.Source;
51 import javax.xml.transform.Transformer;
52 import javax.xml.transform.TransformerFactory;
53 import javax.xml.transform.stream.StreamResult;
54 import javax.xml.transform.stream.StreamSource;
55 import javax.xml.xpath.XPath;
56 import javax.xml.xpath.XPathFactory;
57
58 import org.apache.commons.codec.binary.Base64;
59 import org.openecomp.sdc.api.IDistributionClient;
60 import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
61 import org.openecomp.sdc.api.consumer.INotificationCallback;
62 import org.openecomp.sdc.api.notification.IArtifactInfo;
63 import org.openecomp.sdc.api.notification.INotificationData;
64 import org.openecomp.sdc.api.notification.IResourceInstance;
65 import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
66 import org.openecomp.sdc.api.results.IDistributionClientResult;
67 import org.openecomp.sdc.utils.ArtifactTypeEnum;
68 import org.openecomp.sdc.utils.DistributionActionResultEnum;
69 import org.openecomp.sdc.utils.DistributionStatusEnum;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72 import org.w3c.dom.Document;
73 import org.w3c.dom.Element;
74
75 public class SdncUebCallback implements INotificationCallback {
76
77     private static final Logger LOG = LoggerFactory
78             .getLogger(SdncUebCallback.class);
79
80     private static final int NUM_PASSES = 2;
81
82     private enum SdncArtifactType {
83         VF_LICENSE_MODEL("vf-license-model", "vf-license-model-update",0),
84         UNKNOWN("","",0);
85
86
87         private String tag;
88         private String rpcName;
89         private int pass;
90
91         public int getPass() {
92             return pass;
93         }
94
95         private SdncArtifactType(String tag, String rpcName, int pass) {
96             this.tag = tag;
97             this.rpcName = rpcName;
98             this.pass = pass;
99         }
100
101         public String getTag() {
102             return tag;
103         }
104
105         public String getRpcUrl(String base) {
106             return base+rpcName;
107         }
108
109         public static SdncArtifactType fromTag(String tag) {
110             if (tag != null) {
111                 for (SdncArtifactType artifact: SdncArtifactType.values()) {
112                     if (artifact.getTag().equalsIgnoreCase(tag)) {
113                         return artifact;
114                     }
115                 }
116             }
117
118             return UNKNOWN;
119         }
120     }
121
122     private class SdncAuthenticator extends Authenticator {
123
124         private final String user;
125         private final String passwd;
126
127         SdncAuthenticator(String user, String passwd) {
128             this.user = user;
129             this.passwd = passwd;
130         }
131         @Override
132         protected PasswordAuthentication getPasswordAuthentication() {
133             return new PasswordAuthentication(user, passwd.toCharArray());
134         }
135
136     }
137
138     private class DeployableArtifact {
139         SdncArtifactType type;
140         IArtifactInfo artifactInfo;
141         String svcName;
142         String resourceName;
143         String artifactName;
144         String artifactVersion;
145         File file;
146
147         public String getArtifactName() {
148             return artifactName;
149         }
150
151
152
153         public String getArtifactVersion() {
154             return artifactVersion;
155         }
156
157
158         public SdncArtifactType getType() {
159             return type;
160         }
161
162
163
164         public IArtifactInfo getArtifactInfo() {
165             return artifactInfo;
166         }
167
168
169         public File getFile() {
170             return file;
171         }
172
173
174
175
176         public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, File file) {
177             this.type = type;
178             this.artifactInfo = artifactInfo;
179             this.artifactName = artifactInfo.getArtifactName();
180             this.artifactVersion = artifactInfo.getArtifactVersion();
181             this.file = file;
182         }
183
184
185         public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, String artifactName, String artifactVersion, File file) {
186             this.type = type;
187             this.artifactInfo = null;
188             this.artifactName = artifactName;
189             this.artifactVersion = artifactVersion;
190             this.file = file;
191         }
192
193
194
195         public String getSvcName() {
196             return svcName;
197         }
198
199
200
201         public String getResourceName() {
202             return resourceName;
203         }
204
205     }
206
207     private final IDistributionClient client;
208     private final SdncUebConfiguration config;
209
210     private final LinkedList<DeployableArtifact> deployList[];
211
212
213     public SdncUebCallback(IDistributionClient client, SdncUebConfiguration config) {
214         this.client = client;
215         this.config = config;
216         this.deployList = new LinkedList[NUM_PASSES];
217
218         for (int i = 0 ; i < NUM_PASSES ; i++) {
219             this.deployList[i] = new LinkedList<>();
220         }
221     }
222
223     @Override
224         public void activateCallback(INotificationData data) {
225
226         LOG.info("Received notification : ("+data.getDistributionID()+","+data.getServiceName()+","+data.getServiceVersion()+
227                 ","+data.getServiceDescription());
228
229         String incomingDirName = config.getIncomingDir();
230         String archiveDirName = config.getArchiveDir();
231
232         File incomingDir = null;
233         File archiveDir = null;
234
235         if (!incomingDir.exists()) {
236             incomingDir.mkdirs();
237         }
238
239
240         if (!archiveDir.exists()) {
241             archiveDir.mkdirs();
242         }
243
244         // Process service level artifacts
245         List<IArtifactInfo> artifactList = data.getServiceArtifacts();
246
247         if (artifactList != null) {
248
249             incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()));
250             if (!incomingDir.exists()) {
251                 incomingDir.mkdirs();
252             }
253
254             archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()));
255             if (!archiveDir.exists()) {
256                 archiveDir.mkdirs();
257             }
258             for (IArtifactInfo curArtifact : artifactList)
259             {
260
261                 LOG.info("Received artifact " + curArtifact.getArtifactName());
262
263                 handleArtifact(data, data.getServiceName(), null, curArtifact, incomingDir, archiveDir);
264             }
265         }
266
267
268         // Process resource level artifacts
269         for (IResourceInstance curResource : data.getResources()) {
270
271             LOG.info("Received resource : "+curResource.getResourceName());
272             artifactList = curResource.getArtifacts();
273
274             if (artifactList != null) {
275
276                 incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()) + "/" + escapeFilename(curResource.getResourceName()));
277                 if (!incomingDir.exists()) {
278                     incomingDir.mkdirs();
279                 }
280
281                 archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()) + "/" + escapeFilename(curResource.getResourceName()));
282                 if (!archiveDir.exists()) {
283                     archiveDir.mkdirs();
284                 }
285                 for (IArtifactInfo curArtifact : artifactList)
286                 {
287
288                     LOG.info("Received artifact " + curArtifact.getArtifactName());
289
290                     handleArtifact(data, data.getServiceName(), curResource.getResourceName(), curArtifact, incomingDir, archiveDir);
291                 }
292             }
293         }
294
295         deployDownloadedFiles(incomingDir, archiveDir, data);
296
297
298     }
299
300
301     public void deployDownloadedFiles(File incomingDir, File archiveDir, INotificationData data) {
302
303         if (incomingDir == null) {
304             incomingDir = new File(config.getIncomingDir());
305
306             if (!incomingDir.exists()) {
307                 incomingDir.mkdirs();
308             }
309
310         }
311
312         if (archiveDir == null) {
313             archiveDir = new File(config.getArchiveDir());
314
315             if (!archiveDir.exists()) {
316                 archiveDir.mkdirs();
317             }
318         }
319
320         String curFileName = "";
321         try (DirectoryStream<Path> stream = Files.newDirectoryStream(incomingDir.toPath())) {
322             for (Path file: stream) {
323                 curFileName = file.toString();
324                 handleSuccessfulDownload(null,null, null, null, file.toFile(), archiveDir);
325             }
326         } catch (Exception x) {
327             // IOException can never be thrown by the iteration.
328             // In this snippet, it can only be thrown by newDirectoryStream.
329             LOG.warn("Cannot process spool file "+ curFileName, x);
330         }
331
332         // Deploy scheduled deployments
333
334         for (int pass = 0 ; pass < NUM_PASSES ; pass++) {
335
336             if (deployList[pass] != null) {
337                 while (! deployList[pass].isEmpty()) {
338                     DeployableArtifact artifact = deployList[pass].pop();
339
340                     DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_ERROR;
341
342
343                     try {
344
345                         deployResult = deploySpoolFile(artifact);
346                     } catch (Exception e) {
347                         LOG.error("Caught exception trying to deploy file", e);
348                     }
349
350
351                     IArtifactInfo artifactInfo = artifact.getArtifactInfo();
352
353                     if (artifactInfo != null && data != null) {
354                         IDistributionClientResult deploymentStatus;
355                             deploymentStatus = client.sendDeploymentStatus(buildStatusMessage(
356                                     client, data, artifactInfo,
357                                     deployResult));
358                     }
359
360                 }
361             }
362         }
363     }
364
365     private void handleArtifact(INotificationData data, String svcName, String resourceName, IArtifactInfo artifact, File incomingDir, File archiveDir) {
366
367         // Download Artifact
368         IDistributionClientDownloadResult downloadResult = client
369                 .download(artifact);
370
371         String payload = new String(downloadResult.getArtifactPayload());
372
373
374         File spoolFile = new File(incomingDir.getAbsolutePath() + "/" + artifact.getArtifactName());
375
376         boolean writeSucceeded = false;
377
378         try {
379             FileWriter spoolFileWriter = new FileWriter(spoolFile);
380             spoolFileWriter.write(payload);
381             spoolFileWriter.close();
382             writeSucceeded = true;
383         } catch (Exception e) {
384             LOG.error("Unable to save downloaded file to spool directory ("+ incomingDir.getAbsolutePath() +")", e);
385         }
386
387
388         if (writeSucceeded && downloadResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) {
389             handleSuccessfulDownload(data, svcName, resourceName, artifact, spoolFile, archiveDir);
390
391
392         } else {
393             handleFailedDownload(data, artifact);
394         }
395
396     }
397
398     private void handleFailedDownload(INotificationData data,
399             IArtifactInfo relevantArtifact) {
400         // Send Download Status
401         IDistributionClientResult sendDownloadStatus = client
402                 .sendDownloadStatus(buildStatusMessage(client, data,
403                         relevantArtifact, DistributionStatusEnum.DOWNLOAD_ERROR));
404     }
405
406     private void handleSuccessfulDownload(INotificationData data, String svcName, String resourceName,
407             IArtifactInfo artifact, File spoolFile, File archiveDir) {
408
409         if (data != null && artifact != null) {
410             // Send Download Status
411             IDistributionClientResult sendDownloadStatus = client
412                     .sendDownloadStatus(buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK));
413         }
414
415         // If an override file exists, read that instead of the file we just downloaded
416         ArtifactTypeEnum artifactEnum = ArtifactTypeEnum.YANG_XML;
417
418         if (artifact != null) {
419                 artifact.getArtifactType();
420         }
421         String overrideFileName = config.getOverrideFile();
422         if (overrideFileName != null && overrideFileName.length() > 0) {
423             File overrideFile = new File(overrideFileName);
424
425             if (overrideFile.exists()) {
426                 artifactEnum = ArtifactTypeEnum.YANG_XML;
427                 spoolFile = overrideFile;
428             }
429
430         }
431
432         // Process spool file
433         Document spoolDoc = null;
434         File transformedFile = null;
435
436         // Apply XSLTs and get Doc object
437         try {
438             transformedFile = applyXslts(spoolFile);
439         } catch (Exception e) {
440             LOG.error("Caught exception trying to parse XML file", e);
441         }
442
443         if (transformedFile != null) {
444             try {
445
446                 try {
447
448                     DocumentBuilderFactory dbf = DocumentBuilderFactory
449                             .newInstance();
450                     DocumentBuilder db = dbf.newDocumentBuilder();
451
452                     spoolDoc = db.parse(transformedFile);
453                 } catch (Exception e) {
454                     LOG.error(
455                             "Caught exception trying to parse transformed XML file "
456                                     + transformedFile.getAbsolutePath(), e);
457                 }
458
459             } catch (Exception e) {
460                 LOG.error("Caught exception trying to deploy file", e);
461             }
462         }
463
464
465         if (spoolDoc != null) {
466             // Analyze file type
467             SdncArtifactType artifactType = analyzeFileType(artifactEnum,
468                     spoolFile, spoolDoc);
469
470             if (artifactType != SdncArtifactType.UNKNOWN) {
471
472                 scheduleDeployment(artifactType, svcName, resourceName, artifact, spoolFile.getName(), transformedFile);
473
474             }
475
476             // SDNGC-2660 : Move file to archive directory even if it is an unrecognized type so that
477             // we do not keep trying and failing to process it.
478             try {
479                 Path source = spoolFile.toPath();
480                 Path targetDir = archiveDir.toPath();
481
482                 Files.move(source, targetDir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
483             } catch (IOException e) {
484                 LOG.warn("Could not move "+spoolFile.getAbsolutePath()+" to "+archiveDir.getAbsolutePath(), e);
485             }
486         }
487
488
489     }
490
491
492     private SdncArtifactType analyzeFileType(ArtifactTypeEnum artifactType, File spoolFile, Document spoolDoc) {
493
494         if (artifactType != ArtifactTypeEnum.YANG_XML) {
495             LOG.error("Unexpected artifact type - expecting YANG_XML, got "+artifactType);
496             return SdncArtifactType.UNKNOWN;
497         }
498
499         // Examine outer tag
500
501         try {
502
503
504             Element root = spoolDoc.getDocumentElement();
505
506             String rootName = root.getTagName();
507
508             if (rootName.contains(":")) {
509                 String[] rootNameElems = rootName.split(":");
510                 rootName = rootNameElems[rootNameElems.length - 1];
511             }
512
513             if (rootName != null) {
514                 SdncArtifactType retValue = SdncArtifactType.fromTag(rootName);
515
516                 if (retValue == SdncArtifactType.UNKNOWN) {
517
518                     LOG.error("Unexpected file contents - root tag is "+rootName);
519                 }
520                 return retValue;
521             } else {
522                 LOG.error("Cannot get root tag from file");
523                 return SdncArtifactType.UNKNOWN;
524             }
525
526         } catch (Exception e) {
527             LOG.error("Could not parse YANG_XML file "+spoolFile.getName(), e);
528             return SdncArtifactType.UNKNOWN;
529         }
530     }
531
532     private void scheduleDeployment(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, String spoolFileName, File spoolFile) {
533
534         if (type.getPass() < deployList.length) {
535
536             if (artifactInfo != null) {
537                 LOG.debug("Scheduling "+artifactInfo.getArtifactName()+" version "+artifactInfo.getArtifactVersion()+" for deployment");
538
539                 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, artifactInfo, spoolFile));
540             } else {
541                 SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS");//dd/MM/yyyy
542                 Date now = new Date();
543                 String artifactVersion = sdfDate.format(now);
544                 LOG.debug("Scheduling "+spoolFileName+" version "+artifactVersion+" for deployment");
545                 String artifactName = spoolFileName;
546                 if (artifactInfo != null) {
547                     artifactName = artifactInfo.getArtifactName();
548                 }
549                 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, artifactName, artifactVersion, spoolFile));
550             }
551         } else {
552             LOG.info("Pass for type "+type.getTag()+" is "+type.getPass()+" which is not <= "+deployList.length);
553         }
554     }
555
556
557     private DistributionStatusEnum deploySpoolFile(DeployableArtifact artifact) {
558
559         DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_OK;
560
561         StringBuffer msgBuffer = new StringBuffer();
562
563
564         String namespace = config.getAsdcApiNamespace();
565         if (namespace == null || namespace.length() == 0) {
566             namespace="com:att:sdnctl:asdcapi";
567         }
568
569         msgBuffer.append("<input xmlns='");
570         msgBuffer.append(namespace);
571         msgBuffer.append("'>\n");
572
573         String svcName = artifact.getSvcName();
574         String resourceName = artifact.getResourceName();
575         String artifactName = artifact.getArtifactName();
576
577         if (svcName != null) {
578             if (resourceName != null) {
579                 artifactName = svcName + "/" + resourceName + "/" + artifactName;
580             } else {
581                 artifactName = svcName + "/" + artifactName;
582             }
583         }
584
585         msgBuffer.append("<artifact-name>"+artifactName+"</artifact-name>\n");
586         msgBuffer.append("<artifact-version>"+artifact.getArtifactVersion()+"</artifact-version>\n");
587
588
589         try {
590             BufferedReader rdr = new BufferedReader(new FileReader(artifact.getFile()));
591
592             String curLine = rdr.readLine();
593
594             while (curLine != null) {
595
596                 if (!curLine.startsWith("<?")) {
597                     msgBuffer.append(curLine+"\n");
598                 }
599                 curLine = rdr.readLine();
600             }
601             rdr.close();
602
603         } catch (Exception e) {
604             LOG.error("Could not process spool file "+artifact.getFile().getName(), e);
605             return DistributionStatusEnum.DEPLOY_ERROR;
606         }
607
608         msgBuffer.append("</input>\n");
609
610
611         byte[] msgBytes = msgBuffer.toString().getBytes();
612
613         Document results = postRestXml(artifact.getType().getRpcUrl(config.getAsdcApiBaseUrl()), msgBytes);
614
615         if (results == null) {
616
617             deployResult = DistributionStatusEnum.DEPLOY_ERROR;
618         } else {
619
620             XPathFactory xpf = XPathFactory.newInstance();
621             XPath xp = xpf.newXPath();
622
623             String asdcApiResponseCode = "500";
624
625             try {
626
627                 asdcApiResponseCode = xp.evaluate("//asdc-api-response-code[position()=1]/text()", results.getDocumentElement());
628             } catch (Exception e) {
629                 LOG.error("Caught exception retrying to evaluate xpath", e);
630             }
631
632             if (asdcApiResponseCode.contains("200")) {
633                 LOG.info("Update to SDN-C succeeded");
634                 deployResult = DistributionStatusEnum.DEPLOY_OK;
635             } else {
636                 LOG.info("Update to SDN-C failed (response code "+asdcApiResponseCode+")");
637
638                 if (asdcApiResponseCode.contains("409")) {
639                     deployResult = DistributionStatusEnum.ALREADY_DEPLOYED;
640                 } else {
641
642                     deployResult = DistributionStatusEnum.DEPLOY_ERROR;
643                 }
644             }
645         }
646
647
648
649         return deployResult;
650     }
651
652
653
654
655
656     public static IDistributionStatusMessage buildStatusMessage(
657             final IDistributionClient client, final INotificationData data,
658             final IArtifactInfo relevantArtifact,
659             final DistributionStatusEnum status) {
660         IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() {
661
662             @Override
663                         public long getTimestamp() {
664                 long currentTimeMillis = System.currentTimeMillis();
665                 return currentTimeMillis;
666             }
667
668             @Override
669                         public DistributionStatusEnum getStatus() {
670                 return status;
671             }
672
673             @Override
674                         public String getDistributionID() {
675                 return data.getDistributionID();
676             }
677
678             @Override
679                         public String getConsumerID() {
680                 return client.getConfiguration().getConsumerID();
681             }
682
683             @Override
684                         public String getArtifactURL() {
685                 return relevantArtifact.getArtifactURL();
686             }
687         };
688         return statusMessage;
689
690     }
691
692     private HttpURLConnection getRestXmlConnection(String urlString, String method) throws IOException
693     {
694         URL sdncUrl = new URL(urlString);
695         Authenticator.setDefault(new SdncAuthenticator(config.getSdncUser(), config.getSdncPasswd()));
696
697         HttpURLConnection conn = (HttpURLConnection) sdncUrl.openConnection();
698
699         String authStr = config.getSdncUser()+":"+config.getSdncPasswd();
700         String encodedAuthStr = new String(Base64.encodeBase64(authStr.getBytes()));
701
702         conn.addRequestProperty("Authentication", "Basic "+encodedAuthStr);
703
704         conn.setRequestMethod(method);
705         conn.setRequestProperty("Content-Type", "application/xml");
706         conn.setRequestProperty("Accept", "application/xml");
707
708         conn.setDoInput(true);
709         conn.setDoOutput(true);
710         conn.setUseCaches(false);
711
712         return conn;
713
714     }
715
716     private Document postRestXml(String urlString, byte[] msgBytes) {
717         Document response = null;
718
719         LOG.info("Sending REST POST to "+urlString);
720         LOG.info("Message body:\n"+new String(msgBytes));
721
722         try {
723             HttpURLConnection conn = getRestXmlConnection(urlString, "POST");
724
725             if (conn instanceof HttpsURLConnection) {
726                 HostnameVerifier hostnameVerifier = new HostnameVerifier() {
727                     @Override
728                     public boolean verify(String hostname, SSLSession session) {
729                         return true;
730                     }
731                 };
732                 ((HttpsURLConnection)conn).setHostnameVerifier(hostnameVerifier);
733             }
734
735             // Write message
736             conn.setRequestProperty("Content-Length", ""+msgBytes.length);
737             DataOutputStream outStr = new DataOutputStream(conn.getOutputStream());
738             outStr.write(msgBytes);
739             outStr.close();
740
741
742             // Read response
743             BufferedReader respRdr;
744
745             LOG.info("Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
746
747
748             if (conn.getResponseCode() < 300) {
749
750                 respRdr = new BufferedReader(new InputStreamReader(conn.getInputStream()));
751             } else {
752                 respRdr = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
753             }
754
755             StringBuffer respBuff = new StringBuffer();
756
757             String respLn;
758
759             while ((respLn = respRdr.readLine()) != null) {
760                 respBuff.append(respLn+"\n");
761             }
762             respRdr.close();
763
764             String respString = respBuff.toString();
765
766             LOG.info("Response body :\n"+respString);
767
768             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
769             DocumentBuilder db = dbf.newDocumentBuilder();
770
771
772             response = db.parse(new ByteArrayInputStream(respString.getBytes()));
773
774         } catch (Exception e) {
775
776             LOG.error("Caught exception in postRestXml", e);
777         }
778
779         return response;
780     }
781
782     private File applyXslts(File srcFile) {
783
784         Document doc = null;
785
786
787         File inFile = srcFile;
788         File outFile = null;
789
790         String xsltPathList = config.getXsltPathList();
791
792         if (xsltPathList == null || xsltPathList.length() == 0) {
793             outFile = inFile;
794         } else {
795
796             String[] xsltPaths = xsltPathList.split(",");
797
798             for (String xsltPath : xsltPaths) {
799                 try{
800
801                     outFile = File.createTempFile("tmp", "xml");
802                     TransformerFactory factory = TransformerFactory.newInstance();
803                     Source xslt = new StreamSource(new File(xsltPath));
804                     Transformer transformer = factory.newTransformer(xslt);
805                     Source text = new StreamSource(inFile);
806
807
808                     transformer.transform(text, new StreamResult(outFile));
809
810                     inFile = outFile;
811
812                 } catch (Exception e) {
813                     LOG.error("Caught exception trying to apply XSLT template "+xsltPath, e);
814
815                 }
816
817             }
818         }
819
820         // After transformations, parse transformed XML
821
822
823         return outFile;
824     }
825
826     private String escapeFilename(String str) {
827         StringBuffer retval = new StringBuffer();
828
829         for (int i = 0 ; i < str.length() ; i++) {
830             char curchar = str.charAt(i);
831             if (Character.isJavaIdentifierPart(curchar)) {
832                 retval.append(curchar);
833             }
834         }
835
836         return retval.toString();
837
838     }
839
840 }