Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Top Level Value/Key Codecs #7

Open
ctoestreich opened this issue Jul 8, 2019 · 0 comments
Open

Support Top Level Value/Key Codecs #7

ctoestreich opened this issue Jul 8, 2019 · 0 comments
Labels
type: enhancement New feature or request

Comments

@ctoestreich
Copy link

ctoestreich commented Jul 8, 2019

The default client and factory use a simple codec <String, String>. It is pretty easy to override this, however it isn't documented and the ability to specify a key/value codec could be simplified.

I had to do the following to get a custom protobuf session codec working where the UserSession is a proto we are using. Seems like overkill to have to redefine the entire class to achieve this result.

Also there isn't examples or documentation on the https://micronaut-projects.github.io/micronaut-redis/latest/guide/ site for serializing objects that do not use the session store/jackson. Perhaps the jackson/other serialization could simply be added as top level option like

redis:
    valueSerializer: io.micronaut.jackson.serialize.JacksonObjectSerializer
    keySerializer: io.micronaut.jackson.serialize.JacksonObjectSerializer #or string etc
package xxxxxxxxxxxx;

import xxxxxxxxxxxx.UserSession;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.micronaut.configuration.lettuce.AbstractRedisConfiguration;
import io.micronaut.configuration.lettuce.DefaultRedisClientFactory;
import io.micronaut.configuration.lettuce.DefaultRedisConfiguration;
import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Primary;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Optional;

@Requires(beans = DefaultRedisConfiguration.class)
@Singleton
@Factory
@Replaces(DefaultRedisClientFactory.class)
public class UserSessionRedisClientFactory {

    @Bean(preDestroy = "shutdown")
    @Singleton
    @Primary
    public RedisClient redisClient(AbstractRedisConfiguration config) {
        Optional<RedisURI> uri = config.getUri();
        return uri.map(RedisClient::create)
                .orElseGet(() -> RedisClient.create(config));
    }

    /**
     * Creates the {@link StatefulRedisConnection} from the {@link RedisClient}.
     *
     * @param redisClient The {@link RedisClient}
     * @return The {@link StatefulRedisConnection}
     */
    @Bean(preDestroy = "close")
    @Singleton
    @Primary
    public StatefulRedisConnection<String, UserSession> redisConnection(RedisClient redisClient) {
        return redisClient.connect(new UserSessionCodec());
    }

    /**
     * Creates the {@link StatefulRedisPubSubConnection} from the {@link RedisClient}.
     *
     * @param redisClient The {@link RedisClient}
     * @return The {@link StatefulRedisPubSubConnection}
     */
    @Bean(preDestroy = "close")
    @Singleton
    public StatefulRedisPubSubConnection<String, String> redisPubSubConnection(RedisClient redisClient) {
        return redisClient.connectPubSub();
    }

    public class UserSessionCodec implements RedisCodec<String, UserSession> {
        private Charset charset = Charset.forName("UTF-8");

        @Override
        public String decodeKey(ByteBuffer bytes) {
            return charset.decode(bytes).toString();
        }

        @Override
        public UserSession decodeValue(ByteBuffer bytes) {
            try {
                byte[] array = new byte[bytes.remaining()];
                bytes.get(array);
                return UserSession.parseFrom(array);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public ByteBuffer encodeKey(String key) {
            return charset.encode(key);
        }

        @Override
        public ByteBuffer encodeValue(UserSession value) {
            return ByteBuffer.wrap(value.toByteArray());
        }
    }
}
@ctoestreich ctoestreich changed the title Support Codecs Support Top Level Value/Key Codecs Jul 8, 2019
@pgressa pgressa added the type: enhancement New feature or request label Mar 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants