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

Reply via email to