package jeffaschenk.commons.frameworks.cnxidx.admin; import jeffaschenk.commons.frameworks.cnxidx.utility.StopWatch; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxCMDReturnCodes; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxLapTime; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxManageContext; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxParseDN; import jeffaschenk.commons.touchpoint.model.threads.CircularObjectStack; import javax.naming.*; import javax.naming.directory.*; /** * IRR Backup Reader Thread. Will Read Directory Entry and * pass element to Queue to be eventually written to an LDIF compilent Data file. * Backup output conforms to the LDIF Specification: RFC2849. * @author jeff.schenk * @version 4.4 $Revision * Developed 2005 */ /** * IRRBackupReaderThread * Class to run Reader Thread. */ class IRRBackupReaderThread implements Runnable, idxCMDReturnCodes { /** * IRRBackupReaderThread * Class to provide Reader Thread to initiate Read of Directory Entries * complete set of attributes. */ Thread t; private String THREAD_NAME; private int instance; private CircularObjectStack cosin; // Input Stack. private CircularObjectStack cosout; // Output Stack. private IRRBackupStatusNew ReaderStatus; private static String MP = "IRRBackupReaderThread"; private static idxManageContext IRRSource = null; private static String ENTRY_SOURCE_DN = null; private static boolean VERBOSE = false; private static boolean DEBUG = false; private boolean ExitOnException = false; public static final String ObjectClassName = "objectclass"; public static final String DEFAULT_SEARCH_FILTER = "(" + ObjectClassName + "=*)"; /** * IRRBackupOutputThread Contructor class driven. * * @param cosin Circular Object Stack for placing DN's on Read Queue. * @param cosout Circular Object Stack for placing LDAP Entries on Output Stack. * @param ReaderStatus Object used for Thread Status. * @param IRRSource Managed DirContext * @param ENTRY_SOURCE_DN Specified where to begin Backup in Tree. * @param _VERBOSE Indicate Verbosity. * @param _DEBUG Indicate DEBUGGING. * @param _ExitOnException Indicate Exit on Exceptions. */ IRRBackupReaderThread( int instance, CircularObjectStack cosin, CircularObjectStack cosout, IRRBackupStatusNew ReaderStatus, idxManageContext IRRSource, String ENTRY_SOURCE_DN, boolean _VERBOSE, boolean _DEBUG, boolean _ExitOnException) { // **************************************** // Set My Incoming Parameters. this.cosin = cosin; this.cosout = cosout; this.ENTRY_SOURCE_DN = ENTRY_SOURCE_DN; this.VERBOSE = _VERBOSE; this.DEBUG = _DEBUG; this.ExitOnException = _ExitOnException; this.ReaderStatus = ReaderStatus; this.IRRSource = IRRSource; this.instance = instance; // **************************************** // Ready the Synchronized Object and start // the Thread. THREAD_NAME = "IRRbackup_ReaderThread" + (this.instance + 1); t = new Thread(this, THREAD_NAME); t.start(); // Start the Thread } // End of Contructor. /** * run * Thread to Read LDAP Entry all Attributes and post * Object to Output Stack to be ripped as an LDIF Backup Image. */ public void run() { // *********************************************** // Initialize our StopWatch to measure Duration // of Thread. StopWatch sw = new StopWatch(); sw.start(); // *********************************************** // Initialize Thread Variables. String ZEN = null; int DNcount = 0; long memfree; String tname = Thread.currentThread().getName(); System.out.println(MP + (instance + 1) + ": Thread Established for:[" + tname + "]"); // *********************************************** // Initialize my LAP Timers idxLapTime LP_ENTRY_SEARCH = new idxLapTime(); idxLapTime LP_ENTRY_TO_COS = new idxLapTime(); idxLapTime LP_ENTRY_FROM_COS = new idxLapTime(); // ************************************************** // Obtain Runtime Object. Runtime rt = Runtime.getRuntime(); //****************************************** // Set up our Search Controls. String[] ALL_AttrIDs = {"*"}; SearchControls OS_ctls = new SearchControls(); OS_ctls.setReturningAttributes(ALL_AttrIDs); OS_ctls.setSearchScope(SearchControls.OBJECT_SCOPE); // ************************************** // Loop to process commands from Walker // Thread. try { while (true) { ZEN = null; // BE sure to Clear Previous Entry. LP_ENTRY_FROM_COS.Start(); if (cosin.hasMoreNodes()) { ZEN = (String) cosin.getNext(); } LP_ENTRY_FROM_COS.Stop(); // *************************** // Did anything get pulled // from stack? if ((ZEN == null) || ("".equals(ZEN))) { t.sleep(1000); continue; } // End of Nothing in Stack yet to Process. // *************************** // Should We End Thread? if (IRRBackupNew.END_OF_DATA.equals(ZEN)) { break; } // ***************************** // Is the Entry a LDIF Comment? // Or a Simple NewLine? if ((ZEN.startsWith("#")) || (ZEN.equals("\n"))) { continue; // Ignore Comments and Blank Lines. } // 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 senum = IRRSource.irrctx.search(ZEN, DEFAULT_SEARCH_FILTER, OS_ctls); LP_ENTRY_SEARCH.Stop(); if (LP_ENTRY_SEARCH.getCurrentDuration() > 1000) { System.out.println(MP + (instance + 1) + ": Warning ** Entry Search took " + LP_ENTRY_SEARCH.getElapsedtoString() + " to Complete to Obtain:[" + ZEN + "]"); } // End of Warning Check for Long Search. // **************************** // Ignore any NULL Results. if (senum == null) { continue; } // *************************** // Obtain each SearchResult // and place on Output Stack. while (senum.hasMore()) { SearchResult sr = (SearchResult) senum.next(); IRRBackupSearchResult isr = new IRRBackupSearchResult(ZEN, sr); LP_ENTRY_TO_COS.Start(); cosout.push(isr); LP_ENTRY_TO_COS.Stop(); DNcount++; } // End of Enumeration While Loop. } catch (Exception e) { System.err.println(MP + (instance + 1) + ": IRR Exception on IRRbackup, Obtaining Source Entry, " + e); e.printStackTrace(); ReaderStatus.setError(EXIT_IRR_BACKUP_FAILURE); return; // End Thread. } // End of exception } // End of Outer While Loop. } catch (Exception e) { System.err.println(MP + (instance + 1) + ": IRR Exception on IRRbackup, Obtaining Data From Object Stack. " + e); return; // End Thread. } // End of exception // ******************************************* // Show number of entries passed through the // Stack. if (DNcount > 0) { System.out.println(MP + (instance + 1) + ": Successful Backup Reader Thread Completed with Entries Passed to Output Stack:[" + DNcount + "]"); } else { System.out.println(MP + (instance + 1) + ": Backup Reader Thread Completed, " + " However with NO Entries Passed to Output Stack, since no DN entries were obtained from Stack."); } // *************************************** // Show the Lap Timings. System.out.println(MP + (instance + 1) + ": Lap Time for Entry Search: " + LP_ENTRY_SEARCH); System.out.println(MP + (instance + 1) + ": Lap Time for Entry to Output Stack: " + LP_ENTRY_TO_COS); System.out.println(MP + (instance + 1) + ": Lap Time for Entry From Input Stack: " + LP_ENTRY_FROM_COS); // *************************************** // Show the Duration of Thread. sw.stop(); System.out.println(MP + (instance + 1) + ": Thread Duration: " + sw.getElapsedTimeString()); // *************************************** // Done. return; } // End of run. } ///:~ End of Class IRRBackupReaderThread