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