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.idxLDIFReader;
import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
/**
* Java Command line utility, driven from properties and command
* line parameters to Restore the Entire, a portion (container) or even
* a single entry and optionally all of its children to
* the IRR Directory from a LDIF format input file on disk.
* Backup input conforms to the LDIF Specification: RFC2849.
* <br>
* <b>Usage:</b><br>
* IRRrestore <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.
* --infile
* Specify Full Input file Path for restore to be read.
* Will read a <infile> and <infile>.schema.xml files.
* </pre>
* <b>Optional Parameters are:</b>
* <pre>
* --jar
* Specify LDIF infile specifies a JAR path.
* --restoreonlyDN
* Specify to restore only current DN.
* --schemacheck
* Specify to check current and backup schema are in sync.
* --noschemacheck
* Specify not to check current and backup schema are in sync.
* --withchildren
* Specify to restore specified restoreonlyDN and all it's children.
* --version
* Display Version information and exit.
* --?
* This Display.
*
* </pre>
*
* @author jeff.schenk
* @version 4.4 $Revision
* Developed 2005
*/
public class IRRrestore implements idxCMDReturnCodes {
public static String VERSION = "Version: 4.4 2005-11-30, " +
"FRAMEWORK, Incorporated.";
public static String MP = "IRRrestore: ";
private idxManageContext IRRDest = null;
private static String IRRHost = null;
private static String IRRPrincipal = null;
private static String IRRCredentials = null;
private static String INPUT_FILENAME = null;
private static String RESTOREONLY_SOURCEDN = null;
private static boolean RESTOREONLY_WITH_CHILDREN = false;
private static boolean RESTOREONLY = false;
private static boolean INJAR = false;
private static boolean VERBOSE = false;
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 + "IRRrestore <Required Parameters> <Optional Parameters>");
System.err.println("\n" + MP + "Required Parameters are:");
System.err.println(MP + "--hosturl ");
System.err.println("\tSpecify IRR(Directory) LDAP URL, ldap://hostname.acme.com");
System.err.println(MP + "--irrid ");
System.err.println("\tSpecify IRR(Directory) LDAP BIND DN, cn=irradmin,o=icosdsa");
System.err.println(MP + "--irrpw ");
System.err.println("\tSpecify 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 + "--infile ");
System.err.println("\tSpecify Full Input file Path for restore to be read.");
System.err.println("\n" + MP + "Optional Parameters are:");
System.err.println(MP + "--jar ");
System.err.println("\tSpecify LDIF Input is located in a JAR.");
System.err.println(MP + "--restoreonlyDN ");
System.err.println("\tSpecify to restore only current DN.");
System.err.println(MP + "--withchildren ");
System.err.println("\tSpecify to restore specified restoreonlyDN and all it's children.");
System.err.println(MP + "--version");
System.err.println("\tDisplay Version information and exit.");
System.err.println(MP + "--?");
System.err.println("\tThe Above Display.");
System.exit(EXIT_USAGE);
} // End of Subclass
/**
* IRRrestore Contructor class driven from
* Main or other Class Caller.
*
* @param _IRRHost Source IRR LDAP URL.
* @param _IRRPrincipal Source IRR Principal.
* @param _IRRCredentials Source IRR Credentials.
* @param _INPUT_FILENAME Input Filename or Input JAR Class.
* @param _RESTOREONLY_SOURCEDN RestoreOnly Source DN.
* @param _INJAR Indicate LDIF Input in JAR.
* @param _RESTOREONLY_WITH_CHILDREN Indicate Restore Only with Children.
* @param _RESTOREONLY Indicate Restore Only of Source DN.
* @param _VERBOSE Indicate Verbosity.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
public IRRrestore(String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _INPUT_FILENAME,
String _RESTOREONLY_SOURCEDN,
boolean _INJAR,
boolean _RESTOREONLY_WITH_CHILDREN,
boolean _RESTOREONLY,
boolean _VERBOSE,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
INPUT_FILENAME = _INPUT_FILENAME;
INJAR = _INJAR;
RESTOREONLY_SOURCEDN = _RESTOREONLY_SOURCEDN;
RESTOREONLY_WITH_CHILDREN = _RESTOREONLY_WITH_CHILDREN;
RESTOREONLY = _RESTOREONLY;
VERBOSE = _VERBOSE;
ExitOnException = _ExitOnException;
} // End of Constructor for IRRrestore.
/**
* perform Method class performs the requested IRR Function Utility.
*
* @throws jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxIRRException
* for any specific IRR unrecoverable errors during function.
* @throws Exception for any unrecoverable errors during function.
*/
public void perform() throws Exception, idxIRRException {
// *******************************************
// Initialize.
CompoundName RESTOREONLY_Name = null;
CompoundName Incoming_Name = null;
// ********************************************
// Create a Compound Name for our SourceDN
//
if (RESTOREONLY) {
try {
// ***********************************************
// Now determine if SourceDN is Valid.
idxParseDN zSdn = new idxParseDN(RESTOREONLY_SOURCEDN);
if (!zSdn.isValid()) {
if (ExitOnException) {
System.err.println(MP + "Restore Only Source DN [" +
RESTOREONLY_SOURCEDN +
"] is Invalid, unable to continue.");
System.exit(EXIT_IRR_RESTORE_FAILURE);
} else {
throw new idxIRRException(MP + "Restore Only Source DN [" +
RESTOREONLY_SOURCEDN +
"] is Invalid, unable to continue.");
} // End of Inner Else.
} // End of If.
RESTOREONLY_Name = idxNameParser.parse(RESTOREONLY_SOURCEDN);
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + "Restore Only Source DN [" +
RESTOREONLY_SOURCEDN +
"] is Invalid, unable to continue.");
System.exit(EXIT_IRR_RESTORE_FAILURE);
} else {
throw new idxIRRException(MP + "Restore Only Source DN [" +
RESTOREONLY_SOURCEDN +
"] is Invalid, unable to continue.");
} // End of Inner Else.
} // End of exception
} // End of If.
// ***********************************************
// Now initiate a Connection to the Directory
// for a LDAP Source Context
if (VERBOSE) {
System.out.println(MP + "Attempting Destination Directory Connection to Host URL:[" + IRRHost + "]");
}
IRRDest = new idxManageContext(IRRHost,
IRRPrincipal,
IRRCredentials,
"Restore Destination");
// ************************************************
// Exit on all Exceptions.
IRRDest.setExitOnException(ExitOnException);
// ************************************************
// Now Try to Open and Obtain Context.
try {
IRRDest.open();
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + e);
System.exit(EXIT_IRR_UNABLE_TO_OBTAIN_CONTEXT);
} else {
throw e;
}
} // End of exception
// ************************************************
// Disable Factories.
try {
IRRDest.disableDSAEFactories();
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + e);
System.exit(EXIT_GENERIC_FAILURE);
} else {
throw e;
}
} // End of exception
// *****************************************
// Open Input File and Start Restore Process
if (VERBOSE) {
if (INJAR) {
System.out.println(MP + "Starting Directory Restore using LDIF JAR Class:[" + INPUT_FILENAME + "]");
} else {
System.out.println(MP + "Starting Directory Restore using LDIF Input File:[" + INPUT_FILENAME + "]");
} // End of Else.
} // End of Verbose.
// *****************************************
// Initialize.
BufferedReader LDIFIN = null;
int entries_exceptions = 0;
int entries_duplicate = 0;
int entries_skipped = 0;
int entries_restored = 0;
Attributes current_entry_attributes = null;
String current_dn = null;
String LDIFVersion = null;
// *****************************************
// Open up Input.
try {
if (INJAR) {
// ******************************************
// Open up the Input Stream from a JAR.
LDIFIN = new BufferedReader(
new InputStreamReader(
ClassLoader.getSystemResourceAsStream(INPUT_FILENAME)), 16384);
} else {
// ******************************************
// Open up the Input Stream from a File.
LDIFIN = new BufferedReader(
new FileReader(INPUT_FILENAME), 16384);
} // End of Else.
// ******************************************
// Obtain our Reader Instance with our Input.
idxLDIFReader ldif = new idxLDIFReader(LDIFIN);
Incoming_Name = null;
while (ldif.hasMore()) {
current_entry_attributes = ldif.getNextEntry();
current_dn = ldif.getCurrentDN();
if ((current_dn == null) ||
(current_dn.equals(""))) {
continue;
}
// *************************************
// Detect the Version, if possible.
if ((LDIFVersion == null) ||
(LDIFVersion.equals(""))) {
LDIFVersion = ldif.getVersion();
if ((LDIFVersion != null) &&
(!LDIFVersion.equals(""))) {
if (VERBOSE) {
System.out.println(MP + "LDIF VERSION Detected:[" +
LDIFVersion + "]");
} // End of Verbose.
}
} // End of LDIF Version Detection.
// ***************************************
// If we have a RestoreOnlyDN Specified
// filter out the ones we do not need.
//
if (RESTOREONLY) {
try {
Incoming_Name = idxNameParser.parse(current_dn);
} catch (Exception e) {
System.err.println(MP + "Exception Creating incoming Compound Name " + e);
entries_exceptions++;
continue;
} // End of exception
// ****************************************************
// If No Children, Compare Incoming and the RestoreOnly
if (!RESTOREONLY_WITH_CHILDREN) {
if (!Incoming_Name.equals(RESTOREONLY_Name)) {
entries_skipped++;
if (VERBOSE) {
System.out.println(MP + "Skipping DN-> " + current_dn);
}
continue;
}
} else {
// **********************************************************
// If Children, Compare Incoming has a suffix of RestoreOnly
if (!Incoming_Name.endsWith(RESTOREONLY_Name)) {
entries_skipped++;
if (VERBOSE) {
System.out.println(MP + "Skipping DN-> " + current_dn);
}
continue;
}
} // End of Else.
} // End of If RestoreOnly
// ***************************************
// Now Perform Bind the Entry.
if (VERBOSE) {
System.out.println(MP + "Processing DN-> " + current_dn);
}
try {
if (current_entry_attributes.size() == 0) {
entries_skipped++;
if (VERBOSE) {
System.out.println(MP + "Skipping Glue Node (No Attributes) DN-> " + current_dn);
}
continue;
} // end of If.
IRRDest.irrctx.bind("\042" + current_dn + "\042",
null, current_entry_attributes);
} catch (NameAlreadyBoundException e) {
if (VERBOSE) {
System.out.println(MP + "*WARNING, Unable to Restore entry, since it already Exists.");
}
entries_duplicate++;
continue; // Continue While Loop.
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + "Error Binding Entry, unable to continue, " + e);
System.exit(EXIT_IRR_RESTORE_BINDING_ENTRY);
} else {
throw e;
}
} // End of exception
if (VERBOSE) {
System.out.println(MP + "Entry Restored.");
}
entries_restored++;
} // End of While Loop.
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + "Exception during processing LDIF Input. " + e);
e.printStackTrace();
System.exit(EXIT_IRR_RESTORE_LDIF_INPUT_FAILURE);
} else {
throw e;
}
} // End of exception
// ***************************************
// Close our Input File.
try {
LDIFIN.close();
} catch (Exception e) {
if (ExitOnException) {
System.err.println(MP + "Exception closing LDIF Input. " + e);
System.exit(EXIT_IRR_RESTORE_LDIF_INPUT_CLOSE_FAILURE);
} else {
throw e;
}
} // End of exception
// ***************************************
// Close up Shop.
if (VERBOSE) {
System.out.println(MP + "Closing Destination Directory Context.");
}
try {
IRRDest.close();
} catch (Exception e) {
if (ExitOnException) {
System.err.println(e);
System.exit(EXIT_IRR_CLOSE_FAILURE);
} else {
throw e;
}
} // End of exception
// ****************************************
// Show the Statistics
if (entries_exceptions > 0) {
System.out.println(MP + "Entry Exceptions: [" + entries_exceptions + "]");
}
if (entries_duplicate > 0) {
System.out.println(MP + "Entry Duplicates: [" + entries_duplicate + "]");
}
if (entries_skipped > 0) {
System.out.println(MP + "Entries Skipped: [" + entries_skipped + "]");
}
// ****************************************
// Any Entries Restored?
if (entries_restored == 0) {
System.out.println(MP + "No Entries were Restored.");
} else {
System.out.println(MP + "Entries Restored: [" + entries_restored + "]");
}
} // End of Perform Method.
/**
* Main
*
* @param args Incoming Argument Array.
* @see jeffaschenk.commons.frameworks.cnxidx.admin.IRRrestore
* @see IRRbackup
*/
public static void main(String[] args) {
// ****************************************
// 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 + VERSION);
System.out.println(MP + "Unknown Values Encountered, Terminating Process.");
Zin.showUnNamed();
Usage();
} // End of If.
// ***************************************
// Was Version Info Requested?
if (Zin.doesNameExist("version")) {
System.out.println(MP + VERSION);
System.exit(EXIT_VERSION);
} // End of If.
// ***************************************
// Was Help Info Requested?
if ((Zin.doesNameExist("?")) ||
(Zin.doesNameExist("usage"))) {
System.out.println(MP + VERSION);
Usage();
} // End of If.
// ***************************************
// Was Verbosity Requested?
if (Zin.doesNameExist("verbose")) {
VERBOSE = true;
}
// ****************************************
// Send the Greeting.
if (VERBOSE) {
System.out.println(MP + VERSION);
}
// ***************************************
// 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("infile",
true, true));
VAR.add(new idxArgVerificationRules("restoreonlydn",
false, true));
VAR.add(new idxArgVerificationRules("withchildren",
false, false));
VAR.add(new idxArgVerificationRules("jar",
false, false));
VAR.add(new idxArgVerificationRules("verbose",
false, false));
// *****************************
// Deprecated.
VAR.add(new idxArgVerificationRules("noschemacheck",
false, false));
VAR.add(new idxArgVerificationRules("schemacheck",
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)) {
System.out.println(MP + VERSION);
Usage();
} // End of If.
// ***************************************
// 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();
if (VERBOSE) {
System.out.println(MP + "IRR ID:[" + IRRPrincipal + "]");
}
IRRCredentials = clPC.getCredentials();
// if (VERBOSE)
// { System.out.println(MP+"IRR Password:["+IRRCredentials+"]"); }
} else {
System.out.println(MP + VERSION);
System.out.println(MP + "Required Principal and Credentials not Specified, unable to continue.");
Usage();
} // End of Else.
// *****************************************
// For all Specified Boolean indicators,
// set them appropreiately.
//
if (Zin.doesNameExist("withchildren")) {
RESTOREONLY_WITH_CHILDREN = true;
}
if (Zin.doesNameExist("jar")) {
INJAR = true;
}
// **************************************************
// Load up the RunTime Arguments.
//
IRRHost = (String) Zin.getValue("hosturl");
System.out.println(MP + "IRR Host URL:[" + IRRHost + "]");
INPUT_FILENAME = ((String) Zin.getValue("infile")).trim();
if (!INJAR) {
System.out.println(MP + "Input File:[" + INPUT_FILENAME + "]");
} else {
System.out.println(MP + "Input JAR Class:[" + INPUT_FILENAME + "]");
} // End of Else.
if (Zin.doesNameExist("restoreonlydn")) {
RESTOREONLY_SOURCEDN = ((String) Zin.getValue("restoreonlydn")).trim();
}
// ************************************************
// Show Operational Parameters
if ((RESTOREONLY_SOURCEDN == null) ||
(RESTOREONLY_SOURCEDN.equals("")) ||
(RESTOREONLY_SOURCEDN.equals("*"))) {
if (VERBOSE) {
System.out.println(MP + "All Input entries will be Restored.");
}
RESTOREONLY_SOURCEDN = "";
RESTOREONLY = false;
RESTOREONLY_WITH_CHILDREN = false;
} else {
if (VERBOSE) {
System.out.println(MP + "Only DN: [" + RESTOREONLY_SOURCEDN + "] " +
"will be restored from the LDIF Input Source.");
} // End of Verbose.
RESTOREONLY = true;
if ((RESTOREONLY_WITH_CHILDREN) && (VERBOSE)) {
System.out.println(MP + "Children will be restored for above DN.");
}
} // End of Else.
// ****************************************
// Note The Start Time.
idxElapsedTime elt = new idxElapsedTime();
// ****************************************
// Initailize Constructor.
IRRrestore FUNCTION = new IRRrestore(
IRRHost,
IRRPrincipal,
IRRCredentials,
INPUT_FILENAME,
RESTOREONLY_SOURCEDN,
INJAR,
RESTOREONLY_WITH_CHILDREN,
RESTOREONLY,
VERBOSE,
true);
// ****************************************
// Perform Function.
try {
FUNCTION.perform();
} catch (Exception e) {
System.err.println(MP + "IRR Exception Performing IRRrestore.\n" + e);
System.exit(EXIT_GENERIC_FAILURE);
} // End of Exception.
// ****************************************
// Note The End Time.
elt.setEnd();
// ****************************************
// Exit
if (VERBOSE) {
System.out.println(MP + "Done, Elapsed Time: " + elt.getElapsed());
}
System.exit(EXIT_SUCCESSFUL);
} // End of Main
} // End of Class IRRrestore