package jeffaschenk.commons.frameworks.cnxidx.resiliency.ldap;
import jeffaschenk.commons.frameworks.cnxidx.utility.StopWatch;
import jeffaschenk.commons.frameworks.cnxidx.utility.logging.FrameworkLogger;
import jeffaschenk.commons.frameworks.cnxidx.utility.logging.FrameworkLoggerLevel;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.io.*;
/**
* IRR Change Log Static utility Methods for Accessing Files
* produced from either internal change Log or from the LDAP
* Export change Log produced by the DC-Directory.
*
* @author jeff.schenk
* @version 4.4 $Revision
* Developed 2005
*/
public class IRRChangeLogFileUtility {
// *******************************
// Common Logging Facility.
private static final String CLASSNAME
= IRRChangeLogFileUtility.class.getName();
// *****************************
// Filename Search Patterns
// This Pattern has been deprecated.
// pattern: ^IRRCHGLOG.\d{12}.\d{12}\056ldif$
public static final String IRRCHGLOG_FILENAME_PATTERN =
"^IRRCHGLOG.\\d{12}.\\d{12}\\056ldif$";
// This is our Default Pattern,
// pattern: ^\d{12}.\d{4}(\056\d{3})??$
public static final String DCLLDIFEXPORT_FILENAME_PATTERN =
"^\\d{12}.\\d{4}(\\056\\d{3})??$";
// This is our Default Pattern for obtaining
// Reference Files which are referred to by our base file.
// pattern: ^<FILENAME>_ref*
public static final String DCLLDIFEXPORT_REFERENCE_PATTERN =
"_ref*";
// **************************************
// FileName Globals.
public static final String PROCESSED = "PROCESSED";
public static final String BLOCKED = "BLOCKED";
public static final String UNDERSCORE = "_";
/**
* processedFileCount, check for any processed files within the Change Log File System Directory.
*
* @param INPUT_PATH Input File System Path of Directory where Log Restore Files Reside.
*/
protected static long processedFileCount(String INPUT_PATH) {
String METHODNAME = "processedFileCount";
long count = 0;
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory.
//
TreeMap LOGFILES =
IRRChangeLogFileUtility.obtainDirListing(
INPUT_PATH, DCLLDIFEXPORT_FILENAME_PATTERN);
// ************************************
// Now simple Iterate Through the
// Log Files and drive the Restore.
Set mySet = LOGFILES.entrySet();
Iterator itr = mySet.iterator();
while (itr.hasNext()) {
Map.Entry oit = (Map.Entry) itr.next();
File _infile =
(File) oit.getValue();
// *******************************************
// Verify the file has yet to be processed or
// not.
File _processedfile =
getProcessedFile(_infile);
// Eliminate Blocked File References.
File _blockedfile =
getBlockedFile(_infile);
if (_processedfile.exists() || _blockedfile.exists()) {
count++;
}
} // End of While Loop.
// *************************
// return
return (count);
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of processedFileCount Method.
/**
* obtainProcessedFileMap, check for any unprocessed files within the Change Log File System Directory.
*
* @param INPUT_PATH Input File System Path of Directory where Log Restore Files Reside.
*/
protected static Map<Object,File> obtainProcessedFileMap(String INPUT_PATH) {
String METHODNAME = "obtainPocessedFileMap";
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory.
//
TreeMap<String,File> LOGFILES =
IRRChangeLogFileUtility.obtainDirListing(
INPUT_PATH, DCLLDIFEXPORT_FILENAME_PATTERN);
// **************************************
// Create a new Map to return.
Map<Object,File> RLOGFILES = new TreeMap<>();
// ************************************
// Now simple Iterate Through the
// Log Files and drive the Restore.
Set mySet = LOGFILES.entrySet();
Iterator itr = mySet.iterator();
while (itr.hasNext()) {
Map.Entry oit = (Map.Entry) itr.next();
File _infile =
(File) oit.getValue();
// *******************************************
// Verify the file has yet to be processed or
// not.
File _processedfile =
getProcessedFile(_infile);
// Eliminate Blocked File References.
File _blockedfile =
getBlockedFile(_infile);
// ***********************************************
// Add the file to the list if it has been flagged.
if ((_processedfile.exists()) || (_blockedfile.exists())) {
RLOGFILES.put(oit.getKey(), _infile);
}
} // End of While Loop.
// *************************
// return
return RLOGFILES;
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of obtainProcessedFileMap Method.
/**
* unprocessedFileCount, check for any unprocessed files within the Change Log File System Directory.
*
* @param INPUT_PATH Input File System Path of Directory where Log Restore Files Reside.
*/
protected static long unprocessedFileCount(String INPUT_PATH) {
String METHODNAME = "unprocessedFileCount";
long count = 0;
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory.
//
TreeMap LOGFILES =
IRRChangeLogFileUtility.obtainDirListing(
INPUT_PATH, DCLLDIFEXPORT_FILENAME_PATTERN);
// ************************************
// Now simple Iterate Through the
// Log Files and drive the Restore.
Set mySet = LOGFILES.entrySet();
Iterator itr = mySet.iterator();
while (itr.hasNext()) {
Map.Entry oit = (Map.Entry) itr.next();
File _infile =
(File) oit.getValue();
// *******************************************
// Verify the file has yet to be processed or
// not.
File _processedfile =
getProcessedFile(_infile);
// Eliminate Blocked File References.
File _blockedfile =
getBlockedFile(_infile);
if (!_processedfile.exists() && !_blockedfile.exists()) {
count++;
}
} // End of While Loop.
// *************************
// return
return (count);
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of unprocessedFileCount Method.
/**
* obtainUnprocessedFileMap, check for any unprocessed files within the Change Log File System Directory.
*
* @param INPUT_PATH Input File System Path of Directory where Log Restore Files Reside.
* @return TreeMap
*/
protected static TreeMap obtainUnprocessedFileMap(String INPUT_PATH) {
String METHODNAME = "obtainUnprocessedFileMap";
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory.
//
TreeMap<String,File> LOGFILES =
IRRChangeLogFileUtility.obtainDirListing(
INPUT_PATH, DCLLDIFEXPORT_FILENAME_PATTERN);
// **************************************
// Create a new Map to return.
TreeMap<Object,File> RLOGFILES = new TreeMap<>();
// ************************************
// Now simple Iterate Through the
// Log Files and drive the Restore.
Set mySet = LOGFILES.entrySet();
Iterator itr = mySet.iterator();
while (itr.hasNext()) {
Map.Entry oit = (Map.Entry) itr.next();
File _infile =
(File) oit.getValue();
// *******************************************
// Verify the file has yet to be processed or
// not.
File _processedfile =
getProcessedFile(_infile);
// Eliminate Blocked File References.
File _blockedfile =
getBlockedFile(_infile);
// ***********************************************
// Add the file to the list if it does not
// have a flagged file.
if ((!_processedfile.exists()) && (!_blockedfile.exists())) {
RLOGFILES.put(oit.getKey(), _infile);
}
} // End of While Loop.
// *************************
// return
return RLOGFILES;
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of obtainUnprocessedFileMap Method.
/**
* obtainReferenceFileMap, check for any reference files within the Change Log File System Directory.
*
* @param changelog_filename Input File System Path of Directory where Log Restore Files Reside.
* @return TreeMap --
*/
protected static TreeMap obtainReferenceFileMap(final String changelog_filename) {
String METHODNAME = "obtainReferenceFileMap";
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Ensure we have both parameters
if ((changelog_filename == null) ||
(changelog_filename.equalsIgnoreCase(""))) {
return null;
}
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory
// applying our filter.
//
File f = new File(changelog_filename);
return
IRRChangeLogFileUtility.obtainDirListing(
f.getParent(), "^" + f.getName() + DCLLDIFEXPORT_REFERENCE_PATTERN);
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of obtainReferencedFileMap Method.
/**
* deleteReferenceFiles, check for any reference files within the Change Log File System Directory for
* a specific base change log file and delete those files.
*
* @param changelog_filename Input File System Path of Directory where Log Restore Files Reside.
* @return long -- returns number of deleted referenced files.
*/
protected static long deleteReferenceFiles(final String changelog_filename) {
String METHODNAME = "deleteReferenceFiles";
long delete_count = 0;
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
try {
// ************************************
// Ensure we have both parameters
if ((changelog_filename == null) ||
(changelog_filename.equalsIgnoreCase(""))) {
return 0;
}
// ************************************
// Obtain the current list of LOG Files
// that are contained within our
// Input Path File System Directory
// applying our filter.
//
TreeMap RFILES =
IRRChangeLogFileUtility.obtainReferenceFileMap(
changelog_filename);
// *************************************
// Now loop to delete those files.
Set mySet = RFILES.entrySet();
Iterator itr = mySet.iterator();
while (itr.hasNext()) {
Map.Entry oit = (Map.Entry) itr.next();
File _reffile =
(File) oit.getValue();
// *******************************
// Issue File Delete.
try {
if (_reffile.delete()) {
delete_count++;
}
} catch (SecurityException se) {
// TODO
} // End of Exception Processing.
} // End of While Loop.
// **********************
// Return number files
// deleted.
return delete_count;
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of deleteReferenceFiles Method.
/**
* obtain a Directory Listing using a Pattern and return a TreeMap sorted by the filename.
*/
protected static TreeMap<String,File> obtainDirListing(String _dirname, String _pattern) {
String METHODNAME = "obtainDirListing";
// **********************************
// Initialize Logging
StopWatch sw = new StopWatch();
sw.start();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.ENTERING_METHOD,
new String[]{METHODNAME});
// *********************
// Compile Our Pattern.
Pattern pattern = null;
Matcher pm = null;
TreeMap<String,File> _tm = new TreeMap<>();
try {
pattern = Pattern.compile(_pattern);
} catch (PatternSyntaxException pse) {
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.SEVERE,
ErrorConstants.DIRLIST_REGEX_PATTERN_SYNTAX_EXCEPTION,
new String[]{_pattern, pse.getMessage()});
return (_tm);
} // End of Exception.
try {
// ******************************
// Obtain the Directory Listing.
File ld = new File(_dirname);
if (!ld.isDirectory()) {
return (_tm);
}
String contents[] = ld.list();
for (int i = 0; i < contents.length; i++) {
if (pm == null) {
pm = pattern.matcher((String) contents[i]);
} else {
pm.reset((String) contents[i]);
}
// ********************************
// Display the Filtered Contents
if (pm.find()) {
File DGD = new File(_dirname +
File.separator + contents[i]);
if (DGD.isDirectory()) {
continue;
}
// *****************************
// Save to our TreeMap.
_tm.put(contents[i], DGD);
} // End of find if.
} // End of For Loop.
// *******************
// Return.
return (_tm);
} finally {
sw.stop();
FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.DEBUG,
MessageConstants.FINALIZING_METHOD,
new String[]{METHODNAME, sw.getElapsedTimeString()});
} // End of Final Processing for Method.
} // End of obtainDirListing Method.
/**
* get Processed File Object for use to persist to indicate
* log file has been fully processed.
*
* @param infile Filename.
* @return File
*/
protected static File getProcessedFile(File infile) {
return new File(infile.getAbsolutePath() + UNDERSCORE + PROCESSED);
} // End of getProcessedFile.
/**
* get Processed File Object for use to persist to indicate
* log file has been fully processed.
*
* @param infile Filename.
* @return File
*/
protected static File getBlockedFile(File infile) {
return new File(infile.getAbsolutePath() + UNDERSCORE + BLOCKED);
} // End of getBlockedFile.
/**
* get Blocked File Object for use to persist to indicate
* log file has been fully processed.
*
* @param filename
* @return File
*/
protected static File getBlockedFile(String filename) {
return new File(filename + UNDERSCORE + BLOCKED);
} // End of getBlockedFile.
/**
* get Processed File Object for use to persist to indicate
* log file has been fully processed.
*
* @param filename
* @return File
*/
protected static File getProcessedFile(String filename) {
return new File(filename + UNDERSCORE + PROCESSED);
} // End of getProcessedFile.
/**
* get Processed File Object for use to persist to indicate
* log file has been fully processed.
*
* @param changelogstatus
* @return File
*/
protected static File getProcessedFile(ChangeLogStatus changelogstatus) {
return new File(changelogstatus.getLogFileName() + UNDERSCORE + PROCESSED);
} // End of getProcessedFile.
} ///:~ End of IRRChangeLogUtility Class.