--- /dev/null
+/*\r
+ * ============LICENSE_START====================================================\r
+ * org.onap.music.mdbc\r
+ * =============================================================================\r
+ * Copyright (C) 2018 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
+package org.onap.music.mdbc.examples;\r
+\r
+import java.sql.*;\r
+import java.util.HashMap;\r
+import java.util.Random;\r
+\r
+import org.apache.calcite.avatica.remote.Driver;\r
+\r
+public class MdbcTestClientNew {\r
+ private String lastName = "Lastname";\r
+ private int baseId = 700;\r
+ private int baseIdRange = 50;\r
+ private int maxCalls = 50; \r
+ private int maxTimeMs = 60000;\r
+ private int minDelayBetweenTestsMs = 1000;\r
+ private int additionalDelayBetweenTestsMs = 1000;\r
+ private boolean doDelete = true;\r
+ private boolean doUpdate = true;\r
+ private int connectionCloseChancePct = 50;\r
+ \r
+ private boolean explainConnection = true;\r
+ \r
+ public static class Employee {\r
+ public final int empid;\r
+ public String lastname;\r
+ public String firstname;\r
+ public String address;\r
+ public String city;\r
+ \r
+ public Employee(int empid, String lastname, String firstname, String address, String city) {\r
+ super();\r
+ this.empid = empid;\r
+ this.lastname = lastname;\r
+ this.firstname = firstname;\r
+ this.address = address;\r
+ this.city = city;\r
+ }\r
+\r
+ public String getLastname() {\r
+ return lastname;\r
+ }\r
+\r
+ public void setLastname(String lastname) {\r
+ this.lastname = lastname;\r
+ }\r
+\r
+ public String getFirstname() {\r
+ return firstname;\r
+ }\r
+\r
+ public void setFirstname(String firstname) {\r
+ this.firstname = firstname;\r
+ }\r
+\r
+ public String getAddress() {\r
+ return address;\r
+ }\r
+\r
+ public void setAddress(String address) {\r
+ this.address = address;\r
+ }\r
+\r
+ public String getCity() {\r
+ return city;\r
+ }\r
+\r
+ public void setCity(String city) {\r
+ this.city = city;\r
+ }\r
+\r
+ public int getEmpid() {\r
+ return empid;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "Employee: " + empid + ", " + lastname + ", " + firstname + ", " + address + ", " + city;\r
+ }\r
+\r
+ \r
+ }\r
+\r
+ public MdbcTestClientNew(String[] args) {\r
+ lastName = args[0];\r
+ baseId = Integer.parseInt(args[1]);\r
+ baseIdRange = Integer.parseInt(args[2]);\r
+ maxCalls = Integer.parseInt(args[3]);\r
+ maxTimeMs = Integer.parseInt(args[4]);\r
+ minDelayBetweenTestsMs = Integer.parseInt(args[5]);\r
+ additionalDelayBetweenTestsMs = Integer.parseInt(args[6]);\r
+ doDelete = (args[7].toUpperCase().startsWith("Y")); \r
+ doUpdate = (args[8].toUpperCase().startsWith("Y"));\r
+ connectionCloseChancePct = Integer.parseInt(args[9]);\r
+ }\r
+\r
+ public MdbcTestClientNew() {\r
+ // Use default values\r
+ }\r
+\r
+ private void doTest(Connection connection, Random r) throws SQLException {\r
+ HashMap<Integer, Employee> employeeMap = new HashMap<Integer, Employee>();\r
+\r
+ Statement querySt = connection.createStatement();\r
+ doLog("Before select");\r
+\r
+ if (explainConnection) {\r
+ doLog("querySt is a: ");\r
+ Class<?> qsClass = querySt.getClass();\r
+ while (qsClass!=null) {\r
+ doLog(">>> " + qsClass.getName());\r
+ qsClass = qsClass.getSuperclass();\r
+ }\r
+ doLog("connection is a ");\r
+ qsClass = connection.getClass();\r
+ while (qsClass!=null) {\r
+ doLog(">>> " + qsClass.getName());\r
+ qsClass = qsClass.getSuperclass();\r
+ }\r
+ explainConnection = false;\r
+ }\r
+ \r
+ ResultSet rs = querySt.executeQuery("select * from persons");\r
+ doLog("After select");\r
+ while (rs.next()) {\r
+// doLog("PersonId = " + rs.getInt("personId") + ", lastname = " + rs.getString("lastname") + ", firstname = " + rs.getString("firstname"));\r
+ Employee emp = new Employee(rs.getInt("personId"), rs.getString("lastname"), rs.getString("firstname"), rs.getString("address"), rs.getString("city"));\r
+ employeeMap.put(rs.getInt("personId"), emp);\r
+ doLog("Found: " + emp);\r
+ }\r
+ querySt.close();\r
+\r
+ Statement insertStmt = connection.createStatement();\r
+\r
+ insertStmt.execute(generateStatement(employeeMap, r));\r
+ while (r.nextBoolean()) {\r
+ insertStmt.execute(generateStatement(employeeMap, r));\r
+ }\r
+\r
+ connection.commit();\r
+\r
+ insertStmt.close();\r
+ }\r
+ \r
+ private String generateStatement(HashMap<Integer, Employee> employeeMap, Random r) {\r
+ String toRet = null;\r
+ \r
+ int which = r.nextInt(3);\r
+ if (which==0 && doDelete) {\r
+ toRet = generateDelete(employeeMap, r);\r
+ } else if (which==1 && doUpdate) {\r
+ toRet = generateUpdate(employeeMap, r);\r
+ } \r
+ if (toRet==null) {\r
+ toRet = generateInsert(employeeMap, r);\r
+ }\r
+ \r
+ doLog("Generated statement: " + toRet);\r
+ \r
+ return toRet;\r
+ }\r
+\r
+ private String generateInsert(HashMap<Integer, Employee> employeeMap, Random r) {\r
+ String toRet = null;\r
+ \r
+ Integer id = null;\r
+ int range = baseIdRange;\r
+ while (id==null) {\r
+ id = baseId + r.nextInt(range);\r
+ if (employeeMap.containsKey(id)) id = null;\r
+ range+=(baseIdRange/5);\r
+ }\r
+ Employee newEmp = new Employee(id, lastName, Character.toUpperCase(randomLetter(r)) + generateLetters(r, 4+r.nextInt(4)), generateLetters(r, 4).toUpperCase(), generateLetters(r, 4).toUpperCase());\r
+ toRet = "insert into persons values (" + id + ", '" + newEmp.getLastname() + "', '" + newEmp.getFirstname() + "', '" + newEmp.getAddress() + "', '" + newEmp.getCity() + "')";\r
+ employeeMap.put(id, newEmp);\r
+ \r
+ return toRet;\r
+ }\r
+\r
+ private String generateUpdate(HashMap<Integer, Employee> employeeMap, Random r) {\r
+ String toRet = null;\r
+ \r
+ Employee toUpd = chooseTarget(employeeMap, r);\r
+ if (toUpd!=null) {\r
+ String newFirst = null;\r
+ if (toUpd.getFirstname().length()<=3 || r.nextBoolean()) {\r
+ newFirst = toUpd.getFirstname() + randomLetter(r);\r
+ } else {\r
+ newFirst = toUpd.getFirstname().substring(0, toUpd.getFirstname().length()-1);\r
+ }\r
+// toRet = "update persons set firstname = '" + newFirst + "' where personid = " + toUpd.getEmpid();\r
+ toRet = "update persons set firstname = '" + newFirst + "' where personid = " + toUpd.getEmpid() + " and lastname = '" + toUpd.getLastname() + "'";\r
+ toUpd.setFirstname(newFirst);\r
+ }\r
+ \r
+ return toRet;\r
+ }\r
+\r
+ private String generateLetters(Random r, int count) {\r
+ StringBuffer toRet = new StringBuffer();\r
+ for (int i=0; i<count; i++) {\r
+ Character c = null;\r
+ while (c==null) {\r
+ c = randomLetter(r);\r
+ char cc = c.charValue();\r
+ if ( (cc=='a' || cc=='e' || cc=='i' || cc=='o' || cc=='u') ^ (i%2==0) ) c = null;\r
+ }\r
+ toRet.append(c);\r
+ }\r
+ return toRet.toString();\r
+ }\r
+\r
+ private char randomLetter(Random r) {\r
+ int a = (int)'a';\r
+ return (char)(a+r.nextInt(26));\r
+ }\r
+\r
+ private String generateDelete(HashMap<Integer, Employee> employeeMap, Random r) {\r
+ String toRet = null;\r
+ \r
+ Employee toDel = chooseTarget(employeeMap, r);\r
+ if (toDel!=null) {\r
+ toRet = "delete from persons where personid = " + toDel.getEmpid() + " and lastname = '" + toDel.getLastname() + "'";\r
+ employeeMap.remove(toDel.getEmpid());\r
+ }\r
+ \r
+ return toRet;\r
+ }\r
+\r
+ \r
+ \r
+ private Employee chooseTarget(HashMap<Integer, Employee> employeeMap, Random r) {\r
+ Employee toPick = null;\r
+ int count = 0;\r
+ for (int id : employeeMap.keySet()) {\r
+ Employee emp = employeeMap.get(id);\r
+ if (!emp.getLastname().equals(lastName)) continue;\r
+ count++;\r
+ if (r.nextInt(count)==0) toPick = emp;\r
+ }\r
+ return toPick;\r
+ }\r
+\r
+ public void runTests() {\r
+ try {\r
+ Class.forName("org.apache.calcite.avatica.remote.Driver");\r
+ } catch (ClassNotFoundException e) {\r
+ e.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ \r
+ Connection connection = null;\r
+\r
+ Random r = new Random();\r
+ boolean done = false;\r
+ int calls = 0;\r
+ long startTime = new java.util.Date().getTime();\r
+ while (!done) {\r
+ if (connection==null) {\r
+ try {\r
+ doLog("Opening new connection");\r
+ connection = DriverManager.getConnection("jdbc:avatica:remote:url=http://localhost:30000/test;serialization=protobuf");\r
+ connection.setAutoCommit(false);\r
+ } catch (SQLException e) {\r
+ e.printStackTrace();\r
+ return;\r
+ }\r
+ } else {\r
+ doLog("Keeping open connection");\r
+ }\r
+ \r
+ try {\r
+ doLog("Running test");\r
+ doTest(connection, r);\r
+ doLog("Test complete");\r
+ } catch (SQLException e1) {\r
+ e1.printStackTrace();\r
+ done = true;\r
+ if (connection!=null) {\r
+ try {\r
+ doLog("Closing connection in catch block");\r
+ connection.close();\r
+ } catch (SQLException e) {\r
+ e.printStackTrace();\r
+ done = true;\r
+ } finally {\r
+ connection = null;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!done && connection!=null && r.nextInt(100)<connectionCloseChancePct) {\r
+ try {\r
+ doLog("Closing connection");\r
+ connection.close();\r
+ connection = null;\r
+ } catch (SQLException e) {\r
+ e.printStackTrace();\r
+ done = true;\r
+ }\r
+ } else {\r
+ doLog("Not closing connection");\r
+ }\r
+ \r
+ calls++;\r
+ long msElapsed = (new java.util.Date().getTime()) - startTime;\r
+ if (calls>maxCalls || msElapsed > maxTimeMs) done = true;\r
+ \r
+ if (!done) {\r
+ long delay = r.nextInt(minDelayBetweenTestsMs);\r
+ while (r.nextBoolean()) delay += r.nextInt(additionalDelayBetweenTestsMs);\r
+ synchronized(r) {\r
+ try {\r
+ r.wait(delay);\r
+ } catch (InterruptedException e) {\r
+ e.printStackTrace();\r
+ done = true;\r
+ }\r
+ }\r
+ }\r
+ \r
+ doLog("");\r
+ }\r
+\r
+ if (connection!=null) {\r
+ try {\r
+ doLog("Closing connection at end");\r
+ connection.close();\r
+ } catch (SQLException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ doLog("All done.");\r
+ }\r
+\r
+ private void doLog(String string) {\r
+ System.out.println(">>> " + string);\r
+ }\r
+ \r
+ public static void main(String[] args) {\r
+ MdbcTestClientNew mtc = null;\r
+ if (args.length==0) {\r
+ mtc = new MdbcTestClientNew();\r
+ } else if (args.length==10) {\r
+ mtc = new MdbcTestClientNew(args);\r
+ } else {\r
+ System.out.println("Usage: [this] lastname baseId baseIdRange maxCalls maxTimeMs minDelayBetweenTestsMs additionalDelayBetweenTestsMs doDelete doUpdate connectionCloseChancePct");\r
+ System.out.println(" lastname: Lastname for all inserts/updates/deletes");\r
+ System.out.println(" baseId/baseRange: Id for all inserts will be between baseId and (baseId+baseRange). In case of collision baseRange will be increased until available Id is found.");\r
+ System.out.println(" maxCalls/maxTimeMs: Maximum number of commits (each of which may be 1+ updates) or time (in ms) that the test will run, whichever comes first"); \r
+ System.out.println(" minDelayBetweenTestsMs/additionalDelayBetweenTestsMs: After each test, delay for minDelayBetweenTestsMs ms plus (0 or more) times additionalDelayBetweenTestsMs ms");\r
+ System.out.println(" doUpdate/doDelete: If \"Y\", will try to generate updates and deletes in addition to inserts. Any failures to generate an update/delete will be replaced with an insert.");\r
+ System.out.println(" connectionCloseChancePct: after each commit, percent chance of closing connection and opening a new one.");\r
+ System.out.println("Default settings: Lastname 700 50 50 60000 1000 1000 Y Y 50");\r
+ }\r
+ \r
+ mtc.runTests(); \r
+ }\r
+ \r
+}\r