net.sf.sasl.aop.distributed.lock
Class DistributedLockAspect

java.lang.Object
  extended by net.sf.sasl.aop.AbstractRootAspect
      extended by net.sf.sasl.aop.distributed.lock.DistributedLockAspect
All Implemented Interfaces:
org.aopalliance.aop.Advice, org.aopalliance.intercept.Interceptor, org.aopalliance.intercept.MethodInterceptor, org.springframework.core.Ordered, org.springframework.core.PriorityOrdered

public class DistributedLockAspect
extends AbstractRootAspect
implements org.aopalliance.intercept.MethodInterceptor

The task that the aspect addresses is to provide a thread shared distributed lock session, if none exists for the current thread and to do static and dynamic distributed locks and unlocks, which have been declared via distributed lock annotations. So the aspect focuses on the following fields:

Scenario:
Suppose there exists a distributed trade service with a service operation tradeResources(Integer customerIdOfferer, Integer customerIdBuyer, Integer tradeId), with the additional consistency conditions that negative resource states are not allowed and a trade could not get traded multiple times. Than the following things have to be done in the correct order: With the aspect the lock part (a.), b.), d.)) becomes fairly easy, for example: tradeResources(@DistributedDynamicMutexLockKey(prefix="customer-id-") Integer customerIdOfferer, @DistributedDynamicMutexLockKey(prefix="customer-id-") Integer customerIdBuyer, @DistributedDynamicMutexLockKey(prefix="trade-id-", lockOrderNumber=0) Integer tradeId)
Functional description:
Lock Session and lock sequence behaviour:
For each method the aspect is proxied before it will check, if there exists a thread shared lock session. If no lock session is provided it will allocate a new one and release it after the target method call finished (successful or with an error). If the thread shared lock session supports nested lock sequences than a new lock sequence will be opened by the aspect and released after the target method call finished, else the current lock sequence of the lock session will be used and no cleanup will be done.
Lock behaviour:
The aspect will do all locks, which were declared via annotations at class, method or parameter level for the target invocation at the proxied target class (interface annotations are currently not supported). All allocated locks will be released after the target invocation finished, expect for the case, that the lock session does not support nested lock sequences and existed before. A lock will definitely fail, if another lock sequence holds an unlocked lock.

Since:
0.0.1 (sasl-aop-distributed-library)
Author:
Philipp Förmer

Field Summary
 
Fields inherited from class net.sf.sasl.aop.AbstractRootAspect
logger
 
Fields inherited from interface org.springframework.core.Ordered
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE
 
Constructor Summary
DistributedLockAspect()
           
 
Method Summary
protected  LockInformation buildLockInformationFromDynamicLockKey(DistributedDynamicMutexLockKey lockKeyAnnotation, DistributedDynamicMutexLockKeys parentAnnotation, Method targetMethod, Object[] targetArguments, int curParameterIndex)
          Maps a DistributedMutexLockKey annotation to a lock information.
protected  LockInformation buildLockInformationFromStaticLockKey(DistributedStaticMutexLock lockAnnotation, DistributedStaticMutexLocks parentAnnotation)
          Maps a DistributedStaticMutexLock annotation to a lock information.
protected  void buildLockInformationList(List<LockInformation> lockInformationList, Annotation[] annotations, Method targetMethod, Object[] targetArguments, int curParameterIndex)
          Maps an array of annotations (from the method or a parameter) to lock informations and adds the mapped lock informations to the passed lock information list.
protected  List<LockInformation> buildUnsortedLockInformationList(org.aopalliance.intercept.MethodInvocation invocation)
          Builds an unsorted list of lock informations from the lock annotations which are present at the method and parameters of the method.
protected  void doAnnotationDeclaredLocks(ILockSession session, org.aopalliance.intercept.MethodInvocation invocation)
          Will do all locks, which are declared via annotations at the target method, in the current lock sequence of the passed lock session.
 ILockSessionFactory getLockSessionFactory()
           
 ReflectionHelper getReflectionHelper()
           
 SpringProxyHelper getSpringProxyHelper()
           
 Object invoke(org.aopalliance.intercept.MethodInvocation invocation)
          Please see the header documentation of the class what this method does.
 void setLockSessionFactory(ILockSessionFactory lockSessionFactory)
          Sets a lock session factory from which lock sessions will be created or fetched.
 void setReflectionHelper(ReflectionHelper reflectionHelper)
          Sets a reflection helper which will be used for reflection operations.
 void setSpringProxyHelper(SpringProxyHelper springProxyHelper)
          Sets the spring proxy helper which will be used for spring proxy reflection operations.
 
Methods inherited from class net.sf.sasl.aop.AbstractRootAspect
getLogger, getOrder, setLogger, setLoggerByName, setOrder
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DistributedLockAspect

public DistributedLockAspect()
                      throws ReflectionException
Throws:
ReflectionException
Since:
0.0.1 (sasl-aop-distributed-library)
Method Detail

getLockSessionFactory

public ILockSessionFactory getLockSessionFactory()
Returns:
null or non null
Since:
0.0.1 (sasl-aop-distributed-library)
See Also:
setLockSessionFactory(ILockSessionFactory)

setLockSessionFactory

public void setLockSessionFactory(ILockSessionFactory lockSessionFactory)
                           throws IllegalArgumentException
Sets a lock session factory from which lock sessions will be created or fetched.

Parameters:
lockSessionFactory -
Throws:
IllegalArgumentException
Since:
0.0.1 (sasl-aop-distributed-library)

getSpringProxyHelper

public SpringProxyHelper getSpringProxyHelper()
Returns:
non null.
Since:
0.0.1 (sasl-aop-distributed-library)
See Also:
setSpringProxyHelper(SpringProxyHelper)

setSpringProxyHelper

public void setSpringProxyHelper(SpringProxyHelper springProxyHelper)
Sets the spring proxy helper which will be used for spring proxy reflection operations.

Parameters:
springProxyHelper - non null.
Since:
0.0.1 (sasl-aop-distributed-library)

getReflectionHelper

public ReflectionHelper getReflectionHelper()
Returns:
non null.
Since:
0.0.1 (sasl-aop-distributed-library)
See Also:
setReflectionHelper(ReflectionHelper)

setReflectionHelper

public void setReflectionHelper(ReflectionHelper reflectionHelper)
Sets a reflection helper which will be used for reflection operations.

Parameters:
reflectionHelper - non null.
Since:
0.0.1 (sasl-aop-distributed-library)

invoke

public Object invoke(org.aopalliance.intercept.MethodInvocation invocation)
              throws Throwable
Please see the header documentation of the class what this method does.

Specified by:
invoke in interface org.aopalliance.intercept.MethodInterceptor
Throws:
Throwable
Since:
0.0.1 (sasl-aop-distributed-library)
See Also:
MethodInterceptor.invoke(org.aopalliance.intercept.MethodInvocation)

doAnnotationDeclaredLocks

protected void doAnnotationDeclaredLocks(ILockSession session,
                                         org.aopalliance.intercept.MethodInvocation invocation)
                                  throws DeadlockException,
                                         LockOperationException,
                                         InterruptedException,
                                         ReflectionException,
                                         IllegalAnnotationAttributeValueException
Will do all locks, which are declared via annotations at the target method, in the current lock sequence of the passed lock session. The locks will be acquired and locked in ascending sorted mode by their (orderNumber, lockKey).

Parameters:
session - non null.
invocation - non null.
Throws:
DeadlockException - if a deadlock constellation occurred during trying to lock a mutex.
LockOperationException - if the lock session forbids to execute an operation, for example a mutex should be locked in the current lock sequence but is already acquired (not locked) by another sequence.
InterruptedException - if a tryLock was done which exceeded the maximum wait time.
ReflectionException - if a reflection operation failed, for example because a field/method is not present.
IllegalAnnotationAttributeValueException
Since:
0.0.1 (sasl-aop-distributed-library)

buildUnsortedLockInformationList

protected List<LockInformation> buildUnsortedLockInformationList(org.aopalliance.intercept.MethodInvocation invocation)
                                                          throws ReflectionException,
                                                                 IllegalAnnotationAttributeValueException
Builds an unsorted list of lock informations from the lock annotations which are present at the method and parameters of the method.

Parameters:
invocation - non null.
Returns:
non null.
Throws:
ReflectionException - if a reflection operation failed, for example because a field/method is not present.
IllegalAnnotationAttributeValueException
Since:
0.0.1 (sasl-aop-distributed-library)

buildLockInformationList

protected void buildLockInformationList(List<LockInformation> lockInformationList,
                                        Annotation[] annotations,
                                        Method targetMethod,
                                        Object[] targetArguments,
                                        int curParameterIndex)
                                 throws ReflectionException,
                                        IllegalAnnotationAttributeValueException
Maps an array of annotations (from the method or a parameter) to lock informations and adds the mapped lock informations to the passed lock information list.

Parameters:
lockInformationList - non null.
annotations - non null.
targetMethod - null or non null, depending if dynamic locks should be processed or not.
targetArguments - null or non null, depending if dynamic locks should be processed or not.
curParameterIndex - lesser than zero if no annotations of a parameter should get processed, the current parameter index else.
Throws:
ReflectionException - if a reflection operation failed.
IllegalAnnotationAttributeValueException
Since:
0.0.1 (sasl-aop-distributed-library)

buildLockInformationFromStaticLockKey

protected LockInformation buildLockInformationFromStaticLockKey(DistributedStaticMutexLock lockAnnotation,
                                                                DistributedStaticMutexLocks parentAnnotation)
Maps a DistributedStaticMutexLock annotation to a lock information. If the annotation is nested in a DistributedStaticMutexLocks annotation and the DistributedStaticMutexLock annotation does not override default annotation attribute values, than the equipollent values of the parent annotation will be applied to the lock information.

Parameters:
lockAnnotation - non null.
parentAnnotation - null or non null.
Returns:
non null.
Since:
0.0.1 (sasl-aop-distributed-library)

buildLockInformationFromDynamicLockKey

protected LockInformation buildLockInformationFromDynamicLockKey(DistributedDynamicMutexLockKey lockKeyAnnotation,
                                                                 DistributedDynamicMutexLockKeys parentAnnotation,
                                                                 Method targetMethod,
                                                                 Object[] targetArguments,
                                                                 int curParameterIndex)
                                                          throws ReflectionException,
                                                                 IllegalAnnotationAttributeValueException
Maps a DistributedMutexLockKey annotation to a lock information. If the annotation is nested in a DistributedMutexLockKeys annotation and the DistributedMutexLockKey annotation does not override default annotation attribute values, than the equipollent values of the parent annotation will be applied to the lock information.

Parameters:
lockKeyAnnotation - non null.
parentAnnotation - null or non null.
targetMethod - non null.
targetArguments - non null.
curParameterIndex - lesser than zero if no annotation of a parameter should get processed, the current parameter index else.
Returns:
non null.
Throws:
ReflectionException
IllegalAnnotationAttributeValueException
Since:
0.0.1 (sasl-aop-distributed-library)


Copyright © 2010. All Rights Reserved.