Replace ATT headers
[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     public 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.info(elr);\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.info(elr);\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.info(elr);\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.info(elr);\r
113                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
114                 return;\r
115             }\r
116             // Check with the Authorizer\r
117             AuthorizationResponse aresp = authz.decide(req);\r
118             if (!aresp.isAuthorized()) {\r
119                 message = "Policy Engine disallows access.";\r
120                 elr.setMessage(message);\r
121                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
122                 eventlogger.info(elr);\r
123                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
124                 return;\r
125             }\r
126 \r
127             // Delete Subscription\r
128             if (doDelete(sub)) {\r
129                 activeSubs--;\r
130                 // send response\r
131                 elr.setResult(HttpServletResponse.SC_NO_CONTENT);\r
132                 eventlogger.info(elr);\r
133                 resp.setStatus(HttpServletResponse.SC_NO_CONTENT);\r
134                 provisioningDataChanged();\r
135             } else {\r
136                 // Something went wrong with the DELETE\r
137                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
138                 eventlogger.info(elr);\r
139                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, intlogger);\r
140             }\r
141         } finally {\r
142             eelflogger.info(EelfMsgs.EXIT);\r
143         }\r
144     }\r
145 \r
146     /**\r
147      * GET on the &lt;subscriptionUrl&gt; -- get information about a subscription. See the <i>Retreiving Information\r
148      * about a Subscription</i> section in the <b>Provisioning API</b> document for details on how this method should be\r
149      * invoked.\r
150      */\r
151     @Override\r
152     public void doGet(HttpServletRequest req, HttpServletResponse resp) {\r
153         setIpFqdnRequestIDandInvocationIDForEelf("doGet", req);\r
154         eelflogger.info(EelfMsgs.ENTRY);\r
155         try {\r
156             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");\r
157             EventLogRecord elr = new EventLogRecord(req);\r
158             String message = isAuthorizedForProvisioning(req);\r
159             if (message != null) {\r
160                 elr.setMessage(message);\r
161                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
162                 eventlogger.info(elr);\r
163                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
164                 return;\r
165             }\r
166             if (isProxyServer()) {\r
167                 super.doGet(req, resp);\r
168                 return;\r
169             }\r
170             String bhdr = req.getHeader(BEHALF_HEADER);\r
171             if (bhdr == null) {\r
172                 message = "Missing " + BEHALF_HEADER + " header.";\r
173                 elr.setMessage(message);\r
174                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
175                 eventlogger.info(elr);\r
176                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
177                 return;\r
178             }\r
179             int subid = getIdFromPath(req);\r
180             if (subid < 0) {\r
181                 message = "Missing or bad subscription number.";\r
182                 elr.setMessage(message);\r
183                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
184                 eventlogger.info(elr);\r
185                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
186                 return;\r
187             }\r
188             Subscription sub = Subscription.getSubscriptionById(subid);\r
189             if (sub == null) {\r
190                 message = "Missing or bad subscription number.";\r
191                 elr.setMessage(message);\r
192                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
193                 eventlogger.info(elr);\r
194                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
195                 return;\r
196             }\r
197             // Check with the Authorizer\r
198             AuthorizationResponse aresp = authz.decide(req);\r
199             if (!aresp.isAuthorized()) {\r
200                 message = "Policy Engine disallows access.";\r
201                 elr.setMessage(message);\r
202                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
203                 eventlogger.info(elr);\r
204                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
205                 return;\r
206             }\r
207 \r
208             // send response\r
209             elr.setResult(HttpServletResponse.SC_OK);\r
210             eventlogger.info(elr);\r
211             resp.setStatus(HttpServletResponse.SC_OK);\r
212             resp.setContentType(SUBFULL_CONTENT_TYPE);\r
213             try {\r
214                 resp.getOutputStream().print(sub.asJSONObject(true).toString());\r
215             } catch (IOException ioe) {\r
216                 eventlogger.error("IOException: " + ioe.getMessage());\r
217             }\r
218         } finally {\r
219             eelflogger.info(EelfMsgs.EXIT);\r
220         }\r
221     }\r
222 \r
223     /**\r
224      * PUT on the &lt;subscriptionUrl&gt; -- modify a subscription. See the <i>Modifying a Subscription</i> section in\r
225      * the <b>Provisioning API</b> document for details on how this method should be invoked.\r
226      */\r
227     @Override\r
228     public void doPut(HttpServletRequest req, HttpServletResponse resp) {\r
229         setIpFqdnRequestIDandInvocationIDForEelf("doPut", req);\r
230         eelflogger.info(EelfMsgs.ENTRY);\r
231         try {\r
232             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_SUBID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + "");\r
233             EventLogRecord elr = new EventLogRecord(req);\r
234             String message = isAuthorizedForProvisioning(req);\r
235             if (message != null) {\r
236                 elr.setMessage(message);\r
237                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
238                 eventlogger.info(elr);\r
239                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
240                 return;\r
241             }\r
242             if (isProxyServer()) {\r
243                 super.doPut(req, resp);\r
244                 return;\r
245             }\r
246             String bhdr = req.getHeader(BEHALF_HEADER);\r
247             if (bhdr == null) {\r
248                 message = "Missing " + BEHALF_HEADER + " header.";\r
249                 elr.setMessage(message);\r
250                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
251                 eventlogger.info(elr);\r
252                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
253                 return;\r
254             }\r
255             int subid = getIdFromPath(req);\r
256             if (subid < 0) {\r
257                 message = "Missing or bad subscription number.";\r
258                 elr.setMessage(message);\r
259                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
260                 eventlogger.info(elr);\r
261                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
262                 return;\r
263             }\r
264             Subscription oldsub = Subscription.getSubscriptionById(subid);\r
265             if (oldsub == null) {\r
266                 message = "Missing or bad subscription number.";\r
267                 elr.setMessage(message);\r
268                 elr.setResult(HttpServletResponse.SC_NOT_FOUND);\r
269                 eventlogger.info(elr);\r
270                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
271                 return;\r
272             }\r
273             // Check with the Authorizer\r
274             AuthorizationResponse aresp = authz.decide(req);\r
275             if (!aresp.isAuthorized()) {\r
276                 message = "Policy Engine disallows access.";\r
277                 elr.setMessage(message);\r
278                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
279                 eventlogger.info(elr);\r
280                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
281                 return;\r
282             }\r
283             // check content type is SUB_CONTENT_TYPE, version 1.0\r
284             ContentHeader ch = getContentHeader(req);\r
285             String ver = ch.getAttribute("version");\r
286             if (!ch.getType().equals(SUB_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {\r
287                 message = "Incorrect content-type";\r
288                 elr.setMessage(message);\r
289                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);\r
290                 eventlogger.info(elr);\r
291                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);\r
292                 return;\r
293             }\r
294             JSONObject jo = getJSONfromInput(req);\r
295             if (jo == null) {\r
296                 message = "Badly formed JSON";\r
297                 elr.setMessage(message);\r
298                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
299                 eventlogger.info(elr);\r
300                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
301                 return;\r
302             }\r
303             if (intlogger.isDebugEnabled()) {\r
304                 intlogger.debug(jo.toString());\r
305             }\r
306             Subscription sub = null;\r
307             try {\r
308                 sub = new Subscription(jo);\r
309             } catch (InvalidObjectException e) {\r
310                 message = e.getMessage();\r
311                 elr.setMessage(message);\r
312                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
313                 eventlogger.info(elr);\r
314                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
315                 return;\r
316             }\r
317             sub.setSubid(oldsub.getSubid());\r
318             sub.setFeedid(oldsub.getFeedid());\r
319             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header\r
320 \r
321             String subjectgroup = (req.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")); //Adding for group feature:Rally US708115\r
322             if (!oldsub.getSubscriber().equals(sub.getSubscriber()) && subjectgroup == null) {\r
323                 message = "This subscriber must be modified by the same subscriber that created it.";\r
324                 elr.setMessage(message);\r
325                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
326                 eventlogger.info(elr);\r
327                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
328                 return;\r
329             }\r
330 \r
331             // Update SUBSCRIPTIONS table entries\r
332             if (doUpdate(sub)) {\r
333                 // send response\r
334                 elr.setResult(HttpServletResponse.SC_OK);\r
335                 eventlogger.info(elr);\r
336                 resp.setStatus(HttpServletResponse.SC_OK);\r
337                 resp.setContentType(SUBFULL_CONTENT_TYPE);\r
338                 try {\r
339                     resp.getOutputStream().print(sub.asLimitedJSONObject().toString());\r
340                 } catch (IOException ioe) {\r
341                     eventlogger.error("IOException: " + ioe.getMessage());\r
342                 }\r
343 \r
344                 /**Change Owner ship of Subscriber     Adding for group feature:Rally US708115*/\r
345                 if (jo.has("changeowner") && subjectgroup != null) {\r
346                     try {\r
347                         Boolean changeowner = (Boolean) jo.get("changeowner");\r
348                         if (changeowner != null && changeowner.equals(true)) {\r
349                             sub.setSubscriber(req.getHeader(BEHALF_HEADER));\r
350                             sub.changeOwnerShip();\r
351                         }\r
352                     } catch (JSONException je) {\r
353                         eventlogger.error("JSONException: " + je.getMessage());\r
354                     }\r
355                 }\r
356                 /***End of change ownership*/\r
357 \r
358                 provisioningDataChanged();\r
359             } else {\r
360                 // Something went wrong with the UPDATE\r
361                 elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
362                 eventlogger.info(elr);\r
363                 sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, intlogger);\r
364             }\r
365         } finally {\r
366             eelflogger.info(EelfMsgs.EXIT);\r
367         }\r
368     }\r
369 \r
370     /**\r
371      * POST on the &lt;subscriptionUrl&gt; -- control a subscription. See the <i>Resetting a Subscription's Retry\r
372      * Schedule</i> section in the <b>Provisioning API</b> document for details on how this method should be invoked.\r
373      */\r
374     @Override\r
375     public void doPost(HttpServletRequest req, HttpServletResponse resp) {\r
376 // OLD pre-3.0 code\r
377 //        String message = "POST not allowed for the subscriptionURL.";\r
378 //        EventLogRecord elr = new EventLogRecord(req);\r
379 //        elr.setMessage(message);\r
380 //        elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);\r
381 //        eventlogger.info(elr);\r
382 //        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, message);\r
383 \r
384         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);\r
385         eelflogger.info(EelfMsgs.ENTRY);\r
386         try {\r
387             eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER));\r
388             EventLogRecord elr = new EventLogRecord(req);\r
389             String message = isAuthorizedForProvisioning(req);\r
390             if (message != null) {\r
391                 elr.setMessage(message);\r
392                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
393                 eventlogger.info(elr);\r
394                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
395                 return;\r
396             }\r
397             if (isProxyServer()) {\r
398                 super.doPost(req, resp);\r
399                 return;\r
400             }\r
401             String bhdr = req.getHeader(BEHALF_HEADER);\r
402             if (bhdr == null) {\r
403                 message = "Missing " + BEHALF_HEADER + " header.";\r
404                 elr.setMessage(message);\r
405                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
406                 eventlogger.info(elr);\r
407                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
408                 return;\r
409             }\r
410             final int subid = getIdFromPath(req);\r
411             if (subid < 0 || Subscription.getSubscriptionById(subid) == null) {\r
412                 message = "Missing or bad subscription number.";\r
413                 elr.setMessage(message);\r
414                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
415                 eventlogger.info(elr);\r
416                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
417                 return;\r
418             }\r
419             // check content type is SUBCNTRL_CONTENT_TYPE, version 1.0\r
420             ContentHeader ch = getContentHeader(req);\r
421             String ver = ch.getAttribute("version");\r
422             if (!ch.getType().equals(SUBCNTRL_CONTENT_TYPE) || !ver.equals("1.0")) {\r
423                 message = "Incorrect content-type";\r
424                 elr.setMessage(message);\r
425                 elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);\r
426                 eventlogger.info(elr);\r
427                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);\r
428                 return;\r
429             }\r
430             // Check with the Authorizer\r
431             AuthorizationResponse aresp = authz.decide(req);\r
432             if (!aresp.isAuthorized()) {\r
433                 message = "Policy Engine disallows access.";\r
434                 elr.setMessage(message);\r
435                 elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
436                 eventlogger.info(elr);\r
437                 sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
438                 return;\r
439             }\r
440             JSONObject jo = getJSONfromInput(req);\r
441             if (jo == null) {\r
442                 message = "Badly formed JSON";\r
443                 elr.setMessage(message);\r
444                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
445                 eventlogger.info(elr);\r
446                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
447                 return;\r
448             }\r
449             try {\r
450                 // Only the active POD sends notifications\r
451                 boolean active = SynchronizerTask.getSynchronizer().isActive();\r
452                 boolean b = jo.getBoolean("failed");\r
453                 if (active && !b) {\r
454                     // Notify all nodes to reset the subscription\r
455                     SubscriberNotifyThread t = new SubscriberNotifyThread();\r
456                     t.resetSubscription(subid);\r
457                     t.start();\r
458                 }\r
459                 // send response\r
460                 elr.setResult(HttpServletResponse.SC_ACCEPTED);\r
461                 eventlogger.info(elr);\r
462                 resp.setStatus(HttpServletResponse.SC_ACCEPTED);\r
463             } catch (JSONException e) {\r
464                 message = "Badly formed JSON";\r
465                 elr.setMessage(message);\r
466                 elr.setResult(HttpServletResponse.SC_BAD_REQUEST);\r
467                 eventlogger.info(elr);\r
468                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
469             }\r
470         } finally {\r
471             eelflogger.info(EelfMsgs.EXIT);\r
472         }\r
473     }\r
474 \r
475     /**\r
476      * A Thread class used to serially send reset notifications to all nodes in the DR network, when a POST is received\r
477      * for a subscription.\r
478      */\r
479     public class SubscriberNotifyThread extends Thread {\r
480 \r
481         public static final String URL_TEMPLATE = "http://%s/internal/resetSubscription/%d";\r
482         private List<String> urls = new Vector<String>();\r
483 \r
484         public SubscriberNotifyThread() {\r
485             setName("SubscriberNotifyThread");\r
486         }\r
487 \r
488         public void resetSubscription(int subid) {\r
489             for (String nodename : BaseServlet.getNodes()) {\r
490                 String u = String.format(URL_TEMPLATE, nodename, subid);\r
491                 urls.add(u);\r
492             }\r
493         }\r
494 \r
495         public void run() {\r
496             try {\r
497                 while (!urls.isEmpty()) {\r
498                     String u = urls.remove(0);\r
499                     try {\r
500                         URL url = new URL(u);\r
501                         HttpURLConnection conn = (HttpURLConnection) url.openConnection();\r
502                         conn.connect();\r
503                         conn.getContentLength();    // Force the GET through\r
504                         conn.disconnect();\r
505                     } catch (IOException e) {\r
506                         intlogger.info("IOException Error accessing URL: " + u + ": " + e.getMessage());\r
507                     }\r
508                 }\r
509             } catch (Exception e) {\r
510                 intlogger.warn("Caught exception in SubscriberNotifyThread: " + e);\r
511             }\r
512         }\r
513     }\r
514 }\r