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