package jeffaschenk.commons.frameworks.cnxidx.admin; import jeffaschenk.commons.frameworks.cnxidx.utility.commandlinearguments.CommandLinePrincipalCredentials; import jeffaschenk.commons.frameworks.cnxidx.utility.commandlinearguments.idxArgParser; import jeffaschenk.commons.frameworks.cnxidx.utility.commandlinearguments.idxArgVerificationRules; import jeffaschenk.commons.frameworks.cnxidx.utility.commandlinearguments.idxArgVerifier; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxCMDReturnCodes; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxElapsedTime; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxParseDN; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * Java Command line utility, driven from properties and command * line parameters to Copy an Entry from a Source to a Destination, * by a specified number of Threads. * This provides a Thread and concurrent write of Data by * several different Threads. The Destination DN will be modified to * specify the thread number, to allow full concurrency. This will * provide a means to test performance and load conditions on the directory. * <br> * <br> * This utility command can copy entries from one Directory to another, since * both a Source and Destination Directory Contexts are established. * <br> * <b>Usage:</b><br> * IRRcopyXT <Required Parameters> <Optional Parameters> * <br> * <b>Required Parameters are:</b> * <pre> * --hosturl * Specify IRR(Directory) LDAP URL, ldap://hostname.acme.com * --irrid * Specify IRR(Directory) LDAP BIND DN, cn=irradmin,o=icosdsa * --irrpw * Specify IRR(Directory) LDAP BIND Password * --idu * Specify FRAMEWORK Keystore Alias to obtain IRRID and IRRPW. * --sourcedn * Specify Full DN of Source Entry. * --destdn * Specify Full DN of Destination Entry. * --tid * Specify Thread Name prefix. * </pre> * <b>Optional Parameters are:</b> * <pre> * --desthosturl * Specify Destination IRR(Directory) LDAP URL, ldap://hostname.acme.com * --destirrid * Specify Destination IRR(Directory) LDAP BIND DN, cn=irradmin,o=icosdsa * --destirrpw * Specify Destination IRR(Directory) LDAP BIND Password * --destidu * Specify FRAMEWORK Keystore Alias to obtain Destination IRRID and IRRPW. * --verbose * Specify Additional Logging Information. * --debug * Specify Additional Debugging Information. * --overwrite * Specify Existing Destination Entry will be overwritten. * --withchildren * Specify Copy of Source children entries to Destination as well as parent entry. * --version * Display Version information and exit. * --threads * Number of Concurrent Threads to run, default is two (2). * --? * This Display. * * </pre> * * @author jeff.schenk * @version 1.0 $Revision * Developed 2001 */ class IRRcopyXT implements Runnable, idxCMDReturnCodes { String tname; // Name of Thread Thread t; List<String> RunnerArgs; IRRcopyXT(String _threadname, List<String> _runnerargs) { tname = _threadname; RunnerArgs = _runnerargs; t = new Thread(this, tname); System.out.println("** New Thread Created: " + t); t.start(); // Start the Thread. } // End of Constructor Class. public void run() { IRROMRunner xrunner = new IRROMRunner(this.tname); // **************************************** // Execute the Function. try { xrunner.setFUNCTION(this.RunnerArgs); xrunner.performFUNCTION(); } catch (Exception e) { System.out.println(this.tname + " Exception, existing."); } // End of Exception. } // End of Run Method. } //:~ End of IRRcopyXT class class IRRcopyXTexecutor implements idxCMDReturnCodes { private static String VERSION = "Version: 1.0 2001-12-15, " + "FRAMEWORK, Incorporated."; private static String MP = "IRRcopyXTexecutor: "; private static String IRRHost = null; private static String IRRPrincipal = null; private static String IRRCredentials = null; private static String ENTRY_SOURCE_DN = null; private static String IRRDestHost = null; private static String IRRDestPrincipal = null; private static String IRRDestCredentials = null; private static String ENTRY_DESTINATION_DN = null; private static boolean OVERWRITE_DESTINATION_ENTRY = false; private static boolean COPY_WITH_CHILDREN = false; private static boolean VERBOSE = false; private static boolean DEBUG = false; private static String TID = null; private static int THREADS = 2; private boolean ExitOnException = false; /** * Usage * Class to print Usage parameters and simple exit. */ static void Usage() { System.err.println(MP + "Usage:"); System.err.println(MP + "IRRcopyXT <Required Parameters> <Optional Parameters>"); System.err.println("\n" + MP + "Required Parameters are:"); System.err.println(MP + "--hosturl "); System.err.println("\tSpecify Source IRR(Directory) LDAP URL, ldap://hostname.acme.com"); System.err.println(MP + "--irrid "); System.err.println("\tSpecify Source IRR(Directory) LDAP BIND DN, cn=irradmin,o=icosdsa"); System.err.println(MP + "--irrpw "); System.err.println("\tSpecify Source IRR(Directory) LDAP BIND Password"); System.err.println(MP + "--idu "); System.err.println("\tSpecify FRAMEWORK Keystore Alias to obtain IRRID and IRRPW."); System.err.println(MP + "--sourcedn "); System.err.println("\tSpecify Full DN of Source Entry."); System.err.println(MP + "--destdn "); System.err.println("\tSpecify Full DN of Destination Entry."); System.err.println(MP + "--tid "); System.err.println("\tSpecify Thread Name Prefix."); System.err.println("\n" + MP + "Optional Parameters are:"); System.err.println(MP + "--desthosturl "); System.err.println("\tSpecify Destination IRR(Directory) LDAP URL, ldap://hostname.acme.com"); System.err.println(MP + "--destirrid "); System.err.println("\tSpecify Destination IRR(Directory) LDAP BIND DN, cn=irradmin,o=icosdsa"); System.err.println(MP + "--destirrpw "); System.err.println("\tSpecify Destination IRR(Directory) LDAP BIND Password"); System.err.println(MP + "--destidu "); System.err.println("\tSpecify FRAMEWORK Keystore Alias to obtain Destination IRRID and IRRPW."); System.err.println(MP + "--verbose"); System.err.println("\tSpecify Additional Logging Information."); System.err.println(MP + "--debug"); System.err.println("\tSpecify Additional Debugging Information."); System.err.println(MP + "--overwrite"); System.err.println("\tSpecify Existing Destination Entry will be overwritten."); System.err.println(MP + "--withchildren"); System.err.println("\tSpecify Copy of Source children entries to Destination as well as parent entry."); System.err.println(MP + "--version"); System.err.println("\tDisplay Version information and exit."); System.err.println(MP + "--threads"); System.err.println("\tSpecify number of concurrent Threads, default is 2."); System.err.println(MP + "--?"); System.err.println("\tThe Above Display."); System.exit(EXIT_USAGE); } // End of Subclass /** * Main * * @param args Incoming Argument Array. */ public static void main(String args[]) { // **************************************** // Send the Greeting. System.out.println(MP + VERSION); // **************************************** // Parse the incoming Arguments and // create objects for each entity. // idxArgParser Zin = new idxArgParser(); Zin.parse(args); // *************************************** // Do I have any unnamed Values? if (!Zin.IsUnNamedEmpty()) { System.out.println(MP + "Unknown Values Encountered, Terminating Process."); Zin.showUnNamed(); Usage(); } // End of If. // *************************************** // Was Version Info Requested? if (Zin.doesNameExist("version")) { System.exit(EXIT_VERSION); } // *************************************** // Was Help Info Requested? if ((Zin.doesNameExist("?")) || (Zin.doesNameExist("usage"))) { Usage(); } // *************************************** // Was Verbosity Requested? if (Zin.doesNameExist("verbose")) { VERBOSE = true; } // *************************************** // Was Debugging Requested? if (Zin.doesNameExist("debug")) { DEBUG = true; } // *************************************** // Show Arguments if Verbose Selected. if (VERBOSE) { Zin.show(); } // *************************************** // Build our verification Rule Set. // // idxArgVerificationRules Parameters are: // String Name of argument name. // Boolean Required Argument Indicator. // Boolean StringObject Argument Indicator. // String Name of Value Verification Routine. // LinkedList<idxArgVerificationRules> VAR = new LinkedList<>(); VAR.add(new idxArgVerificationRules("hosturl", true, true)); VAR.add(new idxArgVerificationRules("irrid", false, true)); VAR.add(new idxArgVerificationRules("irrpw", false, true)); VAR.add(new idxArgVerificationRules("idu", false, true)); VAR.add(new idxArgVerificationRules("desthosturl", false, true)); VAR.add(new idxArgVerificationRules("destirrid", false, true)); VAR.add(new idxArgVerificationRules("destirrpw", false, true)); VAR.add(new idxArgVerificationRules("destidu", false, true)); VAR.add(new idxArgVerificationRules("sourcedn", true, true)); VAR.add(new idxArgVerificationRules("destdn", true, true)); VAR.add(new idxArgVerificationRules("tid", true, true)); VAR.add(new idxArgVerificationRules("overwrite", false, false)); VAR.add(new idxArgVerificationRules("withchildren", false, false)); VAR.add(new idxArgVerificationRules("threads", false, true)); VAR.add(new idxArgVerificationRules("verbose", false, false)); VAR.add(new idxArgVerificationRules("debug", false, false)); // *************************************** // Run the Verification Rule Set. // If we do not have a positive return, // then an invalid argument was detected, // so show Usage and die. // idxArgVerifier AV = new idxArgVerifier(); AV.setVerbose(VERBOSE); if (!AV.Verify(MP, Zin, VAR)) { Usage(); } // *************************************** // Obtain Authentication Principal and // Credentials from the KeyStore or // the command line. // CommandLinePrincipalCredentials clPC = new CommandLinePrincipalCredentials(Zin); // ************************************************** // Load up the Principal/Credentials. // if (clPC.wasObtained()) { IRRPrincipal = clPC.getPrincipal(); System.out.println(MP + "IRR ID:[" + IRRPrincipal + "]"); IRRCredentials = clPC.getCredentials(); //System.out.println(MP+"IRR Password:["+IRRCredentials+"]"); } else { System.out.println(MP + "Required Principal and Credentials not Specified, unable to continue."); Usage(); } // End of Else. // ************************************************** // Load up the Destination Principal/Credentials. // if (clPC.wasDestObtained()) { IRRDestPrincipal = clPC.getDestPrincipal(); IRRDestCredentials = clPC.getDestCredentials(); } else { IRRDestPrincipal = IRRPrincipal; IRRDestCredentials = IRRCredentials; } // End of Else. System.out.println(MP + "IRR Destination ID:[" + IRRDestPrincipal + "]"); //System.out.println(MP+"IRR Destination Password:["+IRRDestCredentials+"]"); // ***************************************** // For all Specified Boolean indicators, // set them appropreiately. // if (Zin.doesNameExist("withchildren")) { COPY_WITH_CHILDREN = true; } if (Zin.doesNameExist("overwrite")) { OVERWRITE_DESTINATION_ENTRY = true; } // ************************************************** // Load up the RunTime Arguments. // TID = (String) Zin.getValue("tid"); System.out.println(MP + "Thread Name Prefix:[" + TID + "]"); IRRHost = (String) Zin.getValue("hosturl"); System.out.println(MP + "IRR Host URL:[" + IRRHost + "]"); if (!Zin.doesNameExist("desthosturl")) { IRRDestHost = IRRHost; } else { IRRDestHost = (String) Zin.getValue("desthosturl"); } System.out.println(MP + "IRR Destination Host URL:[" + IRRDestHost + "]"); ENTRY_SOURCE_DN = ((String) Zin.getValue("sourcedn")).trim(); ENTRY_SOURCE_DN = ENTRY_SOURCE_DN.toLowerCase(); System.out.println(MP + "Source DN:[" + ENTRY_SOURCE_DN + "]"); ENTRY_DESTINATION_DN = ((String) Zin.getValue("destdn")).trim(); ENTRY_DESTINATION_DN = ENTRY_DESTINATION_DN.toLowerCase(); System.out.println(MP + "Destination DN:[" + ENTRY_DESTINATION_DN + "]"); if (Zin.doesNameExist("threads")) { try { THREADS = Integer.parseInt( ((String) Zin.getValue("threads")).trim()); } catch (Exception e) { System.err.println(MP + "Unable to obtain correct Thread Value Specified.\n" + e); System.exit(EXIT_GENERIC_FAILURE); } // End of Exception. } // End of If. // ************************************************ // Show Operational Parameters if (OVERWRITE_DESTINATION_ENTRY) { System.out.println(MP + "Will Overwrite existing Destination Entry with new entry."); } else { System.out.println(MP + "Will NOT Overwrite existing Destination Entry with new entry."); } if (COPY_WITH_CHILDREN) { System.out.println(MP + "Will Copy Source Children along with this to new Destination."); } else { System.out.println(MP + "Will NOT copy any Source Children."); } System.out.println(MP + "Will spawn:[" + THREADS + "] for Concurrent Copy from same Source to Same Destination."); // **************************************** // Note The Start Time. idxElapsedTime elt = new idxElapsedTime(); int tnum; IRRcopyXT mythreads[] = new IRRcopyXT[THREADS]; for (tnum = 0; tnum < THREADS; tnum++) { String destDN = ENTRY_DESTINATION_DN; idxParseDN tDdn = new idxParseDN(ENTRY_DESTINATION_DN); if (tDdn.isValid()) { destDN = tDdn.getNamingAttribute() + "=" + tDdn.getNamingValue() + "(" + TID + "." + tnum + ")," + tDdn.getPDN(); } // End of If. // ******************************************************** // Construct the Running Arguments for this Thread. List<String> RunnerArgs = new ArrayList<>(); RunnerArgs.add("jeffaschenk.commons.frameworks.cnxidx.admin.IRRcopyEntry"); RunnerArgs.add("--hosturl"); RunnerArgs.add("\047" + IRRHost + "\047"); RunnerArgs.add("--irrid"); RunnerArgs.add("\047" + IRRPrincipal + "\047"); RunnerArgs.add("--irrpw"); RunnerArgs.add("\047" + IRRCredentials + "\047"); RunnerArgs.add("--sourcedn"); RunnerArgs.add("\047" + ENTRY_SOURCE_DN + "\047"); RunnerArgs.add("--desthosturl"); RunnerArgs.add("\047" + IRRDestHost + "\047"); RunnerArgs.add("--destirrid"); RunnerArgs.add("\047" + IRRDestPrincipal + "\047"); RunnerArgs.add("--destirrpw"); RunnerArgs.add("\047" + IRRDestCredentials + "\047"); RunnerArgs.add("--destdn"); RunnerArgs.add("\047" + destDN + "\047"); // ****************************************** // Look for any possible Boolean Indicators if (COPY_WITH_CHILDREN) { RunnerArgs.add("--withchildren"); } if (OVERWRITE_DESTINATION_ENTRY) { RunnerArgs.add("--overwrite"); } if (VERBOSE) { RunnerArgs.add("--verbose"); } if (DEBUG) { RunnerArgs.add("--debug"); } // **************************************** // Initialize Thread. System.out.println(MP + "Starting Thread Name: " + TID + "." + tnum); mythreads[tnum] = new IRRcopyXT(TID + "." + tnum, RunnerArgs); } // End of For Loop. // *************************************************** // Show Thread Status. for (tnum = 0; tnum < THREADS; tnum++) { if (mythreads[tnum].t.isAlive()) { System.out.println(MP + "Thread " + tnum + " is Running..."); } } // End of For Loop. // ****************************************** // Now Join and Wait for Completion. // try { System.out.println(MP + "Main Thread waiting for Worker Threads to Complete..."); for (tnum = 0; tnum < THREADS; tnum++) { mythreads[tnum].t.join(); } } catch (InterruptedException e) { System.err.println(MP + "Main Thread Interrupted, Terminating."); System.exit(EXIT_GENERIC_FAILURE); } // End of Exception. // **************************************** // Note The End Time. elt.setEnd(); // **************************************** // Exit System.out.println(MP + "Done, Elapsed Time: " + elt.getElapsed()); System.exit(EXIT_SUCCESSFUL); } // End of Main. } //:~ End of IRRcopyXTexecutor