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.*;
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 Backup the Entire Directory or a portion of
* the IRR Directory to an LDIF format output file on disk.
* Backup output conforms to the LDIF Specification: RFC2849.
* <br>
* <b>Usage:</b><br>
* IRRbackup <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.
* --outfile
* Specify Full Output file Path for backup to be written.
* Will write a <outfile>.ldif and <outfile>.schema.xml files.
* </pre>
* <b>Optional Parameters are:</b>
* <pre>
* --outputbufsize
* Specify Output Buffer Size, Default 128KB.
* --filter
* Specify Search Filter, default is (objectclass=*).
* --sourcedn
* Specify Full DN of Source Entry to be used as base, default is [ROOT].
* --withchildren
* Specify Source Entry and All Children Entries to be read for backup.
* --withschema
* Specify Source Schema will be read for backup as well as data entries.
* --append
* Specify to Append LDIF Existing Output File.
* --notnice
* Output Standard LDIF, Default will provide Nice DNs.
* --version
* Display Version information and exit.
* --verbose
* Output Additional Information.
* --debug
* Output Debugging Information.
* --?
* This Display.
*
* </pre>
*
* @author jeff.schenk
* @version 1.0 $Revision
* Developed 2001-2002
*/
public class IRRbackup implements idxCMDReturnCodes {
private static String VERSION = "Version: 1.0 2002-01-22, " +
"FRAMEWORK, Incorporated.";
private static String MP = "IRRbackup: ";
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 OUTPUT_FILENAME = null;
private static String SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private static boolean BACKUP_WITH_CHILDREN = false;
private static boolean BACKUP_SCHEMA = false;
private static boolean APPEND = false;
private static boolean NICE = true;
private static int OBUFSIZE = 0;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
private boolean ExitOnException = false;
private PipedWriter BPQout;
private PipedReader BPQin;
/**
* Usage
* Class to print Usage parameters and simple exit.
*/
static void Usage() {
System.err.println(MP + "Usage:");
System.err.println(MP + "IRRbackup <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 + "--outfile ");
System.err.println("\tSpecify Full Output file Path for backup to be written.");
System.err.println("\tWill write a <outfile>.ldif and <outfile>.schema.xml files.");
System.err.println("\n" + MP + "Optional Parameters are:");
System.err.println(MP + "--filter");
System.err.println("\tSpecify Search Filter, default is (objectclass=*).");
System.err.println(MP + "--sourcedn ");
System.err.println("\tSpecify Full DN of Source Entry to be used as base, default is [ROOT].");
System.err.println(MP + "--withchildren ");
System.err.println("\tSpecify Backup of Source Entry and all Children.");
System.err.println(MP + "--withschema ");
System.err.println("\tSpecify Backup of Source Schema as well.");
System.err.println(MP + "--append ");
System.err.println("\tSpecify to Append LDIF Output to Existing File.");
System.err.println(MP + "--notnice ");
System.err.println("\tSpecify to Output Standard LDIF Output, default is Nice DNs.");
System.err.println(MP + "--outputbufsize ");
System.err.println("\tSpecify LDIF Output Buffer Size.");
System.err.println(MP + "--version");
System.err.println("\tDisplay Version information and exit.");
System.err.println(MP + "--debug");
System.err.println("\tDisplay Debugging Information.");
System.err.println(MP + "--?");
System.err.println("\tThe Above Display.");
System.exit(EXIT_USAGE);
} // End of Subclass
/**
* IRRbackup 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 _ENTRY_SOURCE_DN Source DN Starting Base for Backup.
* @param _SearchFilter Search Filter.
* @param _OUTPUT_FILENAME Destination Output Filename.
* @param _OBUFSIZE BufferedWriter Output Buffer Size.
* @param _BACKUP_WITH_CHILDREN Indicate if Children should be included in backup.
* @param _BACKUP_SCHEMA Indicate if schema should be included in backup.
* @param _APPEND Indicate if Output Should be Appended.
* @param _NICE Indicate if Nice Output.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
public IRRbackup(String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
String _OUTPUT_FILENAME,
int _OBUFSIZE,
boolean _BACKUP_WITH_CHILDREN,
boolean _BACKUP_SCHEMA,
boolean _APPEND,
boolean _NICE,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
OUTPUT_FILENAME = _OUTPUT_FILENAME;
OBUFSIZE = _OBUFSIZE;
BACKUP_WITH_CHILDREN = _BACKUP_WITH_CHILDREN;
BACKUP_SCHEMA = _BACKUP_SCHEMA;
APPEND = _APPEND;
NICE = _NICE;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
} // End of Constructor for IRRbackup.
/**
* perform Method class performs the requested IRR Function Utility.
*
* @throws Exception for any unrecoverable errors during function.
* @throws idxIRRException for any unrecoverable errors during function.
*/
public void perform() throws Exception, idxIRRException {
// ********************************************
// We shall start two threads
// A Producer or a Thread that will walk the
// Directory Tree and a Output Thread that
// will perform the Directory Object read
// and write the LDIF Output for backup.
//
// ********************************************
// ********************************************
// Establish Status Objects.
IRRbackupStatus WalkerStatus = new IRRbackupStatus();
IRRbackupStatus WriterStatus = new IRRbackupStatus();
// ********************************************
// Set up a PIPE for Thread Communication.
BPQout = new PipedWriter();
try {
BPQin = new PipedReader(BPQout);
} catch (IOException e) {
if (ExitOnException) {
System.err.println(MP + "Unable to Obtain PipedReader for Thread Communications, Terminating");
System.exit(EXIT_IRR_BACKUP_FAILURE);
} else {
throw new idxIRRException(MP + "Unable to Obtain PipeReader for Thread Communcations, Terminating.");
}
} // End of Exception.
System.out.println(MP + "Starting Backup Object Obtainer and LDIF Output Thread...");
IRRbackupOutput OT;
OT = new IRRbackupOutput(BPQin,
WriterStatus,
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
OUTPUT_FILENAME,
OBUFSIZE,
BACKUP_WITH_CHILDREN,
BACKUP_SCHEMA,
APPEND,
NICE,
VERBOSE,
DEBUG,
ExitOnException);
System.out.println(MP + "Starting Backup Directory Tree Walker Thread...");
IRRbackupWalker WT;
WT = new IRRbackupWalker(BPQout,
WalkerStatus,
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
OUTPUT_FILENAME,
OBUFSIZE,
BACKUP_WITH_CHILDREN,
BACKUP_SCHEMA,
APPEND,
NICE,
VERBOSE,
DEBUG,
ExitOnException);
// ******************************************
// Show Status.
//
if (OT.t.isAlive()) {
System.out.println(MP + "Object Obtainer and LDIF Output Thread is Running...");
}
if (WT.t.isAlive()) {
System.out.println(MP + "Tree Walker Thread is Running...");
}
// ******************************************
// Now Join and Wait for Completion.
//
try {
System.out.println(MP + "Main Thread waiting for Worker Threads to Complete...");
OT.t.join();
WT.t.join();
} catch (InterruptedException e) {
if (ExitOnException) {
System.err.println(MP + "Main Thread Interrupted, Terminating.");
System.exit(EXIT_IRR_BACKUP_FAILURE);
} else {
throw new idxIRRException(MP + "Main Thread Interrupted, Terminating.");
}
} // End of Exception.
// ******************************************
// Determine if all went well?
//
if (WalkerStatus.getError() != 0) {
if (ExitOnException) {
System.err.println(MP + "Exception in Walker Thread, Error Code:[" +
WalkerStatus.getError() + "]");
System.exit(WalkerStatus.getError());
} else {
throw new idxIRRException(MP + "Exception in Walker Thread, Error Code:[" +
WalkerStatus.getError() + "]");
} // End of Else.
} // End of If.
if (WriterStatus.getError() != 0) {
if (ExitOnException) {
System.err.println(MP + "Exception in Writer Thread, Error Code:[" +
WriterStatus.getError() + "]");
System.exit(WriterStatus.getError());
} else {
throw new idxIRRException(MP + "Exception in Writer Thread, Error Code:[" +
WriterStatus.getError() + "]");
} // End of Else.
} // End of If.
// ********************
// Done.
return;
} // End of Performbackup
/**
* Main
*
* @param args Incoming Argument Array.
* @see jeffaschenk.commons.frameworks.cnxidx.admin.IRRbackup
*/
public static void main(String[] args) {
long starttime, endtime;
// ****************************************
// 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;
}
if (Zin.doesNameExist("debug")) {
DEBUG = true;
}
// ***************************************
// Show Arguments if Verbose Selected.
if (DEBUG) {
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("outfile",
true, true));
VAR.add(new idxArgVerificationRules("sourcedn",
false, true));
VAR.add(new idxArgVerificationRules("filter",
false, true));
VAR.add(new idxArgVerificationRules("withchildren",
false, false));
VAR.add(new idxArgVerificationRules("withschema",
false, false));
VAR.add(new idxArgVerificationRules("append",
false, false));
VAR.add(new idxArgVerificationRules("notnice",
false, false));
VAR.add(new idxArgVerificationRules("outputbufsize",
false, true));
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(DEBUG);
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();
if (DEBUG) {
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.
// *****************************************
// For all Specified Boolean indicators,
// set them appropreiately.
//
if (Zin.doesNameExist("withchildren")) {
BACKUP_WITH_CHILDREN = true;
}
if (Zin.doesNameExist("withschema")) {
BACKUP_SCHEMA = true;
}
if (Zin.doesNameExist("append")) {
APPEND = true;
}
if (Zin.doesNameExist("notnice")) {
NICE = false;
}
// **************************************************
// Load up the RunTime Arguments.
//
IRRHost = (String) Zin.getValue("hosturl");
System.out.println(MP + "IRR Host URL:[" + IRRHost + "]");
OUTPUT_FILENAME = ((String) Zin.getValue("outfile")).trim();
System.out.println(MP + "Output File:[" + OUTPUT_FILENAME + "]");
if (Zin.doesNameExist("sourcedn")) {
ENTRY_SOURCE_DN = ((String) Zin.getValue("sourcedn")).trim();
}
if (Zin.doesNameExist("filter")) {
SearchFilter = ((String) Zin.getValue("filter")).trim();
}
if (Zin.doesNameExist("outputbufsize")) {
try {
OBUFSIZE = Integer.parseInt(
(String) Zin.getValue("outputbufsize"));
} catch (Exception e) {
System.err.println(MP + "Output Buffer Size is Invalid, Unable to Continue,\n" + e);
System.exit(EXIT_IRR_BACKUP_FAILURE);
} // End of Exception.
} // End of If.
// ************************************************
// Show Operational Parameters
if (ENTRY_SOURCE_DN == null) {
System.out.println(MP + "Source DN:[ROOT]");
ENTRY_SOURCE_DN = "";
} else {
System.out.println(MP + "Source DN:[" + ENTRY_SOURCE_DN + "]");
}
if (SearchFilter == null) {
SearchFilter = "(objectclass=*)";
}
System.out.println(MP + "Search Filter: " + SearchFilter);
if (BACKUP_WITH_CHILDREN) {
System.out.println(MP + "Will Backup Source Children.");
} else {
System.out.println(MP + "Will NOT Backup any Source Children.");
}
if (BACKUP_SCHEMA) {
System.out.println(MP + "Will Backup IRR Directory Schema in XML Format.");
} else {
System.out.println(MP + "Will NOT Backup IRR Directory Schema.");
}
if (APPEND) {
System.out.println(MP + "Will Append LDIF Output to Existing Backup File.");
}
if (NICE) {
System.out.println(MP + "Will Create Nice LDIF Output, Non-Continued DNs.");
}
// ****************************************
// Note The Start Time.
idxElapsedTime elt = new idxElapsedTime();
// ****************************************
// Initailize Constructor.
IRRbackup FUNCTION = new IRRbackup(
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
OUTPUT_FILENAME,
OBUFSIZE,
BACKUP_WITH_CHILDREN,
BACKUP_SCHEMA,
APPEND,
NICE,
VERBOSE,
DEBUG,
true);
// ****************************************
// Perform Function.
try {
FUNCTION.perform();
} catch (Exception e) {
System.err.println(MP + "IRR Exception Performing IRRbackup.\n" + e);
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 Class IRRbackup
class IRRbackupStatus {
/**
* IRRbackupStatus
* Class to provide Status class for Backup Thread.
*/
private int BackupError = 0;
IRRbackupStatus() {
} // Contructor.
/**
* Set Error Indicator Value.
*
* @param _x Thread Error Code.
*/
public void setError(int _x) {
BackupError = _x;
}
/**
* Get Error Indicator Value.
*
* @return int Thread Error Code.
*/
public int getError() {
return (BackupError);
}
} // End of Class IRRbackupStatus
/**
* IRRbackupWalker
* Class to run Walker Thread.
*/
class IRRbackupWalker implements Runnable, idxCMDReturnCodes {
/**
* IRRbackupWalker
* Class to provide Walker interface to Level Searches.
*/
Thread t;
private BufferedWriter BWQ;
private IRRbackupStatus WalkerStatus;
private static String MP = "IRRbackupTreeWalker: ";
private static idxManageContext IRRSource = null;
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 OUTPUT_FILENAME = null;
private static String SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private static boolean BACKUP_WITH_CHILDREN = false;
private static boolean BACKUP_SCHEMA = false;
private static boolean APPEND = false;
private static boolean NICE = true;
private static int OBUFSIZE = 0;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
private boolean ExitOnException = false;
/**
* IRRbackupWalker Contructor class driven.
*
* @param BPQout Pipe Queue.
* @param _WalkerStatus Object.
* @param _IRRHost Source IRR LDAP URL.
* @param _IRRPrincipal Source IRR Principal.
* @param _IRRCredentials Source IRR Credentials.
* @param _ENTRY_SOURCE_DN Source DN Starting Base for Backup.
* @param _SearchFilter Search Filter.
* @param _OUTPUT_FILENAME Destination Output Filename.
* @param _OBUFSIZE BufferedWriter Output Buffer Size.
* @param _BACKUP_WITH_CHILDREN Indicate if Children should be included in backup.
* @param _BACKUP_SCHEMA Indicate if schema should be included in backup.
* @param _APPEND Indicate if Output Should be Appended.
* @param _NICE Indicate if Nice Output.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
IRRbackupWalker(Writer BPQout,
IRRbackupStatus _WalkerStatus,
String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
String _OUTPUT_FILENAME,
int _OBUFSIZE,
boolean _BACKUP_WITH_CHILDREN,
boolean _BACKUP_SCHEMA,
boolean _APPEND,
boolean _NICE,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
OUTPUT_FILENAME = _OUTPUT_FILENAME;
OBUFSIZE = _OBUFSIZE;
BACKUP_WITH_CHILDREN = _BACKUP_WITH_CHILDREN;
BACKUP_SCHEMA = _BACKUP_SCHEMA;
APPEND = _APPEND;
NICE = _NICE;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
WalkerStatus = _WalkerStatus;
// ****************************************
// Ready the Synchronized Object and start
// the Thread.
//
this.BWQ = new BufferedWriter(BPQout);
t = new Thread(this, "IRRbackup_LevelWalker");
t.start(); // Start the Thread.
} // End of Contructor.
public void run() {
// ***********************************************
// Initialize
long memfree;
String tname = Thread.currentThread().getName();
System.out.println(MP + "Thread Established for:[" + tname + "]");
// ***********************************************
// Initialize my LAP Timers
idxLapTime LP_LEVEL_SEARCH = new idxLapTime();
idxLapTime LP_ENTRY_TO_PIPE = new idxLapTime();
// ***********************************************
// Now initiate a Connection to the Directory
// for a LDAP Source Context
System.out.println(MP + "Attempting Source Walker Directory Connection to Host URL:[" + IRRHost + "]");
IRRSource = new idxManageContext(IRRHost,
IRRPrincipal,
IRRCredentials,
"IRRbackupWalker Source");
// ************************************************
// Exit on all Exceptions.
IRRSource.setExitOnException(ExitOnException);
// ************************************************
// Now Try to Open and Obtain Context.
try {
IRRSource.open();
} catch (Exception e) {
System.err.println(MP + e);
WalkerStatus.setError(EXIT_IRR_UNABLE_TO_OBTAIN_CONTEXT);
return;
} // End of exception
// **********************************************
// Set and Show Current Alias Derefencing State.
try {
IRRSource.disableAliasDereferencing();
IRRSource.showAliasDereferencing();
} catch (Exception e) {
System.err.println(MP + e);
WalkerStatus.setError(EXIT_IRR_UNABLE_TO_OBTAIN_CONTEXT);
return;
} // End of exception
// **********************************************
// Disable Factories..
try {
IRRSource.disableDSAEFactories();
IRRSource.showDSAEFactories();
} catch (Exception e) {
System.err.println(MP + e);
WalkerStatus.setError(EXIT_IRR_UNABLE_TO_OBTAIN_CONTEXT);
return;
} // End of exception
// **************************************************
// Obtain IRR Directory Schema from our Destination.
idxIRRschema schema = new idxIRRschema(IRRSource.irrctx);
// ****************************************
// Set up our Search Controls
String[] NO_Attributes = {"1.1"};
SearchControls OL_ctls = new SearchControls();
OL_ctls.setReturningAttributes(NO_Attributes);
OL_ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
// **************************************************
// Obtain Runtime Object.
Runtime rt = Runtime.getRuntime();
// ****************************************
// Indicate the Backup is starting.
System.out.println(MP + "Starting Backup...");
// ****************************************
// If Debug, show total Memory.
if (DEBUG) {
System.out.println(MP + "Total Memory: [" +
rt.totalMemory() + "].");
memfree = rt.freeMemory();
System.out.println(MP + "Current Free Memory: [" +
memfree + "].");
}
// ****************************************
// Obtain our initial Source Entry.
try {
if ((ENTRY_SOURCE_DN != null) &&
(!ENTRY_SOURCE_DN.equals(""))) {
LP_ENTRY_TO_PIPE.Start();
BWQ.write(ENTRY_SOURCE_DN + "\n");
LP_ENTRY_TO_PIPE.Stop();
BWQ.flush();
} // End of If.
} catch (Exception e) {
System.err.println(MP + "IRR Exception Writing to Thread Pipe,\n" + e);
return; // End Thread.
} // End of Exception
// *****************************************
// Now obtain the IRR Entries for Backup.
//
idxDNLinkList myChildrenList = new idxDNLinkList();
myChildrenList.addFirst(ENTRY_SOURCE_DN);
try {
// *****************************
// Obtain all Subsequent Levels
while (myChildrenList.IsNotEmpty()) {
String myDN = myChildrenList.popfirst();
// *****************************************
// Parse the Destination Entry DN to be sure
// we have any Quotes....
idxParseDN Naming_Source = new idxParseDN(myDN);
LP_LEVEL_SEARCH.Start();
NamingEnumeration nes =
IRRSource.irrctx.search(Naming_Source.getDNwithQuotes(),
SearchFilter, OL_ctls);
LP_LEVEL_SEARCH.Stop();
if (LP_LEVEL_SEARCH.getCurrentDuration() > 1000) {
System.out.println(MP + "Warning ** LEVEL Search took " +
LP_LEVEL_SEARCH.getElapsedtoString() +
" to Complete for Level:[" +
Naming_Source.getDN() + "]");
} // End of If.
// *****************************************
// Loop Throught the Results...
while (nes.hasMore()) {
SearchResult srs = (SearchResult) nes.next();
String RDN = srs.getName();
// *****************************
// Acquire the correct DNs.
String SourceDN = RDN;
if ((myDN != null) &&
(!"".equals(myDN))) {
SourceDN = RDN + "," + myDN;
}
// *****************************
// Now place the Childs DN in
// the Queue to process it's
// Children on the next iteration.
//
myChildrenList.addLast(SourceDN);
// *****************************
// Now Send the Search Result
// Entry to our output thread.
//
LP_ENTRY_TO_PIPE.Start();
BWQ.write(SourceDN + "\n");
LP_ENTRY_TO_PIPE.Stop();
BWQ.flush();
} // End of Inner While.
// **************************************
// If we are not obtaining Children, end.
if (!BACKUP_WITH_CHILDREN) {
break;
}
} // End of Outer While.
} catch (Exception e) {
System.err.println(MP + "IRR Exception on Obtaining Child Entries,\n" + e);
e.printStackTrace();
WalkerStatus.setError(EXIT_IRR_BACKUP_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Tell the LDIF Thread to Finish.
try {
BWQ.write("</EOP>" + "\n");
BWQ.flush();
} catch (Exception e) {
System.err.println(MP + "IRR Exception Writing to Thread Pipe,\n" + e);
return; // End Thread.
} // End of Exception
// ***************************************
// Close up Shop.
System.out.println(MP + "Closing Directory Context.");
try {
IRRSource.close();
} catch (Exception e) {
System.err.println(e);
WalkerStatus.setError(EXIT_IRR_CLOSE_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Show the Lap Timings.
System.out.println(MP + "Lap Time for Level Searches: " + LP_LEVEL_SEARCH);
System.out.println(MP + "Lap Time for Pipe Communications: " + LP_ENTRY_TO_PIPE);
// ***************************************
// Done.
return;
} // End of run.
} // End of Class IRRbackupWalker
/**
* IRRbackupOutput
* Class to run Output Thread.
*/
class IRRbackupOutput implements Runnable, idxCMDReturnCodes {
/**
* IRRbackupOutput
* Class to provide Output Thread to Write LDIF from Entries obtain via pipe.
*/
Thread t;
private BufferedReader BRQ;
private IRRbackupStatus WriterStatus;
private static String MP = "IRRbackupLDIFWriter: ";
private static idxManageContext IRRSource = null;
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 OUTPUT_FILENAME = null;
private static String SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private static boolean BACKUP_WITH_CHILDREN = false;
private static boolean BACKUP_SCHEMA = false;
private static boolean APPEND = false;
private static boolean NICE = true;
private static int OBUFSIZE = 0;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
private boolean ExitOnException = false;
private static String ObjectClassName = "objectclass";
/**
* IRRbackupOutput Contructor class driven.
*
* @param BPQin Pipe.
* @param _IRRHost Source IRR LDAP URL.
* @param _IRRPrincipal Source IRR Principal.
* @param _IRRCredentials Source IRR Credentials.
* @param _ENTRY_SOURCE_DN Source DN Starting Base for Backup.
* @param _SearchFilter Search Filter.
* @param _OUTPUT_FILENAME Destination Output Filename.
* @param _OBUFSIZE BufferedWriter Output Buffer Size.
* @param _BACKUP_WITH_CHILDREN Indicate if Children should be included in backup.
* @param _BACKUP_SCHEMA Indicate if schema should be included in backup.
* @param _APPEND Indicate if Output Should be Appended.
* @param _NICE Indicate if Nice Output.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
IRRbackupOutput(Reader BPQin,
IRRbackupStatus _WriterStatus,
String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
String _OUTPUT_FILENAME,
int _OBUFSIZE,
boolean _BACKUP_WITH_CHILDREN,
boolean _BACKUP_SCHEMA,
boolean _APPEND,
boolean _NICE,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
OUTPUT_FILENAME = _OUTPUT_FILENAME;
OBUFSIZE = _OBUFSIZE;
BACKUP_WITH_CHILDREN = _BACKUP_WITH_CHILDREN;
BACKUP_SCHEMA = _BACKUP_SCHEMA;
APPEND = _APPEND;
NICE = _NICE;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
WriterStatus = _WriterStatus;
// ****************************************
// Ready the Synchronized Object and start
// the Thread.
//
this.BRQ = new BufferedReader(BPQin);
t = new Thread(this, "IRRbackup_LDIFWriter");
t.start(); // Start the Thread
} // End of Contructor.
/**
* run
* Thread to Output LDIF Backup Image.
*/
public void run() {
// ***********************************************
// Initialize
String ZEN = null;
int DNcount = 0;
long memfree;
String tname = Thread.currentThread().getName();
System.out.println(MP + "Thread Established for:[" + tname + "]");
// ***********************************************
// Initialize my LAP Timers
idxLapTime LP_ENTRY_SEARCH = new idxLapTime();
idxLapTime LP_ENTRY_TO_LDIF = new idxLapTime();
idxLapTime LP_ENTRY_FROM_PIPE = new idxLapTime();
// ***********************************************
// Now initiate a Connection to the Directory
// for a LDAP Source Context
System.out.println(MP + "Attempting Source Object Directory Connection to Host URL:[" + IRRHost + "]");
IRRSource = new idxManageContext(IRRHost,
IRRPrincipal,
IRRCredentials,
"IRRbackupWriter Source");
// ************************************************
// Exit on all Exceptions.
IRRSource.setExitOnException(ExitOnException);
// ************************************************
// Now Try to Open and Obtain Context.
try {
IRRSource.open();
} catch (Exception e) {
System.err.println(MP + e);
WriterStatus.setError(EXIT_IRR_CLOSE_FAILURE);
return;
} // End of exception
// **********************************************
// Set and Show Current Alias Derefencing State.
try {
IRRSource.disableAliasDereferencing();
IRRSource.showAliasDereferencing();
} catch (Exception e) {
System.err.println(MP + e);
WriterStatus.setError(EXIT_IRR_CLOSE_FAILURE);
return;
} // End of exception
// **********************************************
// Disable Factories..
try {
IRRSource.disableDSAEFactories();
IRRSource.showDSAEFactories();
} catch (Exception e) {
System.err.println(MP + e);
WriterStatus.setError(EXIT_IRR_CLOSE_FAILURE);
return;
} // End of exception
// **************************************************
// Obtain IRR Directory Schema from our Destination.
idxIRRschema schema = new idxIRRschema(IRRSource.irrctx);
// **************************************************
// Obtain Runtime Object.
Runtime rt = Runtime.getRuntime();
//******************************************
// Set up our Search Filter.
if (SearchFilter == null) {
SearchFilter = "(objectclass=*)";
}
//******************************************
// Set up our Search Controls.
String[] ALL_AttrIDs = {"*"};
SearchControls OS_ctls = new SearchControls();
OS_ctls.setReturningAttributes(ALL_AttrIDs);
OS_ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
// *******************************************
// Obtain the Directory Schema and Backup.
// If Specified.
if (BACKUP_SCHEMA) {
try {
BackupSchema(schema);
} catch (Exception e) {
System.err.println(MP + "Exception opening Backup Schema Output File. " + e);
WriterStatus.setError(EXIT_IRR_BACKUP_SCHEMA_OUTPUT_FAILURE);
return; // End Thread.
} // End of exception
} // End of If Schema Backup.
// **************************************
// Open up the File Output Stream.
System.out.println(MP + "Preparing Backup Output File...");
BufferedWriter LDIFOUT = null;
try {
if (OBUFSIZE <= 0) {
OBUFSIZE = 131072;
} // 128KB Buffer.
System.out.println(MP + "Backup Output File Buffer Size:[" + OBUFSIZE + "]");
LDIFOUT = new BufferedWriter(new FileWriter(OUTPUT_FILENAME + ".ldif", APPEND), OBUFSIZE);
if (!APPEND) {
LDIFOUT.write("version: 1\n");
}
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("# FRAMEWORK IRR Directory LDIF Backup.\n");
if (ENTRY_SOURCE_DN.equals("")) {
LDIFOUT.write("# Source DN: [" + "ROOT" + "]\n");
} else {
LDIFOUT.write("# Source DN: [" + ENTRY_SOURCE_DN + "]\n");
}
LDIFOUT.write("# Source Filter: [" + SearchFilter + "]\n");
LDIFOUT.write("# Source Host: [" + IRRHost + "]\n");
LDIFOUT.write("# Start Time: " + CurrentTimeStamp.get() + "\n");
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("\n");
} catch (Exception e) {
System.err.println(MP + "Exception opening Backup LDIF Output File. " + e);
WriterStatus.setError(EXIT_IRR_BACKUP_LDIF_OUTPUT_FAILURE);
return; // End Thread.
} // End of exception
// **************************************
// Loop to process commands from Walker
// Thread.
try {
while (true) {
LP_ENTRY_FROM_PIPE.Start();
ZEN = BRQ.readLine();
LP_ENTRY_FROM_PIPE.Stop();
// ***************************
// Ignore Null.
if ((ZEN == null) ||
("".equals(ZEN))) {
continue;
}
// ***************************
// Should We End Thread?
if ("</EOP>".equals(ZEN)) {
break;
}
// *****************************
// Is the Entry a LDIF Comment?
// Or a Simple NewLine?
if ((ZEN.startsWith("#")) ||
(ZEN.equals("\n"))) {
try {
LDIFOUT.write(ZEN);
continue;
} catch (Exception e) {
System.err.println(MP + "Exception Writing to Backup LDIF Output File. " + e);
WriterStatus.setError(EXIT_IRR_BACKUP_LDIF_OUTPUT_FAILURE);
return; // End Thread.
} // End of exception
} // End of If.
// *****************************
// Ok, this must be a DN, so
// Process.
//
// *****************************************
// Parse the Destination Entry DN to be sure
// we have any Quotes....
idxParseDN Naming_Source = new idxParseDN(ZEN);
ZEN = Naming_Source.getDNwithQuotes();
// *****************************************
// Obtain the Namespace.
String NameSpace = null;
try {
NameSpace = IRRSource.irrctx.getNameInNamespace();
if (NameSpace.equals("")) {
NameSpace = ZEN;
}
} catch (Exception e) {
{
NameSpace = ZEN;
}
} // End of exception
// *****************************************
// Now obtain the Source Entry.
//
try {
LP_ENTRY_SEARCH.Start();
NamingEnumeration sl =
IRRSource.irrctx.search(ZEN, SearchFilter, OS_ctls);
LP_ENTRY_SEARCH.Stop();
if (LP_ENTRY_SEARCH.getCurrentDuration() > 1000) {
System.out.println(MP + "Warning ** Entry Search took " +
LP_ENTRY_SEARCH.getElapsedtoString() +
" to Complete to Obtain:[" +
ZEN + "]");
}
if (sl == null) {
continue;
}
LP_ENTRY_TO_LDIF.Start();
while (sl.hasMore()) {
SearchResult si = (SearchResult) sl.next();
DNcount++;
String DN = null;
if (NameSpace.equals("")) {
DN = si.getName();
} else if (si.getName().equals("")) {
DN = NameSpace;
} else {
DN = si.getName() + "," + NameSpace;
}
// ******************************************
// Write out the DN.
// Do not write out a JNDI Quoted DN.
// That is not LDIF Compliant.
//
idxParseDN pDN = new idxParseDN(DN);
if (NICE) {
LDIFOUT.write("dn: ");
if (pDN.isQuoted()) {
LDIFOUT.write(pDN.getDN());
} else {
LDIFOUT.write(DN);
}
LDIFOUT.write("\n");
} else {
if (pDN.isQuoted()) {
idxIRROutput.WriteLDIF("dn", pDN.getDN(), LDIFOUT);
} else {
idxIRROutput.WriteLDIF("dn", DN, LDIFOUT);
}
} // End of DN Output.
// Obtain the entries Attributes.
Attributes entryattrs = si.getAttributes();
// Obtain ObjectClass First.
Attribute eo = entryattrs.get(ObjectClassName);
for (NamingEnumeration eov = eo.getAll(); eov.hasMore(); ) {
idxIRROutput.WriteLDIF(eo.getID(), eov.next(), LDIFOUT);
}
// Obtain Naming Attribute Next.
// One will not exist for an Alias.
if (!"".equals(pDN.getNamingAttribute())) {
Attribute en = entryattrs.get(pDN.getNamingAttribute());
if (en != null) {
for (NamingEnumeration env = en.getAll(); env.hasMore(); ) {
idxIRROutput.WriteLDIF(en.getID(), env.next(), LDIFOUT);
}
} // End of Inner If.
} // End of Naming Attribute.
// Finish Obtaining remaining Attributes,
// in no special sequence.
for (NamingEnumeration ea = entryattrs.getAll(); ea.hasMore(); ) {
Attribute attr = (Attribute) ea.next();
if ((!ObjectClassName.equalsIgnoreCase(attr.getID())) &&
(!pDN.getNamingAttribute().equalsIgnoreCase(attr.getID()))) {
for (NamingEnumeration ev = attr.getAll(); ev.hasMore(); ) {
idxIRROutput.WriteLDIF(attr.getID(), ev.next(), LDIFOUT);
}
} // End of If
} // End of Outer For Loop
idxIRROutput.WriteLDIF("", "", LDIFOUT);
LP_ENTRY_TO_LDIF.Stop();
if (LP_ENTRY_TO_LDIF.getCurrentDuration() > 1000) {
System.out.println(MP + "Warning ** Entry to LDIF took " +
LP_ENTRY_TO_LDIF.getElapsedtoString() +
" to Complete for:[" +
DN + "]");
}
} // End of Inner While Loop
} catch (Exception e) {
System.err.println(MP + "IRR Exception on IRRbackup, Obtaining Source Entry, " + e);
e.printStackTrace();
WriterStatus.setError(EXIT_IRR_BACKUP_FAILURE);
return; // End Thread.
} // End of exception
} // End of Outer While Loop.
} catch (Exception e) {
System.err.println(MP + "IRR Exception on IRRbackup, Obtaining Data From Thread Pipe, " + e);
return; // End Thread.
} // End of exception
// ***************************************
// Show number of entries backed up.
try {
if (DNcount > 0) {
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("# End of IRR Backup\n");
LDIFOUT.write("# End Time: " + CurrentTimeStamp.get() + "\n");
LDIFOUT.write("# Entries Contained in LDIF Backup:[" +
DNcount + "]\n");
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("\n");
System.out.println(MP + "Successful Backup, Entries Backed Up:[" +
DNcount + "]");
} else {
LDIFOUT.write("\n");
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("# IRR BACKUP NOT SUCCESSFUL\n");
LDIFOUT.write("# End Time: " + CurrentTimeStamp.get() + "\n");
LDIFOUT.write("# Entries Contained in LDIF Backup:[0]\n");
LDIFOUT.write("# ***********************************************\n");
LDIFOUT.write("\n");
System.out.println(MP + "Exception on Backup, Entries Backed Up:[" +
DNcount + "]");
}
} catch (Exception e) {
System.err.println(MP + "Exception opening Backup LDIF Output File. " + e);
WriterStatus.setError(EXIT_IRR_BACKUP_LDIF_OUTPUT_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Close our Output File.
try {
LDIFOUT.flush();
LDIFOUT.close();
} catch (Exception e) {
System.err.println(MP + "Exception closing Output File. " + e);
WriterStatus.setError(EXIT_IRR_BACKUP_LDIF_OUTPUT_CLOSE_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Close up Shop.
System.out.println(MP + "Closing Directory Context.");
try {
IRRSource.close();
} catch (Exception e) {
System.err.println(e);
WriterStatus.setError(EXIT_IRR_CLOSE_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Show the Lap Timings.
System.out.println(MP + "Lap Time for Entry Search: " + LP_ENTRY_SEARCH);
System.out.println(MP + "Lap Time for Entry to LDIF Output: " + LP_ENTRY_TO_LDIF);
System.out.println(MP + "Lap Time for Pipe Communication: " + LP_ENTRY_FROM_PIPE);
// ***************************************
// Done.
return;
} // End of run.
/**
* BackupSchema
* Backup IRR Directory Schema.
*
* @param schema idxIRRSchema Object
* @throws Exception if errors from accessing schema or writing output of schema.
*/
private void BackupSchema(idxIRRschema schema) throws Exception {
System.out.println(MP + "Starting Backup of Schema...");
BufferedWriter SCHEMAOUT = null;
// Open our Schema Backup File.
SCHEMAOUT = new BufferedWriter(
new FileWriter(OUTPUT_FILENAME + ".schema.xml"));
// Write out Schema Body
SCHEMAOUT.write("<!-- *********************************************** -->\n");
SCHEMAOUT.write("<!-- FRAMEWORK IRR Directory Schema Backup. -->\n");
SCHEMAOUT.write("<!-- Source Host: [" + IRRHost + "] -->\n");
SCHEMAOUT.write("<!-- Start Time: " + CurrentTimeStamp.get() + " -->\n");
SCHEMAOUT.write("<!-- *********************************************** -->\n");
// Write out Schema Body
schema.printAll(SCHEMAOUT);
// Write out the Schema Tail.
SCHEMAOUT.write("<!-- *********************************************** -->\n");
SCHEMAOUT.write("<!-- End of IRR Schema Backup -->\n");
SCHEMAOUT.write("<!-- End Time: " + CurrentTimeStamp.get() + " -->\n");
SCHEMAOUT.write("<!-- *********************************************** -->\n\n");
// Close up the Schema Backup.
SCHEMAOUT.flush();
SCHEMAOUT.close();
// **************************************
// Done with Schema Backup.
System.out.println(MP + "Schema Backup Complete.");
} // End of BackupSchema Method.
} // End of Class IRRbackupOutput