Jasig-CAS is a well-known Web Based Single-Sign-Framework developed with almost all Spring features. Basically you can get more information from the documentation.
TicketRegistryCleaner deletes tickets from datasource based on your configuration. In a High Available (HA) configuration tickets are persisted on databases to serve multiple clients and services with multiple cas-servers. This deletion locks and sometimes casuses deadlocks in oracle since it uses update for. Jasig-Wiki suggests developers to use appropriate locking strategies for their architecture. Although using JPALocking strategy for HA environments is not enough to solve deadlock problems in jasig-cas.
After working with our oracle database administrators i decided to develop a new TicketRegistryCleaner that is only active in one of cas-servers and just cleans the tickets at midnight 02:00 to 05:00.
This kind of approach is not solving the deadlocks, it just pushes the deadlock problems to midnights. If it is necessary for the cleanup a stored procedure can be written to delete the unused and timeout tickets. In the below you will see scheduled registry cleaner source code.
- package com.montoya.sso.ticket.registry.support;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Collection;
- import java.util.Date;
- import java.util.List;
- import javax.validation.constraints.NotNull;
- import org.jasig.cas.ticket.Ticket;
- import org.jasig.cas.ticket.TicketGrantingTicket;
- import org.jasig.cas.ticket.registry.RegistryCleaner;
- import org.jasig.cas.ticket.registry.TicketRegistry;
- import org.jasig.cas.ticket.registry.support.JdbcLockingStrategy;
- import org.jasig.cas.ticket.registry.support.LockingStrategy;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class MontoyaTicketRegistryCleaner implements RegistryCleaner {
- /** The Commons Logging instance. */
- private final Logger log = LoggerFactory.getLogger(getClass());
- @NotNull
- private int startTime;
- @NotNull
- private int endTime;
- /** The instance of the TicketRegistry to clean. */
- @NotNull
- private TicketRegistry ticketRegistry;
- /** Execution locking strategy */
- @NotNull
- private LockingStrategy lock;
- private boolean logUserOutOfServices = true;
- private boolean active;
- public void setActive(boolean active) {
- this.active = active;
- }
- public void setStartTime(int startTime) {
- this.startTime = startTime;
- }
- public void setEndTime(int endTime) {
- this.endTime = endTime;
- }
- /**
- * @see org.jasig.cas.ticket.registry.RegistryCleaner#clean()
- */
- public void clean() {
- if (!active) {
- log.info("MontoyaTicketRegistryCleaner is not active on this node");
- return;
- }
- int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
- if (hour < startTime || hour > endTime) {
- log.debug("TicketRegistryCleaner is active but it is not working except {} - {} ",startTime,endTime);
- return;
- }
- this.log.info("Beginning ticket cleanup.");
- this.log.debug("Attempting to acquire ticket cleanup lock.");
- if (!this.lock.acquire()) {
- this.log.info("Could not obtain lock. Aborting cleanup.");
- return;
- }
- this.log.debug("Acquired lock. Proceeding with cleanup.");
- try {
- final List<Ticket> ticketsToRemove = new ArrayList<Ticket>();
- final Collection<Ticket> ticketsInCache;
- ticketsInCache = this.ticketRegistry.getTickets();
- for (final Ticket ticket : ticketsInCache) {
- if (ticket.isExpired()) {
- ticketsToRemove.add(ticket);
- }
- }
- this.log.info(ticketsToRemove.size() + " tickets found to be removed.");
- for (final Ticket ticket : ticketsToRemove) {
- if (this.logUserOutOfServices && ticket instanceof TicketGrantingTicket) {
- ((TicketGrantingTicket) ticket).expire();
- }
- this.ticketRegistry.deleteTicket(ticket.getId());
- }
- } finally {
- this.log.debug("Releasing ticket cleanup lock.");
- this.lock.release();
- }
- this.log.info("Finished ticket cleanup.");
- }
- /**
- * @param ticketRegistry
- * The ticketRegistry to set.
- */
- public void setTicketRegistry(final TicketRegistry ticketRegistry) {
- this.ticketRegistry = ticketRegistry;
- }
- /**
- * @param strategy
- * Ticket cleanup locking strategy. An exclusive locking strategy
- * is preferable if not required for some ticket backing stores,
- * such as JPA, in a clustered CAS environment. Use
- * {@link JdbcLockingStrategy} for
- * {@link org.jasig.cas.ticket.registry.JpaTicketRegistry} in a
- * clustered CAS environment.
- */
- public void setLock(final LockingStrategy strategy) {
- this.lock = strategy;
- }
- /**
- * Whether to log users out of services when we remove an expired ticket.
- * The default is true. Set this to false to disable.
- *
- * @param logUserOutOfServices
- * whether to log the user out of services or not.
- */
- public void setLogUserOutOfServices(final boolean logUserOutOfServices) {
- this.logUserOutOfServices = logUserOutOfServices;
- }
- }
Hiç yorum yok:
Yorum Gönder