package jeffaschenk.commons.frameworks.cnxidx.resiliency.ldap; import java.io.*; import jeffaschenk.commons.frameworks.cnxidx.utility.StopWatch; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxLapTime; import jeffaschenk.commons.frameworks.cnxidx.utility.logging.FrameworkLogger; import jeffaschenk.commons.frameworks.cnxidx.utility.logging.FrameworkLoggerLevel; import jeffaschenk.commons.touchpoint.model.threads.CircularObjectStack; import org.jgroups.Address; import org.jgroups.Channel; /** * IRR Change Log Restore Service Publisher will publish StackCommands which * can contain replication data or control data to the Members of the current * Group established in the Control Thread. * * @author jeff.schenk * @version 4.4 $Revision * Developed 2005 */ /** * IRRChangeLogRestoreServicePublisherThread * Class to run Publisher Thread. */ class IRRChangeLogRestoreServicePublisherThread implements Runnable { // ******************************* // Common Logging Facility. private static final String CLASSNAME = IRRChangeLogRestoreServicePublisherThread.class.getName(); /** * IRRChangeLogRestoreServicePbblisherThread * Class to provide common thread to publish replication or control commands * to the Members of our Group. */ Thread t; private static final String THREAD_NAME = "IRRChangeLogRestoreServicePublisherThread"; private CircularObjectStack cosin; // Input Stack. private Channel my_channel; // Output to Membership Community. private long messages_published = 0; // Count of Messages Published. // *********************************************** // Initialize my LAP Timers private idxLapTime LP_ENTRY_TO_CHANNEL = new idxLapTime(); private idxLapTime LP_ENTRY_FROM_COS = new idxLapTime(); /** * IRRBackupOutputThread Contructor class driven. * * @param my_channel * @param cosin Circular Object Stack for Obtaining Control Commands. */ IRRChangeLogRestoreServicePublisherThread( Channel my_channel, CircularObjectStack cosin) { // **************************************** // Set My Incoming Parameters. this.cosin = cosin; this.my_channel = my_channel; // **************************************** // Ready the Synchronized Object and start // the Thread. t = new Thread(this, IRRChangeLogRestoreServicePublisherThread.THREAD_NAME); t.start(); // Start the Thread } // End of Contructor. /** * run * Thread to Publish Message from various threads to the JGroups Cloud. */ public void run() { // *********************************************** // Initialize our StopWatch to measure Duration // of Thread. String METHODNAME = "run"; StopWatch sw = new StopWatch(); sw.start(); // *********************************************** // Initialize Thread Variables. StackCommand instackcommand = null; boolean running = true; FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.INFO, MessageConstants.PUBLISHER_THREAD_ESTABLISHED, new String[]{Thread.currentThread().getName()}); // ************************************** // Loop to process commands from Walker // Thread. while (running) { instackcommand = null; // Be sure to Clear Previous Entry. LP_ENTRY_FROM_COS.Start(); if (cosin.hasMoreNodes()) { instackcommand = (StackCommand) cosin.getNext(); } LP_ENTRY_FROM_COS.Stop(); // *************************** // Did anything get pulled // from stack? if (instackcommand == null) { try { Thread.sleep(1000); } catch (InterruptedException ie) { } continue; } // End of Nothing in Stack yet to Process. // ****************************** // Did our Running State trip to // not based upon a End of Thread // command? If so, never place this // Command on the BUS. if (instackcommand.getCommandType() == StackCommand.CL_END_OF_THREAD) { running = false; continue; // Force our loop to End. } // End of Check for End of Thread. // ****************************** // Ok, Assume we are to Publish. // try { LP_ENTRY_TO_CHANNEL.Start(); if (instackcommand.getDestination() != null) { my_channel.send((Address) instackcommand.getDestination(), // (Address)instackcommand.getOriginator(), instackcommand); } else { my_channel.send(null, instackcommand); } LP_ENTRY_TO_CHANNEL.Stop(); messages_published++; } catch (Exception ce) { FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.SEVERE, ErrorConstants.PUBLISH_TO_CHANNEL_EXCEPTION, new String[]{instackcommand.toString(), ce.toString()}); this.logStackTrace(ce, METHODNAME, ErrorConstants.PUBLISH_TO_CHANNEL_EXCEPTION_STACK_TRACE); // TODO Count Number of Exceptions, we really need to retry this.... } // End of Exception Processing. } // End of Outer While Loop. // *************************************** // Show the Lap Timings. FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.INFO, MessageConstants.PUBLISHER_LAPTIME_FROM_STACK, new String[]{LP_ENTRY_FROM_COS.toString()}); FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.INFO, MessageConstants.PUBLISHER_LAPTIME_TO_CHANNEL, new String[]{LP_ENTRY_TO_CHANNEL.toString()}); // *************************************** // Show the Duration of Thread. sw.stop(); FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.INFO, MessageConstants.PUBLISHER_THREAD_SHUTDOWN, new String[]{sw.getElapsedTimeString()}); // *************************************** // Done. return; } // End of run. /** * Get Current Component Status. * * @return String Data Representing Current Status of this Component. */ protected String getStatus() { StringBuffer sb = new StringBuffer(); // ************************************** // Build String Buffer with Status for // this component. // ************************************** // Show Header sb.append(WebAdminResponderThread.COMPONENT_BEGIN); sb.append("Publisher Thread"); sb.append(WebAdminResponderThread.COMPONENT_END); // ************************************** // Show Detail. sb.append(WebAdminResponderThread.BEGIN_TABLE); sb.append(WebAdminResponderThread.build2ColumnRow("Messages Published", Long.toString(this.messages_published))); sb.append(WebAdminResponderThread.build2ColumnRow("Lap Time Messages to Channel", LP_ENTRY_TO_CHANNEL.toString())); sb.append(WebAdminResponderThread.build2ColumnRow("Lap Time Message From Input Stack", LP_ENTRY_FROM_COS.toString())); sb.append(WebAdminResponderThread.END_TABLE); sb.append(WebAdminResponderThread.BREAK); // ************************************** // Return Formatted Status. return sb.toString(); } // End of Protected GetStatus Method. /** * Helper Method to reset Component Statistics. */ protected void resetStatistics() { this.messages_published = 0; LP_ENTRY_TO_CHANNEL.Reset(); LP_ENTRY_FROM_COS.Reset(); } // End of resetStatistics protected method. /** * Provides Logging of Stack Traces from Exceptions detail on the Nested Stack Trace * from Severe Runtime Errors. */ private void logStackTrace(Exception e, String METHODNAME, String MSGNUM) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); pw.close(); FrameworkLogger.log(CLASSNAME, METHODNAME, FrameworkLoggerLevel.SEVERE, MSGNUM, new String[]{e.getMessage(), sw.toString()}); } // End of logStackTrace private Method. } ///:~ End of Class IRRChangeLogRestoreServicePUblisherThread