ratpack.session.store.internal.RedisSessionStore.java Source code

Java tutorial

Introduction

Here is the source code for ratpack.session.store.internal.RedisSessionStore.java

Source

/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.session.store.internal;

import com.google.inject.Inject;
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.api.async.RedisAsyncCommands;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.AsciiString;
import ratpack.exec.Execution;
import ratpack.exec.Operation;
import ratpack.exec.Promise;
import ratpack.session.SessionStore;
import ratpack.session.store.RedisSessionModule;

public class RedisSessionStore implements SessionStore {

    private final RedisSessionModule.Config config;

    private TimerExposingRedisClient redisClient;
    private RedisAsyncCommands<AsciiString, ByteBuf> connection;

    @Inject
    public RedisSessionStore(RedisSessionModule.Config config) {
        this.config = config;
    }

    @Override
    public Operation store(AsciiString sessionId, ByteBuf sessionData) {
        return Promise.<Boolean>async(d -> connection.set(sessionId, sessionData).handleAsync((value, failure) -> {
            if (failure == null) {
                if (value != null && value.equalsIgnoreCase("OK")) {
                    d.success(true);
                } else {
                    d.error(new RuntimeException("Failed to set session data"));
                }
            } else {
                d.error(new RuntimeException("Failed to set session data.", failure));
            }
            return null;
        }, Execution.current().getEventLoop())).operation();
    }

    @Override
    public Promise<ByteBuf> load(AsciiString sessionId) {
        return Promise.<ByteBuf>async(downstream -> {
            downstream.accept(connection.get(sessionId));
        }).map(byteBuf -> {
            if (byteBuf == null) {
                //Must return an empty buffer never null
                return Unpooled.EMPTY_BUFFER;
            }
            return byteBuf;
        });
    }

    @Override
    public Operation remove(AsciiString sessionId) {
        return Promise.<Long>async(d -> d.accept(connection.del(sessionId))).operation();
    }

    @Override
    public Promise<Long> size() {
        return Promise.value(-1L);
    }

    @Override
    public String getName() {
        return "Redis Session Store Service";
    }

    @Override
    public void onStart(@SuppressWarnings("deprecation") ratpack.server.StartEvent event) throws Exception {
        redisClient = new TimerExposingRedisClient(getRedisURI());
        connection = redisClient.connect(new AsciiStringByteBufRedisCodec()).async();
    }

    @Override
    public void onStop(@SuppressWarnings("deprecation") ratpack.server.StopEvent event) throws Exception {
        if (redisClient != null) {
            try {
                redisClient.getTimer().stop();
                redisClient.shutdown();
            } finally {
                redisClient = null;
            }
        }
    }

    private RedisURI getRedisURI() {
        RedisURI.Builder builder = RedisURI.Builder.redis(config.getHost());

        if (config.getPassword() != null) {
            builder.withPassword(config.getPassword());
        }

        if (config.getPort() != null) {
            builder.withPort(config.getPort());
        }

        return builder.build();
    }
}