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