You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by sb...@apache.org on 2011/12/12 12:55:02 UTC
svn commit: r1213196 [1/2] - in /james/server/trunk/util: ./
src/main/java/org/apache/james/util/retry/
src/main/java/org/apache/james/util/retry/api/
src/main/java/org/apache/james/util/retry/naming/
src/main/java/org/apache/james/util/retry/naming/di...
Author: sbrewin
Date: Mon Dec 12 11:55:01 2011
New Revision: 1213196
URL: http://svn.apache.org/viewvc?rev=1213196&view=rev
Log:
JAMES-1352 Supporting utility classes implementing a generic retry mechanism
Added:
james/server/trunk/util/src/main/java/org/apache/james/util/retry/
james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/
james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java (with props)
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/
james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java (with props)
james/server/trunk/util/src/test/java/org/apache/james/util/retry/
james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java (with props)
james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java (with props)
james/server/trunk/util/src/test/java/org/apache/james/util/retry/naming/
james/server/trunk/util/src/test/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandlerTest.java (with props)
Modified:
james/server/trunk/util/pom.xml
Modified: james/server/trunk/util/pom.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/util/pom.xml?rev=1213196&r1=1213195&r2=1213196&view=diff
==============================================================================
--- james/server/trunk/util/pom.xml (original)
+++ james/server/trunk/util/pom.xml Mon Dec 12 11:55:01 2011
@@ -51,6 +51,10 @@
<artifactId>${javax.mail.artifactId}</artifactId>
</dependency>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry;
+
+import org.apache.james.util.retry.api.RetrySchedule;
+
+
+/**
+ * <code>DoublingRetrySchedule</code> is an implementation of <code>RetrySchedule</code> that
+ * returns the lesser of an interval that is double the proceeding interval and the maximum interval.
+ *
+ * <p>When the initial interval is 0, the next interval is 1.
+ *
+ * <p>A multiplier can be specified to scale the results.
+ */
+/**
+ * <code>DoublingRetrySchedule</code>
+ */
+public class DoublingRetrySchedule implements RetrySchedule {
+
+ private long _startInterval = 0;
+ private long _maxInterval = 0;
+ private long _multiplier = 1;
+
+ /**
+ * Creates a new instance of DoublingRetrySchedule.
+ *
+ */
+ private DoublingRetrySchedule() {
+ }
+
+ /**
+ * Creates a new instance of DoublingRetrySchedule.
+ *
+ * @param startInterval
+ * The interval for an index of 0
+ * @param maxInterval
+ * The maximum interval for any index
+ */
+ public DoublingRetrySchedule(long startInterval, long maxInterval) {
+ this(startInterval, maxInterval, 1);
+ }
+
+ /**
+ * Creates a new instance of DoublingRetrySchedule.
+ *
+ * @param startInterval
+ * The interval for an index of 0
+ * @param maxInterval
+ * The maximum interval for any index
+ * @param multiplier
+ * The multiplier to apply to the result
+ */
+ public DoublingRetrySchedule(long startInterval, long maxInterval, int multiplier) {
+ this();
+ _startInterval = Math.max(0, startInterval);
+ _maxInterval = Math.max(0, maxInterval);
+ _multiplier = Math.max(1, multiplier);
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.RetrySchedule#getInterval(int)
+ */
+ @Override
+ public long getInterval(int index) {
+ if (_startInterval > 0)
+ {
+ return getInterval(index, _startInterval);
+ }
+ return index == 0 ? 0 : getInterval(index - 1, 1);
+ }
+
+ private long getInterval(int index, long startInterval) {
+ return _multiplier * Math.min((long) (startInterval * Math.pow(2, index)), _maxInterval);
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("DoublingRetrySchedule [startInterval=").append(_startInterval).append(
+ ", maxInterval=").append(_maxInterval).append(", multiplier=").append(_multiplier).append("]");
+ return builder.toString();
+ }
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/DoublingRetrySchedule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry;
+
+import org.apache.james.util.retry.api.ExceptionRetryingProxy;
+import org.apache.james.util.retry.api.RetryHandler;
+import org.apache.james.util.retry.api.RetrySchedule;
+
+/**
+ * Abstract class <code>ExceptionRetryHandler</code> retries the behaviour defined in abstract method
+ * <code>operation()</code> implemented in a concrete subclass when nominated subclasses of <code>Exception</code>
+ * are thrown. The intervals between retries are defined by a <code>RetrySchedule</code>.
+ * <p>
+ * Concrete subclasses are proxies that forward work via the <code>operation()</code> to a delegate
+ * instance for which retry behaviour is required. Both the proxy and the delegate implement the
+ * same interfaces.
+ * <p>
+ * The method stubs required to perform the proxy call via <code>operation()</code> may be generated by many means,
+ * including explicit code, a <code>DynamicProxy</code> and compile time aspect injection.
+ *
+ * @see org.apache.james.util.retry.naming.RetryingContext
+ */
+abstract public class ExceptionRetryHandler implements RetryHandler {
+ private Class<?>[] _exceptionClasses = null;
+
+ private ExceptionRetryingProxy _proxy = null;
+ private RetrySchedule _schedule;
+ private int _maxRetries = 0;
+
+ /**
+ * Creates a new instance of ExceptionRetryHandler.
+ *
+ */
+ private ExceptionRetryHandler() {
+ super();
+ }
+
+
+ /**
+ * Creates a new instance of ExceptionRetryHandler.
+ *
+ * @param exceptionClasses
+ * @param proxy
+ * @param maxRetries
+ */
+ public ExceptionRetryHandler(Class<?>[] exceptionClasses, ExceptionRetryingProxy proxy, RetrySchedule schedule, int maxRetries) {
+ this();
+ _exceptionClasses = exceptionClasses;
+ _proxy = proxy;
+ _schedule = schedule;
+ _maxRetries = maxRetries;
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.RetryHandler#perform()
+ */
+ public Object perform() throws Exception {
+ boolean success = false;
+ Object result = null;
+ int retryCount = 0;
+ while (!success) {
+ try {
+ if (retryCount > 0) {
+ _proxy.resetDelegate();
+ }
+ result = operation();
+ success = true;
+
+ }
+ catch (Exception ex) {
+ if (retryCount >= _maxRetries || !isRetryable(ex)) {
+ throw ex;
+ }
+ postFailure(ex, retryCount);
+ try {
+ Thread.sleep(getRetryInterval(retryCount));
+ } catch (InterruptedException ex1) {
+ // no-op
+ }
+ retryCount = _maxRetries < 0 ? _maxRetries
+ : retryCount + 1;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param ex
+ * The <code>Throwable</code> to test
+ *
+ * @return true if the array of exception classes contains <strong>ex</strong>
+ */
+ private boolean isRetryable(Throwable ex)
+ {
+ boolean isRetryable = false;
+ for (int i = 0; !isRetryable && i < _exceptionClasses.length; i++ )
+ {
+ isRetryable = _exceptionClasses[i].isInstance(ex);
+ }
+ return isRetryable;
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.RetryHandler#postFailure(javax.naming.NamingException, int)
+ */
+ public void postFailure(Exception ex, int retryCount)
+ {
+ // no-op
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.RetryHandler#operation()
+ */
+ abstract public Object operation() throws Exception;
+
+ /**
+ * @return the retryInterval
+ */
+ public long getRetryInterval(int retryCount) {
+ return _schedule.getInterval(retryCount);
+ }
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/ExceptionRetryHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.api;
+
+
+/**
+ * <code>ExceptionRetryingProxy</code> defines the behaviour for a
+ * proxy that can retry <codeException</code> and its subclasses.
+ */
+public interface ExceptionRetryingProxy {
+ /**
+ * @return a new instance that the proxy delegates to
+ * @throws Exception
+ */
+ abstract public Object newDelegate() throws Exception;
+
+ /**
+ * @return the current instance of the proxy delegate
+ * @throws Exception
+ */
+ abstract public Object getDelegate() throws Exception;
+
+ /**
+ * Resets the delegate instance to a state from which it can perform the
+ * operations delegated to it.
+ *
+ * @throws Exception
+ */
+ abstract public void resetDelegate() throws Exception;
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/ExceptionRetryingProxy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.api;
+
+
+/**
+ * <code>RetryHandler</code>
+ */
+public interface RetryHandler {
+
+ /**
+ * @return the result of invoking an operation
+ * @throws Exception
+ */
+ public abstract Object perform() throws Exception;
+
+ /**
+ * A hook invoked each time an operation fails if a retry is scheduled
+ *
+ * @param ex
+ * The <code>Exception</code> thrown when the operation was invoked
+ * @param retryCount
+ * The number of times
+ */
+ public abstract void postFailure(Exception ex, int retryCount);
+
+ /**
+ * Encapsulates desired behaviour
+ * @return The result of performing the behaviour
+ * @throws Exception
+ */
+ abstract public Object operation() throws Exception;
+
+}
\ No newline at end of file
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetryHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.api;
+
+/**
+ * <code>RetrySchedule</code>
+ */
+public interface RetrySchedule {
+ /**
+ * Returns the interval time in milliseconds at the specified zero based index.
+ *
+ * @param index
+ * @return
+ */
+ public long getInterval(int index);
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/api/RetrySchedule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.naming;
+
+import javax.naming.NamingException;
+
+import org.apache.james.util.retry.api.ExceptionRetryingProxy;
+import org.apache.james.util.retry.api.RetrySchedule;
+import org.slf4j.Logger;
+
+/**
+ * Abstract class <code>LoggingRetryHandler</code> implements logging of failures
+ */
+abstract public class LoggingRetryHandler extends NamingExceptionRetryHandler {
+
+ private Logger _logger = null;
+
+ /**
+ * Creates a new instance of LoggingRetryHandler.
+ *
+ * @param exceptionClasses
+ * @param proxy
+ * @param maxRetries
+ * @param retryInterval
+ * @param logger
+ */
+ public LoggingRetryHandler(Class<?>[] exceptionClasses, ExceptionRetryingProxy proxy,
+ RetrySchedule schedule, int maxRetries, Logger logger) {
+ super(exceptionClasses, proxy, schedule, maxRetries);
+ _logger = logger;
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.AbstractRetryHandler1#postFailure(javax.naming.NamingException, int)
+ */
+ @Override
+ public void postFailure(NamingException ex, int retryCount) {
+ super.postFailure(ex, retryCount);
+ _logger.info(
+ new StringBuilder("Retry failure: ").
+ append(ex.getLocalizedMessage()).
+ append("\n Retrying in ").
+ append(getRetryInterval(retryCount)/1000).
+ append(" seconds").
+ toString()
+ );
+ }
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/LoggingRetryHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.naming;
+
+import javax.naming.NamingException;
+
+import org.apache.james.util.retry.ExceptionRetryHandler;
+import org.apache.james.util.retry.api.ExceptionRetryingProxy;
+import org.apache.james.util.retry.api.RetrySchedule;
+
+/**
+ * Abstract class <code>NamingExceptionRetryHandler</code> narrows the set of Exceptions throwable
+ * by <code>perform</code> to <code>NamingException</code> and its subclasses.
+ * <p><code>RuntimeException</code>s are <strong>not</strong> retried.
+ *
+ * @see org.apache.james.user.ldap.ExceptionRetryHandler
+ *
+ */
+abstract public class NamingExceptionRetryHandler extends ExceptionRetryHandler {
+
+ /**
+ * Creates a new instance of NamingExceptionRetryHandler.
+ *
+ * @param exceptionClasses
+ * @param proxy
+ * @param schedule
+ * @param maxRetries
+ */
+ public NamingExceptionRetryHandler(Class<?>[] exceptionClasses, ExceptionRetryingProxy proxy,
+ RetrySchedule schedule, int maxRetries) {
+ super(exceptionClasses, proxy, schedule, maxRetries);
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.ExceptionRetryHandler#perform()
+ */
+ @Override
+ public Object perform() throws NamingException {
+ try {
+ return super.perform();
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ // Should only ever be a NamingException
+ throw ((NamingException) ex);
+ }
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.RetryHandler#postFailure(java.lang.Exception, int)
+ */
+ @Override
+ public void postFailure(Exception ex, int retryCount) {
+ postFailure(((NamingException) ex), retryCount);
+ }
+
+ public void postFailure(NamingException ex, int retryCount)
+ {
+ // no-op
+ }
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/NamingExceptionRetryHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,602 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.naming;
+
+import java.util.Hashtable;
+
+import javax.naming.Binding;
+import javax.naming.CommunicationException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.ServiceUnavailableException;
+
+import org.apache.james.util.retry.api.ExceptionRetryingProxy;
+import org.apache.james.util.retry.api.RetrySchedule;
+import org.slf4j.Logger;
+
+/**
+ * <code>RetryingContext</code> retries the methods defined by <code>javax.naming.Context</code>
+ * according to the specified schedule.
+ *
+ * @see org.apache.james.util.retry.ExceptionRetryHandler
+ * @see org.apache.james.util.retry.api.ExceptionRetryingProxy
+ * @see javax.naming.Context
+ */
+abstract public class RetryingContext implements Context, ExceptionRetryingProxy {
+
+ static public final Class<?>[] DEFAULT_EXCEPTION_CLASSES = new Class<?>[] {
+ CommunicationException.class,
+ ServiceUnavailableException.class };
+
+ private Context _delegate = null;
+ private RetrySchedule _schedule = null;
+ private int _maxRetries = 0;
+ private Logger _logger = null;
+
+ /**
+ * Creates a new instance of RetryingContext.
+ *
+ * @throws NamingException
+ *
+ */
+ private RetryingContext() throws NamingException {
+ super();
+ }
+
+ /**
+ * Creates a new instance of RetryingContext using the default exception
+ * classes thrown when an external interruption to services on which we
+ * depend occurs.
+ *
+ * @param schedule
+ * @param maxRetries
+ * @param logger
+ * @throws NamingException
+ */
+ public RetryingContext(final RetrySchedule schedule, final int maxRetries, final Logger logger)
+ throws NamingException {
+ this(DEFAULT_EXCEPTION_CLASSES, schedule, maxRetries, logger);
+ }
+
+ /**
+ * Creates a new instance of RetryingContext.
+ *
+ * @param exceptionClasses
+ * @param schedule
+ * @param maxRetries
+ * @param logger
+ * @throws NamingException
+ */
+ public RetryingContext(final Class<?>[] exceptionClasses, final RetrySchedule schedule, final int maxRetries, final Logger logger)
+ throws NamingException {
+ this();
+ _schedule = schedule;
+ _maxRetries = maxRetries;
+ _logger = logger;
+ _delegate = (Context) new LoggingRetryHandler(exceptionClasses, this,
+ _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws Exception {
+ return newDelegate();
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#addToEnvironment(java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public Object addToEnvironment(final String propName, final Object propVal)
+ throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().addToEnvironment(propName, propVal);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
+ */
+ @Override
+ public void bind(final Name name, final Object obj) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().bind(name, obj);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void bind(final String name, final Object obj) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().bind(name, obj);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#close()
+ */
+ @Override
+ public void close() throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().close();
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#composeName(javax.naming.Name,
+ * javax.naming.Name)
+ */
+ @Override
+ public Name composeName(final Name name, final Name prefix) throws NamingException {
+ return (Name) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().composeName(name, prefix);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
+ */
+ @Override
+ public String composeName(final String name, final String prefix) throws NamingException {
+ return (String) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().composeName(name, prefix);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#createSubcontext(javax.naming.Name)
+ */
+ @Override
+ public Context createSubcontext(final Name name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Context newDelegate() throws NamingException {
+ return context.createSubcontext(name);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.Context#createSubcontext(java.lang.String)
+ */
+ @Override
+ public Context createSubcontext(final String name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingContext( getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Context newDelegate() throws NamingException {
+ return context.createSubcontext(name);
+ }
+ };
+ }
+
+ /**
+ * @return
+ * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
+ */
+ @Override
+ public void destroySubcontext(final Name name) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().destroySubcontext(name);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#destroySubcontext(java.lang.String)
+ */
+ @Override
+ public void destroySubcontext(final String name) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().destroySubcontext(name);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#getEnvironment()
+ */
+ @Override
+ public Hashtable<?, ?> getEnvironment() throws NamingException {
+ return (Hashtable<?, ?>) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().getEnvironment();
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#getNameInNamespace()
+ */
+ @Override
+ public String getNameInNamespace() throws NamingException {
+ return (String) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().getNameInNamespace();
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#getNameParser(javax.naming.Name)
+ */
+ @Override
+ public NameParser getNameParser(final Name name) throws NamingException {
+ return (NameParser) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().getNameParser(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#getNameParser(java.lang.String)
+ */
+ @Override
+ public NameParser getNameParser(final String name) throws NamingException {
+ return (NameParser) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().getNameParser(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#list(javax.naming.Name)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<NameClassPair> list(final Name name) throws NamingException {
+ return (NamingEnumeration<NameClassPair>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().list(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#list(java.lang.String)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<NameClassPair> list(final String name) throws NamingException {
+ return (NamingEnumeration<NameClassPair>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().list(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#listBindings(javax.naming.Name)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<Binding> listBindings(final Name name) throws NamingException {
+ return (NamingEnumeration<Binding>) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES,
+ this, _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().listBindings(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#listBindings(java.lang.String)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<Binding> listBindings(final String name) throws NamingException {
+ return (NamingEnumeration<Binding>) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES,
+ this, _schedule, _maxRetries, _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().listBindings(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#lookup(javax.naming.Name)
+ */
+ @Override
+ public Object lookup(final Name name) throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().lookup(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#lookup(java.lang.String)
+ */
+ @Override
+ public Object lookup(final String name) throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().lookup(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#lookupLink(javax.naming.Name)
+ */
+ @Override
+ public Object lookupLink(final Name name) throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().lookupLink(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#lookupLink(java.lang.String)
+ */
+ @Override
+ public Object lookupLink(final String name) throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().lookupLink(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
+ */
+ @Override
+ public void rebind(final Name name, final Object obj) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().rebind(name, obj);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void rebind(final String name, final Object obj) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().rebind(name, obj);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
+ */
+ @Override
+ public Object removeFromEnvironment(final String propName) throws NamingException {
+ return new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return getDelegate().removeFromEnvironment(propName);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
+ */
+ @Override
+ public void rename(final Name oldName, final Name newName) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().rename(oldName, newName);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void rename(final String oldName, final String newName) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().rename(oldName, newName);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#unbind(javax.naming.Name)
+ */
+ @Override
+ public void unbind(final Name name) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().unbind(name);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.Context#unbind(java.lang.String)
+ */
+ @Override
+ public void unbind(final String name) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, _schedule, _maxRetries,
+ _logger) {
+
+ @Override
+ public Object operation() throws NamingException {
+ getDelegate().unbind(name);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.ExceptionRetryingProxy#getDelegate()
+ */
+ public Context getDelegate() {
+ return _delegate;
+ }
+
+
+ /**
+ * @see org.apache.james.user.ldap.api.ExceptionRetryingProxy#resetDelegate()
+ */
+ @Override
+ public void resetDelegate() throws Exception {
+ if (null != _delegate) {
+ _delegate.close();
+ }
+ _delegate = (Context)newDelegate();
+ }
+
+ /**
+ * @return the schedule
+ */
+ public RetrySchedule getSchedule() {
+ return _schedule;
+ }
+
+ /**
+ * @return the maxRetries
+ */
+ public int getMaxRetries() {
+ return _maxRetries;
+ }
+
+ /**
+ * @return the logger
+ */
+ public Logger getLogger() {
+ return _logger;
+ }
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/RetryingContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.naming.directory;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.james.util.retry.api.RetrySchedule;
+import org.apache.james.util.retry.naming.LoggingRetryHandler;
+import org.apache.james.util.retry.naming.RetryingContext;
+import org.slf4j.Logger;
+
+/**
+ * <code>RetryingDirContext</code> retries the methods defined by <code>javax.naming.directory.DirContext</code>
+ * according to the specified schedule.
+ *
+ * @see org.apache.james.util.retry.ExceptionRetryHandler
+ * @see org.apache.james.util.retry.api.ExceptionRetryingProxy
+ * @see javax.naming.directory.DirContext
+ */
+abstract public class RetryingDirContext extends RetryingContext implements DirContext {
+
+
+ /**
+ * Creates a new instance of RetryingDirContext.
+ *
+ * @param schedule
+ * @param maxRetries
+ * @param logger
+ * @throws NamingException
+ */
+ public RetryingDirContext(RetrySchedule schedule, int maxRetries, Logger logger)
+ throws NamingException {
+ super(schedule, maxRetries, logger);
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#bind(javax.naming.Name,
+ * java.lang.Object, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void bind(final Name name, final Object obj, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).bind(name, obj, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#bind(java.lang.String,
+ * java.lang.Object, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void bind(final String name, final Object obj, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).bind(name, obj, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name,
+ * javax.naming.directory.Attributes)
+ */
+ @Override
+ public DirContext createSubcontext(final Name name, final Attributes attrs)
+ throws NamingException {
+ return (DirContext) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).createSubcontext(name, attrs);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String,
+ * javax.naming.directory.Attributes)
+ */
+ @Override
+ public DirContext createSubcontext(final String name, final Attributes attrs)
+ throws NamingException {
+ return (DirContext) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).createSubcontext(name, attrs);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
+ */
+ @Override
+ public Attributes getAttributes(final Name name) throws NamingException {
+ return (Attributes) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).getAttributes(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
+ */
+ @Override
+ public Attributes getAttributes(final String name) throws NamingException {
+ return (Attributes) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).getAttributes(name);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name,
+ * java.lang.String[])
+ */
+ @Override
+ public Attributes getAttributes(final Name name, final String[] attrIds) throws NamingException {
+ return (Attributes) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).getAttributes(name, attrIds);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getAttributes(java.lang.String,
+ * java.lang.String[])
+ */
+ @Override
+ public Attributes getAttributes(final String name, final String[] attrIds)
+ throws NamingException {
+ return (Attributes) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this,
+ getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).getAttributes(name, attrIds);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
+ */
+ @Override
+ public DirContext getSchema(final Name name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingDirContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public DirContext newDelegate() throws NamingException {
+ return ((DirContext) context).getSchema(name);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getSchema(java.lang.String)
+ */
+ @Override
+ public DirContext getSchema(final String name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingDirContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public DirContext newDelegate() throws NamingException {
+ return ((DirContext) context).getSchema(name);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
+ */
+ @Override
+ public DirContext getSchemaClassDefinition(final Name name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingDirContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public DirContext newDelegate() throws NamingException {
+ return ((DirContext) context).getSchemaClassDefinition(name);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
+ */
+ @Override
+ public DirContext getSchemaClassDefinition(final String name) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingDirContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public DirContext newDelegate() throws NamingException {
+ return ((DirContext) context).getSchemaClassDefinition(name);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name,
+ * javax.naming.directory.ModificationItem[])
+ */
+ @Override
+ public void modifyAttributes(final Name name, final ModificationItem[] mods)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).modifyAttributes(name, mods);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
+ * javax.naming.directory.ModificationItem[])
+ */
+ @Override
+ public void modifyAttributes(final String name, final ModificationItem[] mods)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).modifyAttributes(name, mods);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name,
+ * int, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void modifyAttributes(final Name name, final int modOp, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).modifyAttributes(name, modOp, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
+ * int, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void modifyAttributes(final String name, final int modOp, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).modifyAttributes(name, modOp, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#rebind(javax.naming.Name,
+ * java.lang.Object, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void rebind(final Name name, final Object obj, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).rebind(name, obj, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#rebind(java.lang.String,
+ * java.lang.Object, javax.naming.directory.Attributes)
+ */
+ @Override
+ public void rebind(final String name, final Object obj, final Attributes attrs)
+ throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(),
+ getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ ((DirContext) getDelegate()).rebind(name, obj, attrs);
+ return null;
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name,
+ * javax.naming.directory.Attributes)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final Name name,
+ final Attributes matchingAttributes)
+ throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, matchingAttributes);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(java.lang.String,
+ * javax.naming.directory.Attributes)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final String name,
+ final Attributes matchingAttributes)
+ throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, matchingAttributes);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name,
+ * javax.naming.directory.Attributes, java.lang.String[])
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final Name name,
+ final Attributes matchingAttributes,
+ String[] attributesToReturn) throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, matchingAttributes);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(java.lang.String,
+ * javax.naming.directory.Attributes, java.lang.String[])
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final String name,
+ final Attributes matchingAttributes,
+ final String[] attributesToReturn) throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, matchingAttributes,
+ attributesToReturn);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name,
+ * java.lang.String, javax.naming.directory.SearchControls)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final Name name, final String filter,
+ final SearchControls cons)
+ throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, filter, cons);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(java.lang.String,
+ * java.lang.String, javax.naming.directory.SearchControls)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final String name, final String filter,
+ final SearchControls cons)
+ throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, filter, cons);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name,
+ * java.lang.String, java.lang.Object[],
+ * javax.naming.directory.SearchControls)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final Name name, final String filterExpr,
+ final Object[] filterArgs, final SearchControls cons) throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, filterExpr, filterArgs, cons);
+ }
+ }.perform();
+ }
+
+ /**
+ * @see javax.naming.directory.DirContext#search(java.lang.String,
+ * java.lang.String, java.lang.Object[],
+ * javax.naming.directory.SearchControls)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NamingEnumeration<SearchResult> search(final String name, final String filterExpr,
+ final Object[] filterArgs, final SearchControls cons) throws NamingException {
+ return (NamingEnumeration<SearchResult>) new LoggingRetryHandler(
+ DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((DirContext) getDelegate()).search(name, filterExpr, filterArgs, cons);
+ }
+ }.perform();
+ }
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/directory/RetryingDirContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java (added)
+++ james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry.naming.ldap;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.ExtendedRequest;
+import javax.naming.ldap.ExtendedResponse;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.james.util.retry.api.RetrySchedule;
+import org.apache.james.util.retry.naming.LoggingRetryHandler;
+import org.apache.james.util.retry.naming.directory.RetryingDirContext;
+import org.slf4j.Logger;
+
+/**
+ * <code>RetryingLdapContext</code> retries the methods defined by <code>javax.naming.ldap.LdapContext</code>
+ * according to the specified schedule.
+ *
+ * @see org.apache.james.util.retry.ExceptionRetryHandler
+ * @see org.apache.james.util.retry.api.ExceptionRetryingProxy
+ * @see javax.naming.ldap.LdapContext
+ */
+abstract public class RetryingLdapContext extends RetryingDirContext implements LdapContext {
+
+ /**
+ * Creates a new instance of RetryingLdapContext.
+ *
+ * @param maxRetries
+ * @param retryInterval
+ * @throws NamingException
+ */
+ public RetryingLdapContext(RetrySchedule schedule, int maxRetries, Logger logger) throws NamingException {
+ super(schedule, maxRetries, logger);
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#extendedOperation(javax.naming.ldap.ExtendedRequest)
+ */
+ @Override
+ public ExtendedResponse extendedOperation(final ExtendedRequest request) throws NamingException {
+ return (ExtendedResponse) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((LdapContext) getDelegate()).extendedOperation(request);
+ }}.perform();
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#getConnectControls()
+ */
+ @Override
+ public Control[] getConnectControls() throws NamingException {
+ return (Control[]) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((LdapContext) getDelegate()).getConnectControls();
+ }}.perform();
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#getRequestControls()
+ */
+ @Override
+ public Control[] getRequestControls() throws NamingException {
+ return (Control[]) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((LdapContext) getDelegate()).getRequestControls();
+ }}.perform();
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#getResponseControls()
+ */
+ @Override
+ public Control[] getResponseControls() throws NamingException {
+ return (Control[]) new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ return ((LdapContext) getDelegate()).getResponseControls();
+ }}.perform();
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#newInstance(javax.naming.ldap.Control[])
+ */
+ @Override
+ public LdapContext newInstance(final Control[] requestControls) throws NamingException {
+ final Context context = getDelegate();
+ return new RetryingLdapContext(getSchedule(), getMaxRetries(), getLogger()) {
+
+ @Override
+ public Context newDelegate() throws NamingException {
+ return ((LdapContext) context).newInstance(requestControls);
+ }
+ };
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#reconnect(javax.naming.ldap.Control[])
+ */
+ @Override
+ public void reconnect(final Control[] connCtls) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ ((LdapContext) getDelegate()).reconnect(connCtls);
+ return null;
+ }}.perform();
+ }
+
+ /**
+ * @see javax.naming.ldap.LdapContext#setRequestControls(javax.naming.ldap.Control[])
+ */
+ @Override
+ public void setRequestControls(final Control[] requestControls) throws NamingException {
+ new LoggingRetryHandler(DEFAULT_EXCEPTION_CLASSES, this, getSchedule(), getMaxRetries(), getLogger()){
+
+ @Override
+ public Object operation() throws NamingException {
+ ((LdapContext) getDelegate()).setRequestControls(requestControls);
+ return null;
+ }}.perform();
+ }
+
+}
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/main/java/org/apache/james/util/retry/naming/ldap/RetryingLdapContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java (added)
+++ james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry;
+
+
+import org.apache.james.util.retry.api.RetrySchedule;
+
+import junit.framework.TestCase;
+
+/**
+ * <code>DoublingRetryScheduleTest</code>
+ */
+public class DoublingRetryScheduleTest extends TestCase {
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.DoublingRetrySchedule#DoublingRetrySchedule(long, long)}.
+ */
+ public final void testDoublingRetrySchedule() {
+ assertTrue(RetrySchedule.class.isAssignableFrom(new DoublingRetrySchedule(0,0).getClass()));
+ assertEquals(0, new DoublingRetrySchedule(0, 0).getInterval(0));
+ assertEquals(0, new DoublingRetrySchedule(-1, -1).getInterval(0));
+ assertEquals(0, new DoublingRetrySchedule(-1, 0).getInterval(0));
+ assertEquals(0, new DoublingRetrySchedule(0, -1).getInterval(0));
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.DoublingRetrySchedule#getInterval(int)}.
+ */
+ public final void testGetInterval() {
+ assertEquals(0, new DoublingRetrySchedule(0, 8).getInterval(0));
+ assertEquals(1, new DoublingRetrySchedule(0, 8).getInterval(1));
+ assertEquals(2, new DoublingRetrySchedule(0, 8).getInterval(2));
+ assertEquals(4, new DoublingRetrySchedule(0, 8).getInterval(3));
+ assertEquals(8, new DoublingRetrySchedule(0, 8).getInterval(4));
+ assertEquals(8, new DoublingRetrySchedule(0, 8).getInterval(5));
+
+ assertEquals(1, new DoublingRetrySchedule(1, 8).getInterval(0));
+ assertEquals(2, new DoublingRetrySchedule(1, 8).getInterval(1));
+ assertEquals(4, new DoublingRetrySchedule(1, 8).getInterval(2));
+ assertEquals(8, new DoublingRetrySchedule(1, 8).getInterval(3));
+ assertEquals(8, new DoublingRetrySchedule(1, 8).getInterval(4));
+
+ assertEquals(3, new DoublingRetrySchedule(3, 12).getInterval(0));
+ assertEquals(6, new DoublingRetrySchedule(3, 12).getInterval(1));
+ assertEquals(12, new DoublingRetrySchedule(3, 12).getInterval(2));
+ assertEquals(12, new DoublingRetrySchedule(3, 12).getInterval(3));
+
+ assertEquals(0, new DoublingRetrySchedule(0, 8, 1000).getInterval(0));
+ assertEquals(1000, new DoublingRetrySchedule(0, 8, 1000).getInterval(1));
+ assertEquals(2000, new DoublingRetrySchedule(0, 8, 1000).getInterval(2));
+ assertEquals(4000, new DoublingRetrySchedule(0, 8, 1000).getInterval(3));
+ assertEquals(8000, new DoublingRetrySchedule(0, 8, 1000).getInterval(4));
+ assertEquals(8000, new DoublingRetrySchedule(0, 8, 1000).getInterval(5));
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.DoublingRetrySchedule#toString()}.
+ */
+ public final void testToString() {
+ assertEquals("DoublingRetrySchedule [startInterval=0, maxInterval=1, multiplier=1]", new DoublingRetrySchedule(0, 1).toString());
+ }
+
+}
Propchange: james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/test/java/org/apache/james/util/retry/DoublingRetryScheduleTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java?rev=1213196&view=auto
==============================================================================
--- james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java (added)
+++ james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java Mon Dec 12 11:55:01 2011
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.james.util.retry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.Context;
+
+import org.apache.james.util.retry.api.ExceptionRetryingProxy;
+import org.apache.james.util.retry.api.RetryHandler;
+import org.apache.james.util.retry.api.RetrySchedule;
+
+import junit.framework.TestCase;
+
+/**
+ * <code>ExceptionRetryHandlerTest</code>
+ */
+public class ExceptionRetryHandlerTest extends TestCase {
+
+ private Class<?>[] _exceptionClasses = null;
+ private ExceptionRetryingProxy _proxy = null;
+ private RetrySchedule _schedule = null;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ _exceptionClasses = new Class<?>[]{Exception.class};
+ _proxy = new TestRetryingProxy();
+ _schedule = new TestRetrySchedule();
+ }
+
+ private class TestRetryingProxy implements ExceptionRetryingProxy
+ {
+
+ /**
+ * @see org.apache.james.user.ldap.api.ExceptionRetryingProxy#getDelegate()
+ */
+ @Override
+ public Context getDelegate() throws Exception {
+ return null;
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.ExceptionRetryingProxy#newDelegate()
+ */
+ @Override
+ public Context newDelegate() throws Exception {
+ return null;
+ }
+
+ /**
+ * @see org.apache.james.user.ldap.api.ExceptionRetryingProxy#resetDelegate()
+ */
+ @Override
+ public void resetDelegate() throws Exception {
+
+ }
+
+ }
+
+ private class TestRetrySchedule implements RetrySchedule
+ {
+ /**
+ * @see org.apache.james.user.ldap.api.RetrySchedule#getInterval(int)
+ */
+ @Override
+ public long getInterval(int index) {
+ return index;
+ }
+
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.ExceptionRetryHandler#ExceptionRetryHandler(java.lang.Class<?>[], org.apache.james.user.ldap.api.ExceptionRetryingProxy, org.apache.james.user.ldap.api.RetrySchedule, int)}.
+ */
+ public final void testExceptionRetryHandler() {
+ assertTrue(RetryHandler.class.isAssignableFrom(new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 0) {
+
+ @Override
+ public Object operation() throws Exception {
+ return null;
+ }
+ }.getClass()));
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.ExceptionRetryHandler#perform()}.
+ * @throws Exception
+ */
+ public final void testPerform() throws Exception {
+ Object result = new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 0) {
+
+ @Override
+ public Object operation() throws Exception {
+ return "Hi!";
+ }
+ }.perform();
+ assertEquals("Hi!", result);
+
+ try {
+ new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 0) {
+
+ @Override
+ public Object operation() throws Exception {
+ throw new Exception();
+ }
+ }.perform();
+ } catch (Exception ex) {
+ // no-op
+ }
+ assertEquals("Hi!", result);
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.ExceptionRetryHandler#postFailure(java.lang.Exception, int)}.
+ */
+ public final void testPostFailure() {
+ final List<Exception> results = new ArrayList<Exception>();
+ RetryHandler handler = new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 7) {
+
+ @Override
+ public void postFailure(Exception ex, int retryCount) {
+ super.postFailure(ex, retryCount);
+ results.add(ex);
+ }
+
+ @Override
+ public Object operation() throws Exception {
+ throw new Exception();
+ }
+ };
+ try {
+ handler.perform();
+ } catch (Exception ex)
+ {
+ // no-op
+ }
+ assertEquals(7, results.size());
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.ExceptionRetryHandler#operation()}.
+ * @throws Exception
+ */
+ public final void testOperation() throws Exception {
+ RetryHandler handler = new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 0) {
+
+ @Override
+ public Object operation() throws Exception {
+ return "Hi!";
+ }
+ };
+ assertEquals("Hi!", handler.operation());
+ }
+
+ /**
+ * Test method for {@link org.apache.james.user.ldap.ExceptionRetryHandler#getRetryInterval(int)}.
+ */
+ public final void testGetRetryInterval() {
+ ExceptionRetryHandler handler = new ExceptionRetryHandler(
+ _exceptionClasses, _proxy, _schedule, 0) {
+
+ @Override
+ public Object operation() throws Exception {
+ return null;
+ }
+ };
+ assertEquals(8, handler.getRetryInterval(8));
+ }
+
+}
Propchange: james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/util/src/test/java/org/apache/james/util/retry/ExceptionRetryHandlerTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org