<commit_before>package storage

import (
	"crypto/tls"
	"embed"
	"fmt"
	"net/http"
	"time"

	"github.com/go-redis/redis/v8"
	"github.com/golang-migrate/migrate/v4"
	"github.com/golang-migrate/migrate/v4/database/postgres"
	"github.com/golang-migrate/migrate/v4/source/httpfs"
	"github.com/jmoiron/sqlx"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"

	"github.com/brocaar/chirpstack-network-server/v3/internal/config"
	"github.com/brocaar/chirpstack-network-server/v3/internal/migrations/code"
	codemig "github.com/brocaar/chirpstack-network-server/v3/internal/storage/migrations/code"
)

// Migrations
//go:embed migrations/*
var migrations embed.FS

// deviceSessionTTL holds the device-session TTL.
var deviceSessionTTL time.Duration

// schedulerInterval holds the interval in which the Class-B and -C
// scheduler runs.
var schedulerInterval time.Duration

// keyPrefix for Redis.
var keyPrefix string

// Setup configures the storage backend.
func Setup(c config.Config) error {
	log.Info("storage: setting up storage module")

	deviceSessionTTL = c.NetworkServer.DeviceSessionTTL
	schedulerInterval = c.NetworkServer.Scheduler.SchedulerInterval
	keyPrefix = c.Redis.KeyPrefix

	log.Info("storage: setting up Redis client")
	if len(c.Redis.Servers) == 0 {
		return errors.New("at least one redis server must be configured")
	}

	var tlsConfig *tls.Config
	if c.Redis.TLSEnabled {
		tlsConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}

	if c.Redis.Cluster {
		redisClient = redis.NewClusterClient(&redis.ClusterOptions{
			Addrs:     c.Redis.Servers,
			PoolSize:  c.Redis.PoolSize,
			Password:  <PASSWORD>,
			TLSConfig: tlsConfig,
		})
	} else if c.Redis.MasterName != "" {
		redisClient = redis.NewFailoverClient(&redis.FailoverOptions{
			MasterName:       c.Redis.MasterName,
			SentinelAddrs:    c.Redis.Servers,
			SentinelPassword: <PASSWORD>,
			DB:               c.Redis.Database,
			PoolSize:         c.Redis.PoolSize,
			TLSConfig:        tlsConfig,
		})
	} else {
		redisClient = redis.NewClient(&redis.Options{
			Addr:      c.Redis.Servers[0],
			DB:        c.Redis.Database,
			Password:  <PASSWORD>,
			PoolSize:  c.Redis.PoolSize,
			TLSConfig: tlsConfig,
		})
	}

	log.Info("storage: connecting to PostgreSQL")
	d, err := sqlx.Open("postgres", c.PostgreSQL.DSN)
	if err != nil {
		return errors.Wrap(err, "storage: PostgreSQL connection error")
	}
	d.SetMaxOpenConns(c.PostgreSQL.MaxOpenConnections)<commit_msg>Add missing password to Redis Sentinel client. (#550)<commit_after>package storage

import (
	"crypto/tls"
	"embed"
	"fmt"
	"net/http"
	"time"

	"github.com/go-redis/redis/v8"
	"github.com/golang-migrate/migrate/v4"
	"github.com/golang-migrate/migrate/v4/database/postgres"
	"github.com/golang-migrate/migrate/v4/source/httpfs"
	"github.com/jmoiron/sqlx"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"

	"github.com/brocaar/chirpstack-network-server/v3/internal/config"
	"github.com/brocaar/chirpstack-network-server/v3/internal/migrations/code"
	codemig "github.com/brocaar/chirpstack-network-server/v3/internal/storage/migrations/code"
)

// Migrations
//go:embed migrations/*
var migrations embed.FS

// deviceSessionTTL holds the device-session TTL.
var deviceSessionTTL time.Duration

// schedulerInterval holds the interval in which the Class-B and -C
// scheduler runs.
var schedulerInterval time.Duration

// keyPrefix for Redis.
var keyPrefix string

// Setup configures the storage backend.
func Setup(c config.Config) error {
	log.Info("storage: setting up storage module")

	deviceSessionTTL = c.NetworkServer.DeviceSessionTTL
	schedulerInterval = c.NetworkServer.Scheduler.SchedulerInterval
	keyPrefix = c.Redis.KeyPrefix

	log.Info("storage: setting up Redis client")
	if len(c.Redis.Servers) == 0 {
		return errors.New("at least one redis server must be configured")
	}

	var tlsConfig *tls.Config
	if c.Redis.TLSEnabled {
		tlsConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}

	if c.Redis.Cluster {
		redisClient = redis.NewClusterClient(&redis.ClusterOptions{
			Addrs:     c.Redis.Servers,
			PoolSize:  c.Redis.PoolSize,
			Password:  <PASSWORD>,
			TLSConfig: tlsConfig,
		})
	} else if c.Redis.MasterName != "" {
		redisClient = redis.NewFailoverClient(&redis.FailoverOptions{
			MasterName:       c.Redis.MasterName,
			SentinelAddrs:    c.Redis.Servers,
			SentinelPassword: c.Redis.Password,
			DB:               c.Redis.Database,
			PoolSize:         c.Redis.PoolSize,
			Password:         <PASSWORD>,
			TLSConfig:        tlsConfig,
		})
	} else {
		redisClient = redis.NewClient(&redis.Options{
			Addr:      c.Redis.Servers[0],
			DB:        c.Redis.Database,
			Password:  <PASSWORD>,
			PoolSize:  c.Redis.PoolSize,
			TLSConfig: tlsConfig,
		})
	}

	log.Info("storage: connecting to PostgreSQL")
	d, err := sqlx.Open("postgres", c.PostgreSQL.DSN)
	if err != nil {
		return errors.Wrap(err, "storage: PostgreSQL connection error")
	}
	d.SetMaxOpenConns(c.PostgreSQL.MaxOpenConnections)
{'fraction_non_alphanumeric': 0.12297216102543561, 'fraction_numerical': 0.004205888243540957, 'mean_word_length': 3.7835249042145596, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6930589', 'n_tokens_mistral': 1931, 'n_tokens_neox': 1826, 'n_words': 330}