Author: dkulp Date: Fri Jan 8 14:03:45 2010 New Revision: 897209 URL: http://svn.apache.org/viewvc?rev=897209&view=rev Log: Merged revisions 896575 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.2.x-fixes
................ r896575 | dkulp | 2010-01-06 12:47:02 -0500 (Wed, 06 Jan 2010) | 10 lines Merged revisions 896560 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r896560 | dkulp | 2010-01-06 12:36:07 -0500 (Wed, 06 Jan 2010) | 2 lines [CXF-2596] Add a FaultLogger to allow custom handling of fault logging Patch from Tomas Majak applied. Thanks! ........ ................ Added: cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/logging/ - copied from r896575, cxf/branches/2.2.x-fixes/api/src/main/java/org/apache/cxf/logging/ cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/logging/FaultLogger.java - copied unchanged from r896575, cxf/branches/2.2.x-fixes/api/src/main/java/org/apache/cxf/logging/FaultLogger.java Modified: cxf/branches/2.1.x-fixes/ (props changed) cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java cxf/branches/2.1.x-fixes/api/src/test/java/org/apache/cxf/phase/PhaseInterceptorChainTest.java Propchange: cxf/branches/2.1.x-fixes/ ('svn:mergeinfo' removed) Propchange: cxf/branches/2.1.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java?rev=897209&r1=897208&r2=897209&view=diff ============================================================================== --- cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java (original) +++ cxf/branches/2.1.x-fixes/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java Fri Jan 8 14:03:45 2010 @@ -35,6 +35,7 @@ import org.apache.cxf.interceptor.Fault; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.InterceptorChain; +import org.apache.cxf.logging.FaultLogger; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.FaultMode; import org.apache.cxf.message.Message; @@ -82,6 +83,7 @@ private Message pausedMessage; private MessageObserver faultObserver; private PhaseInterceptorIterator iterator; + private final boolean isFineLogging; // currently one chain for one request/response, use below as signal // to avoid duplicate fault processing on nested calling of @@ -91,6 +93,8 @@ private PhaseInterceptorChain(PhaseInterceptorChain src) { + isFineLogging = LOG.isLoggable(Level.FINE); + //only used for clone state = State.EXECUTING; @@ -127,7 +131,8 @@ public PhaseInterceptorChain(SortedSet<Phase> ps) { state = State.EXECUTING; - + isFineLogging = LOG.isLoggable(Level.FINE); + int numPhases = ps.size(); phases = new Phase[numPhases]; nameMap = new HashMap<String, Integer>(); @@ -194,7 +199,7 @@ + ((phaseName == null) ? ": Phase declaration is missing." : ": Phase " + phaseName + " specified does not exist.")); } else { - if (LOG.isLoggable(Level.FINE)) { + if (isFineLogging) { LOG.fine("Adding interceptor " + i + " to phase " + phaseName); } @@ -223,7 +228,6 @@ @SuppressWarnings("unchecked") public synchronized boolean doIntercept(Message message) { updateIterator(); - boolean isFineLogging = LOG.isLoggable(Level.FINE); pausedMessage = message; Message oldMessage = CURRENT_MESSAGE.get(); @@ -264,37 +268,17 @@ description.append("\' "); } } - - FaultMode mode = message.get(FaultMode.class); - if (mode == FaultMode.CHECKED_APPLICATION_FAULT) { - if (LOG.isLoggable(Level.FINE)) { - LogUtils.log(LOG, Level.FINE, - "Application " + description - + "has thrown exception, unwinding now", ex); - } else if (LOG.isLoggable(Level.INFO)) { - Throwable t = ex; - if (ex instanceof Fault - && ex.getCause() != null) { - t = ex.getCause(); - } - - LogUtils.log(LOG, Level.INFO, - "Application " + description - + "has thrown exception, unwinding now: " - + t.getClass().getName() - + ": " + ex.getMessage()); - } - } else if (LOG.isLoggable(Level.WARNING)) { - if (mode == FaultMode.UNCHECKED_APPLICATION_FAULT) { - LogUtils.log(LOG, Level.WARNING, - "Application " + description - + "has thrown exception, unwinding now", ex); - } else { - LogUtils.log(LOG, Level.WARNING, - "Interceptor for " + description - + "has thrown exception, unwinding now", ex); - } + + FaultLogger flogger = (FaultLogger) + message.getContextualProperty(FaultLogger.class.getName()); + boolean useDefaultLogging = true; + if (flogger != null) { + useDefaultLogging = flogger.log(ex, description.toString(), message); + } + if (useDefaultLogging) { + doDefaultLogging(message, ex, description); } + message.setContent(Exception.class, ex); boolean isOneWay = false; @@ -320,7 +304,40 @@ CURRENT_MESSAGE.set(oldMessage); } } - + + private void doDefaultLogging(Message message, RuntimeException ex, StringBuilder description) { + FaultMode mode = message.get(FaultMode.class); + if (mode == FaultMode.CHECKED_APPLICATION_FAULT) { + if (isFineLogging) { + LogUtils.log(LOG, Level.FINE, + "Application " + description + + "has thrown exception, unwinding now", ex); + } else if (LOG.isLoggable(Level.INFO)) { + Throwable t = ex; + if (ex instanceof Fault + && ex.getCause() != null) { + t = ex.getCause(); + } + + LogUtils.log(LOG, Level.INFO, + "Application " + description + + "has thrown exception, unwinding now: " + + t.getClass().getName() + + ": " + ex.getMessage()); + } + } else if (LOG.isLoggable(Level.WARNING)) { + if (mode == FaultMode.UNCHECKED_APPLICATION_FAULT) { + LogUtils.log(LOG, Level.WARNING, + "Application " + description + + "has thrown exception, unwinding now", ex); + } else { + LogUtils.log(LOG, Level.WARNING, + "Interceptor for " + description + + "has thrown exception, unwinding now", ex); + } + } + } + /** * Intercept a message, invoking each phase's handlers in turn, * starting after the specified interceptor. @@ -374,7 +391,6 @@ @SuppressWarnings("unchecked") private void unwind(Message message) { - boolean isFineLogging = LOG.isLoggable(Level.FINE); while (iterator.hasPrevious()) { Interceptor currentInterceptor = iterator.previous(); if (isFineLogging) { @@ -604,7 +620,7 @@ } private void outputChainToLog(boolean modified) { - if (LOG.isLoggable(Level.FINE)) { + if (isFineLogging) { if (modified) { LOG.fine(toString(" was modified")); } else { Modified: cxf/branches/2.1.x-fixes/api/src/test/java/org/apache/cxf/phase/PhaseInterceptorChainTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/api/src/test/java/org/apache/cxf/phase/PhaseInterceptorChainTest.java?rev=897209&r1=897208&r2=897209&view=diff ============================================================================== --- cxf/branches/2.1.x-fixes/api/src/test/java/org/apache/cxf/phase/PhaseInterceptorChainTest.java (original) +++ cxf/branches/2.1.x-fixes/api/src/test/java/org/apache/cxf/phase/PhaseInterceptorChainTest.java Fri Jan 8 14:03:45 2010 @@ -30,6 +30,8 @@ import org.apache.cxf.continuations.SuspendedInvocationException; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.InterceptorChain; +import org.apache.cxf.logging.FaultLogger; +import org.apache.cxf.message.FaultMode; import org.apache.cxf.message.Message; import org.easymock.classextension.EasyMock; import org.easymock.classextension.IMocksControl; @@ -214,6 +216,36 @@ } @Test + public void testSingleInterceptorFailWithCustomLogger() throws Exception { + AbstractPhaseInterceptor p = setUpPhaseInterceptor("phase1", "p1"); + setUpPhaseInterceptorInvocations(p, true, true); + setUpCustomLogger(true, true, false); + control.replay(); + chain.add(p); + chain.doIntercept(message); + } + + @Test + public void testSingleInterceptorFailWithCustomLoggerAndDefaultLogging() throws Exception { + AbstractPhaseInterceptor p = setUpPhaseInterceptor("phase1", "p1"); + setUpPhaseInterceptorInvocations(p, true, true); + setUpCustomLogger(true, true, true); + control.replay(); + chain.add(p); + chain.doIntercept(message); + } + + @Test + public void testSingleInterceptorFailWithoutCustomLogger() throws Exception { + AbstractPhaseInterceptor p = setUpPhaseInterceptor("phase1", "p1"); + setUpPhaseInterceptorInvocations(p, true, true); + setUpCustomLogger(false, true, false); + control.replay(); + chain.add(p); + chain.doIntercept(message); + } + + @Test public void testTwoInterceptorsInSamePhasePass() throws Exception { AbstractPhaseInterceptor p1 = setUpPhaseInterceptor("phase1", "p1"); setUpPhaseInterceptorInvocations(p1, false, false); @@ -412,6 +444,33 @@ } } + private void setUpCustomLogger(boolean useCustomLogger, + boolean expectFault, + boolean returnFromCustomLogger) { + if (useCustomLogger) { + FaultLogger customLogger = control.createMock(FaultLogger.class); + message.getContextualProperty(FaultLogger.class.getName()); + EasyMock.expectLastCall().andReturn(customLogger); + if (expectFault) { + customLogger.log(EasyMock.isA(Exception.class), + EasyMock.isA(String.class), + EasyMock.isA(Message.class)); + EasyMock.expectLastCall().andReturn(returnFromCustomLogger); + if (returnFromCustomLogger) { + //default logging should also be invoked + //not too beautiful way to verify that defaultLogging was invoked. + message.get(FaultMode.class); + EasyMock.expectLastCall().andReturn(FaultMode.RUNTIME_FAULT); + } + } + } else { + message.getContextualProperty(FaultLogger.class.getName()); + EasyMock.expectLastCall().andReturn(null); + } + + } + + public class InsertingPhaseInterceptor extends AbstractPhaseInterceptor<Message> { int invoked;
