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 javax.naming.*;
import javax.naming.directory.*;
/**
* Java Command line utility, driven from properties and command
* line parameters to Analyze the Entire Directory or a portion of
* the IRR Directory.
* <br>
* <b>Usage:</b><br>
* IRRanalyze <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.
* </pre>
* <b>Optional Parameters are:</b>
* <pre>
* --filter
* Specify Search Filter, default is (objectclass=*).
* --sourcedn
* Specify Full DN of Source Entry to be used as base, default is [ROOT].
* --version
* Display Version information and exit.
* --verbose
* Output Additional Information.
* --debug
* Output Debugging Information.
* --?
* This Display.
*
* </pre>
*
* @author jeff.schenk
* @version 5.0 $Revision
* Developed 2001-2005
* @since 1.0
*/
public class IRRanalyze implements idxCMDReturnCodes {
private static String VERSION = "Version: 5.0 2005-07-19, " +
"FRAMEWORK, Incorporated.";
private static String MP = "IRRanalyze: ";
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 SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
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 + "IRRanalyze <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("\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 + "--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
/**
* IRRanalyze 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 Analyze.
* @param _SearchFilter Search Filter.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
public IRRanalyze(String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
} // End of Constructor for IRRanalyze.
/**
* 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 Analyze Thread that
// will Analyze the Entry based upon the
// entries Objectclasses only and
// accmulated status information which will
// be dumped after all entries have been
// processed.
// ********************************************
IRRanalyzeQueue myBBQ = new IRRanalyzeQueue();
myBBQ.setVerbose(VERBOSE);
if (VERBOSE) {
System.out.println(MP + "Starting Directory Analyzer Thread...");
}
IRRanalyzer AT;
AT = new IRRanalyzer(myBBQ,
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
VERBOSE,
DEBUG,
ExitOnException);
if (VERBOSE) {
System.out.println(MP + "Starting Directory Tree Walker Thread...");
}
IRRanalyzeWalker WT;
WT = new IRRanalyzeWalker(myBBQ,
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
VERBOSE,
DEBUG,
ExitOnException);
// ******************************************
// Show Status.
//
if (AT.t.isAlive()) {
if (VERBOSE) {
System.out.println(MP + "Object Obtainer and LDIF Output Thread is Running...");
}
}
if (WT.t.isAlive()) {
if (VERBOSE) {
System.out.println(MP + "Tree Walker Thread is Running...");
}
}
// ******************************************
// Now Join and Wait for Completion.
//
try {
if (VERBOSE) {
System.out.println(MP + "Main Thread waiting for Worker Threads to Complete...");
}
AT.t.join();
WT.t.join();
} catch (InterruptedException e) {
if (ExitOnException) {
System.err.println(MP + "Main Thread Interrupted, Terminating.");
System.exit(EXIT_GENERIC_FAILURE);
} else {
throw new idxIRRException(MP + "Main Thread Interrupted, Terminating.");
}
} // End of Exception.
// ******************************************
// Determine if all went well?
//
if (myBBQ.getErrorWalker() != 0) {
if (ExitOnException) {
System.err.println(MP + "Exception in Walker Thread, Error Code:[" +
myBBQ.getErrorWalker() + "]");
System.exit(myBBQ.getErrorWalker());
} else {
throw new idxIRRException(MP + "Exception in Walker Thread, Error Code:[" +
myBBQ.getErrorWalker() + "]");
}
} // End of If.
if (myBBQ.getErrorAnalyzer() != 0) {
if (ExitOnException) {
System.err.println(MP + "Exception in Analyzer Thread, Error Code:[" +
myBBQ.getErrorAnalyzer() + "]");
System.exit(myBBQ.getErrorAnalyzer());
} else {
throw new idxIRRException(MP + "Exception in Analyzer Thread, Error Code:[" +
myBBQ.getErrorAnalyzer() + "]");
}
} // End of If.
// ********************
// Done.
return;
} // End of Perform Analysis
/**
* Main
*
* @param args Incoming Argument Array.
* @see jeffaschenk.commons.frameworks.cnxidx.admin.IRRanalyze
*/
public static void main(String[] args) {
long starttime, endtime;
// ****************************************
// Parse the incoming Arguments and
// create objects for each entity.
//
idxArgParser Zin = new idxArgParser();
Zin.parse(args);
// ****************************************
// Send the Greeting.
if (VERBOSE) {
System.out.println(MP + VERSION);
}
// ***************************************
// 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.out.println(MP + 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;
}
// ***************************************
// 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("sourcedn",
false, true));
VAR.add(new idxArgVerificationRules("filter",
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(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();
if (VERBOSE) {
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("debug")) {
DEBUG = true;
}
// **************************************************
// Load up the RunTime Arguments.
//
IRRHost = (String) Zin.getValue("hosturl");
if (VERBOSE) {
System.out.println(MP + "IRR Host URL:[" + IRRHost + "]");
}
if (Zin.doesNameExist("sourcedn")) {
ENTRY_SOURCE_DN = ((String) Zin.getValue("sourcedn")).trim();
}
if (Zin.doesNameExist("filter")) {
SearchFilter = ((String) Zin.getValue("filter")).trim();
}
// ************************************************
// Show Operational Parameters
if (ENTRY_SOURCE_DN == null) {
if (VERBOSE) {
System.out.println(MP + "Source DN:[ROOT]");
}
ENTRY_SOURCE_DN = "";
} else {
if (VERBOSE) {
System.out.println(MP + "Source DN:[" + ENTRY_SOURCE_DN + "]");
}
}
if (SearchFilter == null) {
SearchFilter = "(objectclass=*)";
}
if (VERBOSE) {
System.out.println(MP + "Search Filter: " + SearchFilter);
}
// ****************************************
// Note The Start Time.
idxElapsedTime elt = new idxElapsedTime();
// ****************************************
// Initailize Constructor.
IRRanalyze FUNCTION = new IRRanalyze(
IRRHost,
IRRPrincipal,
IRRCredentials,
ENTRY_SOURCE_DN,
SearchFilter,
VERBOSE,
DEBUG,
true);
// ****************************************
// Perform Function.
try {
FUNCTION.perform();
} catch (Exception e) {
System.err.println(MP + "IRR Exception Performing IRRanalyze.\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.out.println(MP + "FRAMEWORK Incorporated, Copyright 2001");
System.exit(EXIT_SUCCESSFUL);
} // End of Main
} // End of Class IRRanalyze
class IRRanalyzeQueue {
/**
* IRRanalyzeQueue
* Class to provide Queue for Threading Analysis of Objects Searches,
* while main thread performs a subtree walk.
*/
private int ErrorWalker = 0;
private int ErrorAnalyzer = 0;
private boolean VERBOSE = false;
private idxDNLinkList Queue = new idxDNLinkList();
/**
* Pop Entry from Synchronized Analyze Queue.
*
* @return current DN to be read and Analyzed.
*/
public String pop() {
// ******************************
// Is there something already in
// the Queue?
synchronized (Queue) {
if (Queue.IsNotEmpty()) {
String ZpoppedDN = Queue.popfirst();
if (VERBOSE) {
System.out.println("Queue popped: " + ZpoppedDN);
}
return (ZpoppedDN);
} // End of If.
} // End of Synchronized
return ("");
} // End of pop Method.
/**
* Push Entry into Synchronized Analyze Queue.
*
* @param _ZQDN DN.
*/
public void push(String _ZQDN) {
// ************************
// Place Entry into Queue.
synchronized (Queue) {
Queue.addLast(_ZQDN);
} // End of Synchronized
if (VERBOSE) {
System.out.println("Queue pushed: " + _ZQDN);
}
return;
} // End of push Method.
/**
* Set Error Indicator Value.
*
* @param _x Thread Error Code.
*/
synchronized void setErrorWalker(int _x) {
ErrorWalker = _x;
}
/**
* Get Error Indicator Value.
*
* @return int Thread Error Code.
*/
synchronized int getErrorWalker() {
return (ErrorWalker);
}
/**
* Set Error Indicator Value.
*
* @param _x Thread Error Code.
*/
synchronized void setErrorAnalyzer(int _x) {
ErrorAnalyzer = _x;
}
/**
* Get Error Indicator Value.
*
* @return int Thread Error Code.
*/
synchronized int getErrorAnalyzer() {
return (ErrorAnalyzer);
}
/**
* Get Any Existing Error Indicator Value.
*
* @return boolean Indicates an Error Does Exist
* for one of the Threads.
*/
synchronized boolean AnyErrors() {
if (ErrorAnalyzer != 0) {
return (true);
} else if (ErrorWalker != 0) {
return (true);
}
return (false);
}
/**
* Set Verbose Indicator.
*
* @param _x Verbose Indicator.
*/
synchronized void setVerbose(boolean _x) {
VERBOSE = _x;
}
} // End of Class IRRanalyzeQueue
/**
* IRRanalyzeWalker
* Class to run Walker Thread.
*/
class IRRanalyzeWalker implements Runnable, idxCMDReturnCodes {
/**
* IRRanalyzeWalker
* Class to provide Walker interface to Queue.
*/
IRRanalyzeQueue BBQ; // Synchronized Object.
Thread t;
private static String MP = "IRRanalyzeTreeWalker: ";
private static idxManageContext IRRSource = null;
private static idxStatus StatSource = 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 SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
private boolean ExitOnException = false;
/**
* IRRanalyzeWalker Contructor class driven.
*
* @param BBQ Synchronized 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 Analyze.
* @param _SearchFilter Search Filter.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
IRRanalyzeWalker(IRRanalyzeQueue BBQ,
String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
// ****************************************
// Ready the Synchronized Object and start
// the Thread.
//
this.BBQ = BBQ;
t = new Thread(this, "IRRanalyzeWalker");
t.start(); // Start the Thread.
} // End of Contructor.
public void run() {
// ***********************************************
// Initialize
long memfree;
String tname = Thread.currentThread().getName();
if (VERBOSE) {
System.out.println(MP + "Thread Established for:[" + tname + "]");
}
// ***********************************************
// Now initiate a Connection to the Directory
// for a LDAP Source Context
if (VERBOSE) {
System.out.println(MP + "Attempting Source Walker Directory Connection to Host URL:[" + IRRHost + "]");
}
IRRSource = new idxManageContext(IRRHost,
IRRPrincipal,
IRRCredentials,
"IRRanalyzeWalker 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);
BBQ.setErrorWalker(EXIT_IRR_UNABLE_TO_OBTAIN_CONTEXT);
return;
} // End of exception
// ************************************************
// Now Disable DSAE Factories..
try {
IRRSource.disableDSAEFactories();
} catch (Exception e) {
System.err.println(MP + e);
BBQ.setErrorWalker(EXIT_GENERIC_FAILURE);
return;
} // End of exception
// ************************************************
// Set up our Status Objects
StatSource = new idxStatus("IRRanalyzeWalker");
StatSource.setOpStatus(1);
// **************************************************
// Obtain IRR Utility Object.
idxIRRutil util = new idxIRRutil();
util.setVerbose(VERBOSE);
// **************************************************
// Obtain Runtime Object.
Runtime rt = Runtime.getRuntime();
// ****************************************
// Indicate the Analyze is starting.
if (VERBOSE) {
System.out.println(MP + "Starting Analysis...");
}
// ****************************************
// 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.
if (!BBQ.AnyErrors()) {
BBQ.push(ENTRY_SOURCE_DN);
} else {
return;
}
// ****************************************
// Obtain all of the Children.
//
idxDNLinkList myChildrenList = new idxDNLinkList();
// ***************************
// Obtain First Level
try {
util.ObtainChildrenForQueue(IRRSource.irrctx,
ENTRY_SOURCE_DN,
SearchFilter,
myChildrenList,
StatSource);
} catch (Exception e) {
System.err.println(MP + "IRR Exception on Obtaining Children Entries,\n" + e);
BBQ.setErrorWalker(EXIT_GENERIC_FAILURE);
return; // End Thread.
} // End of exception
// ***************************
// Obtain all Subsequent Levels
while (myChildrenList.IsNotEmpty()) {
String RDN = myChildrenList.popfirst();
// ****************************************
// Push the Entry to Output Thread.
if (!BBQ.AnyErrors()) {
BBQ.push(RDN);
} else {
return;
}
try {
util.ObtainChildrenForQueue(IRRSource.irrctx,
RDN,
SearchFilter,
myChildrenList,
StatSource);
// ****************************************
// If Verbose, show total Memory.
if (DEBUG) {
memfree = rt.freeMemory();
System.out.println(MP + "Current Free Memory: [" +
memfree + "].");
}
} catch (Exception e) {
System.err.println(MP + "IRR Exception on Obtaining Child Entries,\n" + e);
e.printStackTrace();
BBQ.setErrorWalker(EXIT_GENERIC_FAILURE);
return; // End Thread.
} // End of exception
} // End of While Loop.
// ***************************************
// Tell the our Other Thread we are done.
if (!BBQ.AnyErrors()) {
BBQ.push("<END THREAD>");
}
// ***************************************
// Close up Shop.
if (VERBOSE) {
System.out.println(MP + "Closing Walker Source Directory Context.");
}
try {
IRRSource.close();
} catch (Exception e) {
System.err.println(e);
BBQ.setErrorWalker(EXIT_IRR_CLOSE_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Done.
return;
} // End of run.
} // End of Class IRRanalyzeWalker
/**
* IRRanalyzer
* Class to run Output Thread.
*/
class IRRanalyzer implements Runnable, idxCMDReturnCodes {
/**
* IRRanalyzer
* Class to provide Output Thread to read from Queue.
*/
IRRanalyzeQueue BBQ;
Thread t;
private static String MP = "IRRanalyzer: ";
private static idxManageContext IRRSource = null;
private static idxStatus StatSource = 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 SearchFilter = null;
private static boolean VERBOSE = false;
private static boolean DEBUG = false;
private idxTimeStamp CurrentTimeStamp = new idxTimeStamp();
private boolean ExitOnException = false;
/**
* IRRanalyzer Contructor class driven.
*
* @param BBQ Synchronized 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 Analysis.
* @param _SearchFilter Search Filter.
* @param _VERBOSE Indicate Verbosity.
* @param _DEBUG Indicate DEBUGGING.
* @param _ExitOnException Indicate Exit on Exceptions.
*/
IRRanalyzer(IRRanalyzeQueue BBQ,
String _IRRHost,
String _IRRPrincipal,
String _IRRCredentials,
String _ENTRY_SOURCE_DN,
String _SearchFilter,
boolean _VERBOSE,
boolean _DEBUG,
boolean _ExitOnException) {
// ****************************************
// Set My Incoming Parameters.
//
IRRHost = _IRRHost;
IRRPrincipal = _IRRPrincipal;
IRRCredentials = _IRRCredentials;
ENTRY_SOURCE_DN = _ENTRY_SOURCE_DN;
SearchFilter = _SearchFilter;
VERBOSE = _VERBOSE;
DEBUG = _DEBUG;
ExitOnException = _ExitOnException;
// ****************************************
// Ready the Synchronized Object and start
// the Thread.
//
this.BBQ = BBQ;
t = new Thread(this, "IRRanalyzer");
t.start(); // Start the Thread
} // End of Contructor.
/**
* run
* Thread to Analyze Objects.
*/
public void run() {
// ***********************************************
// Initialize
String ZEN = null;
long memfree;
String tname = Thread.currentThread().getName();
if (VERBOSE) {
System.out.println(MP + "Thread Established for:[" + tname + "]");
}
// ***********************************************
// Now initiate a Connection to the Directory
// for a LDAP Source Context
if (VERBOSE) {
System.out.println(MP + "Attempting Source Object Directory Connection to Host URL:[" + IRRHost + "]");
}
IRRSource = new idxManageContext(IRRHost,
IRRPrincipal,
IRRCredentials,
"IRRanalyzer 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);
BBQ.setErrorAnalyzer(EXIT_IRR_CLOSE_FAILURE);
return;
} // End of exception
// ************************************************
// Now Disable Factories.
try {
IRRSource.disableDSAEFactories();
} catch (Exception e) {
System.err.println(MP + e);
BBQ.setErrorAnalyzer(EXIT_GENERIC_FAILURE);
return;
} // End of exception
// ************************************************
// Set up our Status Objects
StatSource = new idxStatus("IRRanalyzer");
StatSource.setOpStatus(1);
// **************************************************
// Obtain IRR Utility Object.
idxIRRutil util = new idxIRRutil();
util.setVerbose(VERBOSE);
// **************************************************
// Obtain IRR Analysis Summary Statistics Class.
IRRAnalysisSummary ASUMMARY = new IRRAnalysisSummary();
// **************************************************
// Obtain Runtime Object.
Runtime rt = Runtime.getRuntime();
// **************************************
// Loop to process commands from Walker
// Thread.
while (true) {
if (!BBQ.AnyErrors()) {
ZEN = BBQ.pop();
} else {
break;
}
// ***************************
// Ignore Null.
if ((ZEN == null) ||
("".equals(ZEN))) {
continue;
}
// ***************************
// Should We End Thread?
if ("<END THREAD>".equals(ZEN)) {
break;
}
// ***********************************
// Ignore a Comment or simple NewLine
if ((ZEN.startsWith("#")) ||
(ZEN.equals("\n"))) {
continue;
}
// *****************************
// Ok, this must be a DN, so
// Process.
try {
ObtainEntryForAnalysis(IRRSource.irrctx,
ZEN,
SearchFilter,
StatSource,
ASUMMARY);
} catch (Exception e) {
System.err.println(MP + "IRR Exception on IRRanalyze, Obtaining Source Entry, " + e);
BBQ.setErrorAnalyzer(EXIT_GENERIC_FAILURE);
return; // End Thread.
} // End of exception
} // End of While Loop.
// ***************************************
// Show Analysis Results.
System.out.println("\n****\n" +
"* <<- FRAMEWORK IRR Analysis Results ->>\n" +
"****");
System.out.println("As of " + CurrentTimeStamp.get());
System.out.println("IRR Host: " + IRRHost);
System.out.println("IRR Base: " + ENTRY_SOURCE_DN);
System.out.println("Search Filter Used: " + SearchFilter);
System.out.println("Analyzed Entries: " +
StatSource.getCounter("ReadEntries"));
if ((StatSource.getCounter("ReadEntries") > 0) &&
(!BBQ.AnyErrors())) {
System.out.println("Full Analysis was Successful with no Exceptions.");
} else {
System.out.println("Full Analysis was NOT Successful, Exceptions Detected.");
} // end of Else.
// ***************************************
// Dump the DIT Analysis.
System.out.println("\n****\n" +
"* <<- FRAMEWORK IRR DIT Analysis ->>\n" +
"****");
ASUMMARY.ShowClassificationsForDIT();
// ***************************************
// Dump the Data Analysis.
System.out.println("\n****\n" +
"* <<- FRAMEWORK IRR Data Analysis ->>\n" +
"****");
ASUMMARY.ShowClassificationsForData();
// ***************************************
// ***************************************
// End Analysis Results.
System.out.println("\n****\n" +
"* <<- End of Results ->>\n" +
"****");
// ***************************************
// Close up Shop.
if (VERBOSE) {
System.out.println(MP + "Closing Source Directory Context.");
}
try {
IRRSource.close();
} catch (Exception e) {
System.err.println(e);
BBQ.setErrorAnalyzer(EXIT_IRR_CLOSE_FAILURE);
return; // End Thread.
} // End of exception
// ***************************************
// Done.
return;
} // End of run.
/**
* Obtains Entry from Directory Context and performs an Analysis on
* the entry.
*
* @param ctxSource current established Source JNDI Directory Context
* @param DNSource DN of source entry.
* @param SearchFilter Search Filter.
* @param _StatusSource Source Common Status Object.
* @throws idxIRRException if any non-recoverable errors encountered.
*/
public void ObtainEntryForAnalysis(DirContext ctxSource,
String DNSource,
String SearchFilter,
idxStatus _StatusSource,
IRRAnalysisSummary _ASUMMARY)
throws idxIRRException {
//******************************************
// Initialize Status Counter.
_StatusSource.setLastOp("ObtainEntryforAnalysis");
_StatusSource.setLastOpResource(DNSource);
_StatusSource.setLastOpStatus(-1);
//******************************************
// Make sure we have a valid DN.
// If the Source Entry is Blank or caller
// trying to obtain ROOT, just ignore and
// return gracefully.
//
if ((DNSource == null) ||
("".equals(DNSource)) ||
(DNSource.equalsIgnoreCase("ROOT"))) {
return;
}
//******************************************
// Set up our Search Filter.
if (SearchFilter == null) {
SearchFilter = "(objectclass=*)";
}
//******************************************
// Set up our Search Controls.
String[] OCAttr = {"objectclass"};
SearchControls OS_ctls = new SearchControls();
OS_ctls.setReturningAttributes(OCAttr);
OS_ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
// *****************************************
// Parse the Destination Entry DN to be sure
// we have any Quotes....
idxParseDN Naming_Source = new idxParseDN(DNSource);
DNSource = Naming_Source.getDNwithQuotes();
// *****************************************
// Obtain the Namespace.
String NameSpace = null;
try {
NameSpace = ctxSource.getNameInNamespace();
if (NameSpace.equals("")) {
NameSpace = DNSource;
}
} catch (Exception e) {
{
NameSpace = DNSource;
}
} // End of exception
// *****************************************
// Now obtain the Source Entry.
//
try {
IRRAnalyzeEntry(ctxSource.search(DNSource, SearchFilter, OS_ctls),
DNSource,
_ASUMMARY);
_StatusSource.AccumCounter("ReadEntries");
_StatusSource.setLastOpStatus(1);
} catch (NameNotFoundException e) {
_StatusSource.AccumCounter("ReadErrors");
_StatusSource.setLastOpStatus(-1);
throw new idxIRRException("Source DN was not found, in ObtainEntryForAnalysis()");
} catch (Exception e) {
e.printStackTrace();
throw new idxIRRException("Error Performing IRR Analysis Function, in ObtainEntryForAnalysis(),\n" + e);
} // End of exception
} // End of ObtainEntryForAnalysis
/**
* Analyze Entry based upon Objectclass Type.
*
* @param sl JNDI search results.
* @param dnbase Current DN base to properly reflect full DN.
* @param _ASUMMARY Statistics Class.
* @throws Exception when unrecoverable error occurs.
*/
public static void IRRAnalyzeEntry(NamingEnumeration sl,
String dnbase,
IRRAnalysisSummary _ASUMMARY)
throws Exception, idxIRRException {
// *****************************************
// If Empty Enumeration List, simply return.
if (sl == null) {
return;
}
// *****************************************
// Analyze Entry.
SearchResult si = null;
try {
if (sl.hasMore()) {
si = (SearchResult) sl.next();
} else {
return;
}
// Formulate the DN.
String DN = null;
if (dnbase.equals("")) {
DN = si.getName();
} else if (si.getName().equals("")) {
DN = dnbase;
} else {
DN = si.getName() + "," + dnbase;
}
// ********************************************
// Obtain the Current DN.
//
idxParseDN pDN = new idxParseDN(DN);
// ********************************************
// Now Analyze the Current DN for DIT Analysis.
//
_ASUMMARY.ClassifyDN(pDN);
// ********************************************
// Obtain the entries Attributes.
Attributes entryattrs = si.getAttributes();
// ********************************************
// Obtain only ObjectClass Attributes.
Attribute eo = entryattrs.get("objectclass");
for (NamingEnumeration eov = eo.getAll(); eov.hasMore(); ) {
// *******************************************
// Analyze Entry based upon Objectclasses.
String Aname = eo.getID();
Object obvalue = eov.next();
String Avalue = null;
if (obvalue instanceof String) {
Avalue = obvalue.toString();
} else {
continue;
}
// *******************************************
// Now we have the Objectclass Name in Avalue,
// so analyze it.
Avalue = Avalue.toLowerCase();
_ASUMMARY.ClassifyEntry(Avalue);
} // End of For Loop.
} catch (NamingException e) {
System.err.println(MP + "Naming Exception, Cannot continue obtaining search results, " + e);
throw e;
} catch (Exception e) {
System.err.println(MP + "Exception, Cannot continue obtaining search results, " + e);
e.printStackTrace();
throw e;
} // End of Exception
return;
} // End of IRRAnalyzeEntry
} ///:~ End of Class IRRanalyzer
/**
* IRRAnalysisSummary
* Class to run Output Thread.
*/
class IRRAnalysisSummary {
private TreeMap<String, EntrySummary> dataTM = new TreeMap<>(); // Data Summary
private TreeMap<String, DITSummary> ditTM = new TreeMap<>(); // DIT Summary
private TreeMap<String, ObjectClassSummary> ocTM = new TreeMap<>(); // Objectclass Summary
private TreeMap<String, AttributeSummary> atTM = new TreeMap<>(); // Attribute Summary
private int Schema_TotalObjectclasses = 0;
private int Schema_StructuredObjectclasses = 0;
private int Schema_AuxObjectclasses = 0;
private int Schema_AbsObjectclasses = 0;
private int Schema_TotalAttributes = 0;
private int Schema_BinaryAttributes = 0;
private int Schema_DNAttributes = 0;
private int Schema_UserModifiableAttributes = 0;
private int Schema_UserNonModifiableAttributes = 0;
private int Schema_SingleValueAttributes = 0;
private int Schema_MultiValueAttributes = 0;
/**
* Provides Common Analysis Object.
*/
public IRRAnalysisSummary() {
} // End of IRRAnalysisSummary Constructor.
/**
* Classifies IRR Entry
*/
public void ClassifyEntry(String _OCname) {
_OCname = _OCname.toLowerCase();
EntrySummary es = (EntrySummary) dataTM.get(_OCname);
if (es == null) {
es = new EntrySummary();
}
es.counter++;
dataTM.put(_OCname, es);
ObjectClassSummary os = (ObjectClassSummary) ocTM.get(_OCname);
if (os != null) {
os.counter++;
ocTM.put(_OCname, os);
} // End of If.
} // End of ClassifyEntry Method.
/**
* Classifies IRR DN.
*/
public void ClassifyDN(idxParseDN _pDN) {
int deepth = 0;
// *********************************
// Be sure we represent all DIT
// Containers, if not and the
// entry has no children, then
// It will not appear in the summary.
if ((_pDN.getNamingAttribute().equalsIgnoreCase("ou")) ||
(_pDN.getNamingAttribute().equalsIgnoreCase("dc")) ||
(_pDN.getNamingAttribute().equalsIgnoreCase("jsu"))) {
String X500name = toX500Name(_pDN.getDN().toLowerCase());
DITSummary ds = (DITSummary) ditTM.get(X500name);
if (ds == null) {
ds = new DITSummary();
}
ditTM.put(X500name, ds);
} // End of If.
// *************************
// Find the Root DIT Member
String name = _pDN.getPDN();
while (true) {
deepth++;
idxParseDN xDN = new idxParseDN(name);
if (!xDN.isValid()) {
name = "ROOT";
break;
}
if ((xDN.getNamingAttribute().equalsIgnoreCase("ou")) ||
(xDN.getNamingAttribute().equalsIgnoreCase("dc")) ||
(xDN.getNamingAttribute().equalsIgnoreCase("rcu")) ||
(xDN.getNamingAttribute().equalsIgnoreCase("rdu")) ||
(xDN.getNamingAttribute().equalsIgnoreCase("jsu"))) {
name = xDN.getDN();
break;
} // End of If.
else {
name = xDN.getPDN();
} // End of Else.
} // End of While Loop.
// *******************************************
// Count the Entries in this DIT Container.
// Place in as X500name so that it Sorts
// Properly.
String X500name = toX500Name(name.toLowerCase());
DITSummary ds = (DITSummary) ditTM.get(X500name);
if (ds == null) {
ds = new DITSummary();
}
ds.counter++;
ds.deepth = deepth;
ditTM.put(X500name, ds);
} // End of ClassifyDN Method.
/**
* Displays Classifications.
*/
public void ShowClassificationsForDIT() {
System.out.println(JLeft("DIT Containers Discovered:", 49) + " " + JRight("Objects", 8));
Set set = ditTM.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
String Name = (String) e.getKey();
String FName = Name;
Integer ec = new Integer(((DITSummary) e.getValue()).counter);
Integer ed = new Integer(((DITSummary) e.getValue()).deepth);
if (!Name.equalsIgnoreCase("ROOT")) {
if (Name.startsWith("/")) {
Name = Name.substring(1);
if (Name.lastIndexOf("/") > 1) {
Name = Name.substring((Name.lastIndexOf("/") + 1));
}
} // End of If.
int deepth = Count(FName, "/");
int jl = 48 - deepth;
System.out.println(" " +
JLeft(" ", deepth, ".") +
JLeft(Name, jl, ".") + " " +
JRight(ec.toString(), 8));
} else {
System.out.println(" " + JLeft(Name, 48, ".") + " " +
JRight(ec.toString(), 8));
} // End of Else.
} // End of While Loop.
} // End of ShowClassificationsForData Method.
/**
* Displays Classifications.
*/
public void ShowClassificationsForData() {
System.out.println(JLeft("ObjectClasses Discovered:", 49) + " " + JRight("Count", 8));
Set set = dataTM.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
String Name = (String) e.getKey();
Integer ec = new Integer(((EntrySummary) e.getValue()).counter);
System.out.println(" " + JLeft(Name, 48, ".") + " " +
JRight(ec.toString(), 8));
} // End of While Loop.
} // End of ShowClassificationsForData Method.
/**
* Count Characters in a String.
*
* @param _s String incoming LDAP DN.
* @param _o String to be counted.
* @return int Number of occurrences.
*/
private int Count(String _s, String _o) {
int count = 0;
String x = _s;
while (x.indexOf(_o) != -1) {
count++;
if ((x.indexOf(_o) + _o.length()) > x.length()) {
break;
}
x = x.substring((x.indexOf(_o) + _o.length()));
} // End of While Loop.
return (count);
} // End of Count Method.
/**
* toX500Name.
*
* @param _ldapdn String incoming LDAP DN.
* @return String X500 DN.
*/
private String toX500Name(String _ldapdn) {
String X500dn = "";
StringTokenizer st = new StringTokenizer(_ldapdn, ",");
while (st.hasMoreTokens()) {
String ep = st.nextToken();
X500dn = "/" + ep + X500dn;
} // End of While Loop.
return (X500dn);
} // End of toX500Name Method.
/**
* Justify Left a String for Printing.
*
* @param _in
* @param _i Length
* @param _gap
*/
private String JLeft(String _in, int _i, String _gap) {
while (_in.length() < _i) {
_in = _in + _gap;
}
return (_in);
} // End of JLeft Method.
/**
* Justify Left a String for Printing.
*
* @param _in Incoming String.
* @param _i Length
*/
private String JLeft(String _in, int _i) {
return (JLeft(_in, _i, " "));
} // End of JLeft Method.
/**
* Justify Right a String for Printing.
*
* @param _in Incoming String.
* @param _i Length
* @param _gap Gap String.
*/
private String JRight(String _in, int _i, String _gap) {
while (_in.length() < _i) {
_in = _gap + _in;
}
return (_in);
} // End of JRight Method.
/**
* Justify Right a String for Printing.
*
* @param _in Incoming String.
* @param _i Length
*/
private String JRight(String _in, int _i) {
return (JRight(_in, _i, " "));
} // End of JRight Method.
} ///:~ End of IRRAnalysisSummary Class.
/**
* EntrySummary Object.
* Class to contain Entry Analysis.
*/
class EntrySummary {
public int counter = 0;
/**
* Provides Analysis Object.
*/
public EntrySummary() {
} // End of EntrySummary Constructor.
} ///:~ End of EntrySummary Class.
/**
* DITSummary Object.
* Class to contain Entry Analysis.
*/
class DITSummary {
public int counter = 0;
public int deepth = 0;
/**
* Provides Analysis Object.
*/
public DITSummary() {
} // End of DITSummary Constructor.
} ///:~ End of DITSummary Class.
/**
* AttributeSummary Object.
* Class to contain Entry Analysis.
*/
class AttributeSummary {
public int counter = 0;
/**
* Provides Analysis Object.
*/
public AttributeSummary() {
} // End of AttributeSummary Constructor.
} ///:~ End of AttributeSummary Class.
/**
* ObjectClassSummary Object.
* Class to contain Entry Analysis.
*/
class ObjectClassSummary {
public int counter = 0;
/**
* Provides Analysis Object.
*/
public ObjectClassSummary() {
} // End of ObjectClassSummary Constructor.
} ///:~ End of ObjectClassSummary Class.