protected Ticket getTicketFromRedis(final Predicate<Ticket> predicate, final String redisKeyPattern,
                                        final RedisKeyGenerator redisKeyGenerator) {
        val rawTicketId = redisKeyGenerator.rawKey(redisKeyPattern);
        val cachedTicket = ticketCache.stream().parallel().map(cache -> cache.getIfPresent(rawTicketId)).filter(Objects::nonNull);

        val ticket = cachedTicket
            .findFirst()
            .map(this::decodeTicket)
            .filter(predicate)
            .stream()
            .findFirst()
            .orElseGet(() -> Stream.of(redisKeyPattern)
                .map(key -> {
                    val keyspace = redisKeyGenerator.getKeyspace();
                    return redisKeyValueAdapter.get(rawTicketId, keyspace, RedisTicketDocument.class);
                })
                .filter(Objects::nonNull)
                .map(document -> deserializeTicket(document.json(), document.type()))
                .map(this::decodeTicket)
                .filter(predicate)
                .findFirst()
                .orElseGet(() -> handleMissingTicket(rawTicketId, redisKeyPattern)));

        if (ticket != null && predicate.test(ticket) && !ticket.isExpired()) {
            ticketCache.ifAvailable(cache -> cache.put(rawTicketId, ticket));
            return ticket;
        }
        ticketCache.ifAvailable(cache -> cache.invalidate(rawTicketId));
        messagePublisher.ifAvailable(publisher -> publisher.delete(ticket));
        return null;
    }
Key-value ticket registry implementation that stores tickets in redis.

@author Misagh Moayyed
@author Jerome Leleu
@since 5.1.0
support/cas-server-support-redis-ticket-registry/src/main/java/org/apereo/cas/ticket/registry/RedisTicketRegistry.java