Removing clumsy code smells and adding missing JettyFilter test
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / beans / Subscription.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 package org.onap.dmaap.datarouter.provisioning.beans;\r
25 \r
26 import com.att.eelf.configuration.EELFLogger;\r
27 import com.att.eelf.configuration.EELFManager;\r
28 import java.io.InvalidObjectException;\r
29 import java.sql.Connection;\r
30 import java.sql.PreparedStatement;\r
31 import java.sql.ResultSet;\r
32 import java.sql.SQLException;\r
33 import java.sql.Statement;\r
34 import java.util.ArrayList;\r
35 import java.util.Collection;\r
36 import java.util.Date;\r
37 import java.util.List;\r
38 import java.util.Properties;\r
39 import org.json.JSONObject;\r
40 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
41 import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
42 \r
43 \r
44 /**\r
45  * The representation of a Subscription.  Subscriptions can be retrieved from the DB, or stored/updated in the DB.\r
46  *\r
47  * @author Robert Eby\r
48  * @version $Id: Subscription.java,v 1.9 2013/10/28 18:06:53 eby Exp $\r
49  */\r
50 public class Subscription extends Syncable {\r
51 \r
52     private static final String SQLEXCEPTION = "SQLException: ";\r
53     private static final String SUBID_KEY = "subid";\r
54     private static final String SUBID_COL = "SUBID";\r
55     private static final String FEEDID_KEY = "feedid";\r
56     private static final String GROUPID_KEY = "groupid";\r
57     private static final String LAST_MOD_KEY = "last_mod";\r
58     private static final String CREATED_DATE = "created_date";\r
59     private static EELFLogger intlogger = EELFManager.getInstance().getLogger("InternalLog");\r
60     private static int nextSubid = getMaxSubID() + 1;\r
61 \r
62     private int subid;\r
63     private int feedid;\r
64     private int groupid; //New field is added - Groups feature Rally:US708115 - 1610\r
65     private SubDelivery delivery;\r
66     private boolean followRedirect;\r
67     private boolean metadataOnly;\r
68     private String subscriber;\r
69     private SubLinks links;\r
70     private boolean suspended;\r
71     private Date lastMod;\r
72     private Date createdDate;\r
73     private boolean privilegedSubscriber;\r
74     private String aafInstance;\r
75     private boolean decompress;\r
76 \r
77     public static Subscription getSubscriptionMatching(Subscription sub) {\r
78         SubDelivery deli = sub.getDelivery();\r
79         String sql = String.format(\r
80                 "select * from SUBSCRIPTIONS where FEEDID = %d and DELIVERY_URL = \"%s\" and DELIVERY_USER = \"%s\" and DELIVERY_PASSWORD = \"%s\" and DELIVERY_USE100 = %d and METADATA_ONLY = %d and FOLLOW_REDIRECTS = %d",\r
81                 sub.getFeedid(),\r
82                 deli.getUrl(),\r
83                 deli.getUser(),\r
84                 deli.getPassword(),\r
85                 deli.isUse100() ? 1 : 0,\r
86                 sub.isMetadataOnly() ? 1 : 0,\r
87                 sub.isFollowRedirect() ? 1 :0\r
88         );\r
89         List<Subscription> list = getSubscriptionsForSQL(sql);\r
90         return !list.isEmpty() ? list.get(0) : null;\r
91     }\r
92 \r
93     public static Subscription getSubscriptionById(int id) {\r
94         String sql = "select * from SUBSCRIPTIONS where SUBID = " + id;\r
95         List<Subscription> list = getSubscriptionsForSQL(sql);\r
96         return !list.isEmpty() ? list.get(0) : null;\r
97     }\r
98 \r
99     public static Collection<Subscription> getAllSubscriptions() {\r
100         return getSubscriptionsForSQL("select * from SUBSCRIPTIONS");\r
101     }\r
102 \r
103     private static List<Subscription> getSubscriptionsForSQL(String sql) {\r
104         List<Subscription> list = new ArrayList<>();\r
105         try {\r
106             DB db = new DB();\r
107             @SuppressWarnings("resource")\r
108             Connection conn = db.getConnection();\r
109             try (Statement stmt = conn.createStatement()) {\r
110                 try (ResultSet rs = stmt.executeQuery(sql)) {\r
111                     while (rs.next()) {\r
112                         Subscription sub = new Subscription(rs);\r
113                         list.add(sub);\r
114                     }\r
115                 }\r
116             }\r
117             db.release(conn);\r
118         } catch (SQLException e) {\r
119             intlogger.error("PROV0001 getSubscriptionsForSQL: " + e.toString(), e);\r
120         }\r
121         return list;\r
122     }\r
123 \r
124     public static int getMaxSubID() {\r
125         int max = 0;\r
126         try {\r
127             DB db = new DB();\r
128             @SuppressWarnings("resource")\r
129             Connection conn = db.getConnection();\r
130             try (Statement stmt = conn.createStatement()) {\r
131                 try (ResultSet rs = stmt.executeQuery("select MAX(subid) from SUBSCRIPTIONS")) {\r
132                     if (rs.next()) {\r
133                         max = rs.getInt(1);\r
134                     }\r
135                 }\r
136             }\r
137             db.release(conn);\r
138         } catch (SQLException e) {\r
139             intlogger.info("getMaxSubID: " + e.getMessage(), e);\r
140         }\r
141         return max;\r
142     }\r
143 \r
144     public static Collection<String> getSubscriptionUrlList(int feedid) {\r
145         List<String> list = new ArrayList<>();\r
146         String sql = "select SUBID from SUBSCRIPTIONS where FEEDID = ?";\r
147 \r
148         try {\r
149             DB db = new DB();\r
150             @SuppressWarnings("resource")\r
151             Connection conn = db.getConnection();\r
152             try (PreparedStatement stmt = conn.prepareStatement(sql)) {\r
153                 stmt.setString(1, String.valueOf(feedid));\r
154                 try (ResultSet rs = stmt.executeQuery()) {\r
155                     while (rs.next()) {\r
156                         int subid = rs.getInt(SUBID_COL);\r
157                         list.add(URLUtilities.generateSubscriptionURL(subid));\r
158                     }\r
159                 }\r
160             }\r
161             db.release(conn);\r
162         } catch (SQLException e) {\r
163             intlogger.error(SQLEXCEPTION + e.getMessage(), e);\r
164         }\r
165         return list;\r
166     }\r
167 \r
168     /**\r
169      * Return a count of the number of active subscriptions in the DB.\r
170      *\r
171      * @return the count\r
172      */\r
173     public static int countActiveSubscriptions() {\r
174         int count = 0;\r
175         try {\r
176             DB db = new DB();\r
177             @SuppressWarnings("resource")\r
178             Connection conn = db.getConnection();\r
179             try (Statement stmt = conn.createStatement()) {\r
180                 try (ResultSet rs = stmt.executeQuery("select count(*) from SUBSCRIPTIONS")) {\r
181                     if (rs.next()) {\r
182                         count = rs.getInt(1);\r
183                     }\r
184                 }\r
185             }\r
186             db.release(conn);\r
187         } catch (SQLException e) {\r
188             intlogger.warn("PROV0008 countActiveSubscriptions: " + e.getMessage(), e);\r
189         }\r
190         return count;\r
191     }\r
192 \r
193     public Subscription() {\r
194         this("", "", "");\r
195     }\r
196 \r
197     public Subscription(String url, String user, String password) {\r
198         this.subid = -1;\r
199         this.feedid = -1;\r
200         this.groupid = -1; //New field is added - Groups feature Rally:US708115 - 1610\r
201         this.delivery = new SubDelivery(url, user, password, false);\r
202         this.metadataOnly = false;\r
203         this.followRedirect = false;\r
204         this.subscriber = "";\r
205         this.links = new SubLinks();\r
206         this.suspended = false;\r
207         this.lastMod = new Date();\r
208         this.createdDate = new Date();\r
209         this.privilegedSubscriber = false;\r
210         this.aafInstance = "";\r
211         this.decompress = false;\r
212     }\r
213 \r
214     public Subscription(ResultSet rs) throws SQLException {\r
215         this.subid = rs.getInt(SUBID_COL);\r
216         this.feedid = rs.getInt("FEEDID");\r
217         this.groupid = rs.getInt("GROUPID"); //New field is added - Groups feature Rally:US708115 - 1610\r
218         this.delivery = new SubDelivery(rs);\r
219         this.metadataOnly = rs.getBoolean("METADATA_ONLY");\r
220         this.followRedirect = rs.getBoolean("FOLLOW_REDIRECTS");\r
221         this.subscriber = rs.getString("SUBSCRIBER");\r
222         this.links = new SubLinks(rs.getString("SELF_LINK"), URLUtilities.generateFeedURL(feedid), rs.getString("LOG_LINK"));\r
223         this.suspended = rs.getBoolean("SUSPENDED");\r
224         this.lastMod = rs.getDate("LAST_MOD");\r
225         this.createdDate = rs.getDate("CREATED_DATE");\r
226         this.privilegedSubscriber = rs.getBoolean("PRIVILEGED_SUBSCRIBER");\r
227         this.aafInstance = rs.getString("AAF_INSTANCE");\r
228         this.decompress  = rs.getBoolean("DECOMPRESS");\r
229     }\r
230 \r
231     public Subscription(JSONObject jo) throws InvalidObjectException {\r
232         this("", "", "");\r
233         try {\r
234             // The JSONObject is assumed to contain a vnd.dmaap-dr.subscription representation\r
235             this.subid = jo.optInt(SUBID_KEY, -1);\r
236             this.feedid = jo.optInt(FEEDID_KEY, -1);\r
237             this.groupid = jo.optInt(GROUPID_KEY, -1); //New field is added - Groups feature Rally:US708115 - 1610\r
238             this.aafInstance = jo.optString("aaf_instance", "legacy");\r
239             if(!(aafInstance.equalsIgnoreCase("legacy")) && aafInstance.length() > 255) {\r
240                     throw new InvalidObjectException("aaf_instance field is too long");\r
241             }\r
242             JSONObject jdeli = jo.getJSONObject("delivery");\r
243             String url = jdeli.getString("url");\r
244             String user = jdeli.getString("user");\r
245             String password = jdeli.getString("password");\r
246             boolean use100 = jdeli.getBoolean("use100");\r
247 \r
248             //Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
249             Properties p = (new DB()).getProperties();\r
250             if (!url.startsWith("https://") && isHttpsRelaxationFalseAndHasSyncKey(jo, p)) {\r
251                 throw new InvalidObjectException("delivery URL is not HTTPS");\r
252             }\r
253 \r
254             if (url.length() > 256) {\r
255                 throw new InvalidObjectException("delivery url field is too long");\r
256             }\r
257             if (user.length() > 60) {\r
258                 throw new InvalidObjectException("delivery user field is too long");\r
259             }\r
260             if (password.length() > 32) {\r
261                 throw new InvalidObjectException("delivery password field is too long");\r
262             }\r
263             this.delivery = new SubDelivery(url, user, password, use100);\r
264             this.metadataOnly = jo.getBoolean("metadataOnly");\r
265             this.followRedirect = jo.optBoolean("follow_redirect", false);\r
266             this.suspended = jo.optBoolean("suspend", false);\r
267             this.privilegedSubscriber = jo.optBoolean("privilegedSubscriber", false);\r
268             this.decompress = jo.optBoolean("decompress", false);\r
269             this.subscriber = jo.optString("subscriber", "");\r
270             JSONObject jol = jo.optJSONObject("links");\r
271             this.links = (jol == null) ? (new SubLinks()) : (new SubLinks(jol));\r
272         } catch (InvalidObjectException e) {\r
273             throw e;\r
274         } catch (Exception e) {\r
275             intlogger.warn("Invalid JSON: " + e.getMessage(), e);\r
276             throw new InvalidObjectException("Invalid JSON: " + e.getMessage());\r
277         }\r
278     }\r
279 \r
280     private boolean isHttpsRelaxationFalseAndHasSyncKey(JSONObject jo, Properties p) {\r
281         return p.get("org.onap.dmaap.datarouter.provserver.https.relaxation").toString().equals("false") && !jo\r
282                 .has("sync");\r
283     }\r
284 \r
285     public int getSubid() {\r
286         return subid;\r
287     }\r
288 \r
289     public void setSubid(int subid) {\r
290         this.subid = subid;\r
291 \r
292         // Create link URLs\r
293         SubLinks sl = getLinks();\r
294         sl.setSelf(URLUtilities.generateSubscriptionURL(subid));\r
295         sl.setLog(URLUtilities.generateSubLogURL(subid));\r
296     }\r
297 \r
298     public int getFeedid() {\r
299         return feedid;\r
300     }\r
301 \r
302     public void setFeedid(int feedid) {\r
303         this.feedid = feedid;\r
304 \r
305         // Create link URLs\r
306         SubLinks sl = getLinks();\r
307         sl.setFeed(URLUtilities.generateFeedURL(feedid));\r
308     }\r
309     public String getAafInstance() {\r
310         return aafInstance;\r
311     }\r
312 \r
313     public void setAafInstance(String aafInstance) {\r
314         this.aafInstance = aafInstance;\r
315     }\r
316 \r
317     //New getter setters for Groups feature Rally:US708115 - 1610\r
318     public int getGroupid() {\r
319         return groupid;\r
320     }\r
321 \r
322     public void setGroupid(int groupid) {\r
323         this.groupid = groupid;\r
324     }\r
325 \r
326     public SubDelivery getDelivery() {\r
327         return delivery;\r
328     }\r
329 \r
330     public void setDelivery(SubDelivery delivery) {\r
331         this.delivery = delivery;\r
332     }\r
333 \r
334     public boolean isMetadataOnly() {\r
335         return metadataOnly;\r
336     }\r
337 \r
338     public void setMetadataOnly(boolean metadataOnly) {\r
339         this.metadataOnly = metadataOnly;\r
340     }\r
341 \r
342     private boolean isFollowRedirect() {\r
343         return followRedirect;\r
344     }\r
345     public void setFollowRedirect(boolean followRedirect) {\r
346         this.followRedirect = followRedirect;\r
347     }\r
348 \r
349     boolean isSuspended() {\r
350         return suspended;\r
351     }\r
352 \r
353     public void setSuspended(boolean suspended) {\r
354         this.suspended = suspended;\r
355     }\r
356 \r
357     public boolean isPrivilegedSubscriber() {\r
358         return privilegedSubscriber;\r
359     }\r
360 \r
361     public void setPrivilegedSubscriber(boolean privilegedSubscriber) {\r
362         this.privilegedSubscriber = privilegedSubscriber;\r
363     }\r
364 \r
365     public String getSubscriber() {\r
366         return subscriber;\r
367     }\r
368 \r
369     public void setSubscriber(String subscriber) {\r
370         if (subscriber != null) {\r
371             if (subscriber.length() > 8) {\r
372                 subscriber = subscriber.substring(0, 8);\r
373             }\r
374             this.subscriber = subscriber;\r
375         }\r
376     }\r
377 \r
378     public SubLinks getLinks() {\r
379         return links;\r
380     }\r
381 \r
382     void setLinks(SubLinks links) {\r
383         this.links = links;\r
384     }\r
385 \r
386     public boolean isDecompress() {\r
387         return decompress;\r
388     }\r
389 \r
390     public void setDecompress(boolean decompress) {\r
391         this.decompress = decompress;\r
392     }\r
393 \r
394     @Override\r
395     public JSONObject asJSONObject() {\r
396         JSONObject jo = new JSONObject();\r
397         jo.put(SUBID_KEY, subid);\r
398         jo.put(FEEDID_KEY, feedid);\r
399         jo.put(GROUPID_KEY, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
400         jo.put("delivery", delivery.asJSONObject());\r
401         jo.put("metadataOnly", metadataOnly);\r
402         jo.put("follow_redirect", followRedirect);\r
403         jo.put("subscriber", subscriber);\r
404         jo.put("links", links.asJSONObject());\r
405         jo.put("suspend", suspended);\r
406         jo.put(LAST_MOD_KEY, lastMod.getTime());\r
407         jo.put(CREATED_DATE, createdDate.getTime());\r
408         jo.put("privilegedSubscriber", privilegedSubscriber);\r
409         jo.put("aaf_instance", aafInstance);\r
410         jo.put("decompress", decompress);\r
411         return jo;\r
412     }\r
413 \r
414     public JSONObject asLimitedJSONObject() {\r
415         JSONObject jo = asJSONObject();\r
416         jo.remove(SUBID_KEY);\r
417         jo.remove(FEEDID_KEY);\r
418         jo.remove(LAST_MOD_KEY);\r
419         return jo;\r
420     }\r
421 \r
422     public JSONObject asJSONObject(boolean hidepasswords) {\r
423         JSONObject jo = asJSONObject();\r
424         if (hidepasswords) {\r
425             jo.remove(SUBID_KEY);    // we no longer hide passwords, however we do hide these\r
426             jo.remove(FEEDID_KEY);\r
427             jo.remove(LAST_MOD_KEY);\r
428             jo.remove(CREATED_DATE);\r
429         }\r
430         return jo;\r
431     }\r
432 \r
433     @Override\r
434     public boolean doInsert(Connection c) {\r
435         boolean rv = true;\r
436         PreparedStatement ps = null;\r
437         try {\r
438             if (subid == -1) {\r
439                 // No feed ID assigned yet, so assign the next available one\r
440                 setSubid(nextSubid++);\r
441             }\r
442             // In case we insert a feed from synchronization\r
443             if (subid > nextSubid) {\r
444                 nextSubid = subid + 1;\r
445             }\r
446 \r
447             // Create the SUBSCRIPTIONS row\r
448             String sql = "insert into SUBSCRIPTIONS (SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, PRIVILEGED_SUBSCRIBER, FOLLOW_REDIRECTS, DECOMPRESS, AAF_INSTANCE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";\r
449             ps = c.prepareStatement(sql, new String[]{SUBID_COL});\r
450             ps.setInt(1, subid);\r
451             ps.setInt(2, feedid);\r
452             ps.setString(3, getDelivery().getUrl());\r
453             ps.setString(4, getDelivery().getUser());\r
454             ps.setString(5, getDelivery().getPassword());\r
455             ps.setInt(6, getDelivery().isUse100() ? 1 : 0);\r
456             ps.setInt(7, isMetadataOnly() ? 1 : 0);\r
457             ps.setString(8, getSubscriber());\r
458             ps.setBoolean(9, isSuspended());\r
459             ps.setInt(10, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
460             ps.setBoolean(11, isPrivilegedSubscriber());\r
461             ps.setInt(12, isFollowRedirect() ? 1 : 0);\r
462             ps.setBoolean(13, isDecompress());\r
463             ps.setString(14, getAafInstance());\r
464             ps.execute();\r
465             ps.close();\r
466             // Update the row to set the URLs\r
467             sql = "update SUBSCRIPTIONS set SELF_LINK = ?, LOG_LINK = ? where SUBID = ?";\r
468             ps = c.prepareStatement(sql);\r
469             ps.setString(1, getLinks().getSelf());\r
470             ps.setString(2, getLinks().getLog());\r
471             ps.setInt(3, subid);\r
472             ps.execute();\r
473             ps.close();\r
474         } catch (SQLException e) {\r
475             rv = false;\r
476             intlogger.warn("PROV0005 doInsert: " + e.getMessage(), e);\r
477         } finally {\r
478             try {\r
479                 if (ps != null) {\r
480                     ps.close();\r
481                 }\r
482             } catch (SQLException e) {\r
483                 intlogger.error(SQLEXCEPTION + e.getMessage(), e);\r
484             }\r
485         }\r
486         return rv;\r
487     }\r
488 \r
489     @Override\r
490     public boolean doUpdate(Connection c) {\r
491         boolean rv = true;\r
492         PreparedStatement ps = null;\r
493         try {\r
494             String sql = "update SUBSCRIPTIONS set DELIVERY_URL = ?, DELIVERY_USER = ?, DELIVERY_PASSWORD = ?, DELIVERY_USE100 = ?, METADATA_ONLY = ?, SUSPENDED = ?, GROUPID = ?, PRIVILEGED_SUBSCRIBER = ?, FOLLOW_REDIRECTS = ?, DECOMPRESS = ? where SUBID = ?";\r
495             ps = c.prepareStatement(sql);\r
496             ps.setString(1, delivery.getUrl());\r
497             ps.setString(2, delivery.getUser());\r
498             ps.setString(3, delivery.getPassword());\r
499             ps.setInt(4, delivery.isUse100() ? 1 : 0);\r
500             ps.setInt(5, isMetadataOnly() ? 1 : 0);\r
501             ps.setInt(6, suspended ? 1 : 0);\r
502             ps.setInt(7, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
503             ps.setInt(8, privilegedSubscriber ? 1 : 0);\r
504             ps.setInt(9, isFollowRedirect() ? 1 : 0);\r
505             ps.setInt(10, isDecompress() ? 1 : 0);\r
506             ps.setInt(11, subid);\r
507             ps.executeUpdate();\r
508         } catch (SQLException e) {\r
509             rv = false;\r
510             intlogger.warn("PROV0006 doUpdate: " + e.getMessage(), e);\r
511         } finally {\r
512             try {\r
513                 if (ps != null) {\r
514                     ps.close();\r
515                 }\r
516             } catch (SQLException e) {\r
517                 intlogger.error(SQLEXCEPTION + e.getMessage(), e);\r
518             }\r
519         }\r
520         return rv;\r
521     }\r
522 \r
523 \r
524     /**\r
525      * Rally US708115 Change Ownership of Subscription - 1610\r
526      */\r
527     public boolean changeOwnerShip() {\r
528         boolean rv = true;\r
529         PreparedStatement ps = null;\r
530         try {\r
531 \r
532             DB db = new DB();\r
533             @SuppressWarnings("resource")\r
534             Connection c = db.getConnection();\r
535             String sql = "update SUBSCRIPTIONS set SUBSCRIBER = ? where SUBID = ?";\r
536             ps = c.prepareStatement(sql);\r
537             ps.setString(1, this.subscriber);\r
538             ps.setInt(2, subid);\r
539             ps.execute();\r
540             ps.close();\r
541         } catch (SQLException e) {\r
542             rv = false;\r
543             intlogger.warn("PROV0006 doUpdate: " + e.getMessage(), e);\r
544         } finally {\r
545             try {\r
546                 if (ps != null) {\r
547                     ps.close();\r
548                 }\r
549             } catch (SQLException e) {\r
550                 intlogger.error(SQLEXCEPTION + e.getMessage(), e);\r
551             }\r
552         }\r
553         return rv;\r
554     }\r
555 \r
556 \r
557     @Override\r
558     public boolean doDelete(Connection c) {\r
559         boolean rv = true;\r
560         PreparedStatement ps = null;\r
561         try {\r
562             String sql = "delete from SUBSCRIPTIONS where SUBID = ?";\r
563             ps = c.prepareStatement(sql);\r
564             ps.setInt(1, subid);\r
565             ps.execute();\r
566         } catch (SQLException e) {\r
567             rv = false;\r
568             intlogger.warn("PROV0007 doDelete: " + e.getMessage(), e);\r
569         } finally {\r
570             try {\r
571                 if (ps != null) {\r
572                     ps.close();\r
573                 }\r
574             } catch (SQLException e) {\r
575                 intlogger.error(SQLEXCEPTION + e.getMessage(), e);\r
576             }\r
577         }\r
578         return rv;\r
579     }\r
580 \r
581     @Override\r
582     public String getKey() {\r
583         return "" + getSubid();\r
584     }\r
585 \r
586     @Override\r
587     public boolean equals(Object obj) {\r
588         if (!(obj instanceof Subscription)) {\r
589             return false;\r
590         }\r
591         Subscription os = (Subscription) obj;\r
592         if (subid != os.subid) {\r
593             return false;\r
594         }\r
595         if (feedid != os.feedid) {\r
596             return false;\r
597         }\r
598         if (groupid != os.groupid) {\r
599             //New field is added - Groups feature Rally:US708115 - 1610\r
600             return false;\r
601         }\r
602         if (!delivery.equals(os.delivery)) {\r
603             return false;\r
604         }\r
605         if (metadataOnly != os.metadataOnly) {\r
606             return false;\r
607         }\r
608         if (followRedirect != os.followRedirect) {\r
609             return false;\r
610         }\r
611         if (!subscriber.equals(os.subscriber)) {\r
612             return false;\r
613         }\r
614         if (!links.equals(os.links)) {\r
615             return false;\r
616         }\r
617         if (suspended != os.suspended) {\r
618             return false;\r
619         }\r
620         if (!aafInstance.equals(os.aafInstance)) {\r
621             return false;\r
622         }\r
623         return true;\r
624     }\r
625 \r
626     @Override\r
627     public int hashCode() {\r
628         return super.hashCode();\r
629     }\r
630 \r
631     @Override\r
632     public String toString() {\r
633         return "SUB: subid=" + subid + ", feedid=" + feedid;\r
634     }\r
635 }\r