org.softamis.cluster4spring.support
Class RemoteClientInterceptor<E extends Endpoint<SI>,SI extends ServiceMoniker>

java.lang.Object
  extended by org.springframework.remoting.support.RemoteAccessor
      extended by org.softamis.cluster4spring.support.RemoteInvocationBasedAccessor
          extended by org.softamis.cluster4spring.support.RemoteClientInterceptor<E,SI>
Type Parameters:
SI - type of data used to invoke remote service (such as remote service URL)
E - type of endpoints that could be created by this factory
All Implemented Interfaces:
java.util.EventListener, org.aopalliance.aop.Advice, org.aopalliance.intercept.Interceptor, org.aopalliance.intercept.MethodInterceptor, org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.InitializingBean, org.springframework.context.ApplicationListener
Direct Known Subclasses:
RmiClientInterceptor

public abstract class RemoteClientInterceptor<E extends Endpoint<SI>,SI extends ServiceMoniker>
extends RemoteInvocationBasedAccessor
implements org.aopalliance.intercept.MethodInterceptor, org.springframework.beans.factory.InitializingBean, org.springframework.beans.factory.BeanNameAware, org.springframework.context.ApplicationListener

Interceptor for accessing remote services. It contains only general logic related to invoking remote services.

Author:
Andrew Sazonov

Field Summary
protected  java.lang.String fBeanName
          Name of proxy bean registered in spring context
protected  EndpointFactory<E,SI> fEndpointFactory
          Factory used to create endpoints
protected  EndpointProvider<E,SI> fEndpointProvider
          Provider for endpoints used for remote services invocation
protected static org.apache.commons.logging.Log fLog
           
protected  boolean fRefreshEndpointsOnConnectFailure
          Specifies whether endpoints provider should be refreshed if connection failure occurs
protected  boolean fRefreshEndpointsOnStartup
          Specifies whether endpoints should be refreshed on startup
protected  boolean fSwitchEndpointOnFailure
          Specifies whether different endpoint shoudl be selected if connection failure occurs
 
Fields inherited from class org.softamis.cluster4spring.support.RemoteInvocationBasedAccessor
fRemoteInvocationFactory
 
Fields inherited from class org.springframework.remoting.support.RemoteAccessor
logger
 
Constructor Summary
protected RemoteClientInterceptor()
           
 
Method Summary
 void afterPropertiesSet()
          Invoked by Spring as part of bean lifecycle and is used to check whether EndpointProvider is specified and perform other preparations
protected abstract  EndpointFactory<E,SI> createDefaultEndpointFactory()
          Creates default endpoint factory used to create endpoints.
protected  java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation aInvocation)
          First obtains endpoint for invocation.
protected abstract  java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation aInvocation, E aServiceEndpoint)
          Performs invocation of given method invocation using given service endpoint
protected  void doPreprocessApplicationEvent(org.springframework.context.ApplicationEvent aEvent)
          Utility method that is called during processing of application events.
 java.lang.String getBeanName()
          Returns name of proxy bean registered in spring context
protected  EndpointFactory<E,SI> getEndpointFactory()
          Returns factory used to create endpoints
protected abstract  java.lang.String getProtocol()
          Returns protocol which identifies interceptor.
protected  java.lang.Object handleRemoteConnectFailure(org.aopalliance.intercept.MethodInvocation aInvocation, java.lang.Exception aException, E aServiceEndpoint)
          Handles remote connection failure according to specified policies.
 java.lang.Object invoke(org.aopalliance.intercept.MethodInvocation aInvocation)
          Performs invocation of remote service method.
protected abstract  boolean isConnectFailure(org.springframework.remoting.RemoteAccessException aException)
          Utility method that is used to determine whether exception represents connect failure or is "normal" application logic specific exception.
 boolean isRefreshEndpointsOnConnectFailure()
          Returns trues if endpoints provider should be refreshed if connection failure occurs
 boolean isRefreshEndpointsOnStartup()
          Returns true if endpoints should be refreshed on startup
 boolean isSwitchEndpointOnFailure()
          Returns specifies whether different endpoint should be selected if connection failure occurs
protected  void markServiceInvalid(E aServiceEndpoint)
          Marks service denoted by given endpoint as invalid by calling by notifying EndpointProvider
protected  E obtainEndpointToExecute()
          Provides endpoint that should be used for remote service invocation.
 void onApplicationEvent(org.springframework.context.ApplicationEvent aEvent)
          Called by Spring and handles application events
protected  void onContextClosed()
          Handles ContextClosedEvent event.
protected  void onContextRefreshed()
          Handles ContextRefreshedEvent event.
 void prepare()
          Called as part of afterPropertiesSet() procedure and checks whether endpoint factory is specified.
protected  java.lang.Object refreshAndRetry(org.aopalliance.intercept.MethodInvocation aInvocation)
          Refreshes EndpointProvider and tries to invoke invocation again.
protected  void refreshEndpointProvider()
          Forces refresh of endpoint provider.
protected  java.lang.Object retry(org.aopalliance.intercept.MethodInvocation aInvocation)
          Invokes given method invocation.
 void setBeanName(java.lang.String aName)
          Sets name of proxy bean registered in spring context
protected  void setEndpointFactory(EndpointFactory<E,SI> aEndpointFactory)
          Sets factory used to create endpoints.
protected  void setEndpointProvider(EndpointProvider<E,SI> aEndpointProvider)
          Sets provider for endpoints used for remote services invocation
 void setRefreshEndpointsOnConnectFailure(boolean aRefreshOnFailure)
          Set whether to refresh the endpoints on connect failure.
 void setRefreshEndpointsOnStartup(boolean aRefreshEndpointsOnStartup)
          Sets whether endpoints should be refreshed on startup

Default is true

 void setSwitchEndpointOnFailure(boolean aSwitchEndpointOnFailure)
          Set whether to switch endponts on connect failure (ignore connect failure and simply select different endpoint, if any).
protected  void throwRemoteLookupFailureException(java.lang.Throwable aException)
          Utility name used to throw RemoteLookupFailureException
protected  void throwServiceException(org.springframework.remoting.RemoteAccessException aException)
          Utility method that is used to throw reason of RemoteAccessException (if any) or given exception itself.
 
Methods inherited from class org.softamis.cluster4spring.support.RemoteInvocationBasedAccessor
getRemoteInvocationFactory, setRemoteInvocationFactory
 
Methods inherited from class org.springframework.remoting.support.RemoteAccessor
getServiceInterface, setServiceInterface
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

fLog

protected static final org.apache.commons.logging.Log fLog

fBeanName

protected java.lang.String fBeanName
Name of proxy bean registered in spring context


fEndpointProvider

protected EndpointProvider<E extends Endpoint<SI>,SI extends ServiceMoniker> fEndpointProvider
Provider for endpoints used for remote services invocation


fEndpointFactory

protected EndpointFactory<E extends Endpoint<SI>,SI extends ServiceMoniker> fEndpointFactory
Factory used to create endpoints


fRefreshEndpointsOnConnectFailure

protected boolean fRefreshEndpointsOnConnectFailure
Specifies whether endpoints provider should be refreshed if connection failure occurs


fSwitchEndpointOnFailure

protected boolean fSwitchEndpointOnFailure
Specifies whether different endpoint shoudl be selected if connection failure occurs


fRefreshEndpointsOnStartup

protected boolean fRefreshEndpointsOnStartup
Specifies whether endpoints should be refreshed on startup

Constructor Detail

RemoteClientInterceptor

protected RemoteClientInterceptor()
Method Detail

afterPropertiesSet

public void afterPropertiesSet()
                        throws java.lang.Exception
Invoked by Spring as part of bean lifecycle and is used to check whether EndpointProvider is specified and perform other preparations

Specified by:
afterPropertiesSet in interface org.springframework.beans.factory.InitializingBean
Throws:
java.lang.Exception

prepare

public void prepare()
Called as part of afterPropertiesSet() procedure and checks whether endpoint factory is specified. If one is not specified, creates default one.


onApplicationEvent

public void onApplicationEvent(org.springframework.context.ApplicationEvent aEvent)
Called by Spring and handles application events

Specified by:
onApplicationEvent in interface org.springframework.context.ApplicationListener
Parameters:
aEvent - application event

doPreprocessApplicationEvent

protected void doPreprocessApplicationEvent(org.springframework.context.ApplicationEvent aEvent)
Utility method that is called during processing of application events. May be overriden to perform some specific processing

Parameters:
aEvent - application event
See Also:
onApplicationEvent(ApplicationEvent)

onContextRefreshed

protected void onContextRefreshed()
Handles ContextRefreshedEvent event. If specified by appropriate property, performs refreshing of endpoints.

See Also:
setRefreshEndpointsOnStartup(boolean), onApplicationEvent(ApplicationEvent)

onContextClosed

protected void onContextClosed()
Handles ContextClosedEvent event. May be overriden by inherited classes to add additional processing of this event.

See Also:
onApplicationEvent(ApplicationEvent)

refreshEndpointProvider

protected void refreshEndpointProvider()
                                throws org.springframework.remoting.RemoteAccessException
Forces refresh of endpoint provider.

Throws:
org.springframework.remoting.RemoteAccessException - thrown if occured during refreshing provider

invoke

public java.lang.Object invoke(org.aopalliance.intercept.MethodInvocation aInvocation)
                        throws java.lang.Throwable
Performs invocation of remote service method. Specially handles toString() method and delegates further processing to doInvoke()
Specified by:
invoke in interface org.aopalliance.intercept.MethodInterceptor
Parameters:
aInvocation - method invocation to invoke remote method
Returns:
result of method invocation
Throws:
java.lang.Throwable
See Also:
doInvoke(MethodInvocation)

doInvoke

protected java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation aInvocation)
                             throws java.lang.Throwable
First obtains endpoint for invocation. If exception occured during selecting endpoint and is configured to refresh endpoints on connect failure, tries to refresh endpoint provider and obtain endpoint again.

If endpoint if selected, thies to invoke it. If during invocation some exception occured, analyses exception and if this is connect failure, tries to handle it according to specified policies.

Parameters:
aInvocation - method invocation to invoke
Returns:
result of method invocation
Throws:
java.lang.Throwable - application logic specific exception or RemoteAccessException
See Also:
RemoteAccessException, setRefreshEndpointsOnConnectFailure(boolean), setSwitchEndpointOnFailure(boolean), invoke(MethodInvocation), EndpointProvider

throwServiceException

protected void throwServiceException(org.springframework.remoting.RemoteAccessException aException)
                              throws java.lang.Throwable
Utility method that is used to throw reason of RemoteAccessException (if any) or given exception itself.

Parameters:
aException - exception to analyze
Throws:
java.lang.Throwable - reason of remote exception or given exception
See Also:
doInvoke(MethodInvocation)

handleRemoteConnectFailure

protected java.lang.Object handleRemoteConnectFailure(org.aopalliance.intercept.MethodInvocation aInvocation,
                                                      java.lang.Exception aException,
                                                      E aServiceEndpoint)
                                               throws java.lang.Throwable
Handles remote connection failure according to specified policies. First, it marks failed endpoint as invalid via EndpointProvider. Actual processing of failure depends on current configuration:
  • If is configured to refresh on connect failure, tries to refresh EndpointProvider and perform invocation again using fresh endpoint.
  • If is configured to switch endpoint of connect failure, performs invocation again using different endpoint
  • If no one options mentioned above is not set, simply rethrows the original exception.

Parameters:
aInvocation - the aInvocation that failed
aException - the exception raised on remote aInvocation
aServiceEndpoint - service endpoint with failed invocation
Returns:
the result value of the new aInvocation, if succeeded
Throws:
java.lang.Throwable - an exception raised by the new aInvocation, if failed too.
See Also:
markServiceInvalid(Endpoint), setRefreshEndpointsOnConnectFailure(boolean), setSwitchEndpointOnFailure(boolean), doInvoke(MethodInvocation)

refreshAndRetry

protected java.lang.Object refreshAndRetry(org.aopalliance.intercept.MethodInvocation aInvocation)
                                    throws java.lang.Throwable
Refreshes EndpointProvider and tries to invoke invocation again. Called by invoke on connect failure.

Parameters:
aInvocation - the AOP method aInvocation
Returns:
the aInvocation result, if any
Throws:
java.lang.Throwable - in case of aInvocation failure
See Also:
handleRemoteConnectFailure(org.aopalliance.intercept.MethodInvocation,Exception,Endpoint), doInvoke(org.aopalliance.intercept.MethodInvocation)

retry

protected java.lang.Object retry(org.aopalliance.intercept.MethodInvocation aInvocation)
                          throws java.lang.Throwable
Invokes given method invocation. Called by invoke on connect failure.

Parameters:
aInvocation - the AOP method aInvocation
Returns:
the aInvocation result, if any
Throws:
java.lang.Throwable - in case of aInvocation failure
See Also:
handleRemoteConnectFailure(org.aopalliance.intercept.MethodInvocation,Exception,Endpoint), doInvoke(org.aopalliance.intercept.MethodInvocation)

markServiceInvalid

protected void markServiceInvalid(E aServiceEndpoint)
Marks service denoted by given endpoint as invalid by calling by notifying EndpointProvider

Parameters:
aServiceEndpoint - service endpoint that should be invalidated
See Also:
doInvoke(MethodInvocation)

getProtocol

protected abstract java.lang.String getProtocol()
Returns protocol which identifies interceptor. Used for logging.

Returns:
protocol name

createDefaultEndpointFactory

protected abstract EndpointFactory<E,SI> createDefaultEndpointFactory()
Creates default endpoint factory used to create endpoints. Concrete implementation of interceptor will implement this method to impl particular cluster4spring protocol.

Returns:
EndpointFactory that should be used if one is is not specified explicitely

isConnectFailure

protected abstract boolean isConnectFailure(org.springframework.remoting.RemoteAccessException aException)
Utility method that is used to determine whether exception represents connect failure or is "normal" application logic specific exception.

Parameters:
aException - exception to analyze
Returns:
true if given exception represents connect failure

doInvoke

protected abstract java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation aInvocation,
                                             E aServiceEndpoint)
                                      throws java.lang.Throwable
Performs invocation of given method invocation using given service endpoint

Parameters:
aInvocation - the AOP method aInvocation
aServiceEndpoint - endpoint used for remote service invocation
Returns:
the aInvocation result, if any
Throws:
java.lang.Throwable - in case of aInvocation failure

obtainEndpointToExecute

protected E obtainEndpointToExecute()
                                                  throws org.springframework.remoting.RemoteLookupFailureException
Provides endpoint that should be used for remote service invocation. Simply delegates providing endpoints to used EndpointProvider.

Returns:
endpoint to invoke
Throws:
org.springframework.remoting.RemoteLookupFailureException - thrown if EndpointProvider is unable to provide endpoint

throwRemoteLookupFailureException

protected void throwRemoteLookupFailureException(java.lang.Throwable aException)
                                          throws org.springframework.remoting.RemoteLookupFailureException
Utility name used to throw RemoteLookupFailureException

Parameters:
aException - original exception
Throws:
org.springframework.remoting.RemoteLookupFailureException - thrown exception

setRefreshEndpointsOnConnectFailure

public void setRefreshEndpointsOnConnectFailure(boolean aRefreshOnFailure)
Set whether to refresh the endpoints on connect failure.

Default is false.

Can be turned on to allow for hot restart of the RMI server. If a cached RMI stub throws an RMI exception that indicates a remote connect failure, a fresh proxy will be fetched and the invocation will be retried.

Parameters:
aRefreshOnFailure - value of policy, if true - interceptor will refresh service endpoints if remote failure occured.

isSwitchEndpointOnFailure

public boolean isSwitchEndpointOnFailure()
Returns specifies whether different endpoint should be selected if connection failure occurs

Returns:
true if endpoint switch should be performed

setSwitchEndpointOnFailure

public void setSwitchEndpointOnFailure(boolean aSwitchEndpointOnFailure)
Set whether to switch endponts on connect failure (ignore connect failure and simply select different endpoint, if any).

Default is true

Parameters:
aSwitchEndpointOnFailure - specifies whether different endpoint shoudl be selected if connection failure occurs

setRefreshEndpointsOnStartup

public void setRefreshEndpointsOnStartup(boolean aRefreshEndpointsOnStartup)
Sets whether endpoints should be refreshed on startup

Default is true

Parameters:
aRefreshEndpointsOnStartup - specifies whether endpoints should be refreshed on startup

setBeanName

public void setBeanName(java.lang.String aName)
Sets name of proxy bean registered in spring context

Specified by:
setBeanName in interface org.springframework.beans.factory.BeanNameAware
Parameters:
aName - name of proxy bean

setEndpointProvider

protected void setEndpointProvider(EndpointProvider<E,SI> aEndpointProvider)
Sets provider for endpoints used for remote services invocation

Parameters:
aEndpointProvider - provider for endpoints

getEndpointFactory

protected EndpointFactory<E,SI> getEndpointFactory()
Returns factory used to create endpoints

Returns:
factory

setEndpointFactory

protected void setEndpointFactory(EndpointFactory<E,SI> aEndpointFactory)
Sets factory used to create endpoints. If factory is not set explicitely, default one will be created.

Parameters:
aEndpointFactory - factory used to create endpoints
See Also:
createDefaultEndpointFactory()

getBeanName

public java.lang.String getBeanName()
Returns name of proxy bean registered in spring context

Returns:
name of proxy bean

isRefreshEndpointsOnConnectFailure

public boolean isRefreshEndpointsOnConnectFailure()
Returns trues if endpoints provider should be refreshed if connection failure occurs

Returns:
specifies whether endpoints provider should be refreshed if connection failure occurs

isRefreshEndpointsOnStartup

public boolean isRefreshEndpointsOnStartup()
Returns true if endpoints should be refreshed on startup

Returns:
true if endpoints should be refreshed on startup