Done.

https://issues.jasig.org/browse/CAS-930


On Tue, Dec 21, 2010 at 11:38 PM, Scott Battaglia <[email protected]
> wrote:

> Yuri,
>
> Can you open a JIRA issue for this and attach your implementations?
>
> http://issues.jasig.org
>
> Thanks!
> Scott
>
>
> On Tue, Dec 21, 2010 at 5:08 PM, Yuri Negocio Negocio 
> <[email protected]>wrote:
>
>> Hi guys,
>>
>> A few months ago I'm working on customizing the CAS for my organization, I
>> have had some difficulties related to lack of architectural control in data
>> integration, due to the use of various frameworks (JPA, Hibernate, JDBC).
>> One example is the current implementation of the ticket cleaning lock
>> strategy.
>>
>> Because of that, i'm trying to replace the JDBC-based implementations to
>> JPA. The first step was to implement a class that replaces
>> JdbcLockingStrategy called JpaLockingStrategy.
>>
>> The class is fully based on the implementation of JdbcLockingStrategy and
>> has been tested on version 3.4.4 of cas server.
>>
>> Cheers,
>>
>> Yuri Feitosa Negócio
>>
>> import java.sql.Timestamp;
>> import java.util.Calendar;
>> import java.util.List;
>>
>> import javax.persistence.EntityManagerFactory;
>> import javax.validation.constraints.NotNull;
>>
>> import org.apache.commons.logging.Log;
>> import org.apache.commons.logging.LogFactory;
>> import org.jasig.cas.ticket.registry.support.LockingStrategy;
>> import org.springframework.beans.factory.InitializingBean;
>> import org.springframework.orm.jpa.JpaTemplate;
>> import org.springframework.transaction.annotation.Transactional;
>>
>>
>> public class JpaLockingStrategy
>>     implements LockingStrategy, InitializingBean {
>>
>>     protected final Log logger =
>> LogFactory.getLog(JpaLockingStrategy.class);
>>
>>     @NotNull
>>     private JpaTemplate jpaTemplate;
>>
>>     public JpaLockingStrategy(final EntityManagerFactory factory) {
>>             this.jpaTemplate = new JpaTemplate(factory);
>>     }
>>
>>     /** Default lock timeout is 1 hour */
>>     public static final int DEFAULT_LOCK_TIMEOUT = 3600;
>>
>>     /** Unique identifier that identifies the client using this lock
>> instance */
>>     @NotNull
>>     private String uniqueId;
>>
>>     /**
>>      * Application identifier that identifies rows in the locking table,
>>      * each one of which may be for a different application or usage
>> within
>>      * a single application.
>>      */
>>     @NotNull
>>     private String applicationId;
>>
>>     /** Amount of time in seconds lock may be held */
>>     private int lockTimeout = DEFAULT_LOCK_TIMEOUT;
>>
>>     /**
>>      * @param  id  Identifier used to identify this instance in a row of
>> the
>>      *             lock table.  Must be unique across all clients vying
>> for
>>      *             locks for a given application ID.
>>      */
>>     public void setUniqueId(final String id) {
>>         this.uniqueId = id;
>>     }
>>
>>     /**
>>      * @param  id  Application identifier that identifies a row in the
>> lock
>>      *             table for which multiple clients vie to hold the lock.
>>      */
>>     public void setApplicationId(final String id) {
>>         this.applicationId = id;
>>     }
>>
>>
>>     /**
>>      * @param  seconds  Maximum amount of time in seconds lock may be
>> held.
>>      */
>>     public void setLockTimeout(final int seconds) {
>>         this.lockTimeout = seconds;
>>     }
>>
>>     /**
>>      * @see
>> org.jasig.cas.ticket.registry.support.LockingStrategy#acquire()
>>      */
>>     @Transactional
>>     public boolean acquire() {
>>         boolean lockAcquired = false;
>>         try {
>>
>>             List<Lock> locks = this.jpaTemplate.find("SELECT l FROM Lock l
>> WHERE l.applicationId = ?1",this.applicationId);
>>
>>             final Timestamp expDate = getExpirationDate();
>>
>>             if ((locks==null)||locks.isEmpty()) {
>>                    logger.info("New lock. {applicationId: " +
>> this.applicationId + ", uniqueId: " + this.uniqueId + ", timestamp: " +
>> expDate + " }");
>>                 Lock newLock = new Lock();
>>                 // No row exists for this applicationId so create it.
>>                 // Row is created with uniqueId of this instance
>>                 // which indicates the lock is initially held by this
>> instance.
>>                 newLock.setApplicationId(this.applicationId);
>>                 newLock.setExpirationDate(expDate);
>>                 this.jpaTemplate.persist(newLock);
>>                 return true;
>>             } else {
>>                 Lock currentLock = locks.get(0);
>>                 lockAcquired = canAcquire(currentLock);
>>                 if (lockAcquired) {
>>                        logger.info("Lock acquired. {applicationId: " +
>> this.applicationId + ", uniqueId: " + this.uniqueId + ", timestamp: " +
>> expDate + " }");
>>
>>                     // Update unique ID of row to indicate this instance
>> holds lock
>>                     currentLock.setUniqueId(this.uniqueId);
>>
>>                     this.jpaTemplate.merge(currentLock);
>>                 }
>>             }
>>         } finally {
>>
>>         }
>>         return lockAcquired;
>>     }
>>
>>     /**
>>      * @see
>> org.jasig.cas.ticket.registry.support.LockingStrategy#release()
>>      */
>>     @Transactional
>>     public void release() {
>>         logger.info("Lock released. { applicationId: " +
>> this.applicationId + " }");
>>         Lock lock = this.jpaTemplate.find(Lock.class, this.applicationId);
>>         lock.setUniqueId(null);
>>         lock.setExpirationDate(null);
>>         this.jpaTemplate.merge(lock);
>>     }
>>
>>     /**
>>      * Determines whether this instance can acquire the lock.
>>      *
>>      * @param  lockRow  Row of lock data for this application ID.
>>      *
>>      * @return  True if lock can be acquired, false otherwise.
>>      */
>>     private boolean canAcquire(Lock lock) {
>>         if (lock.getUniqueId() != null) {
>>             final Calendar expCal = Calendar.getInstance();
>>             expCal.setTime(lock.getExpirationDate());
>>             return Calendar.getInstance().after(expCal);
>>         }
>>         return true;
>>     }
>>
>>     /**
>>      * @return  The expiration date for a lock acquired at the current
>> system
>>      * time
>>      */
>>     private Timestamp getExpirationDate() {
>>         final Calendar cal = Calendar.getInstance();
>>         cal.add(Calendar.SECOND, this.lockTimeout);
>>         return new Timestamp(cal.getTimeInMillis());
>>     }
>>
>>     public void afterPropertiesSet() throws Exception {
>>         //compatibility
>>     }
>> }
>>
>>
>>
>> import java.util.Date;
>>
>> import javax.persistence.Column;
>> import javax.persistence.Entity;
>> import javax.persistence.Id;
>> import javax.persistence.Table;
>> import javax.persistence.Temporal;
>> import javax.persistence.TemporalType;
>>
>> @Entity
>> @Table(name="LOCKS")
>> public class Lock {
>>
>>     /** Database column name that holds application identifier */
>>     @Id
>>     @Column(name="application_id")
>>     private String applicationId;
>>     /** Database column name that holds unique identifier */
>>     @Column(name="unique_id")
>>     private String uniqueId;
>>
>>     /** Database column name that holds expiration date */
>>     @Temporal(TemporalType.TIMESTAMP)
>>     @Column(name="expiration_date")
>>     private Date expirationDate;
>>
>>     public String getApplicationId() {
>>         return applicationId;
>>     }
>>     public void setApplicationId(String applicationId) {
>>         this.applicationId = applicationId;
>>     }
>>     public String getUniqueId() {
>>         return uniqueId;
>>     }
>>     public void setUniqueId(String uniqueId) {
>>         this.uniqueId = uniqueId;
>>     }
>>     public Date getExpirationDate() {
>>         return expirationDate;
>>     }
>>     public void setExpirationDate(Date expirationDate) {
>>         this.expirationDate = expirationDate;
>>     }
>>
>> }
>>
>>
>> --
>> You are currently subscribed to [email protected] as: 
>> [email protected]
>>
>>
>> To unsubscribe, change settings or access archives, see 
>> http://www.ja-sig.org/wiki/display/JSG/cas-user
>>
>>
> --
> You are currently subscribed to [email protected] as: [email protected]
> To unsubscribe, change settings or access archives, see 
> http://www.ja-sig.org/wiki/display/JSG/cas-user
>
>

-- 
You are currently subscribed to [email protected] as: 
[email protected]
To unsubscribe, change settings or access archives, see 
http://www.ja-sig.org/wiki/display/JSG/cas-user

Reply via email to