001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.uninstaller; 018 019import static org.forgerock.util.Utils.*; 020import static org.opends.admin.ads.util.ConnectionUtils.*; 021import static org.opends.messages.AdminToolMessages.*; 022import static org.opends.messages.QuickSetupMessages.*; 023 024import static com.forgerock.opendj.cli.ArgumentConstants.*; 025import static com.forgerock.opendj.cli.Utils.*; 026 027import java.io.BufferedReader; 028import java.io.File; 029import java.io.FileReader; 030import java.io.IOException; 031import java.net.URI; 032import java.util.Collections; 033import java.util.HashSet; 034import java.util.LinkedHashSet; 035import java.util.Set; 036 037import javax.naming.NamingException; 038import javax.naming.NoPermissionException; 039import javax.naming.ldap.InitialLdapContext; 040import javax.net.ssl.TrustManager; 041 042import org.forgerock.i18n.LocalizableMessage; 043import org.forgerock.i18n.LocalizableMessageBuilder; 044import org.forgerock.i18n.slf4j.LocalizedLogger; 045import org.opends.admin.ads.ADSContext; 046import org.opends.admin.ads.ServerDescriptor; 047import org.opends.admin.ads.TopologyCache; 048import org.opends.admin.ads.TopologyCacheException; 049import org.opends.admin.ads.util.ApplicationTrustManager; 050import org.opends.admin.ads.util.ConnectionUtils; 051import org.opends.guitools.controlpanel.datamodel.ConnectionProtocolPolicy; 052import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 053import org.opends.quicksetup.Application; 054import org.opends.quicksetup.ApplicationException; 055import org.opends.quicksetup.Configuration; 056import org.opends.quicksetup.Constants; 057import org.opends.quicksetup.Installation; 058import org.opends.quicksetup.ProgressStep; 059import org.opends.quicksetup.Step; 060import org.opends.quicksetup.UserDataException; 061import org.opends.quicksetup.event.ProgressUpdateEvent; 062import org.opends.quicksetup.event.ProgressUpdateListener; 063import org.opends.quicksetup.util.PlainTextProgressMessageFormatter; 064import org.opends.quicksetup.util.ServerController; 065import org.opends.quicksetup.util.Utils; 066import org.opends.server.admin.client.cli.SecureConnectionCliArgs; 067import org.opends.server.util.StaticUtils; 068import org.opends.server.util.cli.LDAPConnectionConsoleInteraction; 069 070import com.forgerock.opendj.cli.ArgumentException; 071import com.forgerock.opendj.cli.ClientException; 072import com.forgerock.opendj.cli.ConsoleApplication; 073import com.forgerock.opendj.cli.Menu; 074import com.forgerock.opendj.cli.MenuBuilder; 075import com.forgerock.opendj.cli.MenuResult; 076import com.forgerock.opendj.cli.ReturnCode; 077 078/** 079 * The class used to provide some CLI interface in the uninstall. 080 * 081 * This class basically is in charge of parsing the data provided by the user 082 * in the command line and displaying messages asking the user for information. 083 * 084 * Once the user has provided all the required information it calls Uninstaller 085 * and launches it. 086 * 087 */ 088public class UninstallCliHelper extends ConsoleApplication { 089 090 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 091 092 private UninstallerArgumentParser parser; 093 private LDAPConnectionConsoleInteraction ci; 094 private ControlPanelInfo info; 095 096 private boolean forceNonInteractive; 097 private boolean useSSL = true; 098 private boolean useStartTLS; 099 100 /** 101 * Default constructor. 102 */ 103 public UninstallCliHelper() 104 { 105 // Nothing to do. 106 } 107 108 /** 109 * Creates a UserData based in the arguments provided. It asks user for 110 * additional information if what is provided in the arguments is not enough. 111 * 112 * @param args 113 * the ArgumentParser with the allowed arguments of the command line. 114 * The code assumes that the arguments have already been parsed. 115 * @param rawArguments 116 * the arguments provided in the command line. 117 * @return the UserData object with what the user wants to uninstall and null 118 * if the user cancels the uninstallation. 119 * @throws UserDataException 120 * if there is an error with the data in the arguments. 121 * @throws ClientException 122 * If there is an error processing data in non-interactive mode and 123 * an error must be thrown (not in force on error mode). 124 */ 125 public UninstallUserData createUserData(UninstallerArgumentParser args, 126 String[] rawArguments) 127 throws UserDataException, ClientException 128 { 129 parser = args; 130 UninstallUserData userData = new UninstallUserData(); 131 try 132 { 133 boolean isInteractive; 134 boolean isQuiet; 135 boolean isVerbose; 136 boolean isCanceled = false; 137 138 /* Step 1: analyze the arguments. 139 */ 140 141 isInteractive = args.isInteractive(); 142 143 isQuiet = args.isQuiet(); 144 145 isVerbose = args.isVerbose(); 146 147 userData.setQuiet(isQuiet); 148 userData.setVerbose(isVerbose); 149 userData.setForceOnError(args.isForceOnError()); 150 userData.setTrustManager(args.getTrustManager()); 151 152 userData.setConnectTimeout(getConnectTimeout()); 153 154 /* 155 * Step 2: check that the provided parameters are compatible. 156 */ 157 LocalizableMessageBuilder buf = new LocalizableMessageBuilder(); 158 int v = args.validateGlobalOptions(buf); 159 if (v != ReturnCode.SUCCESS.get()) 160 { 161 throw new UserDataException(null, buf.toMessage()); 162 } 163 164 /* Step 3: If this is an interactive uninstall ask for confirmation to 165 * delete the different parts of the installation if the user did not 166 * specify anything to delete. If we are not in interactive mode 167 * check that the user specified something to be deleted. 168 */ 169 Set<String> outsideDbs; 170 Set<String> outsideLogs; 171 Configuration config = 172 Installation.getLocal().getCurrentConfiguration(); 173 try { 174 outsideDbs = config.getOutsideDbs(); 175 } catch (IOException ioe) { 176 outsideDbs = Collections.emptySet(); 177 logger.info(LocalizableMessage.raw("error determining outside databases", ioe)); 178 } 179 180 try { 181 outsideLogs = config.getOutsideLogs(); 182 } catch (IOException ioe) { 183 outsideLogs = Collections.emptySet(); 184 logger.info(LocalizableMessage.raw("error determining outside logs", ioe)); 185 } 186 187 boolean somethingSpecifiedToDelete = 188 args.removeAll() || 189 args.removeBackupFiles() || 190 args.removeDatabases() || 191 args.removeLDIFFiles() || 192 args.removeConfigurationFiles() || 193 args.removeLogFiles() || 194 args.removeServerLibraries(); 195 196 if (somethingSpecifiedToDelete) 197 { 198 userData.setRemoveBackups(args.removeAll() || args.removeBackupFiles()); 199 userData.setRemoveConfigurationAndSchema(args.removeAll() || 200 args.removeConfigurationFiles()); 201 userData.setRemoveDatabases(args.removeAll() || args.removeDatabases()); 202 userData.setRemoveLDIFs(args.removeAll() || args.removeLDIFFiles()); 203 userData.setRemoveLibrariesAndTools(args.removeAll() || 204 args.removeServerLibraries()); 205 userData.setRemoveLogs(args.removeAll() || args.removeLogFiles()); 206 207 userData.setExternalDbsToRemove(outsideDbs); 208 userData.setExternalLogsToRemove(outsideLogs); 209 } 210 else if (!isInteractive) 211 { 212 throw new UserDataException(null, 213 ERR_CLI_UNINSTALL_NOTHING_TO_BE_UNINSTALLED_NON_INTERACTIVE.get()); 214 } 215 else 216 { 217 isCanceled = askWhatToDelete(userData, outsideDbs, outsideLogs); 218 } 219 String adminUid = args.getAdministratorUID(); 220 if (adminUid == null && !args.isInteractive()) 221 { 222 adminUid = args.getDefaultAdministratorUID(); 223 } 224 userData.setAdminUID(adminUid); 225 userData.setAdminPwd(args.getBindPassword()); 226 String referencedHostName = args.getReferencedHostName(); 227 if (referencedHostName == null && !args.isInteractive()) 228 { 229 referencedHostName = args.getDefaultReferencedHostName(); 230 } 231 try 232 { 233 UninstallData d = new UninstallData(Installation.getLocal()); 234 userData.setReplicationServer( 235 referencedHostName+":"+d.getReplicationServerPort()); 236 } 237 catch (Throwable t) 238 { 239 logger.error(LocalizableMessage.raw("Could not create UninstallData: "+t, t)); 240 userData.setReplicationServer( 241 referencedHostName+":8989"); 242 } 243 info = ControlPanelInfo.getInstance(); 244 info.setTrustManager(userData.getTrustManager()); 245 info.setConnectTimeout(getConnectTimeout()); 246 info.regenerateDescriptor(); 247 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 248 249 String adminConnectorUrl = info.getAdminConnectorURL(); 250 251 if (adminConnectorUrl == null) 252 { 253 logger.warn(LocalizableMessage.raw( 254 "Error retrieving a valid LDAP URL in conf file.")); 255 if (!parser.isInteractive()) 256 { 257 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 258 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 259 } 260 } 261 userData.setLocalServerUrl(adminConnectorUrl); 262 userData.setReferencedHostName(referencedHostName); 263 264 /* 265 * Step 4: check if server is running. Depending if it is running and the 266 * OS we are running, ask for authentication information. 267 */ 268 if (!isCanceled) 269 { 270 isCanceled = checkServerState(userData); 271 } 272 273 if (isCanceled && !userData.isForceOnError()) 274 { 275 logger.info(LocalizableMessage.raw("User cancelled uninstall.")); 276 userData = null; 277 } 278 279 if (userData != null && !args.isQuiet()) 280 { 281 println(); 282 } 283 } 284 catch (Throwable t) 285 { 286 logger.warn(LocalizableMessage.raw("Exception: "+t, t)); 287 if (t instanceof UserDataException) 288 { 289 throw (UserDataException)t; 290 } 291 else if (t instanceof ClientException) 292 { 293 throw (ClientException)t; 294 } 295 else 296 { 297 throw new IllegalStateException("Unexpected error: "+t, t); 298 } 299 } 300 logger.info(LocalizableMessage.raw("Successfully created user data")); 301 return userData; 302 } 303 304 /** 305 * Commodity method used to ask the user to confirm the deletion of certain 306 * parts of the server. It updates the provided UserData object 307 * accordingly. Returns <CODE>true</CODE> if the user cancels and <CODE> 308 * false</CODE> otherwise. 309 * @param userData the UserData object to be updated. 310 * @param outsideDbs the set of relative paths of databases located outside 311 * the installation path of the server. 312 * @param outsideLogs the set of relative paths of log files located outside 313 * the installation path of the server. 314 * @return <CODE>true</CODE> if the user cancels and <CODE>false</CODE> 315 * otherwise. 316 */ 317 private boolean askWhatToDelete(UninstallUserData userData, 318 Set<String> outsideDbs, Set<String> outsideLogs) throws UserDataException 319 { 320 boolean cancelled = false; 321 final int REMOVE_ALL = 1; 322 final int SPECIFY_TO_REMOVE = 2; 323 int[] indexes = {REMOVE_ALL, SPECIFY_TO_REMOVE}; 324 LocalizableMessage[] msgs = new LocalizableMessage[] { 325 INFO_CLI_UNINSTALL_REMOVE_ALL.get(), 326 INFO_CLI_UNINSTALL_SPECIFY_WHAT_REMOVE.get() 327 }; 328 329 MenuBuilder<Integer> builder = new MenuBuilder<>(this); 330 builder.setPrompt(INFO_CLI_UNINSTALL_WHAT_TO_DELETE.get()); 331 332 for (int i=0; i<indexes.length; i++) 333 { 334 builder.addNumberedOption(msgs[i], MenuResult.success(indexes[i])); 335 } 336 337 builder.addQuitOption(); 338 339 builder.setDefault(LocalizableMessage.raw(String.valueOf(REMOVE_ALL)), 340 MenuResult.success(REMOVE_ALL)); 341 342 builder.setMaxTries(CONFIRMATION_MAX_TRIES); 343 344 Menu<Integer> menu = builder.toMenu(); 345 int choice; 346 try 347 { 348 MenuResult<Integer> m = menu.run(); 349 if (m.isSuccess()) 350 { 351 choice = m.getValue(); 352 } 353 else if (m.isQuit()) 354 { 355 choice = REMOVE_ALL; 356 cancelled = true; 357 } 358 else 359 { 360 // Should never happen. 361 throw new RuntimeException(); 362 } 363 } 364 catch (ClientException ce) 365 { 366 logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce)); 367 throw new UserDataException(null, ce.getMessageObject(), ce); 368 } 369 370 if (cancelled) 371 { 372 // Nothing to do 373 } 374 else if (choice == REMOVE_ALL) 375 { 376 userData.setRemoveBackups(true); 377 userData.setRemoveConfigurationAndSchema(true); 378 userData.setRemoveDatabases(true); 379 userData.setRemoveLDIFs(true); 380 userData.setRemoveLibrariesAndTools(true); 381 userData.setRemoveLogs(true); 382 383 userData.setExternalDbsToRemove(outsideDbs); 384 userData.setExternalLogsToRemove(outsideLogs); 385 } 386 else 387 { 388 boolean somethingSelected = false; 389 while (!somethingSelected && !cancelled) 390 { 391 println(); 392// Ask for confirmation for the different items 393 msgs = new LocalizableMessage [] { 394 INFO_CLI_UNINSTALL_CONFIRM_LIBRARIES_BINARIES.get(), 395 INFO_CLI_UNINSTALL_CONFIRM_DATABASES.get(), 396 INFO_CLI_UNINSTALL_CONFIRM_LOGS.get(), 397 INFO_CLI_UNINSTALL_CONFIRM_CONFIGURATION_SCHEMA.get(), 398 INFO_CLI_UNINSTALL_CONFIRM_BACKUPS.get(), 399 INFO_CLI_UNINSTALL_CONFIRM_LDIFS.get(), 400 INFO_CLI_UNINSTALL_CONFIRM_OUTSIDEDBS.get( 401 joinAsString(Constants.LINE_SEPARATOR, outsideDbs)), 402 INFO_CLI_UNINSTALL_CONFIRM_OUTSIDELOGS.get( 403 joinAsString(Constants.LINE_SEPARATOR, outsideLogs) 404 ) 405 }; 406 407 boolean[] answers = new boolean[msgs.length]; 408 try 409 { 410 for (int i=0; i<msgs.length; i++) 411 { 412 boolean ignore = (i == 6 && outsideDbs.isEmpty()) 413 || (i == 7 && outsideLogs.isEmpty()); 414 if (!ignore) 415 { 416 answers[i] = askConfirmation(msgs[i], true, logger); 417 } 418 else 419 { 420 answers[i] = false; 421 } 422 } 423 } 424 catch (ClientException ce) 425 { 426 throw new UserDataException(null, ce.getMessageObject(), ce); 427 } 428 429 if (!cancelled) 430 { 431 for (int i=0; i<answers.length; i++) 432 { 433 switch (i) 434 { 435 case 0: 436 userData.setRemoveLibrariesAndTools(answers[i]); 437 break; 438 439 case 1: 440 userData.setRemoveDatabases(answers[i]); 441 break; 442 443 case 2: 444 userData.setRemoveLogs(answers[i]); 445 break; 446 447 case 3: 448 userData.setRemoveConfigurationAndSchema(answers[i]); 449 break; 450 451 case 4: 452 userData.setRemoveBackups(answers[i]); 453 break; 454 455 case 5: 456 userData.setRemoveLDIFs(answers[i]); 457 break; 458 459 case 6: 460 if (answers[i]) 461 { 462 userData.setExternalDbsToRemove(outsideDbs); 463 } 464 break; 465 466 case 7: 467 if (answers[i]) 468 { 469 userData.setExternalLogsToRemove(outsideLogs); 470 } 471 break; 472 } 473 } 474 if (userData.getExternalDbsToRemove().isEmpty() && 475 userData.getExternalLogsToRemove().isEmpty() && 476 !userData.getRemoveLibrariesAndTools() && 477 !userData.getRemoveDatabases() && 478 !userData.getRemoveConfigurationAndSchema() && 479 !userData.getRemoveBackups() && 480 !userData.getRemoveLDIFs() && 481 !userData.getRemoveLogs()) 482 { 483 somethingSelected = false; 484 println(); 485 printErrorMessage( 486 ERR_CLI_UNINSTALL_NOTHING_TO_BE_UNINSTALLED.get()); 487 } 488 else 489 { 490 somethingSelected = true; 491 } 492 } 493 } 494 } 495 496 return cancelled; 497 } 498 499 /** 500 * Commodity method used to ask the user (when necessary) if the server must 501 * be stopped or not. It also prompts (if required) for authentication. 502 * 503 * @param userData 504 * the UserData object to be updated with the authentication of the 505 * user. 506 * @return <CODE>true</CODE> if the user wants to continue with uninstall and 507 * <CODE>false</CODE> otherwise. 508 * @throws UserDataException 509 * if there is a problem with the data provided by the user (in the 510 * particular case where we are on non-interactive uninstall and 511 * some data is missing or not valid). 512 * @throws ClientException 513 * If there is an error processing data in non-interactive mode and 514 * an error must be thrown (not in force on error mode). 515 */ 516 private boolean checkServerState(UninstallUserData userData) 517 throws UserDataException, ClientException 518 { 519 boolean cancelled = false; 520 boolean interactive = parser.isInteractive(); 521 boolean forceOnError = parser.isForceOnError(); 522 UninstallData conf = null; 523 try 524 { 525 conf = new UninstallData(Installation.getLocal()); 526 } 527 catch (Throwable t) 528 { 529 logger.warn(LocalizableMessage.raw("Error processing task: "+t, t)); 530 throw new UserDataException(Step.CONFIRM_UNINSTALL, 531 getThrowableMsg(INFO_BUG_MSG.get(), t)); 532 } 533 logger.info(LocalizableMessage.raw("interactive: "+interactive)); 534 logger.info(LocalizableMessage.raw("forceOnError: "+forceOnError)); 535 logger.info(LocalizableMessage.raw("conf.isADS(): "+conf.isADS())); 536 logger.info(LocalizableMessage.raw("conf.isReplicationServer(): "+ 537 conf.isReplicationServer())); 538 logger.info(LocalizableMessage.raw("conf.isServerRunning(): "+conf.isServerRunning())); 539 if (conf.isADS() && conf.isReplicationServer()) 540 { 541 if (conf.isServerRunning()) 542 { 543 if (interactive) 544 { 545 try 546 { 547 println(); 548 if (confirmToUpdateRemote()) 549 { 550 cancelled = !askForAuthenticationIfNeeded(userData); 551 if (cancelled) 552 { 553 /* Ask for confirmation to stop server */ 554 println(); 555 cancelled = !confirmToStopServer(); 556 } 557 else 558 { 559 cancelled = !updateUserUninstallDataWithRemoteServers(userData); 560 if (cancelled) 561 { 562 println(); 563 /* Ask for confirmation to stop server */ 564 cancelled = !confirmToStopServer(); 565 } 566 } 567 } 568 else 569 { 570 /* Ask for confirmation to stop server */ 571 cancelled = !confirmToStopServer(); 572 } 573 } 574 catch (ClientException ce) 575 { 576 throw new UserDataException(null, ce.getMessageObject(), ce); 577 } 578 } 579 else 580 { 581 boolean errorWithRemote = 582 !updateUserUninstallDataWithRemoteServers(userData); 583 cancelled = errorWithRemote && !parser.isForceOnError(); 584 logger.info(LocalizableMessage.raw("Non interactive mode. errorWithRemote: "+ 585 errorWithRemote)); 586 } 587 } 588 else if (interactive) 589 { 590 println(); 591 try 592 { 593 if (confirmToUpdateRemoteAndStart()) 594 { 595 boolean startWorked = startServer(userData.isQuiet()); 596 // Ask for authentication if needed, etc. 597 if (startWorked) 598 { 599 cancelled = !askForAuthenticationIfNeeded(userData); 600 if (cancelled) 601 { 602 println(); 603 /* Ask for confirmation to stop server */ 604 cancelled = !confirmToStopServer(); 605 } 606 else 607 { 608 cancelled = 609 !updateUserUninstallDataWithRemoteServers(userData); 610 if (cancelled) 611 { 612 println(); 613 /* Ask for confirmation to stop server */ 614 cancelled = !confirmToStopServer(); 615 } 616 } 617 userData.setStopServer(true); 618 } 619 else 620 { 621 userData.setStopServer(false); 622 println(); 623 /* Ask for confirmation to delete files */ 624 cancelled = !confirmDeleteFiles(); 625 } 626 } 627 else 628 { 629 println(); 630 /* Ask for confirmation to delete files */ 631 cancelled = !confirmDeleteFiles(); 632 } 633 } 634 catch (ClientException ce) 635 { 636 throw new UserDataException(null, ce.getMessageObject(), ce); 637 } 638 } 639 else 640 { 641 boolean startWorked = startServer(userData.isQuiet()); 642 // Ask for authentication if needed, etc. 643 if (startWorked) 644 { 645 userData.setStopServer(true); 646 boolean errorWithRemote = 647 !updateUserUninstallDataWithRemoteServers(userData); 648 cancelled = errorWithRemote && !parser.isForceOnError(); 649 } 650 else 651 { 652 cancelled = !forceOnError; 653 userData.setStopServer(false); 654 } 655 } 656 if (!cancelled || parser.isForceOnError()) 657 { 658 /* During all the confirmations, the server might be stopped. */ 659 userData.setStopServer( 660 Installation.getLocal().getStatus().isServerRunning()); 661 logger.info(LocalizableMessage.raw("Must stop the server after confirmations? "+ 662 userData.getStopServer())); 663 } 664 } 665 else if (conf.isServerRunning()) 666 { 667 try 668 { 669 if (interactive) 670 { 671 println(); 672 /* Ask for confirmation to stop server */ 673 cancelled = !confirmToStopServer(); 674 } 675 676 if (!cancelled) 677 { 678 /* During all the confirmations, the server might be stopped. */ 679 userData.setStopServer( 680 Installation.getLocal().getStatus().isServerRunning()); 681 logger.info(LocalizableMessage.raw("Must stop the server after confirmations? "+ 682 userData.getStopServer())); 683 } 684 } 685 catch (ClientException ce) 686 { 687 throw new UserDataException(null, ce.getMessageObject(), ce); 688 } 689 } 690 else 691 { 692 userData.setStopServer(false); 693 if (interactive) 694 { 695 println(); 696 /* Ask for confirmation to delete files */ 697 try 698 { 699 cancelled = !confirmDeleteFiles(); 700 } 701 catch (ClientException ce) 702 { 703 throw new UserDataException(null, ce.getMessageObject(), ce); 704 } 705 } 706 } 707 logger.info(LocalizableMessage.raw("cancelled: "+cancelled)); 708 return cancelled; 709 } 710 711 /** 712 * Ask for confirmation to stop server. 713 * @return <CODE>true</CODE> if the user wants to continue and stop the 714 * server. <CODE>false</CODE> otherwise. 715 * @throws ClientException if the user reached the confirmation limit. 716 */ 717 private boolean confirmToStopServer() throws ClientException 718 { 719 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_STOP.get(), true, logger); 720 } 721 722 /** 723 * Ask for confirmation to delete files. 724 * @return <CODE>true</CODE> if the user wants to continue and delete the 725 * files. <CODE>false</CODE> otherwise. 726 * @throws ClientException if the user reached the confirmation limit. 727 */ 728 private boolean confirmDeleteFiles() throws ClientException 729 { 730 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_DELETE_FILES.get(), true, 731 logger); 732 } 733 734 /** 735 * Ask for confirmation to update configuration on remote servers. 736 * @return <CODE>true</CODE> if the user wants to continue and stop the 737 * server. <CODE>false</CODE> otherwise. 738 * @throws ClientException if the user reached the confirmation limit. 739 */ 740 private boolean confirmToUpdateRemote() throws ClientException 741 { 742 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_UPDATE_REMOTE.get(), true, 743 logger); 744 } 745 746 /** 747 * Ask for confirmation to update configuration on remote servers. 748 * @return <CODE>true</CODE> if the user wants to continue and stop the 749 * server. <CODE>false</CODE> otherwise. 750 * @throws ClientException if the user reached the confirmation limit. 751 */ 752 private boolean confirmToUpdateRemoteAndStart() throws ClientException 753 { 754 return askConfirmation( 755 INFO_CLI_UNINSTALL_CONFIRM_UPDATE_REMOTE_AND_START.get(), true, logger); 756 } 757 758 /** 759 * Ask for confirmation to provide again authentication. 760 * @return <CODE>true</CODE> if the user wants to provide authentication 761 * again. <CODE>false</CODE> otherwise. 762 * @throws ClientException if the user reached the confirmation limit. 763 */ 764 private boolean promptToProvideAuthenticationAgain() throws ClientException 765 { 766 return askConfirmation( 767 INFO_UNINSTALL_CONFIRM_PROVIDE_AUTHENTICATION_AGAIN.get(), true, logger); 768 } 769 770 /** 771 * Ask for data required to update configuration on remote servers. If all the 772 * data is provided and validated, we assume that the user wants to update the 773 * remote servers. 774 * 775 * @return <CODE>true</CODE> if the user wants to continue and update the 776 * remote servers. <CODE>false</CODE> otherwise. 777 * @throws UserDataException 778 * if there is a problem with the information provided by the user. 779 * @throws ClientException 780 * If there is an error processing data. 781 */ 782 private boolean askForAuthenticationIfNeeded(UninstallUserData userData) 783 throws UserDataException, ClientException 784 { 785 boolean accepted = true; 786 String uid = userData.getAdminUID(); 787 String pwd = userData.getAdminPwd(); 788 789 boolean couldConnect = false; 790 791 while (!couldConnect && accepted) 792 { 793 794 // This is done because we do not need to ask the user about these parameters. 795 // If we force their presence the class LDAPConnectionConsoleInteraction will not prompt the user for them. 796 SecureConnectionCliArgs secureArgsList = parser.getSecureArgsList(); 797 798 secureArgsList.getHostNameArg().setPresent(true); 799 secureArgsList.getPortArg().setPresent(true); 800 secureArgsList.getHostNameArg().clearValues(); 801 secureArgsList.getHostNameArg().addValue( 802 secureArgsList.getHostNameArg().getDefaultValue()); 803 secureArgsList.getPortArg().clearValues(); 804 secureArgsList.getPortArg().addValue( 805 secureArgsList.getPortArg().getDefaultValue()); 806 secureArgsList.getBindDnArg().clearValues(); 807 if (uid != null) 808 { 809 secureArgsList.getBindDnArg().addValue(ADSContext.getAdministratorDN(uid)); 810 secureArgsList.getBindDnArg().setPresent(true); 811 } 812 else 813 { 814 secureArgsList.getBindDnArg().setPresent(false); 815 } 816 secureArgsList.getBindPasswordArg().clearValues(); 817 if (pwd != null) 818 { 819 secureArgsList.getBindPasswordArg().addValue(pwd); 820 secureArgsList.getBindPasswordArg().setPresent(true); 821 } 822 else 823 { 824 secureArgsList.getBindPasswordArg().setPresent(false); 825 } 826 827 if (ci == null) 828 { 829 ci = 830 new LDAPConnectionConsoleInteraction(this, parser.getSecureArgsList()); 831 ci.setDisplayLdapIfSecureParameters(true); 832 } 833 834 try 835 { 836 ci.run(false); 837 userData.setAdminUID(ci.getAdministratorUID()); 838 userData.setAdminPwd(ci.getBindPassword()); 839 840 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 841 842 String adminConnectorUrl = info.getAdminConnectorURL(); 843 if (adminConnectorUrl == null) 844 { 845 logger.warn(LocalizableMessage.raw( 846 "Error retrieving a valid Administration Connector URL in conf file.")); 847 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 848 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 849 } 850 try 851 { 852 URI uri = new URI(adminConnectorUrl); 853 int port = uri.getPort(); 854 secureArgsList.getPortArg().clearValues(); 855 secureArgsList.getPortArg().addValue(String.valueOf(port)); 856 ci.setPortNumber(port); 857 } 858 catch (Throwable t) 859 { 860 logger.error(LocalizableMessage.raw("Error parsing url: "+adminConnectorUrl)); 861 } 862 updateTrustManager(userData, ci); 863 864 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 865 866 adminConnectorUrl = info.getAdminConnectorURL(); 867 868 if (adminConnectorUrl == null) 869 { 870 logger.warn(LocalizableMessage.raw( 871 "Error retrieving a valid Administration Connector URL in conf file.")); 872 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 873 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 874 } 875 876 userData.setLocalServerUrl(adminConnectorUrl); 877 couldConnect = true; 878 } 879 catch (ArgumentException e) 880 { 881 parser.displayMessageAndUsageReference(getErrStream(), e.getMessageObject()); 882 } 883 catch (ClientException e) { 884 printErrorMessage(e.getMessageObject()); 885 println(); 886 } 887 888 if (!couldConnect) 889 { 890 try 891 { 892 accepted = promptToProvideAuthenticationAgain(); 893 if (accepted) 894 { 895 uid = null; 896 pwd = null; 897 } 898 } 899 catch (ClientException ce) 900 { 901 throw new UserDataException(null, ce.getMessageObject(), ce); 902 } 903 } 904 } 905 906 if (accepted) 907 { 908 String referencedHostName = parser.getReferencedHostName(); 909 while (referencedHostName == null) 910 { 911 println(); 912 referencedHostName = askForReferencedHostName(userData.getHostName()); 913 } 914 try 915 { 916 UninstallData d = new UninstallData(Installation.getLocal()); 917 userData.setReplicationServer( 918 referencedHostName+":"+d.getReplicationServerPort()); 919 userData.setReferencedHostName(referencedHostName); 920 } 921 catch (Throwable t) 922 { 923 logger.error(LocalizableMessage.raw("Could not create UninstallData: "+t, t)); 924 } 925 } 926 userData.setUpdateRemoteReplication(accepted); 927 return accepted; 928 } 929 930 private String askForReferencedHostName(String defaultHostName) 931 { 932 String s = defaultHostName; 933 try 934 { 935 s = readInput(INFO_UNINSTALL_CLI_REFERENCED_HOSTNAME_PROMPT.get(), 936 defaultHostName); 937 } 938 catch (ClientException ce) 939 { 940 logger.warn(LocalizableMessage.raw("Error reading input: %s", ce), ce); 941 } 942 return s; 943 } 944 945 private boolean startServer(boolean suppressOutput) 946 { 947 logger.info(LocalizableMessage.raw("startServer, suppressOutput: " + suppressOutput)); 948 boolean serverStarted = false; 949 Application application = new Application() 950 { 951 /** {@inheritDoc} */ 952 @Override 953 public String getInstallationPath() 954 { 955 return Installation.getLocal().getRootDirectory().getAbsolutePath(); 956 } 957 /** {@inheritDoc} */ 958 @Override 959 public String getInstancePath() 960 { 961 String installPath = getInstallationPath(); 962 963 // look for <installPath>/lib/resource.loc 964 String instancePathFileName = installPath + File.separator + "lib" 965 + File.separator + "resource.loc"; 966 File f = new File(instancePathFileName); 967 968 if (! f.exists()) 969 { 970 return installPath; 971 } 972 973 BufferedReader reader; 974 try 975 { 976 reader = new BufferedReader(new FileReader(instancePathFileName)); 977 } 978 catch (Exception e) 979 { 980 return installPath; 981 } 982 983 984 // Read the first line and close the file. 985 String line; 986 try 987 { 988 line = reader.readLine(); 989 return new File(line).getAbsolutePath(); 990 } 991 catch (Exception e) 992 { 993 return installPath; 994 } 995 finally 996 { 997 StaticUtils.close(reader); 998 } 999 } 1000 /** {@inheritDoc} */ 1001 @Override 1002 public ProgressStep getCurrentProgressStep() 1003 { 1004 return UninstallProgressStep.NOT_STARTED; 1005 } 1006 /** {@inheritDoc} */ 1007 @Override 1008 public Integer getRatio(ProgressStep step) 1009 { 1010 return 0; 1011 } 1012 /** {@inheritDoc} */ 1013 @Override 1014 public LocalizableMessage getSummary(ProgressStep step) 1015 { 1016 return null; 1017 } 1018 /** {@inheritDoc} */ 1019 @Override 1020 public boolean isFinished() 1021 { 1022 return false; 1023 } 1024 /** {@inheritDoc} */ 1025 @Override 1026 public boolean isCancellable() 1027 { 1028 return false; 1029 } 1030 /** {@inheritDoc} */ 1031 @Override 1032 public void cancel() 1033 { 1034 } 1035 /** {@inheritDoc} */ 1036 @Override 1037 public void run() 1038 { 1039 } 1040 }; 1041 application.setProgressMessageFormatter( 1042 new PlainTextProgressMessageFormatter()); 1043 if (!suppressOutput) 1044 { 1045 application.addProgressUpdateListener( 1046 new ProgressUpdateListener() { 1047 @Override 1048 public void progressUpdate(ProgressUpdateEvent ev) { 1049 System.out.print(ev.getNewLogs().toString()); 1050 System.out.flush(); 1051 } 1052 }); 1053 } 1054 ServerController controller = new ServerController(application, 1055 Installation.getLocal()); 1056 try 1057 { 1058 if (!suppressOutput) 1059 { 1060 println(); 1061 } 1062 controller.startServer(suppressOutput); 1063 if (!suppressOutput) 1064 { 1065 println(); 1066 } 1067 serverStarted = Installation.getLocal().getStatus().isServerRunning(); 1068 logger.info(LocalizableMessage.raw("server started successfully. serverStarted: "+ 1069 serverStarted)); 1070 } 1071 catch (ApplicationException ae) 1072 { 1073 logger.warn(LocalizableMessage.raw("ApplicationException: "+ae, ae)); 1074 if (!suppressOutput) 1075 { 1076 printErrorMessage(ae.getMessageObject()); 1077 } 1078 } 1079 catch (Throwable t) 1080 { 1081 logger.error(LocalizableMessage.raw("Unexpected error: "+t, t)); 1082 throw new IllegalStateException("Unexpected error: "+t, t); 1083 } 1084 return serverStarted; 1085 } 1086 1087 /** 1088 * Returns an InitialLdapContext using the provided parameters. We try to 1089 * guarantee that the connection is able to read the configuration. 1090 * 1091 * @param host 1092 * the host name. 1093 * @param port 1094 * the port to connect. 1095 * @param useSSL 1096 * whether to use SSL or not. 1097 * @param useStartTLS 1098 * whether to use StartTLS or not. 1099 * @param bindDn 1100 * the bind dn to be used. 1101 * @param pwd 1102 * the password. 1103 * @param connectTimeout 1104 * the timeout in milliseconds to connect to the server. 1105 * @param trustManager 1106 * the trust manager. 1107 * @return an InitialLdapContext connected. 1108 * @throws NamingException 1109 * if there was an error establishing the connection. 1110 */ 1111 private InitialLdapContext createAdministrativeContext(String host, 1112 int port, boolean useSSL, boolean useStartTLS, String bindDn, String pwd, 1113 int connectTimeout, ApplicationTrustManager trustManager) 1114 throws NamingException 1115 { 1116 InitialLdapContext ctx; 1117 String ldapUrl = ConnectionUtils.getLDAPUrl(host, port, useSSL); 1118 if (useSSL) 1119 { 1120 ctx = createLdapsContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null); 1121 } 1122 else if (useStartTLS) 1123 { 1124 ctx = 1125 Utils.createStartTLSContext(ldapUrl, bindDn, pwd, connectTimeout, 1126 null, trustManager, null); 1127 } 1128 else 1129 { 1130 ctx = createLdapContext(ldapUrl, bindDn, pwd, connectTimeout, null); 1131 } 1132 if (!ConnectionUtils.connectedAsAdministrativeUser(ctx)) 1133 { 1134 throw new NoPermissionException(ERR_NOT_ADMINISTRATIVE_USER.get() 1135 .toString()); 1136 } 1137 return ctx; 1138 } 1139 1140 /** 1141 * Updates the contents of the UninstallUserData while trying to connect to 1142 * the remote servers. It returns <CODE>true</CODE> if we could connect to the 1143 * remote servers and all the presented certificates were accepted and 1144 * <CODE>false</CODE> otherwise. continue if 1145 * 1146 * @param userData 1147 * the user data to be updated. 1148 * @return <CODE>true</CODE> if we could connect to the remote servers and all 1149 * the presented certificates were accepted and <CODE>false</CODE> 1150 * otherwise. 1151 * @throws UserDataException 1152 * if were are not in interactive mode and not in force on error 1153 * mode and the operation must be stopped. 1154 * @throws ClientException 1155 * If there is an error processing data in non-interactive mode and 1156 * an error must be thrown (not in force on error mode). 1157 */ 1158 private boolean updateUserUninstallDataWithRemoteServers( 1159 UninstallUserData userData) throws UserDataException, ClientException 1160 { 1161 boolean accepted = false; 1162 boolean interactive = parser.isInteractive(); 1163 boolean forceOnError = parser.isForceOnError(); 1164 1165 boolean exceptionOccurred = true; 1166 1167 LocalizableMessage exceptionMsg = null; 1168 1169 logger.info(LocalizableMessage.raw("Updating user data with remote servers.")); 1170 1171 InitialLdapContext ctx = null; 1172 try 1173 { 1174 info.setTrustManager(userData.getTrustManager()); 1175 info.setConnectTimeout(getConnectTimeout()); 1176 String host = "localhost"; 1177 int port = 389; 1178 String adminUid = userData.getAdminUID(); 1179 String pwd = userData.getAdminPwd(); 1180 String dn = ADSContext.getAdministratorDN(adminUid); 1181 1182 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 1183 String adminConnectorUrl = info.getAdminConnectorURL(); 1184 try 1185 { 1186 URI uri = new URI(adminConnectorUrl); 1187 host = uri.getHost(); 1188 port = uri.getPort(); 1189 } 1190 catch (Throwable t) 1191 { 1192 logger.error(LocalizableMessage.raw("Error parsing url: "+adminConnectorUrl)); 1193 } 1194 ctx = createAdministrativeContext(host, port, useSSL, useStartTLS, dn, 1195 pwd, getConnectTimeout(), 1196 userData.getTrustManager()); 1197 1198 ADSContext adsContext = new ADSContext(ctx); 1199 if (interactive && userData.getTrustManager() == null) 1200 { 1201 // This is required when the user did connect to the server using SSL 1202 // or Start TLS in interactive mode. In this case 1203 // LDAPConnectionInteraction.run does not initialize the keystore and 1204 // the trust manager is null. 1205 forceTrustManagerInitialization(); 1206 updateTrustManager(userData, ci); 1207 } 1208 logger.info(LocalizableMessage.raw("Reloading topology")); 1209 TopologyCache cache = new TopologyCache(adsContext, 1210 userData.getTrustManager(), getConnectTimeout()); 1211 cache.getFilter().setSearchMonitoringInformation(false); 1212 cache.reloadTopology(); 1213 1214 accepted = handleTopologyCache(cache, userData); 1215 1216 exceptionOccurred = false; 1217 } 1218 catch (NamingException ne) 1219 { 1220 logger.warn(LocalizableMessage.raw("Error connecting to server: "+ne, ne)); 1221 if (isCertificateException(ne)) 1222 { 1223 String details = ne.getMessage() != null ? 1224 ne.getMessage() : ne.toString(); 1225 exceptionMsg = INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE.get(details); 1226 } 1227 else 1228 { 1229 exceptionMsg = getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne); 1230 } 1231 } catch (TopologyCacheException te) 1232 { 1233 logger.warn(LocalizableMessage.raw("Error connecting to server: "+te, te)); 1234 exceptionMsg = Utils.getMessage(te); 1235 1236 } catch (ClientException ce) 1237 { 1238 throw ce; 1239 1240 } catch (Throwable t) 1241 { 1242 logger.warn(LocalizableMessage.raw("Error connecting to server: "+t, t)); 1243 exceptionMsg = getThrowableMsg(INFO_BUG_MSG.get(), t); 1244 } 1245 finally 1246 { 1247 StaticUtils.close(ctx); 1248 } 1249 if (exceptionOccurred) 1250 { 1251 if (!interactive) 1252 { 1253 if (forceOnError) 1254 { 1255 println(); 1256 printErrorMessage(ERR_UNINSTALL_ERROR_UPDATING_REMOTE_FORCE.get( 1257 "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(), 1258 "--" + OPTION_LONG_BINDPWD, 1259 "--" + OPTION_LONG_BINDPWD_FILE, 1260 exceptionMsg)); 1261 } 1262 else 1263 { 1264 println(); 1265 throw new UserDataException(null, 1266 ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get( 1267 "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(), 1268 "--" + OPTION_LONG_BINDPWD, 1269 "--" + OPTION_LONG_BINDPWD_FILE, 1270 "--" + parser.forceOnErrorArg.getLongIdentifier(), 1271 exceptionMsg)); 1272 } 1273 } 1274 else 1275 { 1276 try 1277 { 1278 accepted = askConfirmation( 1279 ERR_UNINSTALL_NOT_UPDATE_REMOTE_PROMPT.get(), 1280 false, logger); 1281 } 1282 catch (ClientException ce) 1283 { 1284 throw new UserDataException(null, ce.getMessageObject(), ce); 1285 } 1286 } 1287 } 1288 userData.setUpdateRemoteReplication(accepted); 1289 logger.info(LocalizableMessage.raw("accepted: "+accepted)); 1290 return accepted; 1291 } 1292 1293 /** 1294 * Method that interacts with the user depending on what errors where 1295 * encountered in the TopologyCache object. This method assumes that the 1296 * TopologyCache has been reloaded. 1297 * Returns <CODE>true</CODE> if the user accepts all the problems encountered 1298 * and <CODE>false</CODE> otherwise. 1299 * @param userData the user data. 1300 * @throws UserDataException if there is an error with the information 1301 * provided by the user when we are in non-interactive mode. 1302 * @throws ClientException if there is an error processing data in 1303 * non-interactive mode and an error must be thrown (not in force on error 1304 * mode). 1305 */ 1306 private boolean handleTopologyCache(TopologyCache cache, 1307 UninstallUserData userData) throws UserDataException, ClientException 1308 { 1309 boolean returnValue; 1310 boolean stopProcessing = false; 1311 boolean reloadTopologyCache = false; 1312 1313 logger.info(LocalizableMessage.raw("Handle topology cache.")); 1314 1315 Set<TopologyCacheException> exceptions = new HashSet<>(); 1316 /* Analyze if we had any exception while loading servers. For the moment 1317 * only throw the exception found if the user did not provide the 1318 * Administrator DN and this caused a problem authenticating in one server 1319 * or if there is a certificate problem. 1320 */ 1321 Set<ServerDescriptor> servers = cache.getServers(); 1322 userData.setRemoteServers(servers); 1323 for (ServerDescriptor server : servers) 1324 { 1325 TopologyCacheException e = server.getLastException(); 1326 if (e != null) 1327 { 1328 exceptions.add(e); 1329 } 1330 } 1331 Set<LocalizableMessage> exceptionMsgs = new LinkedHashSet<>(); 1332 /* Check the exceptions and see if we throw them or not. */ 1333 for (TopologyCacheException e : exceptions) 1334 { 1335 logger.info(LocalizableMessage.raw("Analyzing exception: "+e, e)); 1336 if (stopProcessing) 1337 { 1338 break; 1339 } 1340 switch (e.getType()) 1341 { 1342 case NOT_GLOBAL_ADMINISTRATOR: 1343 println(); 1344 printErrorMessage(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); 1345 stopProcessing = true; 1346 break; 1347 case GENERIC_CREATING_CONNECTION: 1348 if (isCertificateException(e.getCause())) 1349 { 1350 if (isInteractive()) 1351 { 1352 println(); 1353 stopProcessing = true; 1354 if (ci.promptForCertificateConfirmation(e.getCause(), 1355 e.getTrustManager(), e.getLdapUrl(), logger)) 1356 { 1357 reloadTopologyCache = true; 1358 updateTrustManager(userData, ci); 1359 } 1360 } 1361 else 1362 { 1363 exceptionMsgs.add( 1364 INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get( 1365 e.getHostPort(), e.getCause().getMessage())); 1366 } 1367 } 1368 else 1369 { 1370 exceptionMsgs.add(Utils.getMessage(e)); 1371 } 1372 break; 1373 default: 1374 exceptionMsgs.add(Utils.getMessage(e)); 1375 } 1376 } 1377 if (isInteractive()) 1378 { 1379 if (!stopProcessing && !exceptionMsgs.isEmpty()) 1380 { 1381 println(); 1382 try 1383 { 1384 returnValue = askConfirmation( 1385 ERR_UNINSTALL_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( 1386 Utils.getMessageFromCollection(exceptionMsgs, 1387 Constants.LINE_SEPARATOR)), true, logger); 1388 } 1389 catch (ClientException ce) 1390 { 1391 throw new UserDataException(null, ce.getMessageObject(), ce); 1392 } 1393 } 1394 else if (reloadTopologyCache) 1395 { 1396 returnValue = updateUserUninstallDataWithRemoteServers(userData); 1397 } 1398 else 1399 { 1400 returnValue = !stopProcessing; 1401 } 1402 } 1403 else 1404 { 1405 logger.info(LocalizableMessage.raw("exceptionMsgs: "+exceptionMsgs)); 1406 if (!exceptionMsgs.isEmpty()) 1407 { 1408 if (parser.isForceOnError()) 1409 { 1410 LocalizableMessage msg = Utils.getMessageFromCollection(exceptionMsgs, 1411 Constants.LINE_SEPARATOR); 1412 println(); 1413 printErrorMessage(msg); 1414 returnValue = false; 1415 } 1416 else 1417 { 1418 LocalizableMessage msg = 1419 ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get( 1420 "--" + parser.getSecureArgsList().getAdminUidArg().getLongIdentifier(), 1421 "--" + OPTION_LONG_BINDPWD, 1422 "--" + OPTION_LONG_BINDPWD_FILE, 1423 "--" + parser.forceOnErrorArg.getLongIdentifier(), 1424 Utils.getMessageFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR)); 1425 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 1426 } 1427 } 1428 else 1429 { 1430 returnValue = true; 1431 } 1432 } 1433 logger.info(LocalizableMessage.raw("Return value: "+returnValue)); 1434 return returnValue; 1435 } 1436 1437 /** {@inheritDoc} */ 1438 @Override 1439 public boolean isAdvancedMode() { 1440 return false; 1441 } 1442 1443 1444 1445 /** {@inheritDoc} */ 1446 @Override 1447 public boolean isInteractive() { 1448 return !forceNonInteractive && parser.isInteractive(); 1449 } 1450 1451 1452 1453 /** {@inheritDoc} */ 1454 @Override 1455 public boolean isMenuDrivenMode() { 1456 return true; 1457 } 1458 1459 1460 1461 /** {@inheritDoc} */ 1462 @Override 1463 public boolean isQuiet() { 1464 return false; 1465 } 1466 1467 1468 1469 /** {@inheritDoc} */ 1470 @Override 1471 public boolean isScriptFriendly() { 1472 return false; 1473 } 1474 1475 1476 1477 /** {@inheritDoc} */ 1478 @Override 1479 public boolean isVerbose() { 1480 return true; 1481 } 1482 1483 /** 1484 * Commodity method to update the user data with the trust manager in the 1485 * LDAPConnectionConsoleInteraction object. 1486 * @param userData the user data to be updated. 1487 * @param ci the LDAPConnectionConsoleInteraction object to be used to update 1488 * the user data object. 1489 */ 1490 private void updateTrustManager(UninstallUserData userData, 1491 LDAPConnectionConsoleInteraction ci) 1492 { 1493 ApplicationTrustManager trust = null; 1494 TrustManager t = ci.getTrustManager(); 1495 if (t != null) 1496 { 1497 if (t instanceof ApplicationTrustManager) 1498 { 1499 trust = (ApplicationTrustManager)t; 1500 } 1501 else 1502 { 1503 trust = new ApplicationTrustManager(ci.getKeyStore()); 1504 } 1505 } 1506 userData.setTrustManager(trust); 1507 } 1508 1509 1510 1511 /** 1512 * Forces the initialization of the trust manager in the 1513 * LDAPConnectionInteraction object. 1514 */ 1515 private void forceTrustManagerInitialization() 1516 { 1517 forceNonInteractive = true; 1518 try 1519 { 1520 ci.initializeTrustManagerIfRequired(); 1521 } 1522 catch (ArgumentException ae) 1523 { 1524 logger.warn(LocalizableMessage.raw("Error initializing trust store: "+ae, ae)); 1525 } 1526 forceNonInteractive = false; 1527 } 1528 1529 private void printErrorMessage(LocalizableMessage msg) 1530 { 1531 super.println(msg); 1532 logger.warn(LocalizableMessage.raw(msg)); 1533 } 1534 1535 /** 1536 * Returns the timeout to be used to connect in milliseconds. The method 1537 * must be called after parsing the arguments. 1538 * @return the timeout to be used to connect in milliseconds. Returns 1539 * {@code 0} if there is no timeout. 1540 * @throw {@code IllegalStateException} if the method is called before 1541 * parsing the arguments. 1542 */ 1543 private int getConnectTimeout() 1544 { 1545 try 1546 { 1547 return parser.getSecureArgsList().getConnectTimeoutArg().getIntValue(); 1548 } 1549 catch (ArgumentException ae) 1550 { 1551 throw new IllegalStateException("Argument parser is not parsed: "+ae, 1552 ae); 1553 } 1554 } 1555}