[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / com / att / research / datarouter / provisioning / beans / Feed.java
diff --git a/datarouter-prov/src/main/java/com/att/research/datarouter/provisioning/beans/Feed.java b/datarouter-prov/src/main/java/com/att/research/datarouter/provisioning/beans/Feed.java
new file mode 100644 (file)
index 0000000..4ee5ab9
--- /dev/null
@@ -0,0 +1,760 @@
+/*******************************************************************************\r
+ * ============LICENSE_START==================================================\r
+ * * org.onap.dmaap\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+\r
+\r
+package com.att.research.datarouter.provisioning.beans;\r
+\r
+import java.io.InvalidObjectException;\r
+import java.sql.Connection;\r
+import java.sql.PreparedStatement;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.json.JSONArray;\r
+import org.json.JSONObject;\r
+\r
+import com.att.research.datarouter.provisioning.utils.DB;\r
+import com.att.research.datarouter.provisioning.utils.JSONUtilities;\r
+import com.att.research.datarouter.provisioning.utils.URLUtilities;\r
+\r
+/**\r
+ * The representation of a Feed.  Feeds can be retrieved from the DB, or stored/updated in the DB.\r
+ * @author Robert Eby\r
+ * @version $Id: Feed.java,v 1.13 2013/10/28 18:06:52 eby Exp $\r
+ */\r
+public class Feed extends Syncable {\r
+       private static Logger intlogger = Logger.getLogger("com.att.research.datarouter.provisioning.internal");\r
+       private static int next_feedid = getMaxFeedID() + 1;\r
+\r
+       private int feedid;\r
+       private int groupid; //New field is added - Groups feature Rally:US708115 - 1610\r
+       private String name;\r
+       private String version;\r
+       private String description;\r
+       private String business_description; // New field is added - Groups feature Rally:US708102 - 1610\r
+       private FeedAuthorization authorization;\r
+       private String publisher;\r
+       private FeedLinks links;\r
+       private boolean deleted;\r
+       private boolean suspended;\r
+       private Date last_mod;\r
+       private Date created_date;\r
+\r
+       /**\r
+        * Check if a feed ID is valid.\r
+        * @param id the Feed ID\r
+        * @return true if it is valid\r
+        */\r
+       @SuppressWarnings("resource")\r
+       public static boolean isFeedValid(int id) {\r
+               int count = 0;\r
+               try {\r
+                       DB db = new DB();\r
+                       Connection conn = db.getConnection();\r
+                       Statement  stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery("select COUNT(*) from FEEDS where FEEDID = " + id);\r
+                       if (rs.next()) {\r
+                               count = rs.getInt(1);\r
+                       }\r
+                       rs.close();\r
+                       stmt.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return count != 0;\r
+       }\r
+       /**\r
+        * Get a specific feed from the DB, based upon its ID.\r
+        * @param id the Feed ID\r
+        * @return the Feed object, or null if it does not exist\r
+        */\r
+       public static Feed getFeedById(int id) {\r
+               String sql = "select * from FEEDS where FEEDID = " + id;\r
+               return getFeedBySQL(sql);\r
+       }\r
+       /**\r
+        * Get a specific feed from the DB, based upon its name and version.\r
+        * @param name the name of the Feed\r
+        * @param version the version of the Feed\r
+        * @return the Feed object, or null if it does not exist\r
+        */\r
+       public static Feed getFeedByNameVersion(String name, String version) {\r
+               name = name.replaceAll("'", "''");\r
+               version = version.replaceAll("'", "''");\r
+               String sql = "select * from FEEDS where NAME = '" + name + "' and VERSION ='" + version + "'";\r
+               return getFeedBySQL(sql);\r
+       }\r
+       /**\r
+        * Return a count of the number of active feeds in the DB.\r
+        * @return the count\r
+        */\r
+       public static int countActiveFeeds() {\r
+               int count = 0;\r
+               try {\r
+                       DB db = new DB();\r
+                       @SuppressWarnings("resource")\r
+                       Connection conn = db.getConnection();\r
+                       Statement  stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery("select count(*) from FEEDS where DELETED = 0");\r
+                       if (rs.next()) {\r
+                               count = rs.getInt(1);\r
+                       }\r
+                       rs.close();\r
+                       stmt.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       intlogger.info("countActiveFeeds: "+e.getMessage());\r
+                       e.printStackTrace();\r
+               }\r
+               return count;\r
+       }\r
+       public static int getMaxFeedID() {\r
+               int max = 0;\r
+               try {\r
+                       DB db = new DB();\r
+                       @SuppressWarnings("resource")\r
+                       Connection conn = db.getConnection();\r
+                       Statement  stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery("select MAX(feedid) from FEEDS");\r
+                       if (rs.next()) {\r
+                               max = rs.getInt(1);\r
+                       }\r
+                       rs.close();\r
+                       stmt.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       intlogger.info("getMaxFeedID: "+e.getMessage());\r
+                       e.printStackTrace();\r
+               }\r
+               return max;\r
+       }\r
+       public static Collection<Feed> getAllFeeds() {\r
+               Map<Integer, Feed> map = new HashMap<Integer, Feed>();\r
+               try {\r
+                       DB db = new DB();\r
+                       @SuppressWarnings("resource")\r
+                       Connection conn = db.getConnection();\r
+                       Statement  stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery("select * from FEEDS");\r
+                       while (rs.next()) {\r
+                               Feed feed = new Feed(rs);\r
+                               map.put(feed.getFeedid(), feed);\r
+                       }\r
+                       rs.close();\r
+\r
+                       String sql = "select * from FEED_ENDPOINT_IDS";\r
+                       rs = stmt.executeQuery(sql);\r
+                       while (rs.next()) {\r
+                               int id = rs.getInt("FEEDID");\r
+                               Feed feed = map.get(id);\r
+                               if (feed != null) {\r
+                                       FeedEndpointID epi = new FeedEndpointID(rs);\r
+                                       Collection<FeedEndpointID> ecoll = feed.getAuthorization().getEndpoint_ids();\r
+                                       ecoll.add(epi);\r
+                               }\r
+                       }\r
+                       rs.close();\r
+\r
+                       sql = "select * from FEED_ENDPOINT_ADDRS";\r
+                       rs = stmt.executeQuery(sql);\r
+                       while (rs.next()) {\r
+                               int id = rs.getInt("FEEDID");\r
+                               Feed feed = map.get(id);\r
+                               if (feed != null) {\r
+                                       Collection<String> acoll = feed.getAuthorization().getEndpoint_addrs();\r
+                                       acoll.add(rs.getString("ADDR"));\r
+                               }\r
+                       }\r
+                       rs.close();\r
+\r
+                       stmt.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return map.values();\r
+       }\r
+       public static List<String> getFilteredFeedUrlList(final String name, final String val) {\r
+               List<String> list = new ArrayList<String>();\r
+               String sql = "select SELF_LINK from FEEDS where DELETED = 0";\r
+               if (name.equals("name")) {\r
+                       sql += " and NAME = ?";\r
+               } else if (name.equals("publ")) {\r
+                       sql += " and PUBLISHER = ?";\r
+               } else if (name.equals("subs")) {\r
+                       sql = "select distinct FEEDS.SELF_LINK from FEEDS, SUBSCRIPTIONS " +\r
+                               "where DELETED = 0 " +\r
+                               "and FEEDS.FEEDID = SUBSCRIPTIONS.FEEDID " +\r
+                               "and SUBSCRIPTIONS.SUBSCRIBER = ?";\r
+               }\r
+               try {\r
+                       DB db = new DB();\r
+                       @SuppressWarnings("resource")\r
+                       Connection conn = db.getConnection();\r
+                       PreparedStatement ps = conn.prepareStatement(sql);\r
+                       if (sql.indexOf('?') >= 0)\r
+                               ps.setString(1, val);\r
+                       ResultSet rs = ps.executeQuery();\r
+                       while (rs.next()) {\r
+                               String t = rs.getString(1);\r
+                               list.add(t.trim());\r
+                       }\r
+                       rs.close();\r
+                       ps.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return list;\r
+       }\r
+       @SuppressWarnings("resource")\r
+       private static Feed getFeedBySQL(String sql) {\r
+               Feed feed = null;\r
+               try {\r
+                       DB db = new DB();\r
+                       Connection conn = db.getConnection();\r
+                       Statement  stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery(sql);\r
+                       if (rs.next()) {\r
+                               feed = new Feed(rs);\r
+                               rs.close();\r
+\r
+                               sql = "select * from FEED_ENDPOINT_IDS where FEEDID = " + feed.feedid;\r
+                               rs = stmt.executeQuery(sql);\r
+                               Collection<FeedEndpointID> ecoll = feed.getAuthorization().getEndpoint_ids();\r
+                               while (rs.next()) {\r
+                                       FeedEndpointID epi = new FeedEndpointID(rs);\r
+                                       ecoll.add(epi);\r
+                               }\r
+                               rs.close();\r
+\r
+                               sql = "select * from FEED_ENDPOINT_ADDRS where FEEDID = " + feed.feedid;\r
+                               rs = stmt.executeQuery(sql);\r
+                               Collection<String> acoll = feed.getAuthorization().getEndpoint_addrs();\r
+                               while (rs.next()) {\r
+                                       acoll.add(rs.getString("ADDR"));\r
+                               }\r
+                       }\r
+                       rs.close();\r
+                       stmt.close();\r
+                       db.release(conn);\r
+               } catch (SQLException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return feed;\r
+       }\r
+\r
+       public Feed() {\r
+               this("", "", "","");\r
+       }\r
+\r
+       public Feed(String name, String version, String desc,String business_description) {\r
+               this.feedid = -1;\r
+               this.groupid = -1; //New field is added - Groups feature Rally:US708115 - 1610\r
+               this.name = name;\r
+               this.version = version;\r
+               this.description = desc;\r
+               this.business_description=business_description; // New field is added - Groups feature Rally:US708102 - 1610\r
+               this.authorization = new FeedAuthorization();\r
+               this.publisher = "";\r
+               this.links = new FeedLinks();\r
+               this.deleted = false;\r
+               this.suspended = false;\r
+               this.last_mod = new Date();\r
+               this.created_date = new Date();\r
+       }\r
+       public Feed(ResultSet rs) throws SQLException {\r
+               this.feedid = rs.getInt("FEEDID");\r
+               this.groupid = rs.getInt("GROUPID"); //New field is added - Groups feature Rally:US708115 - 1610\r
+               this.name = rs.getString("NAME");\r
+               this.version = rs.getString("VERSION");\r
+               this.description = rs.getString("DESCRIPTION");\r
+               this.business_description=rs.getString("BUSINESS_DESCRIPTION"); // New field is added - Groups feature Rally:US708102 - 1610\r
+               this.authorization = new FeedAuthorization();\r
+               this.authorization.setClassification(rs.getString("AUTH_CLASS"));\r
+               this.publisher   = rs.getString("PUBLISHER");\r
+               this.links       = new FeedLinks();\r
+               this.links.setSelf(rs.getString("SELF_LINK"));\r
+               this.links.setPublish(rs.getString("PUBLISH_LINK"));\r
+               this.links.setSubscribe(rs.getString("SUBSCRIBE_LINK"));\r
+               this.links.setLog(rs.getString("LOG_LINK"));\r
+               this.deleted     = rs.getBoolean("DELETED");\r
+               this.suspended   = rs.getBoolean("SUSPENDED");\r
+               this.last_mod    = rs.getDate("LAST_MOD");\r
+               this.created_date    = rs.getTimestamp("CREATED_DATE");\r
+       }\r
+       public Feed(JSONObject jo) throws InvalidObjectException {\r
+               this("", "", "","");\r
+               try {\r
+                       // The JSONObject is assumed to contain a vnd.att-dr.feed representation\r
+                       this.feedid = jo.optInt("feedid", -1);\r
+                       this.groupid = jo.optInt("groupid"); //New field is added - Groups feature Rally:US708115 - 1610\r
+                       this.name = jo.getString("name");\r
+                       if (name.length() > 255)\r
+                               throw new InvalidObjectException("name field is too long");\r
+                       this.version = jo.getString("version");\r
+                       if (version.length() > 20)\r
+                               throw new InvalidObjectException("version field is too long");\r
+                       this.description = jo.optString("description");\r
+                       this.business_description = jo.optString("business_description"); // New field is added - Groups feature Rally:US708102 - 1610\r
+                       if (description.length() > 1000)\r
+                               throw new InvalidObjectException("technical description field is too long");\r
+                       \r
+                       if (business_description.length() > 1000) // New field is added - Groups feature Rally:US708102 - 1610\r
+                               throw new InvalidObjectException("business description field is too long");\r
+\r
+                       this.authorization = new FeedAuthorization();\r
+                       JSONObject jauth = jo.getJSONObject("authorization");\r
+                       this.authorization.setClassification(jauth.getString("classification"));\r
+                       if (this.authorization.getClassification().length() > 32)\r
+                               throw new InvalidObjectException("classification field is too long");\r
+                       JSONArray ja = jauth.getJSONArray("endpoint_ids");\r
+                       for (int i = 0; i < ja.length(); i++) {\r
+                               JSONObject id = ja.getJSONObject(i);\r
+                               FeedEndpointID fid = new FeedEndpointID(id.getString("id"), id.getString("password"));\r
+                               if (fid.getId().length() > 20)\r
+                                       throw new InvalidObjectException("id field is too long ("+fid.getId()+")");\r
+                               if (fid.getPassword().length() > 32)\r
+                                       throw new InvalidObjectException("password field is too long ("+fid.getPassword()+")");\r
+                               this.authorization.getEndpoint_ids().add(fid);\r
+                       }\r
+                       if (this.authorization.getEndpoint_ids().size() < 1)\r
+                               throw new InvalidObjectException("need to specify at least one endpoint_id");\r
+                       ja = jauth.getJSONArray("endpoint_addrs");\r
+                       for (int i = 0; i < ja.length(); i++) {\r
+                               String addr = ja.getString(i);\r
+                               if (!JSONUtilities.validIPAddrOrSubnet(addr))\r
+                                       throw new InvalidObjectException("bad IP addr or subnet mask: "+addr);\r
+                               this.authorization.getEndpoint_addrs().add(addr);\r
+                       }\r
+\r
+                       this.publisher = jo.optString("publisher", "");\r
+                       this.deleted   = jo.optBoolean("deleted", false);\r
+                       this.suspended = jo.optBoolean("suspend", false);\r
+                       JSONObject jol = jo.optJSONObject("links");\r
+                       this.links = (jol == null) ? (new FeedLinks()) : (new FeedLinks(jol));\r
+               } catch (InvalidObjectException e) {\r
+                       throw e;\r
+               } catch (Exception e) {\r
+                       throw new InvalidObjectException("invalid JSON: "+e.getMessage());\r
+               }\r
+       }\r
+       public int getFeedid() {\r
+               return feedid;\r
+       }\r
+       public void setFeedid(int feedid) {\r
+               this.feedid = feedid;\r
+\r
+               // Create link URLs\r
+               FeedLinks fl = getLinks();\r
+               fl.setSelf(URLUtilities.generateFeedURL(feedid));\r
+               fl.setPublish(URLUtilities.generatePublishURL(feedid));\r
+               fl.setSubscribe(URLUtilities.generateSubscribeURL(feedid));\r
+               fl.setLog(URLUtilities.generateFeedLogURL(feedid));\r
+       }\r
+       \r
+       //new getter setters for groups- Rally:US708115 - 1610\r
+       public int getGroupid() {\r
+               return groupid;\r
+       }\r
+\r
+       public void setGroupid(int groupid) {\r
+               this.groupid = groupid;\r
+       }\r
+       \r
+       public String getName() {\r
+               return name;\r
+       }\r
+       public void setName(String name) {\r
+               this.name = name;\r
+       }\r
+       public String getVersion() {\r
+               return version;\r
+       }\r
+       public void setVersion(String version) {\r
+               this.version = version;\r
+       }\r
+       public String getDescription() {\r
+               return description;\r
+       }\r
+       public void setDescription(String description) {\r
+               this.description = description;\r
+       }\r
+    // New field is added - Groups feature Rally:US708102 - 1610\r
+       public String getBusiness_description() {\r
+               return business_description;\r
+       }\r
+\r
+       public void setBusiness_description(String business_description) {\r
+               this.business_description = business_description;\r
+       }\r
+\r
+       public FeedAuthorization getAuthorization() {\r
+               return authorization;\r
+       }\r
+       public void setAuthorization(FeedAuthorization authorization) {\r
+               this.authorization = authorization;\r
+       }\r
+       public String getPublisher() {\r
+               return publisher;\r
+       }\r
+       public void setPublisher(String publisher) {\r
+               if (publisher != null) {\r
+                       if (publisher.length() > 8)\r
+                               publisher = publisher.substring(0, 8);\r
+                       this.publisher = publisher;\r
+               }\r
+       }\r
+       public FeedLinks getLinks() {\r
+               return links;\r
+       }\r
+       public void setLinks(FeedLinks links) {\r
+               this.links = links;\r
+       }\r
+\r
+       public boolean isDeleted() {\r
+               return deleted;\r
+       }\r
+\r
+       public void setDeleted(boolean deleted) {\r
+               this.deleted = deleted;\r
+       }\r
+\r
+       public boolean isSuspended() {\r
+               return suspended;\r
+       }\r
+\r
+       public void setSuspended(boolean suspended) {\r
+               this.suspended = suspended;\r
+       }\r
+\r
+       public Date getLast_mod() {\r
+               return last_mod;\r
+       }\r
+\r
+       public Date getCreated_date() {\r
+               return created_date;\r
+       }\r
+\r
+       @Override\r
+       public JSONObject asJSONObject() {\r
+               JSONObject jo = new JSONObject();\r
+               jo.put("feedid", feedid);\r
+               jo.put("groupid", groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
+               jo.put("name", name);\r
+               jo.put("version", version);\r
+               jo.put("description", description);\r
+               jo.put("business_description", business_description); // New field is added - Groups feature Rally:US708102 - 1610\r
+               jo.put("authorization", authorization.asJSONObject());\r
+               jo.put("publisher", publisher);\r
+               jo.put("links", links.asJSONObject());\r
+               jo.put("deleted", deleted);\r
+               jo.put("suspend", suspended);\r
+               jo.put("last_mod", last_mod.getTime());\r
+               jo.put("created_date", created_date.getTime());\r
+               return jo;\r
+       }\r
+       public JSONObject asLimitedJSONObject() {\r
+               JSONObject jo = asJSONObject();\r
+               jo.remove("deleted");\r
+               jo.remove("feedid");\r
+               jo.remove("last_mod");\r
+               jo.remove("created_date");\r
+               return jo;\r
+       }\r
+       public JSONObject asJSONObject(boolean hidepasswords) {\r
+               JSONObject jo = asJSONObject();\r
+               if (hidepasswords) {\r
+                       jo.remove("feedid");    // we no longer hide passwords, however we do hide these\r
+                       jo.remove("deleted");\r
+                       jo.remove("last_mod");\r
+                       jo.remove("created_date");\r
+               }\r
+               return jo;\r
+       }\r
+       @Override\r
+       public boolean doDelete(Connection c) {\r
+               boolean rv = true;\r
+               PreparedStatement ps = null;\r
+               try {\r
+                       String sql = "delete from FEEDS where FEEDID = ?";\r
+                       ps = c.prepareStatement(sql);\r
+                       ps.setInt(1, feedid);\r
+                       ps.execute();\r
+               } catch (SQLException e) {\r
+                       rv = false;\r
+                       intlogger.warn("PROV0007 doDelete: "+e.getMessage());\r
+                       e.printStackTrace();\r
+               } finally {\r
+                       try {\r
+                               ps.close();\r
+                       } catch (SQLException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               return rv;\r
+       }\r
+       @Override\r
+       public synchronized boolean doInsert(Connection c) {\r
+               boolean rv = true;\r
+//             PreparedStatement ps = null;\r
+               try {\r
+                       if (feedid == -1) {\r
+//                             // Get the next feedid\r
+//                             String sql = "insert into FEEDS_UNIQUEID (FEEDID) values (0)";\r
+//                             ps = c.prepareStatement(sql, new String[] { "FEEDID" });\r
+//                             ps.execute();\r
+//                             ResultSet rs = ps.getGeneratedKeys();\r
+//                             rs.first();\r
+//                             setFeedid(rs.getInt(1));\r
+                               // No feed ID assigned yet, so assign the next available one\r
+                               setFeedid(next_feedid++);\r
+                       }\r
+                       // In case we insert a feed from synchronization\r
+                       if (feedid > next_feedid)\r
+                               next_feedid = feedid+1;\r
+\r
+                       // Create FEED_ENDPOINT_IDS rows\r
+                       FeedAuthorization auth = getAuthorization();\r
+                       String sql = "insert into FEED_ENDPOINT_IDS values (?, ?, ?)";\r
+                       PreparedStatement ps2 = c.prepareStatement(sql);\r
+                       for (FeedEndpointID fid : auth.getEndpoint_ids()) {\r
+                               ps2.setInt(1, feedid);\r
+                               ps2.setString(2, fid.getId());\r
+                               ps2.setString(3, fid.getPassword());\r
+                               ps2.executeUpdate();\r
+                       }\r
+                       ps2.close();\r
+\r
+                       // Create FEED_ENDPOINT_ADDRS rows\r
+                       sql = "insert into FEED_ENDPOINT_ADDRS values (?, ?)";\r
+                       ps2 = c.prepareStatement(sql);\r
+                       for (String t : auth.getEndpoint_addrs()) {\r
+                               ps2.setInt(1, feedid);\r
+                               ps2.setString(2, t);\r
+                               ps2.executeUpdate();\r
+                       }\r
+                       ps2.close();\r
+\r
+                       // Finally, create the FEEDS row\r
+                       sql = "insert into FEEDS (FEEDID, NAME, VERSION, DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK, DELETED, SUSPENDED,BUSINESS_DESCRIPTION, GROUPID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)";\r
+                       ps2 = c.prepareStatement(sql);\r
+                       ps2.setInt(1, feedid);\r
+                       ps2.setString(2, getName());\r
+                       ps2.setString(3, getVersion());\r
+                       ps2.setString(4, getDescription());\r
+                       ps2.setString(5, getAuthorization().getClassification());\r
+                       ps2.setString(6, getPublisher());\r
+                       ps2.setString(7, getLinks().getSelf());\r
+                       ps2.setString(8, getLinks().getPublish());\r
+                       ps2.setString(9, getLinks().getSubscribe());\r
+                       ps2.setString(10, getLinks().getLog());\r
+                       ps2.setBoolean(11, isDeleted());\r
+                       ps2.setBoolean(12, isSuspended());\r
+                       ps2.setString(13,getBusiness_description()); // New field is added - Groups feature Rally:US708102 - 1610\r
+                       ps2.setInt(14,groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
+                       ps2.executeUpdate();\r
+                       ps2.close();\r
+               } catch (SQLException e) {\r
+                       rv = false;\r
+                       intlogger.warn("PROV0005 doInsert: "+e.getMessage());\r
+                       e.printStackTrace();\r
+//             } finally {\r
+//                     try {\r
+//                             ps.close();\r
+//                     } catch (SQLException e) {\r
+//                             e.printStackTrace();\r
+//                     }\r
+               }\r
+               return rv;\r
+       }\r
+       @Override\r
+       public boolean doUpdate(Connection c) {\r
+               boolean rv = true;\r
+               Feed oldobj = getFeedById(feedid);\r
+               PreparedStatement ps = null;\r
+               try {\r
+                       Set<FeedEndpointID> newset = getAuthorization().getEndpoint_ids();\r
+                       Set<FeedEndpointID> oldset = oldobj.getAuthorization().getEndpoint_ids();\r
+\r
+                       // Insert new FEED_ENDPOINT_IDS rows\r
+                       String sql = "insert into FEED_ENDPOINT_IDS values (?, ?, ?)";\r
+                       ps = c.prepareStatement(sql);\r
+                       for (FeedEndpointID fid : newset) {\r
+                               if (!oldset.contains(fid)) {\r
+                                       ps.setInt(1, feedid);\r
+                                       ps.setString(2, fid.getId());\r
+                                       ps.setString(3, fid.getPassword());\r
+                                       ps.executeUpdate();\r
+                               }\r
+                       }\r
+                       ps.close();\r
+\r
+                       // Delete old FEED_ENDPOINT_IDS rows\r
+                       sql = "delete from FEED_ENDPOINT_IDS where FEEDID = ? AND USERID = ? AND PASSWORD = ?";\r
+                       ps = c.prepareStatement(sql);\r
+                       for (FeedEndpointID fid : oldset) {\r
+                               if (!newset.contains(fid)) {\r
+                                       ps.setInt(1, feedid);\r
+                                       ps.setString(2, fid.getId());\r
+                                       ps.setString(3, fid.getPassword());\r
+                                       ps.executeUpdate();\r
+                               }\r
+                       }\r
+                       ps.close();\r
+\r
+                       // Insert new FEED_ENDPOINT_ADDRS rows\r
+                       Set<String> newset2 = getAuthorization().getEndpoint_addrs();\r
+                       Set<String> oldset2 = oldobj.getAuthorization().getEndpoint_addrs();\r
+                       sql = "insert into FEED_ENDPOINT_ADDRS values (?, ?)";\r
+                       ps = c.prepareStatement(sql);\r
+                       for (String t : newset2) {\r
+                               if (!oldset2.contains(t)) {\r
+                                       ps.setInt(1, feedid);\r
+                                       ps.setString(2, t);\r
+                                       ps.executeUpdate();\r
+                               }\r
+                       }\r
+                       ps.close();\r
+\r
+                       // Delete old FEED_ENDPOINT_ADDRS rows\r
+                       sql = "delete from FEED_ENDPOINT_ADDRS where FEEDID = ? AND ADDR = ?";\r
+                       ps = c.prepareStatement(sql);\r
+                       for (String t : oldset2) {\r
+                               if (!newset2.contains(t)) {\r
+                                       ps.setInt(1, feedid);\r
+                                       ps.setString(2, t);\r
+                                       ps.executeUpdate();\r
+                               }\r
+                       }\r
+                       ps.close();\r
+\r
+                       // Finally, update the FEEDS row\r
+                       sql = "update FEEDS set DESCRIPTION = ?, AUTH_CLASS = ?, DELETED = ?, SUSPENDED = ?, BUSINESS_DESCRIPTION=?, GROUPID=? where FEEDID = ?";\r
+                       ps = c.prepareStatement(sql);\r
+                       ps.setString(1, getDescription());\r
+                       ps.setString(2, getAuthorization().getClassification());\r
+                       ps.setInt(3, deleted ? 1 : 0);\r
+                       ps.setInt(4, suspended ? 1 : 0);\r
+                       ps.setString(5, getBusiness_description()); // New field is added - Groups feature Rally:US708102 - 1610\r
+                       ps.setInt(6, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
+                       ps.setInt(7, feedid);\r
+                       ps.executeUpdate();\r
+                       ps.close();\r
+               } catch (SQLException e) {\r
+                       rv = false;\r
+                       intlogger.warn("PROV0006 doUpdate: "+e.getMessage());\r
+                       e.printStackTrace();\r
+               } finally {\r
+                       try {\r
+                               if (ps != null)\r
+                                       ps.close();\r
+                       } catch (SQLException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               return rv;\r
+       }\r
+       \r
+       /**Rally US708115\r
+        * Change Ownership of FEED - 1610\r
+        * */\r
+       public boolean changeOwnerShip() {\r
+               boolean rv = true;\r
+               PreparedStatement ps = null;\r
+               try {\r
+                       \r
+                       DB db = new DB();\r
+                       @SuppressWarnings("resource")\r
+                       Connection c = db.getConnection();\r
+                       String sql = "update FEEDS set PUBLISHER = ? where FEEDID = ?";\r
+                       ps = c.prepareStatement(sql);\r
+                       ps.setString(1, this.publisher);\r
+                       ps.setInt(2, feedid);\r
+                       ps.execute();\r
+                       ps.close();\r
+               } catch (SQLException e) {\r
+                       rv = false;\r
+                       intlogger.warn("PROV0006 doUpdate: "+e.getMessage());\r
+                       e.printStackTrace();\r
+               } finally {\r
+                       try {\r
+                               ps.close();\r
+                       } catch (SQLException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               return rv;\r
+       }\r
+\r
+\r
+       @Override\r
+       public String getKey() {\r
+               return ""+getFeedid();\r
+       }\r
+\r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               if (!(obj instanceof Feed))\r
+                       return false;\r
+               Feed of = (Feed) obj;\r
+               if (feedid != of.feedid)\r
+                       return false;\r
+               if (groupid != of.groupid) //New field is added - Groups feature Rally:US708115 - 1610\r
+                       return false;\r
+               if (!name.equals(of.name))\r
+                       return false;\r
+               if (!version.equals(of.version))\r
+                       return false;\r
+               if (!description.equals(of.description))\r
+                       return false;\r
+               if (!business_description.equals(of.business_description)) // New field is added - Groups feature Rally:US708102 - 1610\r
+                       return false;\r
+               if (!publisher.equals(of.publisher))\r
+                       return false;\r
+               if (!authorization.equals(of.authorization))\r
+                       return false;\r
+               if (!links.equals(of.links))\r
+                       return false;\r
+               if (deleted != of.deleted)\r
+                       return false;\r
+               if (suspended != of.suspended)\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               return "FEED: feedid=" + feedid + ", name=" + name + ", version=" + version;\r
+       }\r
+}\r