* * 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
+ * *\r
* * http://www.apache.org/licenses/LICENSE-2.0\r
- * * \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
\r
package org.onap.dmaap.datarouter.provisioning.utils;\r
\r
-import java.io.File;\r
-import java.io.FileReader;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.LineNumberReader;\r
-import java.lang.reflect.Constructor;\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.sql.Connection;\r
-import java.sql.DatabaseMetaData;\r
-import java.sql.DriverManager;\r
-import java.sql.PreparedStatement;\r
-import java.sql.ResultSet;\r
-import java.sql.SQLException;\r
-import java.sql.Statement;\r
-import java.util.HashSet;\r
-import java.util.LinkedList;\r
-import java.util.NoSuchElementException;\r
-import java.util.Properties;\r
-import java.util.Queue;\r
-import java.util.Set;\r
-\r
import org.apache.log4j.Logger;\r
-import org.onap.dmaap.datarouter.provisioning.beans.DeliveryRecord;\r
-import org.onap.dmaap.datarouter.provisioning.beans.ExpiryRecord;\r
-import org.onap.dmaap.datarouter.provisioning.beans.Loadable;\r
-import org.onap.dmaap.datarouter.provisioning.beans.PublishRecord;\r
+\r
+import java.io.*;\r
+import java.sql.*;\r
+import java.util.*;\r
\r
/**\r
* Load the DB JDBC driver, and manage a simple pool of connections to the DB.\r
* @version $Id$\r
*/\r
public class DB {\r
- /** The name of the properties file (in CLASSPATH) */\r
- public static final String CONFIG_FILE = "provserver.properties";\r
-\r
- private static String DB_DRIVER = "com.mysql.jdbc.Driver";\r
- private static String DB_URL = "jdbc:mysql://127.0.0.1:3306/datarouter";\r
- private static String DB_LOGIN = "datarouter";\r
- private static String DB_PASSWORD = "datarouter";\r
- private static Properties props;\r
- private static Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");\r
- private static Queue<Connection> queue = new LinkedList<Connection>();\r
-\r
- public static String HTTPS_PORT;\r
- public static String HTTP_PORT;\r
-\r
- /**\r
- * Construct a DB object. If this is the very first creation of this object, it will load a copy\r
- * of the properties for the server, and attempt to load the JDBC driver for the database. If a fatal\r
- * error occurs (e.g. either the properties file or the DB driver is missing), the JVM will exit.\r
- */\r
- public DB() {\r
- if (props == null) {\r
- props = new Properties();\r
- InputStream inStream = getClass().getClassLoader().getResourceAsStream(CONFIG_FILE);\r
- try {\r
- props.load(inStream);\r
- DB_DRIVER = (String) props.get("com.att.research.datarouter.db.driver");\r
- DB_URL = (String) props.get("com.att.research.datarouter.db.url");\r
- DB_LOGIN = (String) props.get("com.att.research.datarouter.db.login");\r
- DB_PASSWORD = (String) props.get("com.att.research.datarouter.db.password");\r
- HTTPS_PORT = (String) props.get("com.att.research.datarouter.provserver.https.port");\r
- HTTP_PORT = (String) props.get("com.att.research.datarouter.provserver.http.port");\r
- Class.forName(DB_DRIVER);\r
- } catch (IOException e) {\r
- intlogger.fatal("PROV9003 Opening properties: "+e.getMessage());\r
- e.printStackTrace();\r
- System.exit(1);\r
- } catch (ClassNotFoundException e) {\r
- intlogger.fatal("PROV9004 cannot find the DB driver: "+e);\r
- e.printStackTrace();\r
- System.exit(1);\r
- } finally {\r
- try {\r
- inStream.close();\r
- } catch (IOException e) {\r
- }\r
- }\r
- }\r
- }\r
- /**\r
- * Get the provisioning server properties (loaded from provserver.properties).\r
- * @return the Properties object\r
- */\r
- public Properties getProperties() {\r
- return props;\r
- }\r
- /**\r
- * Get a JDBC connection to the DB from the pool. Creates a new one if none are available.\r
- * @return the Connection\r
- * @throws SQLException\r
- */\r
- @SuppressWarnings("resource")\r
- public Connection getConnection() throws SQLException {\r
- Connection c = null;\r
- while (c == null) {\r
- synchronized (queue) {\r
- try {\r
- c = queue.remove();\r
- } catch (NoSuchElementException e) {\r
- int n = 0;\r
- do {\r
- // Try up to 3 times to get a connection\r
- try {\r
- c = DriverManager.getConnection(DB_URL, DB_LOGIN, DB_PASSWORD);\r
- } catch (SQLException e1) {\r
- if (++n >= 3)\r
- throw e1;\r
- }\r
- } while (c == null);\r
- }\r
- }\r
- if (c != null && !c.isValid(1)) {\r
- c.close();\r
- c = null;\r
- }\r
- }\r
- return c;\r
- }\r
- /**\r
- * Returns a JDBC connection to the pool.\r
- * @param c the Connection to return\r
- * @throws SQLException\r
- */\r
- public void release(Connection c) {\r
- if (c != null) {\r
- synchronized (queue) {\r
- if (!queue.contains(c))\r
- queue.add(c);\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Run all necessary retrofits required to bring the database up to the level required for this version\r
- * of the provisioning server. This should be run before the server itself is started.\r
- * @return true if all retrofits worked, false otherwise\r
- */\r
- public boolean runRetroFits() {\r
- return retroFit1()\r
- && retroFit2()\r
- && retroFit3()\r
- && retroFit4()\r
- && retroFit5()\r
- && retroFit6()\r
- && retroFit7()\r
- && retroFit8()\r
- && retroFit9() //New retroFit call to add CREATED_DATE column Rally:US674199 - 1610\r
- && retroFit10() //New retroFit call to add BUSINESS_DESCRIPTION column Rally:US708102 - 1610\r
- && retroFit11() //New retroFit call for groups feature Rally:US708115 - 1610 \r
- ;\r
- }\r
- /**\r
- * Retrofit 1 - Make sure the expected tables are in MySQL and are initialized.\r
- * Uses mysql_init_0000 and mysql_init_0001 to setup the DB.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- private boolean retroFit1() {\r
- final String[] expected_tables = {\r
- "FEEDS", "FEED_ENDPOINT_ADDRS", "FEED_ENDPOINT_IDS", "PARAMETERS", "SUBSCRIPTIONS"\r
- };\r
- Connection c = null;\r
- try {\r
- c = getConnection();\r
- Set<String> tables = getTableSet(c);\r
- boolean initialize = false;\r
- for (String s : expected_tables) {\r
- initialize |= !tables.contains(s);\r
- }\r
- if (initialize) {\r
- intlogger.info("PROV9001: First time startup; The database is being initialized.");\r
- runInitScript(c, 0); // script 0 creates the provisioning tables\r
- runInitScript(c, 1); // script 1 initializes PARAMETERS\r
- }\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 2 - if the LOG_RECORDS table is missing, add it.\r
- * Uses mysql_init_0002 to create this table.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- private boolean retroFit2() {\r
- Connection c = null;\r
- try {\r
- // If LOG_RECORDS table is missing, add it\r
- c = getConnection();\r
- Set<String> tables = getTableSet(c);\r
- if (!tables.contains("LOG_RECORDS")) {\r
- intlogger.info("PROV9002: Creating LOG_RECORDS table.");\r
- runInitScript(c, 2); // script 2 creates the LOG_RECORDS table\r
- }\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 3 - if the FEEDS_UNIQUEID table (from release 1.0.*) exists, drop it.\r
- * If SUBSCRIPTIONS.SUBID still has the auto_increment attribute, remove it.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit3() {\r
- Connection c = null;\r
- try {\r
- // if SUBSCRIPTIONS.SUBID still has auto_increment, remove it\r
- boolean doremove = false;\r
- c = getConnection();\r
- DatabaseMetaData md = c.getMetaData();\r
- ResultSet rs = md.getColumns("datarouter", "", "SUBSCRIPTIONS", "SUBID");\r
- if (rs != null) {\r
- while (rs.next()) {\r
- doremove = rs.getString("IS_AUTOINCREMENT").equals("YES");\r
- }\r
- rs.close();\r
- rs = null;\r
- }\r
- if (doremove) {\r
- intlogger.info("PROV9002: Modifying SUBSCRIPTIONS SUBID column to remove auto increment.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE SUBSCRIPTIONS MODIFY COLUMN SUBID INT UNSIGNED NOT NULL");\r
- s.close();\r
- }\r
-\r
- // Remove the FEEDS_UNIQUEID table, if it exists\r
- Set<String> tables = getTableSet(c);\r
- if (tables.contains("FEEDS_UNIQUEID")) {\r
- intlogger.info("PROV9002: Dropping FEEDS_UNIQUEID table.");\r
- Statement s = c.createStatement();\r
- s.execute("DROP TABLE FEEDS_UNIQUEID");\r
- s.close();\r
- }\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- private long nextid = 0; // used for initial creation of LOG_RECORDS table.\r
- /**\r
- * Retrofit 4 - if old log tables exist (from release 1.0.*), copy them to LOG_RECORDS, then drop them.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit4() {\r
- Connection c = null;\r
- try {\r
- c = getConnection();\r
- Set<String> tables = getTableSet(c);\r
- if (tables.contains("PUBLISH_RECORDS")) {\r
- intlogger.info("PROV9002: Copying PUBLISH_RECORDS to LOG_RECORDS table.");\r
- copyLogTable("PUBLISH_RECORDS", PublishRecord.class);\r
- intlogger.info("PROV9002: Dropping PUBLISH_RECORDS table.");\r
- Statement s = c.createStatement();\r
- s.execute("DROP TABLE PUBLISH_RECORDS");\r
- s.close();\r
- }\r
- if (tables.contains("DELIVERY_RECORDS")) {\r
- intlogger.info("PROV9002: Copying DELIVERY_RECORDS to LOG_RECORDS table.");\r
- copyLogTable("DELIVERY_RECORDS", DeliveryRecord.class);\r
- intlogger.info("PROV9002: Dropping DELIVERY_RECORDS table.");\r
- Statement s = c.createStatement();\r
- s.execute("DROP TABLE DELIVERY_RECORDS");\r
- s.close();\r
- }\r
- if (tables.contains("EXPIRY_RECORDS")) {\r
- intlogger.info("PROV9002: Copying EXPIRY_RECORDS to LOG_RECORDS table.");\r
- copyLogTable("EXPIRY_RECORDS", ExpiryRecord.class);\r
- intlogger.info("PROV9002: Dropping EXPIRY_RECORDS table.");\r
- Statement s = c.createStatement();\r
- s.execute("DROP TABLE EXPIRY_RECORDS");\r
- s.close();\r
- }\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 5 - Create the new routing tables required for Release 2.\r
- * Adds a new "SUSPENDED" column to FEEDS and SUBSCRIPTIONS.\r
- * Modifies the LOG_RECORDS table to handle new R2 records.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit5() {\r
- final String[] expected_tables = {\r
- "INGRESS_ROUTES", "EGRESS_ROUTES", "NETWORK_ROUTES", "NODESETS", "NODES"\r
- };\r
- Connection c = null;\r
- try {\r
- // If expected tables are not present, then add new routing tables\r
- c = getConnection();\r
- Set<String> tables = getTableSet(c);\r
- boolean initialize = false;\r
- for (String s : expected_tables) {\r
- initialize |= !tables.contains(s);\r
- }\r
- if (initialize) {\r
- intlogger.info("PROV9002: Adding routing tables for Release 2.0.");\r
- runInitScript(c, 3); // script 3 creates the routing tables\r
- }\r
-\r
- // Add SUSPENDED column to FEEDS/SUBSCRIPTIONS\r
- DatabaseMetaData md = c.getMetaData();\r
- for (String tbl : new String[] {"FEEDS", "SUBSCRIPTIONS" }) {\r
- boolean add_col = true;\r
- ResultSet rs = md.getColumns("datarouter", "", tbl, "SUSPENDED");\r
- if (rs != null) {\r
- add_col = !rs.next();\r
- rs.close();\r
- rs = null;\r
- }\r
- if (add_col) {\r
- intlogger.info("PROV9002: Adding SUSPENDED column to "+tbl+" table.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE "+tbl+" ADD COLUMN SUSPENDED BOOLEAN DEFAULT FALSE");\r
- s.close();\r
- }\r
- }\r
-\r
- // Modify LOG_RECORDS for R2\r
- intlogger.info("PROV9002: Modifying LOG_RECORDS table.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE LOG_RECORDS MODIFY COLUMN TYPE ENUM('pub', 'del', 'exp', 'pbf', 'dlx') NOT NULL");\r
- s.close();\r
- s = c.createStatement();\r
- s.execute("ALTER TABLE LOG_RECORDS MODIFY COLUMN REASON ENUM('notRetryable', 'retriesExhausted', 'diskFull', 'other')");\r
- s.close();\r
- boolean add_col = true;\r
- ResultSet rs = md.getColumns("datarouter", "", "LOG_RECORDS", "CONTENT_LENGTH_2");\r
- if (rs != null) {\r
- add_col = !rs.next();\r
- rs.close();\r
- rs = null;\r
- }\r
- if (add_col) {\r
- intlogger.info("PROV9002: Fixing two columns in LOG_RECORDS table (this may take some time).");\r
- s = c.createStatement();\r
- s.execute("ALTER TABLE LOG_RECORDS MODIFY COLUMN CONTENT_LENGTH BIGINT NOT NULL, ADD COLUMN CONTENT_LENGTH_2 BIGINT AFTER RECORD_ID");\r
- s.close();\r
- }\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 6 - Adjust LOG_RECORDS.USER to be 50 chars (MR #74).\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit6() {\r
- Connection c = null;\r
- try {\r
- c = getConnection();\r
- // Modify LOG_RECORDS for R2\r
- intlogger.info("PROV9002: Modifying LOG_RECORDS.USER length.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE LOG_RECORDS MODIFY COLUMN USER VARCHAR(50)");\r
- s.close();\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 7 - Adjust LOG_RECORDS.FEED_FILEID and LOG_RECORDS.DELIVERY_FILEID to be 256 chars.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit7() {\r
- Connection c = null;\r
- try {\r
- c = getConnection();\r
- // Modify LOG_RECORDS for long (>128) FILEIDs\r
- intlogger.info("PROV9002: Modifying LOG_RECORDS.USER length.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE LOG_RECORDS MODIFY COLUMN FEED_FILEID VARCHAR(256), MODIFY COLUMN DELIVERY_FILEID VARCHAR(256)");\r
- s.close();\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- /**\r
- * Retrofit 8 - Adjust FEEDS.NAME to be 255 chars (MR #74).\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
- @SuppressWarnings("resource")\r
- private boolean retroFit8() {\r
- Connection c = null;\r
- try {\r
- c = getConnection();\r
- intlogger.info("PROV9002: Modifying FEEDS.NAME length.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE FEEDS MODIFY COLUMN NAME VARCHAR(255)");\r
- s.close();\r
- } catch (SQLException e) {\r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
- \r
- /**\r
- * Retrofit 9 - Add column FEEDS.CREATED_DATE and SUBSCRIPTIONS.CREATED_DATE, 1610 release user story US674199.\r
- * @return true if the retrofit worked, false otherwise\r
- */\r
-\r
- @SuppressWarnings("resource") \r
- private boolean retroFit9() { \r
- Connection c = null; \r
- try { \r
- c = getConnection(); \r
- // Add CREATED_DATE column to FEEDS/SUBSCRIPTIONS tables\r
- DatabaseMetaData md = c.getMetaData(); \r
- for (String tbl : new String[] {"FEEDS", "SUBSCRIPTIONS" }) { \r
- boolean add_col = true; \r
- ResultSet rs = md.getColumns("datarouter", "", tbl, "CREATED_DATE"); \r
- if (rs != null) { \r
- add_col = !rs.next(); \r
- rs.close(); \r
- rs = null; \r
- } \r
- if (add_col) { \r
- intlogger.info("PROV9002: Adding CREATED_DATE column to "+tbl+" table."); \r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE "+tbl+" ADD COLUMN CREATED_DATE timestamp DEFAULT CURRENT_TIMESTAMP"); \r
- s.close(); \r
- } \r
- } \r
- } catch (SQLException e) { \r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage()); \r
- return false; \r
- } finally { \r
- if (c != null) \r
- release(c); \r
- } \r
- return true; \r
- }\r
-\r
- /**\r
- * Retrofit 10 -Adding business BUSINESS_DESCRIPTION to FEEDS table (Rally\r
- * US708102).\r
- * \r
- * @return true if the retrofit worked, false otherwise\r
- */\r
-\r
- @SuppressWarnings("resource")\r
- private boolean retroFit10() {\r
- Connection c = null;\r
- boolean addColumn = true;\r
- \r
- try {\r
-\r
- c = getConnection(); \r
- // Add BUSINESS_DESCRIPTION column to FEEDS table\r
- DatabaseMetaData md = c.getMetaData(); \r
- boolean add_col = true; \r
- ResultSet rs = md.getColumns("datarouter", "", "FEEDS", "BUSINESS_DESCRIPTION"); \r
- if (rs != null) { \r
- add_col = !rs.next(); \r
- rs.close(); \r
- rs = null; \r
- } \r
- if(add_col) {\r
- intlogger\r
- .info("PROV9002: Adding BUSINESS_DESCRIPTION column to FEEDS table.");\r
- Statement s = c.createStatement();\r
- s.execute("ALTER TABLE FEEDS ADD COLUMN BUSINESS_DESCRIPTION varchar(1000) DEFAULT NULL AFTER DESCRIPTION, MODIFY COLUMN DESCRIPTION VARCHAR(1000)");\r
- s.close();\r
- }\r
- }\r
- catch (SQLException e) {\r
- intlogger\r
- .fatal("PROV9000: The database credentials are not working: "\r
- + e.getMessage());\r
- return false;\r
- } finally {\r
- if (c != null)\r
- release(c);\r
- }\r
- return true;\r
- }\r
-\r
-\r
- /*New retroFit method is added for groups feature Rally:US708115 - 1610 \r
- * @retroFit11()\r
- * @parmas: none\r
- * @return - boolean if table and fields are created (Group table, group id in FEEDS, SUBSCRIPTION TABLES)\r
- */\r
- @SuppressWarnings("resource") \r
- private boolean retroFit11() { \r
- final String[] expected_tables = { \r
- "GROUPS" \r
- }; \r
- Connection c = null; \r
- \r
- try { \r
- // If expected tables are not present, then add new routing tables \r
- c = getConnection(); \r
- Set<String> tables = getTableSet(c); \r
- boolean initialize = false; \r
- for (String s : expected_tables) { \r
- initialize |= !tables.contains(s); \r
- } \r
- if (initialize) { \r
- intlogger.info("PROV9002: Adding GROUPS table for Release 1610."); \r
- runInitScript(c, 4); // script 4 creates the routing tables \r
- } \r
- \r
- // Add GROUPID column to FEEDS/SUBSCRIPTIONS \r
- DatabaseMetaData md = c.getMetaData(); \r
- for (String tbl : new String[] {"FEEDS", "SUBSCRIPTIONS" }) { \r
- boolean add_col = true; \r
- ResultSet rs = md.getColumns("datarouter", "", tbl, "GROUPID"); \r
- if (rs != null) { \r
- add_col = !rs.next(); \r
- rs.close(); \r
- rs = null; \r
- } \r
- if (add_col) { \r
- intlogger.info("PROV9002: Adding GROUPID column to "+tbl+" table."); \r
- Statement s = c.createStatement(); \r
- s.execute("ALTER TABLE "+tbl+" ADD COLUMN GROUPID INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER FEEDID"); \r
- s.close(); \r
- } \r
- } \r
- } catch (SQLException e) { \r
- intlogger.fatal("PROV9000: The database credentials are not working: "+e.getMessage()); \r
- return false; \r
- } finally { \r
- if (c != null) \r
- release(c); \r
- } \r
- return true; \r
- }\r
-\r
-\r
- /**\r
- * Copy the log table <i>table_name</i> to LOG_RECORDS;\r
- * @param table_name the name of the old (1.0.*) table to copy\r
- * @param table_class the class used to instantiate a record from the table\r
- * @throws SQLException if there is a problem getting a MySQL connection\r
- */\r
- @SuppressWarnings("resource")\r
- private void copyLogTable(String table_name, Class<? extends Loadable> table_class) throws SQLException {\r
- long start = System.currentTimeMillis();\r
- int n = 0;\r
- Connection c1 = getConnection();\r
- Connection c2 = getConnection();\r
-\r
- try {\r
- Constructor<? extends Loadable> cnst = table_class.getConstructor(ResultSet.class);\r
- PreparedStatement ps = c2.prepareStatement(LogfileLoader.INSERT_SQL);\r
- Statement stmt = c1.createStatement();\r
- ResultSet rs = stmt.executeQuery("select * from "+table_name);\r
- while (rs.next()) {\r
- Loadable rec = cnst.newInstance(rs);\r
- rec.load(ps);\r
- ps.setLong(18, ++nextid);\r
- ps.executeUpdate();\r
- if ((++n % 10000) == 0)\r
- intlogger.debug(" "+n+" records done.");\r
- }\r
- stmt.close();\r
- ps.close();\r
- } catch (SQLException e) {\r
- e.printStackTrace();\r
- } catch (NoSuchMethodException e) {\r
- e.printStackTrace();\r
- } catch (SecurityException e) {\r
- e.printStackTrace();\r
- } catch (InstantiationException e) {\r
- e.printStackTrace();\r
- } catch (IllegalAccessException e) {\r
- e.printStackTrace();\r
- } catch (IllegalArgumentException e) {\r
- e.printStackTrace();\r
- } catch (InvocationTargetException e) {\r
- e.printStackTrace();\r
- }\r
-\r
- release(c1);\r
- release(c2);\r
- long x = (System.currentTimeMillis() - start);\r
- intlogger.debug(" "+n+" records done in "+x+" ms.");\r
- }\r
-\r
- /**\r
- * Get a set of all table names in the DB.\r
- * @param c a DB connection\r
- * @return the set of table names\r
- */\r
- private Set<String> getTableSet(Connection c) {\r
- Set<String> tables = new HashSet<String>();\r
- try {\r
- DatabaseMetaData md = c.getMetaData();\r
- ResultSet rs = md.getTables("datarouter", "", "", null);\r
- if (rs != null) {\r
- while (rs.next()) {\r
- tables.add(rs.getString("TABLE_NAME"));\r
- }\r
- rs.close();\r
- }\r
- } catch (SQLException e) {\r
- }\r
- return tables;\r
- }\r
- /**\r
- * Initialize the tables by running the initialization scripts located in the directory specified\r
- * by the property <i>com.att.research.datarouter.provserver.dbscripts</i>. Scripts have names of\r
- * the form mysql_init_NNNN.\r
- * @param c a DB connection\r
- * @param n the number of the mysql_init_NNNN script to run\r
- */\r
- private void runInitScript(Connection c, int n) {\r
- String scriptdir = (String) props.get("com.att.research.datarouter.provserver.dbscripts");\r
- StringBuilder sb = new StringBuilder();\r
- try {\r
- String scriptfile = String.format("%s/mysql_init_%04d", scriptdir, n);\r
- if (!(new File(scriptfile)).exists())\r
- return;\r
\r
- LineNumberReader in = new LineNumberReader(new FileReader(scriptfile));\r
- String line;\r
- while ((line = in.readLine()) != null) {\r
- if (!line.startsWith("--")) {\r
- line = line.trim();\r
- sb.append(line);\r
- if (line.endsWith(";")) {\r
- // Execute one DDL statement\r
- String sql = sb.toString();\r
- sb.setLength(0);\r
- Statement s = c.createStatement();\r
- s.execute(sql);\r
- s.close();\r
- }\r
- }\r
- }\r
- in.close();\r
- sb.setLength(0);\r
- } catch (Exception e) {\r
- intlogger.fatal("PROV9002 Error when initializing table: "+e.getMessage());\r
- System.exit(1);\r
- }\r
- }\r
+ private static Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");\r
+\r
+ private static String DB_URL;\r
+ private static String DB_LOGIN;\r
+ private static String DB_PASSWORD;\r
+ private static Properties props;\r
+ private static final Queue<Connection> queue = new LinkedList<>();\r
+\r
+ public static String HTTPS_PORT;\r
+ public static String HTTP_PORT;\r
+\r
+ /**\r
+ * Construct a DB object. If this is the very first creation of this object, it will load a copy of the properties\r
+ * for the server, and attempt to load the JDBC driver for the database. If a fatal error occurs (e.g. either the\r
+ * properties file or the DB driver is missing), the JVM will exit.\r
+ */\r
+ public DB() {\r
+ if (props == null) {\r
+ props = new Properties();\r
+ try {\r
+ props.load(new FileInputStream(System.getProperty(\r
+ "org.onap.dmaap.datarouter.provserver.properties",\r
+ "/opt/app/datartr/etc/provserver.properties")));\r
+ String DB_DRIVER = (String) props.get("org.onap.dmaap.datarouter.db.driver");\r
+ DB_URL = (String) props.get("org.onap.dmaap.datarouter.db.url");\r
+ DB_LOGIN = (String) props.get("org.onap.dmaap.datarouter.db.login");\r
+ DB_PASSWORD = (String) props.get("org.onap.dmaap.datarouter.db.password");\r
+ HTTPS_PORT = (String) props.get("org.onap.dmaap.datarouter.provserver.https.port");\r
+ HTTP_PORT = (String) props.get("org.onap.dmaap.datarouter.provserver.http.port");\r
+ Class.forName(DB_DRIVER);\r
+ } catch (IOException e) {\r
+ intlogger.fatal("PROV9003 Opening properties: " + e.getMessage());\r
+ e.printStackTrace();\r
+ System.exit(1);\r
+ } catch (ClassNotFoundException e) {\r
+ intlogger.fatal("PROV9004 cannot find the DB driver: " + e);\r
+ e.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Get the provisioning server properties (loaded from provserver.properties).\r
+ *\r
+ * @return the Properties object\r
+ */\r
+ public Properties getProperties() {\r
+ return props;\r
+ }\r
+\r
+ /**\r
+ * Get a JDBC connection to the DB from the pool. Creates a new one if none are available.\r
+ *\r
+ * @return the Connection\r
+ */\r
+ @SuppressWarnings("resource")\r
+ public Connection getConnection() throws SQLException {\r
+ Connection connection = null;\r
+ while (connection == null) {\r
+ synchronized (queue) {\r
+ try {\r
+ connection = queue.remove();\r
+ } catch (NoSuchElementException nseEx) {\r
+ int n = 0;\r
+ do {\r
+ // Try up to 3 times to get a connection\r
+ try {\r
+ connection = DriverManager.getConnection(DB_URL, DB_LOGIN, DB_PASSWORD);\r
+ } catch (SQLException sqlEx) {\r
+ if (++n >= 3) {\r
+ throw sqlEx;\r
+ }\r
+ }\r
+ } while (connection == null);\r
+ }\r
+ }\r
+ if (connection != null && !connection.isValid(1)) {\r
+ connection.close();\r
+ connection = null;\r
+ }\r
+ }\r
+ return connection;\r
+ }\r
+\r
+ /**\r
+ * Returns a JDBC connection to the pool.\r
+ *\r
+ * @param connection the Connection to return\r
+ */\r
+ public void release(Connection connection) {\r
+ if (connection != null) {\r
+ synchronized (queue) {\r
+ if (!queue.contains(connection)) {\r
+ queue.add(connection);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Run all necessary retrofits required to bring the database up to the level required for this version of the\r
+ * provisioning server. This should be run before the server itself is started.\r
+ *\r
+ * @return true if all retrofits worked, false otherwise\r
+ */\r
+ public boolean runRetroFits() {\r
+ return retroFit1();\r
+ }\r
+\r
+ /**\r
+ * Retrofit 1 - Make sure the expected tables are in DB and are initialized. Uses sql_init_01.sql to setup the DB.\r
+ *\r
+ * @return true if the retrofit worked, false otherwise\r
+ */\r
+ private boolean retroFit1() {\r
+ final String[] expectedTables = {\r
+ "FEEDS", "FEED_ENDPOINT_ADDRS", "FEED_ENDPOINT_IDS", "PARAMETERS",\r
+ "SUBSCRIPTIONS", "LOG_RECORDS", "INGRESS_ROUTES", "EGRESS_ROUTES",\r
+ "NETWORK_ROUTES", "NODESETS", "NODES", "GROUPS"\r
+ };\r
+ Connection connection = null;\r
+ try {\r
+ connection = getConnection();\r
+ Set<String> actualTables = getTableSet(connection);\r
+ boolean initialize = false;\r
+ for (String table : expectedTables) {\r
+ initialize |= !actualTables.contains(table.toLowerCase());\r
+ }\r
+ if (initialize) {\r
+ intlogger.info("PROV9001: First time startup; The database is being initialized.");\r
+ runInitScript(connection, 1);\r
+ }\r
+ } catch (SQLException e) {\r
+ intlogger.fatal("PROV9000: The database credentials are not working: " + e.getMessage());\r
+ return false;\r
+ } finally {\r
+ if (connection != null) {\r
+ release(connection);\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Get a set of all table names in the DB.\r
+ *\r
+ * @param connection a DB connection\r
+ * @return the set of table names\r
+ */\r
+ private Set<String> getTableSet(Connection connection) {\r
+ Set<String> tables = new HashSet<String>();\r
+ try {\r
+ DatabaseMetaData md = connection.getMetaData();\r
+ ResultSet rs = md.getTables(null, null, "%", null);\r
+ if (rs != null) {\r
+ while (rs.next()) {\r
+ tables.add(rs.getString("TABLE_NAME"));\r
+ }\r
+ rs.close();\r
+ }\r
+ } catch (SQLException e) {\r
+ intlogger.fatal("PROV9010: Failed to get TABLE data from DB: " + e.getMessage());\r
+ }\r
+ return tables;\r
+ }\r
+\r
+ /**\r
+ * Initialize the tables by running the initialization scripts located in the directory specified by the property\r
+ * <i>org.onap.dmaap.datarouter.provserver.dbscripts</i>. Scripts have names of the form sql_init_NN.sql\r
+ *\r
+ * @param connection a DB connection\r
+ * @param scriptId the number of the sql_init_NN.sql script to run\r
+ */\r
+ private void runInitScript(Connection connection, int scriptId) {\r
+ String scriptDir = (String) props.get("org.onap.dmaap.datarouter.provserver.dbscripts");\r
+ StringBuilder strBuilder = new StringBuilder();\r
+ try {\r
+ String scriptFile = String.format("%s/sql_init_%02d.sql", scriptDir, scriptId);\r
+ if (!(new File(scriptFile)).exists()) {\r
+ intlogger.fatal("PROV9005 Failed to load sql script from : " + scriptFile);\r
+ System.exit(1);\r
+ }\r
+ LineNumberReader lineReader = new LineNumberReader(new FileReader(scriptFile));\r
+ String line;\r
+ while ((line = lineReader.readLine()) != null) {\r
+ if (!line.startsWith("--")) {\r
+ line = line.trim();\r
+ strBuilder.append(line);\r
+ if (line.endsWith(";")) {\r
+ // Execute one DDL statement\r
+ String sql = strBuilder.toString();\r
+ strBuilder.setLength(0);\r
+ Statement statement = connection.createStatement();\r
+ statement.execute(sql);\r
+ statement.close();\r
+ }\r
+ }\r
+ }\r
+ lineReader.close();\r
+ strBuilder.setLength(0);\r
+ } catch (Exception e) {\r
+ intlogger.fatal("PROV9002 Error when initializing table: " + e.getMessage());\r
+ System.exit(1);\r
+ }\r
+ }\r
}\r