Remove critical code smells for servlet classes
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / SubscriptionServlet.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * *\r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * *\r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 \r
24 \r
25 package org.onap.dmaap.datarouter.provisioning;\r
26 \r
27 import java.io.IOException;\r
28 import java.io.InvalidObjectException;\r
29 import java.net.HttpURLConnection;\r
30 import java.net.URL;\r
31 import java.util.List;\r
32 import java.util.Vector;\r
33 \r
34 import javax.servlet.http.HttpServletRequest;\r
35 import javax.servlet.http.HttpServletResponse;\r
36 \r
37 import org.json.JSONException;\r
38 import org.json.JSONObject;\r
39 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;\r
40 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;\r
41 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;\r
42 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;\r
43 \r
44 import com.att.eelf.configuration.EELFLogger;\r
45 import com.att.eelf.configuration.EELFManager;\r
46 \r
47 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;\r
48 \r
49 /**\r
50  * This servlet handles provisioning for the <subscriptionURL> which is generated by the provisioning server to\r
51  * handle the inspection, modification, and deletion of a particular subscription to a feed. It supports DELETE to\r
52  * delete a subscription, GET to retrieve information about the subscription, and PUT to modify the subscription.  In DR\r
53  * 3.0, POST is also supported in order to reset the subscription timers for individual subscriptions.\r
54  *\r
55  * @author Robert Eby\r
56  * @version $Id$\r
57  */\r
58 @SuppressWarnings("serial")\r
59 public class SubscriptionServlet extends ProxyServlet {\r
60 \r
61     private static final String SUBCNTRL_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-control";\r
62     //Adding EELF Logger Rally:US664892\r
63     private static EELFLogger eelfLogger = EELFManager.getInstance()\r
64         .getLogger(SubscriptionServlet.class);\r
65 \r
66     /**\r
67      * DELETE on the &lt;subscriptionUrl&gt; -- delete a subscription. See the <i>Deleting a Subscription</i> section in\r
68      * the <b>Provisioning API</b> document for details on how this method should be invoked.\r
69      */\r
70     @Override\r
71     public void doDelete(HttpServletRequest req, HttpServletResponse resp) {\r
72         setIpFqdnRequestIDandInvocationIDForEelf("doDelete", req);\r
73         eelfLogger.info(EelfMsgs.ENTRY);\r
74         try {\r
75             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");\r
76             EventLogRecord elr = new EventLogRecord(req);\r
77             String message = isAuthorizedForProvisioning(req);\r
78             if (message != null) {\r
79                 elr.setMessage(message);\r
80                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
81                 eventlogger.error(elr.toString());\r
82                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
83                 return;\r
84             }\r
85             if (isProxyServer()) {\r
86                 super.doDelete(req, resp);\r
87                 return;\r
88             }\r
89             String bhdr = req.getHeader(BEHALF_HEADER);\r
90             if (bhdr == null) {\r
91                 message = "Missing " + BEHALF_HEADER + " header.";\r
92                 elr.setMessage(message);\r
93                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
94                 eventlogger.error(elr.toString());\r
95                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
96                 return;\r
97             }\r
98             int subid = getIdFromPath(req);\r
99             if (subid < 0) {\r
100                 message = "Missing or bad subscription number.";\r
101                 elr.setMessage(message);\r
102                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
103                 eventlogger.error(elr.toString());\r
104                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
105                 return;\r
106             }\r
107             Subscription sub = Subscription.getSubscriptionById(subid);\r
108             if (sub == null) {\r
109                 message = "Missing or bad subscription number.";\r
110                 elr.setMessage(message);\r
111                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
112                 eventlogger.error(elr.toString());\r
113                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
114                 return;\r
115             }\r
116             /*\r
117              * START - AAF changes\r
118              * TDP EPIC US# 307413\r
119              * CADI code - check on permissions based on Legacy/AAF users to allow to delete/remove subscription\r
120              */\r
121             String aafInstance = sub.getAafInstance();\r
122             if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {\r
123                 AuthorizationResponse aresp = authz.decide(req);\r
124                 if (!aresp.isAuthorized()) {\r
125                     message = "Policy Engine disallows access.";\r
126                     elr.setMessage(message);\r
127                     elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
128                     eventlogger.error(elr.toString());\r
129                     sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
130                     return;\r
131                 }\r
132             } else {\r
133                 String permission = getSubscriberPermission(aafInstance, BaseServlet.DELETE_PERMISSION);\r
134                 eventlogger.info("SubscriptionServlet.doDelete().. Permission String - " + permission);\r
135                 if (!req.isUserInRole(permission)) {\r
136                     message = "AAF disallows access to permission - " + permission;\r
137                     elr.setMessage(message);\r
138                     elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
139                     eventlogger.error(elr.toString());\r
140                     sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
141                     return;\r
142                 }\r
143             }\r
144             /*\r
145              * END - AAF changes\r
146              */\r
147             // Delete Subscription\r
148             if (doDelete(sub)) {\r
149                 activeSubs--;\r
150                 // send response\r
151                 elr.setResult(HttpServletResponse.SC_NO_CONTENT);\r
152                 eventlogger.info(elr.toString());\r
153                 resp.setStatus(HttpServletResponse.SC_NO_CONTENT);\r
154                 provisioningDataChanged();\r
155             } else {\r
156                 // Something went wrong with the DELETE\r
157                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
158                 eventlogger.error(elr.toString());\r
159                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, intlogger);\r
160             }\r
161         } finally {\r
162             eelfLogger.info(EelfMsgs.EXIT);\r
163         }\r
164     }\r
165 \r
166     /**\r
167      * GET on the &lt;subscriptionUrl&gt; -- get information about a subscription. See the <i>Retreiving Information\r
168      * about a Subscription</i> section in the <b>Provisioning API</b> document for details on how this method should be\r
169      * invoked.\r
170      */\r
171     @Override\r
172     public void doGet(HttpServletRequest req, HttpServletResponse resp) {\r
173         setIpFqdnRequestIDandInvocationIDForEelf("doGet", req);\r
174         eelfLogger.info(EelfMsgs.ENTRY);\r
175         try {\r
176             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");\r
177             EventLogRecord elr = new EventLogRecord(req);\r
178             String message = isAuthorizedForProvisioning(req);\r
179             if (message != null) {\r
180                 elr.setMessage(message);\r
181                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
182                 eventlogger.error(elr.toString());\r
183                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
184                 return;\r
185             }\r
186             if (isProxyServer()) {\r
187                 super.doGet(req, resp);\r
188                 return;\r
189             }\r
190             String bhdr = req.getHeader(BEHALF_HEADER);\r
191             if (bhdr == null) {\r
192                 message = "Missing " + BEHALF_HEADER + " header.";\r
193                 elr.setMessage(message);\r
194                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
195                 eventlogger.error(elr.toString());\r
196                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
197                 return;\r
198             }\r
199             int subid = getIdFromPath(req);\r
200             if (subid < 0) {\r
201                 message = "Missing or bad subscription number.";\r
202                 elr.setMessage(message);\r
203                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
204                 eventlogger.error(elr.toString());\r
205                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
206                 return;\r
207             }\r
208             Subscription sub = Subscription.getSubscriptionById(subid);\r
209             if (sub == null) {\r
210                 message = "Missing or bad subscription number.";\r
211                 elr.setMessage(message);\r
212                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
213                 eventlogger.error(elr.toString());\r
214                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
215                 return;\r
216             }\r
217             // Check with the Authorizer\r
218             AuthorizationResponse aresp = authz.decide(req);\r
219             if (!aresp.isAuthorized()) {\r
220                 message = "Policy Engine disallows access.";\r
221                 elr.setMessage(message);\r
222                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
223                 eventlogger.error(elr.toString());\r
224                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
225                 return;\r
226             }\r
227 \r
228             // send response\r
229             elr.setResult(HttpServletResponse.SC_OK);\r
230             eventlogger.info(elr.toString());\r
231             resp.setStatus(HttpServletResponse.SC_OK);\r
232             resp.setContentType(SUBFULL_CONTENT_TYPE);\r
233             try {\r
234                 resp.getOutputStream().print(sub.asJSONObject(true).toString());\r
235             } catch (IOException ioe) {\r
236                 eventlogger.error("PROV0191 SubscriptionServlet.doGet: " + ioe.getMessage(), ioe);\r
237             }\r
238         } finally {\r
239             eelfLogger.info(EelfMsgs.EXIT);\r
240         }\r
241     }\r
242 \r
243     /**\r
244      * PUT on the &lt;subscriptionUrl&gt; -- modify a subscription. See the <i>Modifying a Subscription</i> section in\r
245      * the <b>Provisioning API</b> document for details on how this method should be invoked.\r
246      */\r
247     @Override\r
248     public void doPut(HttpServletRequest req, HttpServletResponse resp) {\r
249         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);\r
250         eelfLogger.info(EelfMsgs.ENTRY);\r
251         try {\r
252             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");\r
253             EventLogRecord elr = new EventLogRecord(req);\r
254             String message = isAuthorizedForProvisioning(req);\r
255             if (message != null) {\r
256                 elr.setMessage(message);\r
257                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
258                 eventlogger.error(elr.toString());\r
259                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
260                 return;\r
261             }\r
262             if (isProxyServer()) {\r
263                 super.doPut(req, resp);\r
264                 return;\r
265             }\r
266             String bhdr = req.getHeader(BEHALF_HEADER);\r
267             if (bhdr == null) {\r
268                 message = "Missing " + BEHALF_HEADER + " header.";\r
269                 elr.setMessage(message);\r
270                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
271                 eventlogger.error(elr.toString());\r
272                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
273                 return;\r
274             }\r
275             int subid = getIdFromPath(req);\r
276             if (subid < 0) {\r
277                 message = "Missing or bad subscription number.";\r
278                 elr.setMessage(message);\r
279                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
280                 eventlogger.error(elr.toString());\r
281                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
282                 return;\r
283             }\r
284             Subscription oldsub = Subscription.getSubscriptionById(subid);\r
285             if (oldsub == null) {\r
286                 message = "Missing or bad subscription number.";\r
287                 elr.setMessage(message);\r
288                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
289                 eventlogger.error(elr.toString());\r
290                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
291                 return;\r
292             }\r
293             // check content type is SUB_CONTENT_TYPE, version 1.0\r
294             ContentHeader ch = getContentHeader(req);\r
295             String ver = ch.getAttribute("version");\r
296             if (!ch.getType().equals(SUB_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {\r
297                 message = "Incorrect content-type";\r
298                 elr.setMessage(message);\r
299                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);\r
300                 eventlogger.error(elr.toString());\r
301                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);\r
302                 return;\r
303             }\r
304             JSONObject jo = getJSONfromInput(req);\r
305             if (jo == null) {\r
306                 message = "Badly formed JSON";\r
307                 elr.setMessage(message);\r
308                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
309                 eventlogger.error(elr.toString());\r
310                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
311                 return;\r
312             }\r
313             if (intlogger.isDebugEnabled()) {\r
314                 intlogger.debug(jo.toString());\r
315             }\r
316             Subscription sub = null;\r
317             try {\r
318                 sub = new Subscription(jo);\r
319             } catch (InvalidObjectException e) {\r
320                 message = e.getMessage();\r
321                 elr.setMessage(message);\r
322                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
323                 eventlogger.error(elr.toString(), e);\r
324                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
325                 return;\r
326             }\r
327 \r
328             /*\r
329              * START - AAF changes\r
330              * TDP EPIC US# 307413\r
331              * CADI code - check on permissions based on Legacy/AAF users to allow to delete/remove subscription\r
332              */\r
333             String aafInstance = sub.getAafInstance();\r
334             if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {\r
335                 AuthorizationResponse aresp = authz.decide(req);\r
336                 if (!aresp.isAuthorized()) {\r
337                     message = "Policy Engine disallows access.";\r
338                     elr.setMessage(message);\r
339                     elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
340                     eventlogger.error(elr.toString());\r
341                     sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
342                     return;\r
343                 }\r
344             } else {\r
345                 String permission = getSubscriberPermission(aafInstance, BaseServlet.EDIT_PERMISSION);\r
346                 eventlogger.info("SubscriptionServlet.doDelete().. Permission String - " + permission);\r
347                 if (!req.isUserInRole(permission)) {\r
348                     message = "AAF disallows access to permission - " + permission;\r
349                     elr.setMessage(message);\r
350                     elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
351                     eventlogger.error(elr.toString());\r
352                     sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
353                     return;\r
354                 }\r
355             }\r
356             /*\r
357              * END - AAF changes\r
358              */\r
359             sub.setSubid(oldsub.getSubid());\r
360             sub.setFeedid(oldsub.getFeedid());\r
361             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header\r
362 \r
363             String subjectgroup = (req.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")); //Adding for group feature:Rally US708115\r
364             if (!oldsub.getSubscriber().equals(sub.getSubscriber()) && subjectgroup == null) {\r
365                 message = "This subscriber must be modified by the same subscriber that created it.";\r
366                 elr.setMessage(message);\r
367                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
368                 eventlogger.error(elr.toString());\r
369                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
370                 return;\r
371             }\r
372 \r
373             // Update SUBSCRIPTIONS table entries\r
374             if (doUpdate(sub)) {\r
375                 // send response\r
376                 elr.setResult(HttpServletResponse.SC_OK);\r
377                 eventlogger.info(elr.toString());\r
378                 resp.setStatus(HttpServletResponse.SC_OK);\r
379                 resp.setContentType(SUBFULL_CONTENT_TYPE);\r
380                 try {\r
381                     resp.getOutputStream().print(sub.asLimitedJSONObject().toString());\r
382                 } catch (IOException ioe) {\r
383                     eventlogger.error("PROV0192 SubscriptionServlet.doPut: " + ioe.getMessage(), ioe);\r
384                 }\r
385 \r
386                 /**Change Owner ship of Subscriber     Adding for group feature:Rally US708115*/\r
387                 if (jo.has("changeowner") && subjectgroup != null) {\r
388                     try {\r
389                         Boolean changeowner = (Boolean) jo.get("changeowner");\r
390                         if (changeowner != null && changeowner.equals(true)) {\r
391                             sub.setSubscriber(req.getHeader(BEHALF_HEADER));\r
392                             sub.changeOwnerShip();\r
393                         }\r
394                     } catch (JSONException je) {\r
395                         eventlogger.error("PROV0193 SubscriptionServlet.doPut: " + je.getMessage(), je);\r
396                     }\r
397                 }\r
398                 /***End of change ownership*/\r
399 \r
400                 provisioningDataChanged();\r
401             } else {\r
402                 // Something went wrong with the UPDATE\r
403                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
404                 eventlogger.error(elr.toString());\r
405                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, intlogger);\r
406             }\r
407         } finally {\r
408             eelfLogger.info(EelfMsgs.EXIT);\r
409         }\r
410     }\r
411 \r
412     /**\r
413      * POST on the &lt;subscriptionUrl&gt; -- control a subscription. See the <i>Resetting a Subscription's Retry\r
414      * Schedule</i> section in the <b>Provisioning API</b> document for details on how this method should be invoked.\r
415      */\r
416     @Override\r
417     public void doPost(HttpServletRequest req, HttpServletResponse resp) {\r
418 \r
419         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);\r
420         eelfLogger.info(EelfMsgs.ENTRY);\r
421         try {\r
422             eelfLogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));\r
423             EventLogRecord elr = new EventLogRecord(req);\r
424             String message = isAuthorizedForProvisioning(req);\r
425             if (message != null) {\r
426                 elr.setMessage(message);\r
427                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
428                 eventlogger.error(elr.toString());\r
429                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
430                 return;\r
431             }\r
432             if (isProxyServer()) {\r
433                 super.doPost(req, resp);\r
434                 return;\r
435             }\r
436             String bhdr = req.getHeader(BEHALF_HEADER);\r
437             if (bhdr == null) {\r
438                 message = "Missing " + BEHALF_HEADER + " header.";\r
439                 elr.setMessage(message);\r
440                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
441                 eventlogger.error(elr.toString());\r
442                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
443                 return;\r
444             }\r
445             final int subid = getIdFromPath(req);\r
446             if (subid < 0 || Subscription.getSubscriptionById(subid) == null) {\r
447                 message = "Missing or bad subscription number.";\r
448                 elr.setMessage(message);\r
449                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
450                 eventlogger.error(elr.toString());\r
451                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
452                 return;\r
453             }\r
454             // check content type is SUBCNTRL_CONTENT_TYPE, version 1.0\r
455             ContentHeader ch = getContentHeader(req);\r
456             String ver = ch.getAttribute("version");\r
457             if (!ch.getType().equals(SUBCNTRL_CONTENT_TYPE) || !ver.equals("1.0")) {\r
458                 message = "Incorrect content-type";\r
459                 elr.setMessage(message);\r
460                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);\r
461                 eventlogger.error(elr.toString());\r
462                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);\r
463                 return;\r
464             }\r
465             // Check with the Authorizer\r
466             AuthorizationResponse aresp = authz.decide(req);\r
467             if (!aresp.isAuthorized()) {\r
468                 message = "Policy Engine disallows access.";\r
469                 elr.setMessage(message);\r
470                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
471                 eventlogger.error(elr.toString());\r
472                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
473                 return;\r
474             }\r
475             JSONObject jo = getJSONfromInput(req);\r
476             if (jo == null) {\r
477                 message = "Badly formed JSON";\r
478                 elr.setMessage(message);\r
479                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
480                 eventlogger.error(elr.toString());\r
481                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
482                 return;\r
483             }\r
484             try {\r
485                 // Only the active POD sends notifications\r
486                 boolean active = SynchronizerTask.getSynchronizer().isActive();\r
487                 boolean b = jo.getBoolean("failed");\r
488                 if (active && !b) {\r
489                     // Notify all nodes to reset the subscription\r
490                     SubscriberNotifyThread t = new SubscriberNotifyThread();\r
491                     t.resetSubscription(subid);\r
492                     t.start();\r
493                 }\r
494                 // send response\r
495                 elr.setResult(HttpServletResponse.SC_ACCEPTED);\r
496                 eventlogger.info(elr.toString());\r
497                 resp.setStatus(HttpServletResponse.SC_ACCEPTED);\r
498             } catch (JSONException e) {\r
499                 message = "Badly formed JSON";\r
500                 elr.setMessage(message);\r
501                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
502                 eventlogger.error(elr.toString(), e);\r
503                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
504             }\r
505         } finally {\r
506             eelfLogger.info(EelfMsgs.EXIT);\r
507         }\r
508     }\r
509 \r
510     /**\r
511      * A Thread class used to serially send reset notifications to all nodes in the DR network, when a POST is received\r
512      * for a subscription.\r
513      */\r
514     public class SubscriberNotifyThread extends Thread {\r
515 \r
516         public static final String URL_TEMPLATE = "http://%s/internal/resetSubscription/%d";\r
517         private List<String> urls = new Vector<String>();\r
518 \r
519         public SubscriberNotifyThread() {\r
520             setName("SubscriberNotifyThread");\r
521         }\r
522 \r
523         public void resetSubscription(int subid) {\r
524             for (String nodename : BaseServlet.getNodes()) {\r
525                 String u = String.format(URL_TEMPLATE, nodename, subid);\r
526                 urls.add(u);\r
527             }\r
528         }\r
529 \r
530         public void run() {\r
531             try {\r
532                 while (!urls.isEmpty()) {\r
533                     String u = urls.remove(0);\r
534                     try {\r
535                         URL url = new URL(u);\r
536                         HttpURLConnection conn = (HttpURLConnection) url.openConnection();\r
537                         conn.connect();\r
538                         conn.getContentLength();    // Force the GET through\r
539                         conn.disconnect();\r
540                     } catch (IOException e) {\r
541                         intlogger.info("PROV0194 Error accessing URL: " + u + ": " + e.getMessage(), e);\r
542                     }\r
543                 }\r
544             } catch (Exception e) {\r
545                 intlogger.warn("PROV0195 Caught exception in SubscriberNotifyThread: " + e.getMessage(), e);\r
546             }\r
547         }\r
548     }\r
549 }\r