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

com.github.lontime.extpac4j.impl.HeaderSessionStore Maven / Gradle / Ivy

The newest version!
package com.github.lontime.extpac4j.impl;

import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import com.github.lontime.base.serial.GenericObjectSerializers;
import com.github.lontime.base.serial.MsgpackSerial;
import com.github.lontime.extredisson.RedissonInstance;
import com.github.lontime.extredisson.codec.StringBytesMapCodec;
import com.github.lontime.shaded.com.twitter.serial.serializer.Serializer;
import com.github.lontime.shaded.org.redisson.api.RedissonClient;
import org.pac4j.core.context.JEEContext;
import org.pac4j.core.profile.CommonProfile;

/**
 * LocalJEESessionStore.
 *
 * @author lontime
 * @since 1.0
 */
public class HeaderSessionStore extends HeaderSimpleSessionStore {

    public static final HeaderSessionStore INSTANCE = new HeaderSessionStore();

    private final RedissonClient redissonClient;

    private final Duration expire;

    public HeaderSessionStore(String headerName, String redissonName) {
        super(headerName);
        this.redissonClient = RedissonInstance.get().client(redissonName);
        this.expire = Duration.ofMinutes(20);
    }

    public HeaderSessionStore(String redissonName) {
        this(null, redissonName);
    }

    public HeaderSessionStore() {
        this(null, null);
    }

    @Override
    public Optional get(JEEContext context, String key) {
        final Optional value = super.get(context, key);
        if (value.isPresent()) {
            return value;
        }
        final Optional sessionId = getSessionId(context);
        return sessionId.map(s -> buildSessionId(s))
                .map(s -> redissonClient.getMapCache(s, StringBytesMapCodec.INSTANCE).get(key))
                .map(s -> MsgpackSerial.INSTANCE.fromByteArrayUnchecked((byte[]) s, getObjectSerializer()));
    }

    @Override
    public void set(JEEContext context, String key, Object value) {
        super.set(context, key, value);
        final Optional sessionId = getSessionId(context);
        if (!sessionId.isPresent()) {
            return;
        }
        final byte[] bytes = MsgpackSerial.INSTANCE.toByteArrayUnchecked(value, getObjectSerializer());
        if (bytes == null) {
            return;
        }
        redissonClient.getMapCache(buildSessionId(sessionId.get()), StringBytesMapCodec.INSTANCE).put(key, bytes, expire.toMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public boolean destroySession(JEEContext context) {
        if (super.destroySession(context)) {
            return getSessionId(context).map(s -> buildSessionId(s))
                    .map(s -> redissonClient.getMapCache(s).delete())
                    .orElse(true);
        }
        return false;
    }

    private String buildSessionId(String id) {
        return "lontime:sessions:" + id;
    }

    protected Serializer getObjectSerializer() {
        final GenericObjectSerializers serializer = getMsgpackObjectSerializer()
                .withSerializer(CommonProfile.class,
                        new UserProfileSerializer() {
                            @Override
                            public CommonProfile createInstance() {
                                return new CommonProfile();
                            }
                        });
        return serializer.getObjectSerializer();
    }

    protected GenericObjectSerializers getMsgpackObjectSerializer() {
        return GenericObjectSerializers.INSTANCE;
    }

    public HeaderSessionStore withSerializer(Class clazz, Serializer serializer) {
        getMsgpackObjectSerializer().withSerializer(clazz, serializer);
        return this;
    }
}