All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apereo.cas.ticket.registry.HazelcastTicketRegistry Maven / Gradle / Ivy

package org.apereo.cas.ticket.registry;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.query.PagingPredicate;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.ticket.Ticket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

/**
 * Hazelcast-based implementation of a {@link TicketRegistry}.
 * 

This implementation just wraps the Hazelcast's {@link IMap} * which is an extension of the standard Java's {@code ConcurrentMap}.

*

The heavy lifting of distributed data partitioning, network cluster discovery and * join, data replication, etc. is done by Hazelcast's Map implementation.

* * @author Dmitriy Kopylenko * @author Jonathan Johnson * @since 4.1.0 */ public class HazelcastTicketRegistry extends AbstractTicketRegistry implements Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(HazelcastTicketRegistry.class); private IMap registry; private HazelcastInstance hazelcastInstance; private int pageSize; /** * Instantiates a new Hazelcast ticket registry. * * @param hz An instance of {@code HazelcastInstance} * @param mapName Name of map to use * @param pageSize the page size */ public HazelcastTicketRegistry(final HazelcastInstance hz, final String mapName, final int pageSize) { this.registry = hz.getMap(mapName); this.hazelcastInstance = hz; this.pageSize = pageSize; } /** * Init. */ @PostConstruct public void init() { LOGGER.info("Setting up Hazelcast Ticket Registry instance [{}] with name [{}]", this.hazelcastInstance, registry.getName()); } @Override public Ticket updateTicket(final Ticket ticket) { addTicket(ticket); return ticket; } @Override public void addTicket(final Ticket ticket) { LOGGER.debug("Adding ticket [{}] with ttl [{}s]", ticket.getId(), ticket.getExpirationPolicy().getTimeToLive()); final Ticket encTicket = encodeTicket(ticket); this.registry.set(encTicket.getId(), encTicket, ticket.getExpirationPolicy().getTimeToLive(), TimeUnit.SECONDS); } @Override public Ticket getTicket(final String ticketId) { final String encTicketId = encodeTicketId(ticketId); if (StringUtils.isNotBlank(encTicketId)) { final Ticket ticket = this.registry.get(encTicketId); return decodeTicket(ticket); } return null; } @Override public boolean deleteSingleTicket(final String ticketId) { return this.registry.remove(ticketId) != null; } @Override public long deleteAll() { final int size = this.registry.size(); this.registry.evictAll(); this.registry.clear(); return size; } @Override public Collection getTickets() { final Collection collection = new HashSet<>(); LOGGER.debug("Attempting to acquire lock from Hazelcast instance..."); final Lock lock = this.hazelcastInstance.getLock(getClass().getName()); lock.lock(); LOGGER.debug("Hazelcast instance lock acquired"); try { LOGGER.debug("Setting up the paging predicate with page size of [{}]", this.pageSize); final PagingPredicate pagingPredicate = new PagingPredicate(this.pageSize); LOGGER.debug("Retrieving the initial collection of tickets from Hazelcast instance..."); Collection entrySet = this.registry.values(pagingPredicate); while (!entrySet.isEmpty()) { collection.addAll(entrySet.stream().map(this::decodeTicket).collect(Collectors.toList())); pagingPredicate.nextPage(); entrySet = this.registry.values(pagingPredicate); } } catch (final Exception e) { LOGGER.debug(e.getMessage(), e); } finally { lock.unlock(); } return collection; } /** * Make sure we shutdown HazelCast when the context is destroyed. */ @PreDestroy public void shutdown() { try { LOGGER.info("Shutting down Hazelcast instance [{}]", this.hazelcastInstance.getConfig().getInstanceName()); this.hazelcastInstance.shutdown(); } catch (final Throwable e) { LOGGER.debug(e.getMessage()); } } @Override public void close() throws IOException { shutdown(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy