From f2f4c72aa6607bd3ad2788c048306d939ff40797 Mon Sep 17 00:00:00 2001 From: Nitesh Agarwal Date: Thu, 17 Feb 2022 19:54:15 +0530 Subject: [PATCH] Add redis cluster client as a session store. --- .gitignore | 3 ++- server/sessionstore/redis_store.go | 4 +--- server/sessionstore/session.go | 34 +++++++++++++++++++++++++++ server/sessionstore/session_client.go | 18 ++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 server/sessionstore/session_client.go diff --git a/.gitignore b/.gitignore index bab8c91..d979474 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ build data.db .DS_Store .env.local -*.tar.gz \ No newline at end of file +*.tar.gz +.vscode/ \ No newline at end of file diff --git a/server/sessionstore/redis_store.go b/server/sessionstore/redis_store.go index 658b5e4..4531e0f 100644 --- a/server/sessionstore/redis_store.go +++ b/server/sessionstore/redis_store.go @@ -4,13 +4,11 @@ import ( "context" "fmt" "log" - - "github.com/go-redis/redis/v8" ) type RedisStore struct { ctx context.Context - store *redis.Client + store RedisSessionClient } // AddUserSession adds the user session to redis diff --git a/server/sessionstore/session.go b/server/sessionstore/session.go index aeaad1d..523dee6 100644 --- a/server/sessionstore/session.go +++ b/server/sessionstore/session.go @@ -3,6 +3,7 @@ package sessionstore import ( "context" "log" + "strings" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/envstore" @@ -121,6 +122,23 @@ func RemoveSocialLoginState(key string) { func InitSession() { if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" { log.Println("using redis store to save sessions") + if isCluster(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)) { + clusterOpt, err := getClusterOptions(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)) + if err != nil { + log.Fatalln("Error parsing redis url:", err) + } + rdb := redis.NewClusterClient(clusterOpt) + ctx := context.Background() + _, err = rdb.Ping(ctx).Result() + if err != nil { + log.Fatalln("Error connecting to redis cluster server", err) + } + SessionStoreObj.RedisMemoryStoreObj = &RedisStore{ + ctx: ctx, + store: rdb, + } + return + } opt, err := redis.ParseURL(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)) if err != nil { log.Fatalln("Error parsing redis url:", err) @@ -144,3 +162,19 @@ func InitSession() { } } } + +func isCluster(url string) bool { + return len(strings.Split(url, ",")) > 1 +} + +func getClusterOptions(url string) (*redis.ClusterOptions, error) { + hostPortsList := strings.Split(url, ",") + opt, err := redis.ParseURL(hostPortsList[0]) + if err != nil { + return nil, err + } + urls := []string{opt.Addr} + urlList := hostPortsList[1:] + urls = append(urls, urlList...) + return &redis.ClusterOptions{Addrs: urls}, nil +} diff --git a/server/sessionstore/session_client.go b/server/sessionstore/session_client.go new file mode 100644 index 0000000..e73cd74 --- /dev/null +++ b/server/sessionstore/session_client.go @@ -0,0 +1,18 @@ +package sessionstore + +import ( + "context" + "time" + + "github.com/go-redis/redis/v8" +) + +type RedisSessionClient interface { + HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd + Del(ctx context.Context, keys ...string) *redis.IntCmd + HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd + HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd + HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd + Get(ctx context.Context, key string) *redis.StringCmd +}