1 21 22 package org.apache.derbyTesting.functionTests.tests.store; 23 import java.sql.Connection ; 24 import java.sql.Statement ; 25 import java.sql.PreparedStatement ; 26 import java.sql.ResultSet ; 27 import java.sql.SQLException ; 28 import org.apache.derby.tools.ij; 29 import org.apache.derbyTesting.functionTests.util.TestUtil; 30 import org.apache.derby.iapi.services.sanity.SanityManager; 31 32 49 50 public class ReEncryptCrashRecovery 51 { 52 53 private static final String TEST_REENCRYPT_PWD_DATABASE = "wombat_pwd_ren" ; 56 private static final String TEST_ENCRYPT_PWD_DATABASE = "wombat_pwd_en"; 59 60 61 private static final String TEST_REENCRYPT_KEY_DATABASE = "wombat_key_ren" ; 64 private static final String TEST_ENCRYPT_KEY_DATABASE = "wombat_key_en"; 67 68 private static final int USING_KEY = 1; 70 private static final int USING_PASSWORD = 2; 71 72 private static final int NONE = 1; 75 private static final int OLD = 2; 76 private static final int NEW = 3; 77 78 private static final String TEST_TABLE_NAME = "emp"; 80 81 private static final String OLD_PASSWORD = "xyz1234abc"; 82 private static final String NEW_PASSWORD = "new1234xyz"; 83 84 private static final String OLD_KEY = "6162636465666768"; 85 private static final String NEW_KEY = "5666768616263646"; 86 87 private String currentTestDatabase ; 89 private int encryptionType; 91 92 private boolean verbose = false; 95 96 97 ReEncryptCrashRecovery() { 98 99 } 100 101 102 105 private void runTest() throws Exception { 106 logMessage("Begin ReEncryptCrashRecovery Test"); 107 108 if (SanityManager.DEBUG) { 109 if (verbose) 110 logMessage("Start testing re-encryption with Password"); 111 currentTestDatabase = TEST_REENCRYPT_PWD_DATABASE; 114 encryptionType = USING_PASSWORD; 115 runCrashRecoveryTestCases(true); 116 117 118 if (verbose) 119 logMessage("Start Testing encryption with Password"); 120 121 currentTestDatabase = TEST_ENCRYPT_PWD_DATABASE; 124 encryptionType = USING_PASSWORD; 125 runCrashRecoveryTestCases(false); 127 128 129 if (verbose) { 130 logMessage("Start Testing Encryption with external Key"); 131 } 132 135 currentTestDatabase = TEST_ENCRYPT_KEY_DATABASE; 136 encryptionType = USING_KEY; 137 runCrashRecoveryTestCases(false); 138 139 if (verbose) 140 logMessage("Start Testing re-encryption with external Key"); 141 142 145 currentTestDatabase = TEST_REENCRYPT_KEY_DATABASE; 146 encryptionType = USING_KEY; 147 runCrashRecoveryTestCases(true); 148 } 149 logMessage("End ReEncryptCrashRecovery Test"); 150 } 151 152 153 158 private void runCrashRecoveryTestCases(boolean reEncrypt) 159 throws SQLException 160 { 161 Connection conn; 162 if (reEncrypt) 163 conn = createEncryptedDatabase(); 164 else 165 conn = createDatabase(); 166 167 createTable(conn, TEST_TABLE_NAME); 168 insert(conn, TEST_TABLE_NAME, 100); 170 conn.commit(); 171 conn.close(); 172 shutdown(); 173 174 int passwordKey = (reEncrypt ? OLD : NONE ); 176 177 crash(reEncrypt, TEST_REENCRYPT_CRASH_BEFORE_COMMT); 178 179 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_COMMT); 180 crashInRecovery(passwordKey, 181 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE); 182 crashInRecovery(passwordKey, 183 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY); 184 crashInRecovery(passwordKey, 185 TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP); 186 187 188 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_COMMT); 189 crashInRecovery(passwordKey, 190 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE); 191 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_COMMT); 193 194 195 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY); 196 crashInRecovery(passwordKey, 197 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE); 198 crashInRecovery(passwordKey, 199 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY); 200 crashInRecovery(passwordKey, 201 TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP); 202 203 204 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY); 205 crashInRecovery(passwordKey, 206 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY); 207 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY); 209 crashInRecovery(passwordKey, 210 TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP); 211 212 213 216 passwordKey = (reEncrypt ? NEW : OLD); 220 crash(reEncrypt, TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT); 221 crashInRecovery(passwordKey, 222 TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP); 223 224 recover(passwordKey); 225 shutdown(); 226 } 227 228 229 233 private void crash(boolean reEncrypt, String debugFlag) 234 { 235 if (verbose) 236 logMessage("Testing : " + debugFlag); 237 setDebugFlag(debugFlag); 239 240 SQLException sqle = null; 241 Connection conn; 242 try { 243 if (reEncrypt) 244 conn = reEncryptDatabase(); 245 else 246 conn = encryptDatabase(); 247 248 }catch (SQLException se) { 249 sqle = se; 252 } 253 254 verifyException(sqle, debugFlag); 256 clearDebugFlag(debugFlag); 258 } 259 260 261 265 private void crashInRecovery(int passwordKey, String debugFlag) 266 throws SQLException 267 { 268 if (verbose) 269 logMessage("Testing : " + debugFlag); 270 271 setDebugFlag(debugFlag); 273 SQLException sqle = null; 274 try { 275 Connection conn = bootDatabase(passwordKey); 276 } catch (SQLException se) { 277 sqle = se; 281 } 282 verifyException(sqle, debugFlag); 284 clearDebugFlag(debugFlag); 286 } 287 288 289 290 294 private void recover(int passwordKey) 295 throws SQLException 296 { 297 300 Connection conn = bootDatabase(passwordKey); 301 302 runConsistencyChecker(conn, TEST_TABLE_NAME); 304 insert(conn, TEST_TABLE_NAME, 100); 307 conn.commit(); 308 conn.close(); 309 } 310 311 312 313 317 318 319 320 326 327 331 332 public static final String TEST_REENCRYPT_CRASH_BEFORE_COMMT = 333 SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_BEFORE_COMMT" : null ; 334 public static final String TEST_REENCRYPT_CRASH_AFTER_COMMT = 335 SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_COMMT" : null ; 336 public static final String TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY = 337 SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY" : null ; 338 public static final String TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT = 339 SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT" : null ; 340 341 public static final String 342 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE = 343 SanityManager.DEBUG ? 344 "TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE" : null; 345 public static final String 346 TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY = 347 SanityManager.DEBUG ? 348 "TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY" : null; 349 public static final String 350 TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP = 351 SanityManager.DEBUG ? 352 "TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP" : null; 353 354 355 void setDebugFlag(String debugFlag) { 356 if (SanityManager.DEBUG) { 357 SanityManager.DEBUG_SET(debugFlag); 358 } 359 } 360 361 void clearDebugFlag(String debugFlag) { 362 if (SanityManager.DEBUG) { 363 SanityManager.DEBUG_CLEAR(debugFlag); 364 } 365 } 366 367 370 private void verifyException(SQLException sqle, String debugFlag) 371 { 372 boolean expectedExcepion = false ; 373 if (sqle != null) 374 { 375 376 if (sqle.getSQLState() != null && 377 sqle.getSQLState().equals("XJ040")) 378 { 379 SQLException ne = sqle.getNextException(); 382 if (ne != null) { 383 String message = ne.getMessage(); 384 if (message.indexOf(debugFlag) != -1) 386 { 387 expectedExcepion = true; 388 } 389 } 390 } 391 392 if (!expectedExcepion) 393 dumpSQLException(sqle); 394 } 395 else 396 { 397 if (SanityManager.DEBUG) 398 { 399 logMessage("Did not crash at " + debugFlag); 400 } 401 } 402 } 403 404 405 411 void createTable(Connection conn, 412 String tableName) throws SQLException { 413 414 Statement s = conn.createStatement(); 415 s.executeUpdate("CREATE TABLE " + tableName + 416 "(id INT," + 417 "name CHAR(200))"); 418 s.executeUpdate("create index " + tableName + "_id_idx on " + 419 tableName + "(id)"); 420 s.close(); 421 } 422 423 424 430 void runConsistencyChecker(Connection conn, 431 String tableName) throws SQLException { 432 Statement stmt = conn.createStatement(); 433 stmt.execute("values SYSCS_UTIL.SYSCS_CHECK_TABLE('APP', 'EMP')"); 434 select(conn, tableName); 436 } 437 438 439 446 void insert(Connection conn, 447 String tableName, 448 int rowCount) throws SQLException 449 { 450 451 PreparedStatement ps = conn.prepareStatement("INSERT INTO " + 452 tableName + 453 " VALUES(?,?)"); 454 int startId = findMax(conn, tableName); 455 for (int i = startId; i < rowCount; i++) { 456 457 ps.setInt(1, i); ps.setString(2 , "skywalker" + i); 459 ps.executeUpdate(); 460 } 461 ps.close(); 462 conn.commit(); 463 } 464 465 471 private int findMax(Connection conn, 472 String tableName) throws SQLException 473 { 474 Statement s = conn.createStatement(); 475 ResultSet rs = s.executeQuery("SELECT max(ID) from " + 476 tableName); 477 rs.next(); 478 int max = rs.getInt(1); 479 rs.close(); 480 s.close(); 481 return max; 482 } 483 484 485 491 void select(Connection conn , 492 String tableName) throws SQLException 493 { 494 495 Statement s = conn.createStatement(); 496 ResultSet rs = s.executeQuery("SELECT ID, name from " + 497 tableName + " order by id" ); 498 int count = 0; 499 int id = 0; 500 while(rs.next()) 501 { 502 int tid = rs.getInt(1); 503 String name = rs.getString(2); 504 if(name.equals("skywalker" + id) && tid!= id) 505 { 506 logMessage("DATA IN THE TABLE IS NOT AS EXPECTED"); 507 logMessage("Got :ID=" + tid + " Name=:" + name); 508 logMessage("Expected: ID=" + id + "Name=" + "skywalker" + id ); 509 } 510 511 id++; 512 count++; 513 } 514 515 rs.close(); 516 s.close(); 517 conn.commit(); 518 } 519 520 521 522 525 private Connection createEncryptedDatabase() throws SQLException 526 { 527 String connAttrs = ""; 528 if (encryptionType == USING_PASSWORD) 529 { 530 connAttrs = "create=true;dataEncryption=true;bootPassword=" + 532 OLD_PASSWORD; 533 } 534 535 if (encryptionType == USING_KEY) 536 { 537 connAttrs = "create=true;dataEncryption=true;encryptionKey=" + 539 OLD_KEY; 540 } 541 542 return TestUtil.getConnection(currentTestDatabase, connAttrs); 543 } 544 545 546 549 private Connection createDatabase() throws SQLException 550 { 551 return TestUtil.getConnection(currentTestDatabase, 552 "create=true" ); 553 } 554 555 556 560 private Connection reEncryptDatabase() throws SQLException 561 { 562 String connAttrs = ""; 563 if (encryptionType == USING_PASSWORD) 564 { 565 connAttrs = "bootPassword=" + OLD_PASSWORD + 567 ";newBootPassword=" + NEW_PASSWORD; 568 } 569 570 if (encryptionType == USING_KEY) 571 { 572 connAttrs = "encryptionKey=" + OLD_KEY + 574 ";newEncryptionKey=" + NEW_KEY; 575 } 576 577 if (verbose) 578 logMessage("re-encrypting " + currentTestDatabase + 579 " with " + connAttrs); 580 581 return TestUtil.getConnection(currentTestDatabase, connAttrs); 582 } 583 584 585 590 private Connection encryptDatabase() 591 throws SQLException 592 { 593 String connAttrs = ""; 594 if (encryptionType == USING_PASSWORD) 595 { 596 connAttrs = "dataEncryption=true;bootPassword=" + OLD_PASSWORD; 598 } 599 if (encryptionType == USING_KEY) 600 { 601 connAttrs = "dataEncryption=true;encryptionKey=" + OLD_KEY; 603 } 604 605 if (verbose) 606 logMessage("encrypting " + currentTestDatabase + 607 " with " + connAttrs); 608 return TestUtil.getConnection(currentTestDatabase, connAttrs); 609 } 610 611 612 617 Connection bootDatabase(int passwordKey) 618 throws SQLException 619 { 620 621 String connAttrs = ""; 622 if (encryptionType == USING_PASSWORD) 623 { 624 if (passwordKey == NEW) 625 connAttrs = "bootPassword=" + NEW_PASSWORD; 626 else if (passwordKey == OLD) 627 connAttrs = "bootPassword=" + OLD_PASSWORD; 628 } 629 630 631 if (encryptionType == USING_KEY) 632 { 633 if (passwordKey == NEW) 634 connAttrs = "encryptionKey=" + NEW_KEY; 635 else if (passwordKey == OLD) 636 connAttrs = "encryptionKey=" + OLD_KEY; 637 } 638 639 if (verbose) 640 logMessage("booting " + currentTestDatabase + 641 " with " + connAttrs); 642 return TestUtil.getConnection(currentTestDatabase, connAttrs); 643 } 644 645 646 647 650 void shutdown() { 651 652 if (verbose) 653 logMessage("Shutdown " + currentTestDatabase); 654 try{ 655 TestUtil.getConnection(currentTestDatabase, "shutdown=true"); 657 }catch(SQLException se){ 658 if (se.getSQLState() == null || !(se.getSQLState().equals("08006"))) 659 { 660 dumpSQLException(se); 662 } 663 } 664 665 666 } 667 668 671 private void dumpSQLException(SQLException sqle) { 672 673 org.apache.derby.tools.JDBCDisplayUtil. ShowSQLException(System.out, sqle); 674 sqle.printStackTrace(System.out); 675 } 676 677 678 void logMessage(String str) 679 { 680 System.out.println(str); 681 } 682 683 684 public static void main(String [] argv) throws Throwable { 685 686 ReEncryptCrashRecovery test = new ReEncryptCrashRecovery(); 687 try { 688 test.runTest(); 689 } 690 catch (SQLException sqle) { 691 org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException( 692 System.out, sqle); 693 sqle.printStackTrace(System.out); 694 } 695 } 696 } 697 | Popular Tags |