Removing passwordencryption key
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / InternalServlet.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * * ===========================================================================
7  * * Licensed under the Apache License, Version 2.0 (the "License");
8  * * you may not use this file except in compliance with the License.
9  * * You may obtain a copy of the License at
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
13  *  * Unless required by applicable law or agreed to in writing, software
14  * * distributed under the License is distributed on an "AS IS" BASIS,
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * * See the License for the specific language governing permissions and
17  * * limitations under the License.
18  * * ============LICENSE_END====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.provisioning;
26
27 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
28
29 import com.att.eelf.configuration.EELFLogger;
30 import com.att.eelf.configuration.EELFManager;
31 import java.io.ByteArrayOutputStream;
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.nio.file.FileStore;
36 import java.nio.file.FileSystem;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.nio.file.StandardCopyOption;
41 import java.util.Properties;
42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse;
44 import org.json.JSONArray;
45 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
46 import org.onap.dmaap.datarouter.provisioning.beans.LogRecord;
47 import org.onap.dmaap.datarouter.provisioning.beans.Parameters;
48 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
49 import org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader;
50 import org.onap.dmaap.datarouter.provisioning.utils.Poker;
51 import org.onap.dmaap.datarouter.provisioning.utils.RLEBitSet;
52 import org.onap.dmaap.datarouter.provisioning.utils.SynchronizerTask;
53
54
55
56 /**
57  * <p>
58  * This servlet handles requests to URLs under /internal on the provisioning server. These include:
59  * </p>
60  * <div class="contentContainer">
61  * <table class="packageSummary" border="0" cellpadding="3" cellspacing="0">
62  * <caption><span>URL Path Summary</span><span class="tabEnd">&nbsp;</span></caption>
63  * <tr>
64  * <th class="colFirst" width="15%">URL Path</th>
65  * <th class="colOne">Method</th>
66  * <th class="colLast">Purpose</th>
67  * </tr>
68  * <tr class="altColor">
69  * <td class="colFirst">/internal/prov</td>
70  * <td class="colOne">GET</td>
71  * <td class="colLast">used to GET a full JSON copy of the provisioning data.</td>
72  * </tr>
73  * <tr class="rowColor">
74  * <td class="colFirst">/internal/fetchProv</td>
75  * <td class="colOne">GET</td>
76  * <td class="colLast">used to signal to a standby POD that the provisioning data should be fetched from the active
77  * POD.</td>
78  * </tr>
79  * <tr class="altColor">
80  * <td class="colFirst" rowspan="2">/internal/logs</td>
81  * <td class="colOne">GET</td>
82  * <td class="colLast">used to GET an index of log files and individual logs for this provisioning server.</td>
83  * </tr>
84  * <tr class="altColor">
85  * <td class="colOne">POST</td>
86  * <td class="colLast">used to POST log files from the individual nodes to this provisioning server.</td>
87  * </tr>
88  * <tr class="rowColor">
89  * <td class="colFirst" rowspan="4">/internal/api</td>
90  * <td class="colOne">GET</td>
91  * <td class="colLast">used to GET an individual parameter value. The parameter name is specified by the path after
92  * /api/.</td>
93  * </tr>
94  * <tr class="rowColor">
95  * <td class="colOne">PUT</td>
96  * <td class="colLast">used to set an individual parameter value. The parameter name is specified by the path after
97  * /api/.</td>
98  * </tr>
99  * <tr class="rowColor">
100  * <td class="colOne">DELETE</td>
101  * <td class="colLast">used to remove an individual parameter value. The parameter name is specified by the path after
102  * /api/.</td>
103  * </tr>
104  * <tr class="rowColor">
105  * <td class="colOne">POST</td>
106  * <td class="colLast">used to create a new individual parameter value. The parameter name is specified by the path
107  * after /api/.</td>
108  * </tr>
109  * <tr class="altColor">
110  * <td class="colFirst">/internal/halt</td>
111  * <td class="colOne">GET</td>
112  * <td class="colLast">used to halt the server (must be accessed from 127.0.0.1).</td>
113  * </tr>
114  * <tr class="rowColor">
115  * <td class="colFirst" rowspan="2">/internal/drlogs</td>
116  * <td class="colOne">GET</td>
117  * <td class="colLast">used to get a list of DR log entries available for retrieval.
118  * Note: these are the actual data router log entries sent to the provisioning server by the nodes, not the provisioning
119  * server's internal logs (access via /internal/logs above). The range is returned as a list of record sequence
120  * numbers.</td>
121  * </tr>
122  * <tr class="rowColor">
123  * <td class="colOne">POST</td>
124  * <td class="colLast">used to retrieve specific log entries.
125  * The sequence numbers of the records to fetch are POST-ed; the records matching the sequence numbers are
126  * returned.</td>
127  * </tr>
128  * <tr class="altColor">
129  * <td class="colFirst">/internal/route/*</td>
130  * <td class="colOne">*</td>
131  * <td class="colLast">URLs under this path are handled via the
132  * {@link RouteServlet}</td>
133  * </tr>
134  * </table>
135  * </div>
136  * <p>
137  * Authorization to use these URLs is a little different than for other URLs on the provisioning server. For the most
138  * part, the IP address that the request comes from should be either:
139  * </p>
140  * <ol>
141  * <li>an IP address of a provisioning server, or</li>
142  * <li>the IP address of a node (to allow access to /internal/prov), or</li>
143  * <li>an IP address from the "<i>special subnet</i>" which is configured with
144  * the PROV_SPECIAL_SUBNET parameter.
145  * </ol>
146  * <p>
147  * In addition, requests to /internal/halt can ONLY come from localhost (127.0.0.1) on the HTTP port.
148  * </p>
149  * <p>
150  * All DELETE/GET/PUT/POST requests made to /internal/api on this servlet on the standby server are proxied to the
151  * active server (using the {@link ProxyServlet}) if it is up and reachable.
152  * </p>
153  *
154  * @author Robert Eby
155  * @version $Id: InternalServlet.java,v 1.23 2014/03/24 18:47:10 eby Exp $
156  */
157
158 @SuppressWarnings("serial")
159 public class InternalServlet extends ProxyServlet {
160
161
162     private static final Object lock = new Object();
163     private static Integer logseq = 0; // another piece of info to make log spool file names unique
164     //Adding EELF Logger Rally:US664892
165     private static EELFLogger eelfLogger = EELFManager.getInstance()
166         .getLogger(InternalServlet.class);
167
168     /**
169      * Delete a parameter at the address /internal/api/&lt;parameter&gt;. See the <b>Internal API</b> document for
170      * details on how this method should be invoked.
171      */
172     @Override
173     public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
174         setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);
175         eelfLogger.info(EelfMsgs.ENTRY);
176         try {
177             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
178                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
179             EventLogRecord elr = new EventLogRecord(req);
180             if (!isAuthorizedForInternal(req)) {
181                 elr.setMessage(UNAUTHORIZED);
182                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
183                 eventlogger.error(elr.toString());
184                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, UNAUTHORIZED, eventlogger);
185                 return;
186             }
187
188             String path = req.getPathInfo();
189             if (path.startsWith(API)) {
190                 if (isProxyOK(req) && isProxyServer()) {
191                     super.doDelete(req, resp);
192                     return;
193                 }
194                 String key = path.substring(5);
195                 if (key.length() > 0) {
196                     Parameters param = Parameters.getParameter(key);
197                     if (param != null) {
198                         if (doDelete(param)) {
199                             elr.setResult(HttpServletResponse.SC_OK);
200                             eventlogger.info(elr.toString());
201                             resp.setStatus(HttpServletResponse.SC_OK);
202                             provisioningDataChanged();
203                             provisioningParametersChanged();
204                         } else {
205                             // Something went wrong with the DELETE
206                             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
207                             eventlogger.error(elr.toString());
208                             sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
209                                     DB_PROBLEM_MSG, eventlogger);
210                         }
211                         return;
212                     }
213                 }
214             }
215             sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, BAD_URL, eventlogger);
216         } finally {
217             eelfLogger.info(EelfMsgs.EXIT);
218         }
219     }
220
221     /**
222      * Get some information (such as a parameter) underneath the /internal/ namespace. See the <b>Internal API</b>
223      * document for details on how this method should be invoked.
224      */
225     @Override
226     public void doGet(HttpServletRequest req, HttpServletResponse resp) {
227         setIpFqdnRequestIDandInvocationIDForEelf("doGet",req);
228         eelfLogger.info(EelfMsgs.ENTRY);
229         try {
230             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
231                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
232             String path = req.getPathInfo();
233             Properties props = ProvRunner.getProvProperties();
234             if ("/halt".equals(path) && !req.isSecure()) {
235                 // request to halt the server - can ONLY come from localhost
236                 String remote = req.getRemoteAddr();
237                 if (remote.equals(props.getProperty("org.onap.dmaap.datarouter.provserver.localhost"))) {
238                     intlogger.info("PROV0009 Request to HALT received.");
239                     resp.setStatus(HttpServletResponse.SC_OK);
240                     ProvRunner.shutdown();
241                 } else {
242                     intlogger.info("PROV0010 Disallowed request to HALT received from " + remote);
243                     resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
244                 }
245                 return;
246             }
247
248             EventLogRecord elr = new EventLogRecord(req);
249             if (!isAuthorizedForInternal(req)) {
250                 elr.setMessage(UNAUTHORIZED);
251                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
252                 eventlogger.error(elr.toString());
253                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, UNAUTHORIZED, eventlogger);
254                 return;
255             }
256             if ("/fetchProv".equals(path) && !req.isSecure()) {
257                 // if request came from active_pod or standby_pod and it is not us, reload prov data
258                 SynchronizerTask sync = SynchronizerTask.getSynchronizer();
259                 sync.doFetch();
260                 resp.setStatus(HttpServletResponse.SC_OK);
261                 return;
262             }
263             if ("/prov".equals(path)) {
264                 if (isProxyOK(req) && isProxyServer()) {
265                     if (super.doGetWithFallback(req, resp)) {
266                         return;
267                     }
268                     // fall back to returning the local data if the remote is unreachable
269                     intlogger.info("Active server unavailable; falling back to local copy.");
270                 }
271                 Poker pkr = Poker.getPoker();
272                 resp.setStatus(HttpServletResponse.SC_OK);
273                 resp.setContentType(PROVFULL_CONTENT_TYPE2);
274                 try {
275                     resp.getOutputStream().print(pkr.getProvisioningString());
276                 } catch (IOException ioe) {
277                     intlogger.error("PROV0131 InternalServlet.doGet: " + ioe.getMessage(), ioe);
278                 }
279                 return;
280             }
281             if ("/logs".equals(path) || LOGS.equals(path)) {
282                 resp.setStatus(HttpServletResponse.SC_OK);
283                 resp.setContentType("application/json");
284                 try {
285                     resp.getOutputStream().print(generateLogfileList().toString());
286                 } catch (IOException ioe) {
287                     intlogger.error("PROV0132 InternalServlet.doGet: " + ioe.getMessage(), ioe);
288                 }
289                 return;
290             }
291             if (path.startsWith(LOGS)) {
292                 String logdir = props.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir");
293                 String logfile = path.substring(6);
294                 if (logdir != null && logfile != null && logfile.indexOf('/') < 0) {
295                     File log = new File(logdir + File.separator + logfile);
296                     if (log.exists() && log.isFile()) {
297                         resp.setStatus(HttpServletResponse.SC_OK);
298                         resp.setContentType(TEXT_CT);
299                         Path logpath = Paths.get(log.getAbsolutePath());
300                         try {
301                             Files.copy(logpath, resp.getOutputStream());
302                         } catch (IOException ioe) {
303                             intlogger.error("PROV0133 InternalServlet.doGet: " + ioe.getMessage(), ioe);
304                         }
305                         return;
306                     }
307                 }
308                 sendResponseError(resp, HttpServletResponse.SC_NO_CONTENT, "No file.", eventlogger);
309                 return;
310             }
311             if (path.startsWith(API)) {
312                 if (isProxyOK(req) && isProxyServer()) {
313                     super.doGet(req, resp);
314                     return;
315                 }
316                 String key = path.substring(5);
317                 if (key.length() > 0) {
318                     Parameters param = Parameters.getParameter(key);
319                     if (param != null) {
320                         resp.setStatus(HttpServletResponse.SC_OK);
321                         resp.setContentType(TEXT_CT);
322                         try {
323                             resp.getOutputStream().print(param.getValue() + "\n");
324                         } catch (IOException ioe) {
325                             intlogger.error("PROV0134 InternalServlet.doGet: " + ioe.getMessage(), ioe);
326                         }
327                         return;
328                     }
329                 }
330             }
331             if ("/drlogs".equals(path) || "/drlogs/".equals(path)) {
332                 // Special POD <=> POD API to determine what log file records are loaded here
333                 LogfileLoader lfl = LogfileLoader.getLoader();
334                 resp.setStatus(HttpServletResponse.SC_OK);
335                 resp.setContentType(TEXT_CT);
336                 try {
337                     resp.getOutputStream().print(lfl.getBitSet().toString());
338                 } catch (IOException ioe) {
339                     intlogger.error("PROV0135 InternalServlet.doGet: " + ioe.getMessage(), ioe);
340                 }
341                 return;
342             }
343             sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, BAD_URL, eventlogger);
344         } finally {
345             eelfLogger.info(EelfMsgs.EXIT);
346         }
347     }
348
349     /**
350      * Modify a parameter at the address /internal/api/&lt;parameter&gt;. See the <b>Internal API</b> document for
351      * details on how this method should be invoked.
352      */
353     @Override
354     public void doPut(HttpServletRequest req, HttpServletResponse resp) {
355         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);
356         eelfLogger.info(EelfMsgs.ENTRY);
357         try {
358             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID,
359                     req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");
360             EventLogRecord elr = new EventLogRecord(req);
361             if (!isAuthorizedForInternal(req)) {
362                 elr.setMessage(UNAUTHORIZED);
363                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
364                 eventlogger.error(elr.toString());
365                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, UNAUTHORIZED, eventlogger);
366                 return;
367             }
368             String path = req.getPathInfo();
369             if (path.startsWith(API)) {
370                 if (isProxyOK(req) && isProxyServer()) {
371                     super.doPut(req, resp);
372                     return;
373                 }
374                 String key = path.substring(5);
375                 if (key.length() > 0) {
376                     Parameters param = Parameters.getParameter(key);
377                     if (param != null) {
378                         String str = catValues(req.getParameterValues("val"));
379                         param.setValue(str);
380                         if (doUpdate(param)) {
381                             elr.setResult(HttpServletResponse.SC_OK);
382                             eventlogger.info(elr.toString());
383                             resp.setStatus(HttpServletResponse.SC_OK);
384                             provisioningDataChanged();
385                             provisioningParametersChanged();
386                         } else {
387                             // Something went wrong with the UPDATE
388                             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
389                             eventlogger.error(elr.toString());
390                             sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
391                                     DB_PROBLEM_MSG, eventlogger);
392                         }
393                         return;
394                     }
395                 }
396             }
397             sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, BAD_URL, eventlogger);
398         } finally {
399             eelfLogger.info(EelfMsgs.EXIT);
400         }
401     }
402
403     /**
404      * Create some new information (such as a parameter or log entries) underneath the /internal/ namespace. See the
405      * <b>Internal API</b> document for details on how this method should be invoked.
406      */
407     @SuppressWarnings("resource")
408     @Override
409     public void doPost(HttpServletRequest req, HttpServletResponse resp) {
410         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);
411         eelfLogger.info(EelfMsgs.ENTRY);
412         try {
413             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));
414             EventLogRecord elr = new EventLogRecord(req);
415             if (!isAuthorizedForInternal(req)) {
416                 elr.setMessage(UNAUTHORIZED);
417                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);
418                 eventlogger.error(elr.toString());
419                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, UNAUTHORIZED, eventlogger);
420                 return;
421             }
422
423             String path = req.getPathInfo();
424             if (path.startsWith(API)) {
425                 if (isProxyOK(req) && isProxyServer()) {
426                     super.doPost(req, resp);
427                     return;
428                 }
429                 String key = path.substring(5);
430                 if (key.length() > 0) {
431                     Parameters param = Parameters.getParameter(key);
432                     if (param == null) {
433                         String str = catValues(req.getParameterValues("val"));
434                         param = new Parameters(key, str);
435                         if (doInsert(param)) {
436                             elr.setResult(HttpServletResponse.SC_OK);
437                             eventlogger.info(elr.toString());
438                             resp.setStatus(HttpServletResponse.SC_OK);
439                             provisioningDataChanged();
440                             provisioningParametersChanged();
441                         } else {
442                             // Something went wrong with the INSERT
443                             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
444                             eventlogger.error(elr.toString());
445                             sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
446                                     DB_PROBLEM_MSG, eventlogger);
447                         }
448                         return;
449                     }
450                 }
451             }
452
453             if ("/logs".equals(path) || LOGS.equals(path)) {
454                 String ctype = req.getHeader("Content-Type");
455                 if (!TEXT_CT.equals(ctype)) {
456                     elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
457                     elr.setMessage("Bad media type: " + ctype);
458                     resp.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
459                     eventlogger.error(elr.toString());
460                     return;
461                 }
462                 String spooldir =
463                         ProvRunner.getProvProperties().getProperty("org.onap.dmaap.datarouter.provserver.spooldir");
464                 String spoolname = String.format("%d-%d-", System.currentTimeMillis(), Thread.currentThread().getId());
465                 synchronized (lock) {
466                     // perhaps unnecessary, but it helps make the name unique
467                     spoolname += logseq.toString();
468                     logseq++;
469                 }
470                 String encoding = req.getHeader("Content-Encoding");
471                 if (encoding != null) {
472                     if ("gzip".equals(encoding.trim())) {
473                         spoolname += ".gz";
474                     } else {
475                         elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
476                         resp.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
477                         eventlogger.error(elr.toString());
478                         return;
479                     }
480                 }
481                 // Determine space available -- available space must be at least 5%
482                 FileSystem fs = (Paths.get(spooldir)).getFileSystem();
483                 long total = 0;
484                 long avail = 0;
485                 for (FileStore store : fs.getFileStores()) {
486                     try {
487                         total += store.getTotalSpace();
488                         avail += store.getUsableSpace();
489                     } catch (IOException ioe) {
490                         intlogger.error("PROV0136 InternalServlet.doPost: " + ioe.getMessage(), ioe);
491                     }
492                 }
493                 try {
494                     fs.close();
495                 } catch (UnsupportedOperationException | IOException e) {
496                     intlogger.error("PROV0137 InternalServlet.doPost: " + e.getMessage(), e);
497                 }
498                 if (total != 0 && ((avail * 100) / total) < 5) {
499                     elr.setResult(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
500                     resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
501                     eventlogger.error(elr.toString());
502                     return;
503                 }
504                 Path tmppath = Paths.get(spooldir, spoolname);
505                 Path donepath = Paths.get(spooldir, "IN." + spoolname);
506                 try {
507                     Files.copy(req.getInputStream(), Paths.get(spooldir, spoolname),
508                             StandardCopyOption.REPLACE_EXISTING);
509                     Files.move(tmppath, donepath, StandardCopyOption.REPLACE_EXISTING);
510                     elr.setResult(HttpServletResponse.SC_CREATED);
511                     resp.setStatus(HttpServletResponse.SC_CREATED);
512                     eventlogger.info(elr.toString());
513                     LogfileLoader.getLoader();    // This starts the logfile loader "task"
514                 } catch (IOException ioe) {
515                     intlogger.error("PROV0138 InternalServlet.doPost: " + ioe.getMessage(), ioe);
516                 }
517                 return;
518             }
519
520             if ("/drlogs".equals(path) || "/drlogs/".equals(path)) {
521                 // Receive post request and generate log entries
522                 String ctype = req.getHeader("Content-Type");
523                 if (!TEXT_CT.equals(ctype)) {
524                     elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
525                     elr.setMessage("Bad media type: " + ctype);
526                     resp.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
527                     eventlogger.error(elr.toString());
528                     return;
529                 }
530                 try {
531                     InputStream is = req.getInputStream();
532                     ByteArrayOutputStream bos = new ByteArrayOutputStream();
533                     int ch;
534                     while ((ch = is.read()) >= 0) {
535                         bos.write(ch);
536                     }
537                     elr.setResult(HttpServletResponse.SC_OK);
538                     resp.setStatus(HttpServletResponse.SC_OK);
539                     resp.setContentType(TEXT_CT);
540                     RLEBitSet bs = new RLEBitSet(bos.toString());    // The set of records to retrieve
541                     LogRecord.printLogRecords(resp.getOutputStream(), bs);
542                     eventlogger.info(elr.toString());
543                 } catch (IOException ioe) {
544                     intlogger.error("PROV0139 InternalServlet.doPost: " + ioe.getMessage(), ioe);
545                 }
546                 return;
547             }
548
549             elr.setResult(HttpServletResponse.SC_NOT_FOUND);
550             sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, BAD_URL, eventlogger);
551             eventlogger.error(elr.toString());
552         } finally {
553             eelfLogger.info(EelfMsgs.EXIT);
554         }
555     }
556
557     private String catValues(String[] val) {
558         StringBuilder sb = new StringBuilder();
559         if (val != null) {
560             String pfx = "";
561             for (String s : val) {
562                 sb.append(pfx);
563                 sb.append(s);
564                 pfx = "|";
565             }
566         }
567         return sb.toString();
568     }
569
570     private JSONArray generateLogfileList() {
571         JSONArray ja = new JSONArray();
572         Properties prop = ProvRunner.getProvProperties();
573         String str = prop.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir");
574         if (str != null) {
575             String[] dirs = str.split(",");
576             for (String dir : dirs) {
577                 File file = new File(dir);
578                 String[] list = file.list();
579                 if (list != null) {
580                     for (String s2 : list) {
581                         if (!s2.startsWith(".")) {
582                             ja.put(s2);
583                         }
584                     }
585                 }
586             }
587         }
588         return ja;
589     }
590 }