001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2007-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2012-2015 ForgeRock AS. 026 */ 027package org.opends.server.tools.dsreplication; 028 029import static com.forgerock.opendj.cli.ArgumentConstants.*; 030import static com.forgerock.opendj.cli.Utils.*; 031 032import static org.opends.messages.AdminToolMessages.*; 033import static org.opends.messages.ToolMessages.*; 034 035import java.io.File; 036import java.io.OutputStream; 037import java.util.ArrayList; 038import java.util.Collection; 039import java.util.LinkedList; 040 041import org.forgerock.i18n.LocalizableMessage; 042import org.forgerock.i18n.LocalizableMessageBuilder; 043import org.opends.quicksetup.Constants; 044import org.opends.server.admin.AdministrationConnector; 045import org.opends.server.admin.client.cli.SecureConnectionCliArgs; 046import org.opends.server.admin.client.cli.SecureConnectionCliParser; 047import org.opends.server.admin.client.cli.TaskScheduleArgs; 048import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler; 049import org.opends.server.extensions.ConfigFileHandler; 050import org.opends.server.tasks.PurgeConflictsHistoricalTask; 051 052import com.forgerock.opendj.cli.Argument; 053import com.forgerock.opendj.cli.ArgumentException; 054import com.forgerock.opendj.cli.ArgumentGroup; 055import com.forgerock.opendj.cli.BooleanArgument; 056import com.forgerock.opendj.cli.ClientException; 057import com.forgerock.opendj.cli.CommonArguments; 058import com.forgerock.opendj.cli.FileBasedArgument; 059import com.forgerock.opendj.cli.IntegerArgument; 060import com.forgerock.opendj.cli.StringArgument; 061import com.forgerock.opendj.cli.SubCommand; 062 063/** 064 * This class is used to parse the arguments passed to the replication CLI. 065 * It also checks the compatibility between the values and that all the 066 * required information has been provided. However it does not do any 067 * verification that require connection to any server. 068 */ 069public class ReplicationCliArgumentParser extends SecureConnectionCliParser 070{ 071 /** Arguments used when enabling replication for a server. */ 072 static class ServerArgs 073 { 074 /** The 'hostName' argument for the first server. */ 075 StringArgument hostNameArg; 076 /** The 'port' argument for the first server. */ 077 IntegerArgument portArg; 078 /** The 'bindDN' argument for the first server. */ 079 StringArgument bindDnArg; 080 /** The 'bindPasswordFile' argument for the first server. */ 081 FileBasedArgument bindPasswordFileArg; 082 /** The 'bindPassword' argument for the first server. */ 083 StringArgument bindPasswordArg; 084 /** The 'replicationPort' argument for the first server. */ 085 IntegerArgument replicationPortArg; 086 /** The 'noReplicationServer' argument for the first server. */ 087 BooleanArgument noReplicationServerArg; 088 /** The 'onlyReplicationServer' argument for the first server. */ 089 BooleanArgument onlyReplicationServerArg; 090 /** The 'secureReplication' argument for the first server. */ 091 BooleanArgument secureReplicationArg; 092 093 094 /** 095 * Get the password which has to be used for the command to connect to this server without 096 * prompting the user in the enable replication subcommand. If no password was specified return 097 * null. 098 * 099 * @return the password which has to be used for the command to connect to this server without 100 * prompting the user in the enable replication subcommand. If no password was specified 101 * return null. 102 */ 103 String getBindPassword() 104 { 105 return ReplicationCliArgumentParser.getBindPassword(bindPasswordArg, bindPasswordFileArg); 106 } 107 108 boolean configureReplicationDomain() 109 { 110 return !onlyReplicationServerArg.isPresent(); 111 } 112 113 boolean configureReplicationServer() 114 { 115 return !noReplicationServerArg.isPresent(); 116 } 117 } 118 119 private SubCommand enableReplicationSubCmd; 120 private SubCommand disableReplicationSubCmd; 121 private SubCommand initializeReplicationSubCmd; 122 private SubCommand initializeAllReplicationSubCmd; 123 private SubCommand postExternalInitializationSubCmd; 124 private SubCommand preExternalInitializationSubCmd; 125 private SubCommand statusReplicationSubCmd; 126 private SubCommand purgeHistoricalSubCmd; 127 128 private int defaultAdminPort = 129 AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 130 131 /** No-prompt argument. */ 132 BooleanArgument noPromptArg; 133 private String defaultLocalHostValue; 134 135 /** Arguments for the first server. */ 136 ServerArgs server1 = new ServerArgs(); 137 /** Arguments for the second server. */ 138 ServerArgs server2 = new ServerArgs(); 139 140 /** The 'skipPortCheckArg' argument to not check replication ports. */ 141 private BooleanArgument skipPortCheckArg; 142 /** The 'noSchemaReplication' argument to not replicate schema. */ 143 BooleanArgument noSchemaReplicationArg; 144 /** The 'useSecondServerAsSchemaSource' argument to not replicate schema. */ 145 private BooleanArgument useSecondServerAsSchemaSourceArg; 146 /** The 'disableAll' argument to disable all the replication configuration of server. */ 147 BooleanArgument disableAllArg; 148 /** The 'disableReplicationServer' argument to disable the replication server. */ 149 BooleanArgument disableReplicationServerArg; 150 /** The 'hostName' argument for the source server. */ 151 private StringArgument hostNameSourceArg; 152 /** The 'port' argument for the source server. */ 153 private IntegerArgument portSourceArg; 154 /** The 'hostName' argument for the destination server. */ 155 private StringArgument hostNameDestinationArg; 156 /** The 'port' argument for the destination server. */ 157 private IntegerArgument portDestinationArg; 158 /** The 'suffixes' global argument. */ 159 StringArgument baseDNsArg; 160 /**The 'quiet' argument. */ 161 private BooleanArgument quietArg; 162 /**The 'scriptFriendly' argument. */ 163 BooleanArgument scriptFriendlyArg; 164 /**Properties file argument. */ 165 StringArgument propertiesFileArgument; 166 /**No-properties file argument. */ 167 BooleanArgument noPropertiesFileArgument; 168 /** 169 * The argument that the user must set to display the equivalent 170 * non-interactive mode argument. 171 */ 172 BooleanArgument displayEquivalentArgument; 173 /** 174 * The argument that allows the user to dump the equivalent non-interactive 175 * command to a file. 176 */ 177 StringArgument equivalentCommandFileArgument; 178 /** The argument that the user must set to have advanced options in interactive mode. */ 179 BooleanArgument advancedArg; 180 181 /** 182 * The argument set by the user to specify the configuration class 183 * (useful when dsreplication purge-historical runs locally). 184 */ 185 private StringArgument configClassArg; 186 187 /** 188 * The argument set by the user to specify the configuration file 189 * (useful when dsreplication purge-historical runs locally). 190 */ 191 private StringArgument configFileArg; 192 193 TaskScheduleArgs taskArgs; 194 195 /** The 'maximumDuration' argument for the purge of historical. */ 196 IntegerArgument maximumDurationArg; 197 198 /** The text of the enable replication subcommand. */ 199 static final String ENABLE_REPLICATION_SUBCMD_NAME = "enable"; 200 /** The text of the disable replication subcommand. */ 201 static final String DISABLE_REPLICATION_SUBCMD_NAME = "disable"; 202 /** The text of the initialize replication subcommand. */ 203 static final String INITIALIZE_REPLICATION_SUBCMD_NAME = "initialize"; 204 /** The text of the initialize all replication subcommand. */ 205 public static final String INITIALIZE_ALL_REPLICATION_SUBCMD_NAME = "initialize-all"; 206 /** The text of the pre external initialization subcommand. */ 207 static final String PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME = "pre-external-initialization"; 208 /** The text of the initialize all replication subcommand. */ 209 static final String POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME = "post-external-initialization"; 210 211 /** The text of the status replication subcommand. */ 212 static final String STATUS_REPLICATION_SUBCMD_NAME = "status"; 213 /** The text of the purge historical subcommand. */ 214 static final String PURGE_HISTORICAL_SUBCMD_NAME = "purge-historical"; 215 /** This CLI is always using the administration connector with SSL. */ 216 private static final boolean alwaysSSL = true; 217 218 /** 219 * Creates a new instance of this argument parser with no arguments. 220 * 221 * @param mainClassName 222 * The fully-qualified name of the Java class that should 223 * be invoked to launch the program with which this 224 * argument parser is associated. 225 */ 226 ReplicationCliArgumentParser(String mainClassName) 227 { 228 super(mainClassName, 229 INFO_REPLICATION_TOOL_DESCRIPTION.get(ENABLE_REPLICATION_SUBCMD_NAME, 230 INITIALIZE_REPLICATION_SUBCMD_NAME), 231 false); 232 setShortToolDescription(REF_SHORT_DESC_DSREPLICATION.get()); 233 setVersionHandler(new DirectoryServerVersionHandler()); 234 } 235 236 /** 237 * Initialize the parser with the Global options and subcommands. 238 * 239 * @param outStream 240 * The output stream to use for standard output, or {@code null} 241 * if standard output is not needed. 242 * @throws ArgumentException 243 * If there is a problem with any of the parameters used to create this argument. 244 */ 245 void initializeParser(OutputStream outStream) 246 throws ArgumentException 247 { 248 taskArgs = new TaskScheduleArgs(); 249 initializeGlobalArguments(outStream); 250 try 251 { 252 defaultAdminPort = secureArgsList.getAdminPortFromConfig(); 253 } 254 catch (Throwable t) 255 { 256 // Ignore 257 } 258 createEnableReplicationSubCommand(); 259 createDisableReplicationSubCommand(); 260 createInitializeReplicationSubCommand(); 261 createInitializeAllReplicationSubCommand(); 262 createPreExternalInitializationSubCommand(); 263 createPostExternalInitializationSubCommand(); 264 createStatusReplicationSubCommand(); 265 createPurgeHistoricalSubCommand(); 266 } 267 268 /** 269 * Checks all the options parameters and updates the provided LocalizableMessageBuilder 270 * with the errors that where encountered. 271 * 272 * This method assumes that the method parseArguments for the parser has 273 * already been called. 274 * @param buf the LocalizableMessageBuilder object where we add the error messages 275 * describing the errors encountered. 276 */ 277 void validateOptions(LocalizableMessageBuilder buf) 278 { 279 validateGlobalOptions(buf); 280 validateSubcommandOptions(buf); 281 } 282 283 /** {@inheritDoc} */ 284 @Override 285 public int validateGlobalOptions(LocalizableMessageBuilder buf) 286 { 287 int returnValue; 288 super.validateGlobalOptions(buf); 289 ArrayList<LocalizableMessage> errors = new ArrayList<>(); 290 if (secureArgsList.bindPasswordArg.isPresent() && 291 secureArgsList.bindPasswordFileArg.isPresent()) { 292 LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( 293 secureArgsList.bindPasswordArg.getLongIdentifier(), 294 secureArgsList.bindPasswordFileArg.getLongIdentifier()); 295 errors.add(message); 296 } 297 298 // Check that we can write on the provided path where we write the 299 // equivalent non-interactive commands. 300 if (equivalentCommandFileArgument.isPresent()) 301 { 302 String file = equivalentCommandFileArgument.getValue(); 303 if (!canWrite(file)) 304 { 305 errors.add(ERR_REPLICATION_CANNOT_WRITE_EQUIVALENT_COMMAND_LINE_FILE.get(file)); 306 } 307 else 308 { 309 File f = new File(file); 310 if (f.isDirectory()) 311 { 312 errors.add( 313 ERR_REPLICATION_EQUIVALENT_COMMAND_LINE_FILE_DIRECTORY.get(file)); 314 } 315 } 316 } 317 318 if (noPromptArg.isPresent() && advancedArg.isPresent()) 319 { 320 LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( 321 noPromptArg.getLongIdentifier(), 322 advancedArg.getLongIdentifier()); 323 errors.add(message); 324 } 325 326 if (!isInteractive()) 327 { 328 // Check that we have the required data 329 if (!baseDNsArg.isPresent() && 330 !isStatusReplicationSubcommand() && 331 !disableAllArg.isPresent() && 332 !disableReplicationServerArg.isPresent()) 333 { 334 errors.add(ERR_REPLICATION_NO_BASE_DN_PROVIDED.get()); 335 } 336 if (getBindPasswordAdmin() == null && 337 !isPurgeHistoricalSubcommand()) 338 { 339 errors.add(ERR_REPLICATION_NO_ADMINISTRATOR_PASSWORD_PROVIDED.get( 340 "--"+secureArgsList.bindPasswordArg.getLongIdentifier(), 341 "--"+secureArgsList.bindPasswordFileArg.getLongIdentifier())); 342 } 343 } 344 345 if (baseDNsArg.isPresent()) 346 { 347 LinkedList<String> baseDNs = baseDNsArg.getValues(); 348 for (String dn : baseDNs) 349 { 350 if (!isDN(dn)) 351 { 352 errors.add(ERR_REPLICATION_NOT_A_VALID_BASEDN.get(dn)); 353 } 354 if (dn.equalsIgnoreCase(Constants.REPLICATION_CHANGES_DN)) 355 { 356 errors.add(ERR_REPLICATION_NOT_A_USER_SUFFIX.get(Constants.REPLICATION_CHANGES_DN)); 357 } 358 } 359 } 360 if (!errors.isEmpty()) 361 { 362 for (LocalizableMessage error : errors) 363 { 364 addMessage(buf, error); 365 } 366 } 367 368 if (buf.length() > 0) 369 { 370 returnValue = ReplicationCliReturnCode.CONFLICTING_ARGS.getReturnCode(); 371 } 372 else 373 { 374 returnValue = ReplicationCliReturnCode.SUCCESSFUL_NOP.getReturnCode(); 375 } 376 return returnValue; 377 } 378 379 /** 380 * Initialize Global option. 381 * 382 * @param outStream 383 * The output stream used for the usage. 384 * @throws ArgumentException 385 * If there is a problem with any of the parameters used 386 * to create this argument. 387 */ 388 private void initializeGlobalArguments(OutputStream outStream) 389 throws ArgumentException 390 { 391 ArrayList<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL)); 392 393 Argument[] argsToRemove = { 394 secureArgsList.hostNameArg, 395 secureArgsList.portArg, 396 secureArgsList.bindDnArg, 397 secureArgsList.bindPasswordFileArg, 398 secureArgsList.bindPasswordArg 399 }; 400 401 for (Argument arg : argsToRemove) 402 { 403 defaultArgs.remove(arg); 404 } 405 defaultArgs.remove(super.noPropertiesFileArg); 406 defaultArgs.remove(super.propertiesFileArg); 407 // Remove it from the default location and redefine it. 408 defaultArgs.remove(getAdminUidArg()); 409 410 int index = 0; 411 412 baseDNsArg = new StringArgument("baseDNs", OPTION_SHORT_BASEDN, 413 OPTION_LONG_BASEDN, false, true, true, INFO_BASEDN_PLACEHOLDER.get(), 414 null, 415 null, INFO_DESCRIPTION_REPLICATION_BASEDNS.get()); 416 baseDNsArg.setPropertyName(OPTION_LONG_BASEDN); 417 defaultArgs.add(index++, baseDNsArg); 418 419 secureArgsList.adminUidArg = new StringArgument("adminUID", 'I', 420 OPTION_LONG_ADMIN_UID, false, false, true, 421 INFO_ADMINUID_PLACEHOLDER.get(), 422 Constants.GLOBAL_ADMIN_UID, null, 423 INFO_DESCRIPTION_REPLICATION_ADMIN_UID.get( 424 ENABLE_REPLICATION_SUBCMD_NAME)); 425 getAdminUidArg().setPropertyName(OPTION_LONG_ADMIN_UID); 426 getAdminUidArg().setHidden(false); 427 defaultArgs.add(index++, getAdminUidArg()); 428 429 secureArgsList.bindPasswordArg = new StringArgument( 430 OPTION_LONG_ADMIN_PWD.toLowerCase(), 431 OPTION_SHORT_BINDPWD, OPTION_LONG_ADMIN_PWD, false, false, true, 432 INFO_BINDPWD_PLACEHOLDER.get(), null, null, 433 INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORD.get()); 434 defaultArgs.add(index++, secureArgsList.bindPasswordArg); 435 436 secureArgsList.bindPasswordFileArg = new FileBasedArgument( 437 OPTION_LONG_ADMIN_PWD_FILE.toLowerCase(), 438 OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_ADMIN_PWD_FILE, false, false, 439 INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, 440 INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORDFILE.get()); 441 defaultArgs.add(index++, secureArgsList.bindPasswordFileArg); 442 443 defaultArgs.remove(verboseArg); 444 445 quietArg = CommonArguments.getQuiet(); 446 defaultArgs.add(index++, quietArg); 447 448 noPromptArg = CommonArguments.getNoPrompt(); 449 defaultArgs.add(index++, noPromptArg); 450 451 displayEquivalentArgument = CommonArguments.getDisplayEquivalentCommand(); 452 453 defaultArgs.add(index++, displayEquivalentArgument); 454 455 equivalentCommandFileArgument = 456 CommonArguments 457 .getEquivalentCommandFile( 458 INFO_REPLICATION_DESCRIPTION_EQUIVALENT_COMMAND_FILE_PATH.get()); 459 defaultArgs.add(index++, equivalentCommandFileArgument); 460 461 advancedArg = CommonArguments.getAdvancedMode(); 462 defaultArgs.add(index++, advancedArg); 463 464 configClassArg = 465 CommonArguments.getConfigClass(ConfigFileHandler.class.getName()); 466 defaultArgs.add(index++, configClassArg); 467 468 configFileArg = CommonArguments.getConfigFile(); 469 defaultArgs.add(index++, configFileArg); 470 471 for (int i=0; i<index; i++) 472 { 473 Argument arg = defaultArgs.get(i); 474 arg.setPropertyName(arg.getLongIdentifier()); 475 } 476 477 this.propertiesFileArgument = CommonArguments.getPropertiesFile(); 478 defaultArgs.add(this.propertiesFileArgument); 479 setFilePropertiesArgument(this.propertiesFileArgument); 480 481 this.noPropertiesFileArgument = CommonArguments.getNoPropertiesFile(); 482 defaultArgs.add(this.noPropertiesFileArgument); 483 setNoPropertiesFileArgument(this.noPropertiesFileArgument); 484 485 initializeGlobalArguments(defaultArgs, null); 486 } 487 488 /** 489 * Initialize the global options with the provided set of arguments. 490 * @param args the arguments to use to initialize the global options. 491 * @param argGroup the group to which args will be added. 492 * @throws ArgumentException if there is a conflict with the provided 493 * arguments. 494 */ 495 @Override 496 protected void initializeGlobalArguments( 497 Collection<Argument> args, 498 ArgumentGroup argGroup) 499 throws ArgumentException 500 { 501 502 for (Argument arg : args) 503 { 504 if (arg == advancedArg) 505 { 506 ArgumentGroup toolOptionsGroup = new ArgumentGroup( 507 INFO_DESCRIPTION_CONFIG_OPTIONS_ARGS.get(), 2); 508 addGlobalArgument(advancedArg, toolOptionsGroup); 509 } 510 else 511 { 512 addGlobalArgument(arg, argGroup); 513 } 514 } 515 516 // Set the propertiesFile argument 517 setFilePropertiesArgument(propertiesFileArg); 518 } 519 520 /** 521 * Creates the enable replication subcommand and all the specific options 522 * for the subcommand. 523 */ 524 private void createEnableReplicationSubCommand() throws ArgumentException 525 { 526 createServerArgs1(); 527 createServerArgs2(); 528 529 skipPortCheckArg = new BooleanArgument( 530 "skipportcheck", 'S', "skipPortCheck", 531 INFO_DESCRIPTION_ENABLE_REPLICATION_SKIPPORT.get()); 532 533 noSchemaReplicationArg = new BooleanArgument( 534 "noschemareplication", null, "noSchemaReplication", 535 INFO_DESCRIPTION_ENABLE_REPLICATION_NO_SCHEMA_REPLICATION.get()); 536 537 useSecondServerAsSchemaSourceArg = new BooleanArgument( 538 "usesecondserverasschemasource", null, "useSecondServerAsSchemaSource", 539 INFO_DESCRIPTION_ENABLE_REPLICATION_USE_SECOND_AS_SCHEMA_SOURCE.get( 540 "--"+noSchemaReplicationArg.getLongIdentifier())); 541 542 enableReplicationSubCmd = new SubCommand(this, 543 ENABLE_REPLICATION_SUBCMD_NAME, 544 INFO_DESCRIPTION_SUBCMD_ENABLE_REPLICATION.get()); 545 546 Argument[] argsToAdd = { 547 server1.hostNameArg, server1.portArg, server1.bindDnArg, server1.bindPasswordArg, 548 server1.bindPasswordFileArg, server1.replicationPortArg, server1.secureReplicationArg, 549 server1.noReplicationServerArg, server1.onlyReplicationServerArg, 550 server2.hostNameArg, server2.portArg, server2.bindDnArg, server2.bindPasswordArg, 551 server2.bindPasswordFileArg, server2.replicationPortArg, server2.secureReplicationArg, 552 server2.noReplicationServerArg, server2.onlyReplicationServerArg, 553 skipPortCheckArg, noSchemaReplicationArg, useSecondServerAsSchemaSourceArg 554 }; 555 for (Argument arg : argsToAdd) 556 { 557 arg.setPropertyName(arg.getLongIdentifier()); 558 enableReplicationSubCmd.addArgument(arg); 559 } 560 } 561 562 private void createServerArgs1() throws ArgumentException 563 { 564 ServerArgs server = server1; 565 server.hostNameArg = new StringArgument("host1", OPTION_SHORT_HOST, 566 "host1", false, false, true, INFO_HOST_PLACEHOLDER.get(), 567 getDefaultHostValue(), 568 null, INFO_DESCRIPTION_ENABLE_REPLICATION_HOST1.get()); 569 570 server.portArg = new IntegerArgument("port1", OPTION_SHORT_PORT, "port1", 571 false, false, true, INFO_PORT_PLACEHOLDER.get(), 572 defaultAdminPort, null, 573 true, 1, 574 true, 65336, 575 INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT1.get()); 576 577 server.bindDnArg = new StringArgument("bindDN1", OPTION_SHORT_BINDDN, 578 "bindDN1", false, false, true, INFO_BINDDN_PLACEHOLDER.get(), 579 "cn=Directory Manager", null, 580 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN1.get()); 581 582 server.bindPasswordArg = new StringArgument("bindPassword1", 583 null, "bindPassword1", false, false, true, 584 INFO_BINDPWD_PLACEHOLDER.get(), null, null, 585 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD1.get()); 586 587 server.bindPasswordFileArg = new FileBasedArgument("bindPasswordFile1", 588 null, "bindPasswordFile1", false, false, 589 INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, 590 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE1.get()); 591 592 server.replicationPortArg = new IntegerArgument("replicationPort1", 'r', 593 "replicationPort1", false, false, true, INFO_PORT_PLACEHOLDER.get(), 594 8989, null, 595 true, 1, 596 true, 65336, 597 INFO_DESCRIPTION_ENABLE_REPLICATION_PORT1.get()); 598 599 server.secureReplicationArg = new BooleanArgument("secureReplication1", null, 600 "secureReplication1", 601 INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION1.get()); 602 603 server.noReplicationServerArg = new BooleanArgument( 604 "noreplicationserver1", null, "noReplicationServer1", 605 INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER1.get()); 606 607 server.onlyReplicationServerArg = new BooleanArgument( 608 "onlyreplicationserver1", null, "onlyReplicationServer1", 609 INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER1.get()); 610 } 611 612 private void createServerArgs2() throws ArgumentException 613 { 614 ServerArgs server = server2; 615 server.hostNameArg = new StringArgument("host2", 'O', 616 "host2", false, false, true, INFO_HOST_PLACEHOLDER.get(), 617 getDefaultHostValue(), 618 null, INFO_DESCRIPTION_ENABLE_REPLICATION_HOST2.get()); 619 620 server.portArg = new IntegerArgument("port2", null, "port2", 621 false, false, true, INFO_PORT_PLACEHOLDER.get(), defaultAdminPort, null, 622 true, 1, 623 true, 65336, 624 INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2.get()); 625 626 server.bindDnArg = new StringArgument("bindDN2", null, 627 "bindDN2", false, false, true, INFO_BINDDN_PLACEHOLDER.get(), 628 "cn=Directory Manager", null, 629 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN2.get()); 630 631 server.bindPasswordArg = new StringArgument("bindPassword2", 632 null, "bindPassword2", false, false, true, 633 INFO_BINDPWD_PLACEHOLDER.get(), null, null, 634 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD2.get()); 635 636 server.bindPasswordFileArg = new FileBasedArgument("bindPasswordFile2", 637 'F', "bindPasswordFile2", false, false, 638 INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, 639 INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE2.get()); 640 641 server.replicationPortArg = new IntegerArgument("replicationPort2", 'R', 642 "replicationPort2", false, false, true, INFO_PORT_PLACEHOLDER.get(), 643 8989, null, 644 true, 1, 645 true, 65336, 646 INFO_DESCRIPTION_ENABLE_REPLICATION_PORT2.get()); 647 648 server.secureReplicationArg = new BooleanArgument("secureReplication2", null, 649 "secureReplication2", 650 INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION2.get()); 651 652 server.noReplicationServerArg = new BooleanArgument( 653 "noreplicationserver2", null, "noReplicationServer2", 654 INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER2.get()); 655 656 server.onlyReplicationServerArg = new BooleanArgument( 657 "onlyreplicationserver2", null, "onlyReplicationServer2", 658 INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER2.get()); 659 } 660 661 /** 662 * Creates the disable replication subcommand and all the specific options 663 * for the subcommand. Note: this method assumes that 664 * initializeGlobalArguments has already been called and that hostNameArg and 665 * portArg have been created. 666 */ 667 private void createDisableReplicationSubCommand() 668 throws ArgumentException 669 { 670 disableReplicationSubCmd = new SubCommand(this, 671 DISABLE_REPLICATION_SUBCMD_NAME, 672 INFO_DESCRIPTION_SUBCMD_DISABLE_REPLICATION.get()); 673 secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue()); 674 secureArgsList.bindDnArg = new StringArgument("bindDN", OPTION_SHORT_BINDDN, 675 OPTION_LONG_BINDDN, false, false, true, INFO_BINDDN_PLACEHOLDER.get(), 676 "cn=Directory Manager", OPTION_LONG_BINDDN, 677 INFO_DESCRIPTION_DISABLE_REPLICATION_BINDDN.get()); 678 disableReplicationServerArg = new BooleanArgument( 679 "disablereplicationserver", null, "disableReplicationServer", 680 INFO_DESCRIPTION_DISABLE_REPLICATION_SERVER.get()); 681 disableAllArg = new BooleanArgument( 682 "disableall", 'a', "disableAll", 683 INFO_DESCRIPTION_DISABLE_ALL.get()); 684 685 686 Argument[] argsToAdd = { secureArgsList.hostNameArg, 687 secureArgsList.portArg, secureArgsList.bindDnArg, 688 disableReplicationServerArg, disableAllArg}; 689 for (Argument arg : argsToAdd) 690 { 691 disableReplicationSubCmd.addArgument(arg); 692 } 693 } 694 695 /** 696 * Creates the initialize replication subcommand and all the specific options 697 * for the subcommand. 698 */ 699 private void createInitializeReplicationSubCommand() 700 throws ArgumentException 701 { 702 hostNameSourceArg = new StringArgument("hostSource", OPTION_SHORT_HOST, 703 "hostSource", false, false, true, INFO_HOST_PLACEHOLDER.get(), 704 getDefaultHostValue(), null, 705 INFO_DESCRIPTION_INITIALIZE_REPLICATION_HOST_SOURCE.get()); 706 707 portSourceArg = new IntegerArgument("portSource", OPTION_SHORT_PORT, 708 "portSource", false, false, true, INFO_PORT_PLACEHOLDER.get(), 709 defaultAdminPort, null, 710 true, 1, 711 true, 65336, 712 INFO_DESCRIPTION_INITIALIZE_REPLICATION_SERVER_PORT_SOURCE.get()); 713 714 hostNameDestinationArg = new StringArgument("hostDestination", 'O', 715 "hostDestination", false, false, true, INFO_HOST_PLACEHOLDER.get(), 716 getDefaultHostValue(), null, 717 INFO_DESCRIPTION_INITIALIZE_REPLICATION_HOST_DESTINATION.get()); 718 719 portDestinationArg = new IntegerArgument("portDestination", null, 720 "portDestination", false, false, true, INFO_PORT_PLACEHOLDER.get(), 721 defaultAdminPort, 722 null, 723 true, 1, 724 true, 65336, 725 INFO_DESCRIPTION_INITIALIZE_REPLICATION_SERVER_PORT_DESTINATION.get()); 726 727 initializeReplicationSubCmd = new SubCommand(this, 728 INITIALIZE_REPLICATION_SUBCMD_NAME, 729 INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION.get( 730 INITIALIZE_ALL_REPLICATION_SUBCMD_NAME)); 731 732 Argument[] argsToAdd = { 733 hostNameSourceArg, portSourceArg, hostNameDestinationArg, 734 portDestinationArg 735 }; 736 for (Argument arg : argsToAdd) 737 { 738 arg.setPropertyName(arg.getLongIdentifier()); 739 initializeReplicationSubCmd.addArgument(arg); 740 } 741 } 742 743 /** 744 * Creates the initialize all replication subcommand and all the specific 745 * options for the subcommand. Note: this method assumes that 746 * initializeGlobalArguments has already been called and that hostNameArg and 747 * portArg have been created. 748 */ 749 private void createInitializeAllReplicationSubCommand() 750 throws ArgumentException 751 { 752 initializeAllReplicationSubCmd = new SubCommand(this, 753 INITIALIZE_ALL_REPLICATION_SUBCMD_NAME, 754 INFO_DESCRIPTION_SUBCMD_INITIALIZE_ALL_REPLICATION.get( 755 INITIALIZE_REPLICATION_SUBCMD_NAME)); 756 secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue()); 757 Argument[] argsToAdd = { secureArgsList.hostNameArg, 758 secureArgsList.portArg }; 759 for (Argument arg : argsToAdd) 760 { 761 initializeAllReplicationSubCmd.addArgument(arg); 762 } 763 } 764 765 /** 766 * Creates the subcommand that the user must launch before doing an external 767 * initialization of the topology ( and all the specific 768 * options for the subcommand. Note: this method assumes that 769 * initializeGlobalArguments has already been called and that hostNameArg and 770 * portArg have been created. 771 */ 772 private void createPreExternalInitializationSubCommand() 773 throws ArgumentException 774 { 775 preExternalInitializationSubCmd = new SubCommand(this, 776 PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME, 777 INFO_DESCRIPTION_SUBCMD_PRE_EXTERNAL_INITIALIZATION.get( 778 POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME)); 779 secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue()); 780 BooleanArgument externalInitializationLocalOnlyArg = new BooleanArgument( 781 "local-only", 782 'l', 783 "local-only", 784 LocalizableMessage.EMPTY); 785 externalInitializationLocalOnlyArg.setHidden(true); 786 787 Argument[] argsToAdd = { secureArgsList.hostNameArg, 788 secureArgsList.portArg, 789 externalInitializationLocalOnlyArg}; 790 791 for (Argument arg : argsToAdd) 792 { 793 preExternalInitializationSubCmd.addArgument(arg); 794 } 795 } 796 797 /** 798 * Creates the subcommand that the user must launch after doing an external 799 * initialization of the topology ( and all the specific 800 * options for the subcommand. Note: this method assumes that 801 * initializeGlobalArguments has already been called and that hostNameArg and 802 * portArg have been created. 803 */ 804 private void createPostExternalInitializationSubCommand() 805 throws ArgumentException 806 { 807 postExternalInitializationSubCmd = new SubCommand(this, 808 POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME, 809 INFO_DESCRIPTION_SUBCMD_POST_EXTERNAL_INITIALIZATION.get( 810 PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME)); 811 secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue()); 812 Argument[] argsToAdd = { secureArgsList.hostNameArg, 813 secureArgsList.portArg }; 814 for (Argument arg : argsToAdd) 815 { 816 postExternalInitializationSubCmd.addArgument(arg); 817 } 818 } 819 820 /** 821 * Creates the status replication subcommand and all the specific options 822 * for the subcommand. Note: this method assumes that 823 * initializeGlobalArguments has already been called and that hostNameArg and 824 * portArg have been created. 825 */ 826 private void createStatusReplicationSubCommand() throws ArgumentException 827 { 828 statusReplicationSubCmd = new SubCommand(this, 829 STATUS_REPLICATION_SUBCMD_NAME, 830 INFO_DESCRIPTION_SUBCMD_STATUS_REPLICATION.get()); 831 scriptFriendlyArg = new BooleanArgument( 832 "script-friendly", 833 's', 834 "script-friendly", 835 INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()); 836 scriptFriendlyArg.setPropertyName(scriptFriendlyArg.getLongIdentifier()); 837 secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue()); 838 Argument[] argsToAdd = { secureArgsList.hostNameArg, 839 secureArgsList.portArg, scriptFriendlyArg }; 840 for (Argument arg : argsToAdd) 841 { 842 statusReplicationSubCmd.addArgument(arg); 843 } 844 } 845 846 /** 847 * Creates the purge historical subcommand and all the specific options 848 * for the subcommand. Note: this method assumes that 849 * initializeGlobalArguments has already been called and that hostNameArg and 850 * portArg have been created. 851 */ 852 private void createPurgeHistoricalSubCommand() 853 throws ArgumentException 854 { 855 maximumDurationArg = new IntegerArgument( 856 "maximumDuration", 857 null, // shortId 858 "maximumDuration", 859 true, // isRequired 860 false, // isMultivalued 861 true, // needsValue 862 INFO_MAXIMUM_DURATION_PLACEHOLDER.get(), 863 PurgeConflictsHistoricalTask.DEFAULT_MAX_DURATION, 864 null, 865 true, 0, 866 false, Integer.MAX_VALUE, 867 INFO_DESCRIPTION_PURGE_HISTORICAL_MAXIMUM_DURATION.get()); 868 869 purgeHistoricalSubCmd = new SubCommand( 870 this, 871 PURGE_HISTORICAL_SUBCMD_NAME, 872 INFO_DESCRIPTION_SUBCMD_PURGE_HISTORICAL.get()); 873 874 Argument[] argsToAdd = { 875 secureArgsList.hostNameArg, 876 secureArgsList.portArg, 877 maximumDurationArg}; 878 879 for (Argument arg : argsToAdd) 880 { 881 arg.setPropertyName(arg.getLongIdentifier()); 882 purgeHistoricalSubCmd.addArgument(arg); 883 } 884 for (Argument arg : taskArgs.getArguments()) 885 { 886 purgeHistoricalSubCmd.addArgument(arg); 887 } 888 } 889 890 /** 891 * Tells whether the user specified to have an interactive operation or not. 892 * This method must be called after calling parseArguments. 893 * @return <CODE>true</CODE> if the user specified to have an interactive 894 * operation and <CODE>false</CODE> otherwise. 895 */ 896 public boolean isInteractive() 897 { 898 return !noPromptArg.isPresent(); 899 } 900 901 /** 902 * Tells whether the user specified to have a quite operation or not. 903 * This method must be called after calling parseArguments. 904 * @return <CODE>true</CODE> if the user specified to have a quite operation 905 * and <CODE>false</CODE> otherwise. 906 */ 907 public boolean isQuiet() 908 { 909 return quietArg.isPresent(); 910 } 911 912 /** 913 * Tells whether the user specified to have a script-friendly output or not. 914 * This method must be called after calling parseArguments. 915 * @return <CODE>true</CODE> if the user specified to have a script-friendly 916 * output and <CODE>false</CODE> otherwise. 917 */ 918 public boolean isScriptFriendly() 919 { 920 return scriptFriendlyArg.isPresent(); 921 } 922 923 /** 924 * Get the global administrator password which has to be used for the command 925 * to connect to the server(s) without prompting the user. If no password was 926 * specified, return null. 927 * 928 * @return the global administrator password which has to be used for the 929 * command to connect to the server(s) without prompting the user. If no 930 * password was specified, return null. 931 */ 932 public String getBindPasswordAdmin() 933 { 934 return getBindPassword(secureArgsList.bindPasswordArg, 935 secureArgsList.bindPasswordFileArg); 936 } 937 938 /** 939 * Returns the Administrator UID explicitly provided in the command-line. 940 * @return the Administrator UID explicitly provided in the command-line. 941 */ 942 @Override 943 public String getAdministratorUID() 944 { 945 return getValue(getAdminUidArg()); 946 } 947 948 /** 949 * Returns the default Administrator UID value. 950 * @return the default Administrator UID value. 951 */ 952 public String getAdministratorUIDOrDefault() 953 { 954 return getValueOrDefault(getAdminUidArg()); 955 } 956 957 /** 958 * Returns the Administrator UID argument. 959 * @return the Administrator UID argument. 960 */ 961 StringArgument getAdminUidArg() 962 { 963 return secureArgsList.adminUidArg; 964 } 965 966 /** 967 * Returns the first server replication port explicitly provided in the enable 968 * replication subcommand. 969 * @return the first server replication port explicitly provided in the enable 970 * replication subcommand. Returns -1 if no port was explicitly provided. 971 */ 972 public int getReplicationPort1() 973 { 974 return getValue(server1.replicationPortArg); 975 } 976 977 /** 978 * Returns the second server replication port explicitly provided in the 979 * enable replication subcommand. 980 * @return the second server replication port explicitly provided in the 981 * enable replication subcommand. Returns -1 if no port was explicitly 982 * provided. 983 */ 984 public int getReplicationPort2() 985 { 986 return getValue(server2.replicationPortArg); 987 } 988 989 /** 990 * Returns whether the user asked to skip the replication port checks (if the 991 * ports are free) or not. 992 * @return <CODE>true</CODE> the user asked to skip the replication port 993 * checks (if the ports are free) and <CODE>false</CODE> otherwise. 994 */ 995 boolean skipReplicationPortCheck() 996 { 997 return skipPortCheckArg.isPresent(); 998 } 999 1000 /** 1001 * Returns whether the user asked to not replicate the schema between servers. 1002 * @return <CODE>true</CODE> if the user asked to not replicate schema and 1003 * <CODE>false</CODE> otherwise. 1004 */ 1005 boolean noSchemaReplication() 1006 { 1007 return noSchemaReplicationArg.isPresent(); 1008 } 1009 1010 /** 1011 * Returns whether the user asked to use the second server to initialize the 1012 * schema of the first server. 1013 * @return <CODE>true</CODE> if the user asked to use the second server to 1014 * initialize the schema of the first server and <CODE>false</CODE> otherwise. 1015 */ 1016 boolean useSecondServerAsSchemaSource() 1017 { 1018 return useSecondServerAsSchemaSourceArg.isPresent(); 1019 } 1020 1021 /** 1022 * Returns the host name explicitly provided in the disable replication 1023 * subcommand. 1024 * @return the host name explicitly provided in the disable replication 1025 * subcommand. 1026 */ 1027 public String getHostNameToDisable() 1028 { 1029 return getValue(secureArgsList.hostNameArg); 1030 } 1031 1032 /** 1033 * Returns the host name default value in the disable replication 1034 * subcommand. 1035 * @return the host name default value in the disable replication 1036 * subcommand. 1037 */ 1038 public String getHostNameToDisableOrDefault() 1039 { 1040 return getValueOrDefault(secureArgsList.hostNameArg); 1041 } 1042 1043 /** 1044 * Returns the server bind dn explicitly provided in the disable replication 1045 * subcommand. 1046 * @return the server bind dn explicitly provided in the disable replication 1047 * subcommand. 1048 */ 1049 public String getBindDNToDisable() 1050 { 1051 return getValue(secureArgsList.bindDnArg); 1052 } 1053 1054 /** 1055 * Returns the server bind dn default value in the disable replication 1056 * subcommand. 1057 * @return the server bind dn default value in the enable replication 1058 * subcommand. 1059 */ 1060 public String getDefaultBindDnToDisable() 1061 { 1062 return getDefaultValue(secureArgsList.bindDnArg); 1063 } 1064 1065 /** 1066 * Returns the host name explicitly provided in the status replication 1067 * subcommand. 1068 * @return the host name explicitly provided in the status replication 1069 * subcommand. 1070 */ 1071 public String getHostNameToStatus() 1072 { 1073 return getValue(secureArgsList.hostNameArg); 1074 } 1075 1076 /** 1077 * Returns the host name default value in the status replication subcommand. 1078 * @return the host name default value in the status replication subcommand. 1079 */ 1080 public String getHostNameToStatusOrDefault() 1081 { 1082 return getValueOrDefault(secureArgsList.hostNameArg); 1083 } 1084 1085 /** 1086 * Returns the host name explicitly provided in the initialize all replication 1087 * subcommand. 1088 * @return the host name explicitly provided in the initialize all replication 1089 * subcommand. 1090 */ 1091 public String getHostNameToInitializeAll() 1092 { 1093 return getValue(secureArgsList.hostNameArg); 1094 } 1095 1096 /** 1097 * Returns the host name default value in the initialize all replication 1098 * subcommand. 1099 * @return the host name default value in the initialize all replication 1100 * subcommand. 1101 */ 1102 public String getHostNameToInitializeAllOrDefault() 1103 { 1104 return getValueOrDefault(secureArgsList.hostNameArg); 1105 } 1106 1107 /** 1108 * Returns the host name explicitly provided in the pre external 1109 * initialization subcommand. 1110 * @return the host name explicitly provided in the pre external 1111 * initialization subcommand. 1112 */ 1113 public String getHostNameToPreExternalInitialization() 1114 { 1115 return getValue(secureArgsList.hostNameArg); 1116 } 1117 1118 /** 1119 * Returns the host name default value in the pre external initialization 1120 * subcommand. 1121 * @return the host name default value in the pre external initialization 1122 * subcommand. 1123 */ 1124 public String getDefaultHostNameToPreExternalInitialization() 1125 { 1126 return getDefaultValue(secureArgsList.hostNameArg); 1127 } 1128 1129 /** 1130 * Returns the host name explicitly provided in the post external 1131 * initialization subcommand. 1132 * @return the host name explicitly provided in the post external 1133 * initialization subcommand. 1134 */ 1135 public String getHostNameToPostExternalInitialization() 1136 { 1137 return getValue(secureArgsList.hostNameArg); 1138 } 1139 1140 /** 1141 * Returns the host name default value in the post external initialization 1142 * subcommand. 1143 * @return the host name default value in the post external initialization 1144 * subcommand. 1145 */ 1146 public String getDefaultHostNameToPostExternalInitialization() 1147 { 1148 return getDefaultValue(secureArgsList.hostNameArg); 1149 } 1150 1151 /** 1152 * Returns the source host name explicitly provided in the initialize 1153 * replication subcommand. 1154 * @return the source host name explicitly provided in the initialize 1155 * replication subcommand. 1156 */ 1157 public String getHostNameSource() 1158 { 1159 return getValue(hostNameSourceArg); 1160 } 1161 1162 /** 1163 * Returns the first host name default value in the initialize replication 1164 * subcommand. 1165 * @return the first host name default value in the initialize replication 1166 * subcommand. 1167 */ 1168 public String getHostNameSourceOrDefault() 1169 { 1170 return getValueOrDefault(hostNameSourceArg); 1171 } 1172 1173 /** 1174 * Returns the destination host name explicitly provided in the initialize 1175 * replication subcommand. 1176 * @return the destination host name explicitly provided in the initialize 1177 * replication subcommand. 1178 */ 1179 public String getHostNameDestination() 1180 { 1181 return getValue(hostNameDestinationArg); 1182 } 1183 1184 /** 1185 * Returns the destination host name default value in the initialize 1186 * replication subcommand. 1187 * @return the destination host name default value in the initialize 1188 * replication subcommand. 1189 */ 1190 public String getHostNameDestinationOrDefault() 1191 { 1192 return getValueOrDefault(hostNameDestinationArg); 1193 } 1194 1195 /** 1196 * Returns the source server port explicitly provided in the initialize 1197 * replication subcommand. 1198 * @return the source server port explicitly provided in the initialize 1199 * replication subcommand. Returns -1 if no port was explicitly provided. 1200 */ 1201 public int getPortSource() 1202 { 1203 return getValue(portSourceArg); 1204 } 1205 1206 /** 1207 * Returns the source server port default value in the initialize replication 1208 * subcommand. 1209 * @return the source server port default value in the initialize replication 1210 * subcommand. 1211 */ 1212 public int getPortSourceOrDefault() 1213 { 1214 return getValueOrDefault(portSourceArg); 1215 } 1216 1217 /** 1218 * Returns the destination server port explicitly provided in the initialize 1219 * replication subcommand. 1220 * @return the destination server port explicitly provided in the initialize 1221 * replication subcommand. Returns -1 if no port was explicitly provided. 1222 */ 1223 public int getPortDestination() 1224 { 1225 return getValue(portDestinationArg); 1226 } 1227 1228 /** 1229 * Returns the destination server port default value in the initialize 1230 * replication subcommand. 1231 * @return the destination server port default value in the initialize 1232 * replication subcommand. 1233 */ 1234 public int getPortDestinationOrDefault() 1235 { 1236 return getValueOrDefault(portDestinationArg); 1237 } 1238 1239 /** 1240 * Returns the server port explicitly provided in the disable replication 1241 * subcommand. 1242 * @return the server port explicitly provided in the disable replication 1243 * subcommand. Returns -1 if no port was explicitly provided. 1244 */ 1245 public int getPortToDisable() 1246 { 1247 return getValue(secureArgsList.portArg); 1248 } 1249 1250 /** 1251 * Returns the server port default value in the disable replication 1252 * subcommand. 1253 * @return the server port default value in the disable replication 1254 * subcommand. 1255 */ 1256 public int getPortToDisableOrDefault() 1257 { 1258 return getValueOrDefault(secureArgsList.portArg); 1259 } 1260 1261 /** 1262 * Returns the server port explicitly provided in the initialize all 1263 * replication subcommand. 1264 * @return the server port explicitly provided in the initialize all 1265 * replication subcommand. Returns -1 if no port was explicitly provided. 1266 */ 1267 public int getPortToInitializeAll() 1268 { 1269 return getValue(secureArgsList.portArg); 1270 } 1271 1272 /** 1273 * Returns the server port default value in the initialize all replication 1274 * subcommand. 1275 * @return the server port default value in the initialize all replication 1276 * subcommand. 1277 */ 1278 public int getPortToInitializeAllOrDefault() 1279 { 1280 return getValueOrDefault(secureArgsList.portArg); 1281 } 1282 1283 /** 1284 * Returns the server port explicitly provided in the pre external 1285 * initialization subcommand. 1286 * @return the server port explicitly provided in the pre external 1287 * initialization subcommand. Returns -1 if no port was explicitly provided. 1288 */ 1289 public int getPortToPreExternalInitialization() 1290 { 1291 return getValue(secureArgsList.portArg); 1292 } 1293 1294 /** 1295 * Returns the server port default value in the pre external initialization 1296 * subcommand. 1297 * @return the server port default value in the pre external initialization 1298 * subcommand. 1299 */ 1300 public int getDefaultPortToPreExternalInitialization() 1301 { 1302 return getDefaultValue(secureArgsList.portArg); 1303 } 1304 1305 /** 1306 * Returns the server port explicitly provided in the post external 1307 * initialization subcommand. 1308 * @return the server port explicitly provided in the post external 1309 * initialization subcommand. Returns -1 if no port was explicitly provided. 1310 */ 1311 public int getPortToPostExternalInitialization() 1312 { 1313 return getValue(secureArgsList.portArg); 1314 } 1315 1316 /** 1317 * Returns the server port default value in the post external initialization 1318 * subcommand. 1319 * @return the server port default value in the post external initialization 1320 * subcommand. 1321 */ 1322 public int getDefaultPortToPostExternalInitialization() 1323 { 1324 return getDefaultValue(secureArgsList.portArg); 1325 } 1326 1327 /** 1328 * Returns the server port explicitly provided in the status replication 1329 * subcommand. 1330 * @return the server port explicitly provided in the status replication 1331 * subcommand. Returns -1 if no port was explicitly provided. 1332 */ 1333 public int getPortToStatus() 1334 { 1335 return getValue(secureArgsList.portArg); 1336 } 1337 1338 /** 1339 * Returns the server port default value in the status replication subcommand. 1340 * @return the server port default value in the status replication subcommand. 1341 */ 1342 public int getPortToStatusOrDefault() 1343 { 1344 return getValueOrDefault(secureArgsList.portArg); 1345 } 1346 1347 /** 1348 * Returns the list of base DNs provided by the user. 1349 * @return the list of base DNs provided by the user. 1350 */ 1351 public LinkedList<String> getBaseDNs() 1352 { 1353 return baseDNsArg.getValues(); 1354 } 1355 1356 /** 1357 * Returns the config class value provided in the hidden argument of the 1358 * command-line. 1359 * @return the config class value provided in the hidden argument of the 1360 * command-line. 1361 */ 1362 public String getConfigClass() 1363 { 1364 return getValue(configClassArg); 1365 } 1366 1367 /** 1368 * Returns the config file value provided in the hidden argument of the 1369 * command-line. 1370 * @return the config file value provided in the hidden argument of the 1371 * command-line. 1372 */ 1373 public String getConfigFile() 1374 { 1375 return getValue(configFileArg); 1376 } 1377 1378 /** 1379 * Returns the argument's value if present or else return the argument's default value. 1380 * 1381 * @param arg the argument 1382 * @return the argument's value if present, the argument's default value if not present 1383 */ 1384 static String getValueOrDefault(StringArgument arg) 1385 { 1386 String v = getValue(arg); 1387 String defaultValue = getDefaultValue(arg); 1388 return v != null ? v : defaultValue; 1389 } 1390 1391 /** 1392 * Returns the argument's value if present or else return the argument's default value. 1393 * 1394 * @param arg the argument 1395 * @return the argument's value if present, the argument's default value if not present 1396 */ 1397 static int getValueOrDefault(IntegerArgument arg) 1398 { 1399 int v = getValue(arg); 1400 int defaultValue = getDefaultValue(arg); 1401 return v != -1 ? v : defaultValue; 1402 } 1403 1404 /** 1405 * Returns the value of the provided argument only if the user provided it 1406 * explicitly. 1407 * @param arg the StringArgument to be handled. 1408 * @return the value of the provided argument only if the user provided it 1409 * explicitly. 1410 */ 1411 static String getValue(StringArgument arg) 1412 { 1413 return arg.isPresent() ? arg.getValue() : null; 1414 } 1415 1416 /** 1417 * Returns the default value of the provided argument. 1418 * @param arg the StringArgument to be handled. 1419 * @return the default value of the provided argument. 1420 */ 1421 static String getDefaultValue(StringArgument arg) 1422 { 1423 return arg.getDefaultValue(); 1424 } 1425 1426 /** 1427 * Returns the value of the provided argument only if the user provided it 1428 * explicitly. 1429 * @param arg the StringArgument to be handled. 1430 * @return the value of the provided argument only if the user provided it 1431 * explicitly. 1432 */ 1433 static int getValue(IntegerArgument arg) 1434 { 1435 if (arg.isPresent()) 1436 { 1437 try 1438 { 1439 return arg.getIntValue(); 1440 } 1441 catch (ArgumentException ae) 1442 { 1443 // This is a bug 1444 throw new IllegalStateException( 1445 "There was an argument exception calling "+ 1446 "ReplicationCliParser.getValue(). This appears to be a bug "+ 1447 "because this method should be called after calling "+ 1448 "parseArguments which should result in an error.", ae); 1449 } 1450 } 1451 return -1; 1452 } 1453 1454 /** 1455 * Returns the default value of the provided argument. 1456 * @param arg the StringArgument to be handled. 1457 * @return the default value of the provided argument. 1458 */ 1459 static int getDefaultValue(IntegerArgument arg) 1460 { 1461 String v = arg.getDefaultValue(); 1462 return v != null ? Integer.parseInt(v) : -1; 1463 } 1464 1465 /** 1466 * Checks the subcommand options and updates the provided LocalizableMessageBuilder 1467 * with the errors that were encountered with the subcommand options. 1468 * 1469 * This method assumes that the method parseArguments for the parser has 1470 * already been called. 1471 * @param buf the LocalizableMessageBuilder object where we add the error messages 1472 * describing the errors encountered. 1473 */ 1474 private void validateSubcommandOptions(LocalizableMessageBuilder buf) 1475 { 1476 if (isEnableReplicationSubcommand()) 1477 { 1478 validateEnableReplicationOptions(buf); 1479 } 1480 else if (isDisableReplicationSubcommand()) 1481 { 1482 validateDisableReplicationOptions(buf); 1483 } 1484 else if (isStatusReplicationSubcommand()) 1485 { 1486 validateStatusReplicationOptions(buf); 1487 } 1488 else if (isInitializeReplicationSubcommand()) 1489 { 1490 validateInitializeReplicationOptions(buf); 1491 } 1492 else if (isInitializeAllReplicationSubcommand()) 1493 { 1494 validateInitializeAllReplicationOptions(buf); 1495 } 1496 else if (isPreExternalInitializationSubcommand()) 1497 { 1498 validatePreExternalInitializationOptions(buf); 1499 } 1500 else if (isPostExternalInitializationSubcommand()) 1501 { 1502 validatePostExternalInitializationOptions(buf); 1503 } 1504 else if (isPurgeHistoricalSubcommand()) 1505 { 1506 validatePurgeHistoricalOptions(buf); 1507 } 1508 else 1509 { 1510 // This can occur if the user did not provide any subcommand. We assume 1511 // that the error informing of this will be generated in 1512 // validateGlobalOptions. 1513 } 1514 } 1515 1516 /** 1517 * Checks the purge historical subcommand options and updates the 1518 * provided LocalizableMessageBuilder with the errors that were encountered with the 1519 * subcommand options. 1520 * 1521 * This method assumes that the method parseArguments for the parser has 1522 * already been called. 1523 * @param buf the LocalizableMessageBuilder object where we add the error messages 1524 * describing the errors encountered. 1525 */ 1526 private void validatePurgeHistoricalOptions(LocalizableMessageBuilder buf) 1527 { 1528 try 1529 { 1530 if (!isInteractive() && !connectionArgumentsPresent()) 1531 { 1532 taskArgs.validateArgsIfOffline(); 1533 } 1534 else 1535 { 1536 taskArgs.validateArgs(); 1537 } 1538 } 1539 catch (ClientException | ArgumentException e) 1540 { 1541 addMessage(buf, e.getMessageObject()); 1542 } 1543 } 1544 1545 /** 1546 * Returns whether the user provided subcommand is the enable replication 1547 * or not. 1548 * @return <CODE>true</CODE> if the user provided subcommand is the 1549 * enable replication and <CODE>false</CODE> otherwise. 1550 */ 1551 public boolean isEnableReplicationSubcommand() 1552 { 1553 return isSubcommand(ENABLE_REPLICATION_SUBCMD_NAME); 1554 } 1555 1556 /** 1557 * Returns whether the user provided subcommand is the disable replication 1558 * or not. 1559 * @return <CODE>true</CODE> if the user provided subcommand is the 1560 * disable replication and <CODE>false</CODE> otherwise. 1561 */ 1562 public boolean isDisableReplicationSubcommand() 1563 { 1564 return isSubcommand(DISABLE_REPLICATION_SUBCMD_NAME); 1565 } 1566 1567 /** 1568 * Returns whether the user provided subcommand is the status replication 1569 * or not. 1570 * @return <CODE>true</CODE> if the user provided subcommand is the 1571 * status replication and <CODE>false</CODE> otherwise. 1572 */ 1573 public boolean isStatusReplicationSubcommand() 1574 { 1575 return isSubcommand(STATUS_REPLICATION_SUBCMD_NAME); 1576 } 1577 1578 /** 1579 * Returns whether the user provided subcommand is the purge historical 1580 * or not. 1581 * @return <CODE>true</CODE> if the user provided subcommand is the 1582 * purge historical and <CODE>false</CODE> otherwise. 1583 */ 1584 public boolean isPurgeHistoricalSubcommand() 1585 { 1586 return isSubcommand(PURGE_HISTORICAL_SUBCMD_NAME); 1587 } 1588 1589 /** 1590 * Returns whether the user provided subcommand is the initialize all 1591 * replication or not. 1592 * @return <CODE>true</CODE> if the user provided subcommand is the 1593 * initialize all replication and <CODE>false</CODE> otherwise. 1594 */ 1595 public boolean isInitializeAllReplicationSubcommand() 1596 { 1597 return isSubcommand(INITIALIZE_ALL_REPLICATION_SUBCMD_NAME); 1598 } 1599 1600 /** 1601 * Returns whether the user provided subcommand is the pre external 1602 * initialization or not. 1603 * @return <CODE>true</CODE> if the user provided subcommand is the 1604 * pre external initialization and <CODE>false</CODE> otherwise. 1605 */ 1606 public boolean isPreExternalInitializationSubcommand() 1607 { 1608 return isSubcommand(PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME); 1609 } 1610 1611 /** 1612 * Returns whether the user provided subcommand is the post external 1613 * initialization or not. 1614 * @return <CODE>true</CODE> if the user provided subcommand is the 1615 * post external initialization and <CODE>false</CODE> otherwise. 1616 */ 1617 public boolean isPostExternalInitializationSubcommand() 1618 { 1619 return isSubcommand(POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME); 1620 } 1621 1622 /** 1623 * Returns whether the user provided subcommand is the initialize replication 1624 * or not. 1625 * @return <CODE>true</CODE> if the user provided subcommand is the 1626 * initialize replication and <CODE>false</CODE> otherwise. 1627 */ 1628 public boolean isInitializeReplicationSubcommand() 1629 { 1630 return isSubcommand(INITIALIZE_REPLICATION_SUBCMD_NAME); 1631 } 1632 1633 /** 1634 * Returns whether the command-line subcommand has the name provided 1635 * or not. 1636 * @param name the name of the subcommand. 1637 * @return <CODE>true</CODE> if command-line subcommand has the name provided 1638 * and <CODE>false</CODE> otherwise. 1639 */ 1640 private boolean isSubcommand(String name) 1641 { 1642 SubCommand subCommand = getSubCommand(); 1643 return subCommand != null && subCommand.getName().equalsIgnoreCase(name); 1644 } 1645 1646 /** 1647 * Checks the enable replication subcommand options and updates the provided 1648 * LocalizableMessageBuilder with the errors that were encountered with the subcommand 1649 * options. 1650 * 1651 * This method assumes that the method parseArguments for the parser has 1652 * already been called. 1653 * @param buf the LocalizableMessageBuilder object where we add the error messages 1654 * describing the errors encountered. 1655 */ 1656 private void validateEnableReplicationOptions(LocalizableMessageBuilder buf) 1657 { 1658 Argument[][] conflictingPairs = 1659 { 1660 { server1.bindPasswordArg, server1.bindPasswordFileArg }, 1661 { server2.bindPasswordArg, server2.bindPasswordFileArg }, 1662 { server1.replicationPortArg, server1.noReplicationServerArg }, 1663 { server1.noReplicationServerArg, server1.onlyReplicationServerArg }, 1664 { server2.replicationPortArg, server2.noReplicationServerArg }, 1665 { server2.noReplicationServerArg, server2.onlyReplicationServerArg }, 1666 {noSchemaReplicationArg, useSecondServerAsSchemaSourceArg} 1667 }; 1668 1669 for (Argument[] conflictingPair : conflictingPairs) 1670 { 1671 Argument arg1 = conflictingPair[0]; 1672 Argument arg2 = conflictingPair[1]; 1673 if (arg1.isPresent() && arg2.isPresent()) 1674 { 1675 LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( 1676 arg1.getLongIdentifier(), arg2.getLongIdentifier()); 1677 addMessage(buf, message); 1678 } 1679 } 1680 1681 if (server1.hostNameArg.getValue().equalsIgnoreCase(server2.hostNameArg.getValue()) 1682 && !isInteractive() 1683 && server1.portArg.getValue().equals(server2.portArg.getValue())) 1684 { 1685 LocalizableMessage message = ERR_REPLICATION_ENABLE_SAME_SERVER_PORT.get( 1686 server1.hostNameArg.getValue(), server1.portArg.getValue()); 1687 addMessage(buf, message); 1688 } 1689 } 1690 1691 /** 1692 * Checks the disable replication subcommand options and updates the provided 1693 * LocalizableMessageBuilder with the errors that were encountered with the subcommand 1694 * options. 1695 * 1696 * This method assumes that the method parseArguments for the parser has 1697 * already been called. 1698 * @param buf the LocalizableMessageBuilder object where we add the error messages 1699 * describing the errors encountered. 1700 */ 1701 private void validateDisableReplicationOptions(LocalizableMessageBuilder buf) 1702 { 1703 Argument[][] conflictingPairs = 1704 { 1705 {getAdminUidArg(), secureArgsList.bindDnArg}, 1706 {disableAllArg, disableReplicationServerArg}, 1707 {disableAllArg, baseDNsArg} 1708 }; 1709 1710 for (Argument[] conflictingPair : conflictingPairs) 1711 { 1712 Argument arg1 = conflictingPair[0]; 1713 Argument arg2 = conflictingPair[1]; 1714 if (arg1.isPresent() && arg2.isPresent()) 1715 { 1716 LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( 1717 arg1.getLongIdentifier(), arg2.getLongIdentifier()); 1718 addMessage(buf, message); 1719 } 1720 } 1721 } 1722 1723 /** 1724 * Checks the initialize all replication subcommand options and updates the 1725 * provided LocalizableMessageBuilder with the errors that were encountered with the 1726 * subcommand options. 1727 * 1728 * This method assumes that the method parseArguments for the parser has 1729 * already been called. 1730 * @param buf the LocalizableMessageBuilder object where we add the error messages 1731 * describing the errors encountered. 1732 */ 1733 private void validateInitializeAllReplicationOptions(LocalizableMessageBuilder buf) 1734 { 1735 } 1736 1737 /** 1738 * Checks the pre external initialization subcommand options and updates the 1739 * provided LocalizableMessageBuilder with the errors that were encountered with the 1740 * subcommand options. 1741 * 1742 * This method assumes that the method parseArguments for the parser has 1743 * already been called. 1744 * @param buf the LocalizableMessageBuilder object where we add the error messages 1745 * describing the errors encountered. 1746 */ 1747 private void validatePreExternalInitializationOptions(LocalizableMessageBuilder buf) 1748 { 1749 validateInitializeAllReplicationOptions(buf); 1750 } 1751 1752 /** 1753 * Checks the post external initialization subcommand options and updates the 1754 * provided LocalizableMessageBuilder with the errors that were encountered with the 1755 * subcommand options. 1756 * 1757 * This method assumes that the method parseArguments for the parser has 1758 * already been called. 1759 * @param buf the LocalizableMessageBuilder object where we add the error messages 1760 * describing the errors encountered. 1761 */ 1762 private void validatePostExternalInitializationOptions(LocalizableMessageBuilder buf) 1763 { 1764 validateInitializeAllReplicationOptions(buf); 1765 } 1766 1767 /** 1768 * Checks the status replication subcommand options and updates the provided 1769 * LocalizableMessageBuilder with the errors that were encountered with the subcommand 1770 * options. 1771 * 1772 * This method assumes that the method parseArguments for the parser has 1773 * already been called. 1774 * @param buf the LocalizableMessageBuilder object where we add the error messages 1775 * describing the errors encountered. 1776 */ 1777 private void validateStatusReplicationOptions(LocalizableMessageBuilder buf) 1778 { 1779 if (quietArg.isPresent()) 1780 { 1781 LocalizableMessage message = ERR_REPLICATION_STATUS_QUIET.get( 1782 STATUS_REPLICATION_SUBCMD_NAME, "--"+quietArg.getLongIdentifier()); 1783 addMessage(buf, message); 1784 } 1785 } 1786 1787 /** 1788 * Checks the initialize replication subcommand options and updates the 1789 * provided LocalizableMessageBuilder with the errors that were encountered with the 1790 * subcommand options. 1791 * 1792 * This method assumes that the method parseArguments for the parser has 1793 * already been called. 1794 * @param buf the LocalizableMessageBuilder object where we add the error messages 1795 * describing the errors encountered. 1796 */ 1797 private void validateInitializeReplicationOptions(LocalizableMessageBuilder buf) 1798 { 1799 if (hostNameSourceArg.getValue().equalsIgnoreCase(hostNameDestinationArg.getValue()) 1800 && !isInteractive() 1801 && portSourceArg.getValue().equals(portDestinationArg.getValue())) 1802 { 1803 LocalizableMessage message = ERR_REPLICATION_INITIALIZE_SAME_SERVER_PORT.get( 1804 hostNameSourceArg.getValue(), portSourceArg.getValue()); 1805 addMessage(buf, message); 1806 } 1807 } 1808 1809 /** 1810 * Adds a message to the provided LocalizableMessageBuilder. 1811 * @param buf the LocalizableMessageBuilder. 1812 * @param message the message to be added. 1813 */ 1814 private void addMessage(LocalizableMessageBuilder buf, LocalizableMessage message) 1815 { 1816 if (buf.length() > 0) 1817 { 1818 buf.append(LINE_SEPARATOR); 1819 } 1820 buf.append(message); 1821 } 1822 1823 /** 1824 * Returns the default value to be used for the host. 1825 * @return the default value to be used for the host. 1826 */ 1827 private String getDefaultHostValue() 1828 { 1829 if (defaultLocalHostValue == null) 1830 { 1831 try 1832 { 1833 defaultLocalHostValue = 1834 java.net.InetAddress.getLocalHost().getHostName(); 1835 } 1836 catch (Throwable t) 1837 { 1838 } 1839 if (defaultLocalHostValue == null) 1840 { 1841 defaultLocalHostValue = "localhost"; 1842 } 1843 } 1844 return defaultLocalHostValue; 1845 } 1846 1847 /** 1848 * Returns the SecureConnectionCliArgs object containing the arguments 1849 * of this parser. 1850 * @return the SecureConnectionCliArgs object containing the arguments 1851 * of this parser. 1852 */ 1853 public SecureConnectionCliArgs getSecureArgsList() 1854 { 1855 return secureArgsList; 1856 } 1857 1858 /** 1859 * Returns the TaskScheduleArgs object containing the arguments 1860 * of this parser. 1861 * @return the TaskScheduleArgs object containing the arguments 1862 * of this parser. 1863 */ 1864 public TaskScheduleArgs getTaskArgsList() 1865 { 1866 return taskArgs; 1867 } 1868 1869 /** 1870 * Returns whether the user specified connection arguments or not. 1871 * @return {@code true} if the user specified connection arguments and 1872 * {@code false} otherwise. 1873 */ 1874 boolean connectionArgumentsPresent() 1875 { 1876 if (isPurgeHistoricalSubcommand()) { 1877 boolean secureArgsPresent = getSecureArgsList() != null && 1878 getSecureArgsList().argumentsPresent(); 1879 // This have to be explicitly specified because their original definition 1880 // has been replaced. 1881 boolean adminArgsPresent = getAdminUidArg().isPresent() || 1882 secureArgsList.bindPasswordArg.isPresent() || 1883 secureArgsList.bindPasswordFileArg.isPresent(); 1884 return secureArgsPresent || adminArgsPresent; 1885 } 1886 return true; 1887 } 1888 1889 /** 1890 * Returns the maximum duration explicitly provided in the purge historical 1891 * replication subcommand. 1892 * @return the maximum duration explicitly provided in the purge historical 1893 * replication subcommand. Returns -1 if no port was explicitly provided. 1894 */ 1895 public int getMaximumDuration() 1896 { 1897 return getValue(maximumDurationArg); 1898 } 1899 1900 /** 1901 * Returns the maximum duration default value in the purge historical 1902 * replication subcommand. 1903 * @return the maximum duration default value in the purge historical 1904 * replication subcommand. 1905 */ 1906 public int getMaximumDurationOrDefault() 1907 { 1908 return getValueOrDefault(maximumDurationArg); 1909 } 1910}