Skip to content

Commit 93b917e

Browse files
iwpndARolek
authored andcommitted
feat: allow connection to redis using uri
closes: #1010 chore: resolve review comments
1 parent 0f3131f commit 93b917e

File tree

3 files changed

+102
-32
lines changed

3 files changed

+102
-32
lines changed

cache/redis/README.md

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
# RedisCache
22

3-
This package implements tegola's cache interface for use with Redis. If a redis instance is running locally with default configurations solely for tegola simply include the following snippet in tegola's config file:
3+
This package implements tegola's cache interface for use with Redis.
4+
If a redis instance is running locally with default configurations solely
5+
for tegola simply include the following snippet in tegola's config file:
46

57
```toml
68
[cache]
79
type="redis"
810
```
911

1012
## Properties
13+
1114
The rediscache config supports the following properties:
1215

13-
- `network` (string): [Optional] Network type, either `tcp` or `unix`. Defaults to 'tcp'.
14-
- `address` (string): [Optional] the address of the Redis instance in form of `ip:port`. Defaults to '127.0.0.1:6379'.
15-
- `password` (string): [Optional] password for the Redis instance. Defaults to '' (no password).
16-
- `db` (int): [Optional] the database within the Redis instance to cache to.
17-
- `max_zoom` (int): [Optional] the max zoom the cache should cache to. After this zoom, Set() calls will return before doing work.
18-
- `ttl` (int): [Optional] the key ttl time in seconds. Defaults to 0 (the key has no expiration time).
19-
- `ssl` (bool): [Optional] encrypt connection to the Redis server. Defaults to false (no SSL/TLS)
16+
> [!IMPORTANT]
17+
> Connecting to redis via `uri` is going to be the default from v0.22.0
18+
> onwards. The properties `network`, `address`, `password` `db` and `ssl`
19+
> are deprecated.
2020
21+
- `uri` (string): protocol `redis://` or `rediss://` followed by `<user>:<password>@<host>:<port>/<database>`
22+
- `network` (string): [Optional] Network type, either `tcp` or `unix`.
23+
Defaults to 'tcp'.
24+
- `address` (string): [Optional] the address of the Redis instance in form
25+
of `ip:port`. Defaults to '127.0.0.1:6379'.
26+
- `password` (string): [Optional] password for the Redis instance.
27+
Defaults to '' (no password).
28+
- `db` (int): [Optional] the database within the Redis instance to cache to.
29+
- `max_zoom` (int): [Optional] the max zoom the cache should cache to.
30+
After this zoom, Set() calls will return before doing work.
31+
- `ttl` (int): [Optional] the key ttl time in seconds. Defaults to 0
32+
(the key has no expiration time).
33+
- `ssl` (bool): [Optional] encrypt connection to the Redis server.
34+
Defaults to false (no SSL/TLS)

cache/redis/redis.go

+20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/go-spatial/tegola"
1111
"github.com/go-spatial/tegola/cache"
1212
"github.com/go-spatial/tegola/dict"
13+
"github.com/go-spatial/tegola/internal/log"
1314
)
1415

1516
const CacheType = "redis"
@@ -22,13 +23,15 @@ const (
2223
ConfigKeyMaxZoom = "max_zoom"
2324
ConfigKeyTTL = "ttl"
2425
ConfigKeySSL = "ssl"
26+
ConfigKeyURI = "uri"
2527
)
2628

2729
var (
2830
// default values
2931
defaultNetwork = "tcp"
3032
defaultAddress = "127.0.0.1:6379"
3133
defaultPassword = ""
34+
defaultURI = ""
3235
defaultDB = 0
3336
defaultMaxZoom = uint(tegola.MaxZ)
3437
defaultTTL = 0
@@ -39,8 +42,25 @@ func init() {
3942
cache.Register(CacheType, New)
4043
}
4144

45+
// TODO @iwpnd: deprecate connection with Addr
4246
// CreateOptions creates redis.Options from an implicit or explicit c
4347
func CreateOptions(c dict.Dicter) (opts *redis.Options, err error) {
48+
uri, err := c.String(ConfigKeyURI, &defaultURI)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
if uri != "" {
54+
opts, err := redis.ParseURL(uri)
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
return opts, nil
60+
}
61+
62+
log.Warn("connecting to redis using 'Addr' is deprecated. use 'uri' instead.")
63+
4464
network, err := c.String(ConfigKeyNetwork, &defaultNetwork)
4565
if err != nil {
4666
return nil, err

cache/redis/redis_test.go

+60-24
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestCreateOptions(t *testing.T) {
5050

5151
tests := map[string]tcase{
5252
"test complete config": {
53-
config: map[string]interface{}{
53+
config: map[string]any{
5454
"network": "tcp",
5555
"address": "127.0.0.1:6379",
5656
"password": "test",
@@ -65,8 +65,31 @@ func TestCreateOptions(t *testing.T) {
6565
Password: "test",
6666
},
6767
},
68+
"test with uri no ssl": {
69+
config: map[string]any{
70+
"uri": "redis://user:[email protected]:6379/0",
71+
},
72+
expected: &goredis.Options{
73+
Network: "tcp",
74+
DB: 0,
75+
Addr: "127.0.0.1:6379",
76+
Password: "test",
77+
},
78+
},
79+
"test with uri with ssl": {
80+
config: map[string]any{
81+
"uri": "rediss://user:[email protected]:6379/0",
82+
},
83+
expected: &goredis.Options{
84+
Network: "tcp",
85+
DB: 0,
86+
Addr: "127.0.0.1:6379",
87+
Password: "test",
88+
TLSConfig: &tls.Config{ /* no deep comparison */ },
89+
},
90+
},
6891
"test empty config": {
69-
config: map[string]interface{}{},
92+
config: map[string]any{},
7093
expected: &goredis.Options{
7194
Network: "tcp",
7295
DB: 0,
@@ -76,7 +99,7 @@ func TestCreateOptions(t *testing.T) {
7699
},
77100
"test ssl config": {
78101
name: "test test ssl config",
79-
config: map[string]interface{}{
102+
config: map[string]any{
80103
"network": "tcp",
81104
"address": "127.0.0.1:6379",
82105
"password": "test",
@@ -94,7 +117,7 @@ func TestCreateOptions(t *testing.T) {
94117
},
95118
"test bad address": {
96119
name: "test test ssl config",
97-
config: map[string]interface{}{
120+
config: map[string]any{
98121
"network": "tcp",
99122
"address": 2,
100123
"password": "test",
@@ -108,7 +131,7 @@ func TestCreateOptions(t *testing.T) {
108131
},
109132
"test bad host": {
110133
name: "test test ssl config",
111-
config: map[string]interface{}{
134+
config: map[string]any{
112135
"network": "tcp",
113136
"address": "::8080",
114137
"db": 0,
@@ -117,7 +140,7 @@ func TestCreateOptions(t *testing.T) {
117140
},
118141
"test missing host": {
119142
name: "test test ssl config",
120-
config: map[string]interface{}{
143+
config: map[string]any{
121144
"network": "tcp",
122145
"address": ":8080",
123146
"db": 0,
@@ -126,7 +149,7 @@ func TestCreateOptions(t *testing.T) {
126149
},
127150
"test missing port": {
128151
name: "test test ssl config",
129-
config: map[string]interface{}{
152+
config: map[string]any{
130153
"network": "tcp",
131154
"address": "localhost",
132155
"db": 0,
@@ -135,7 +158,7 @@ func TestCreateOptions(t *testing.T) {
135158
},
136159
"test bad db": {
137160
name: "test test ssl config",
138-
config: map[string]interface{}{
161+
config: map[string]any{
139162
"network": "tcp",
140163
"address": "127.0.0.1:6379",
141164
"db": "fails",
@@ -148,7 +171,7 @@ func TestCreateOptions(t *testing.T) {
148171
},
149172
"test bad password": {
150173
name: "test test ssl config",
151-
config: map[string]interface{}{
174+
config: map[string]any{
152175
"network": "tcp",
153176
"address": "127.0.0.1:6379",
154177
"password": 0,
@@ -161,7 +184,7 @@ func TestCreateOptions(t *testing.T) {
161184
},
162185
"test bad network": {
163186
name: "test test ssl config",
164-
config: map[string]interface{}{
187+
config: map[string]any{
165188
"network": 0,
166189
"address": "127.0.0.1:6379",
167190
},
@@ -173,7 +196,7 @@ func TestCreateOptions(t *testing.T) {
173196
},
174197
"test bad ssl": {
175198
name: "test test ssl config",
176-
config: map[string]interface{}{
199+
config: map[string]any{
177200
"network": "tcp",
178201
"address": "127.0.0.1:6379",
179202
"ssl": 0,
@@ -265,7 +288,7 @@ func TestNew(t *testing.T) {
265288

266289
tests := map[string]tcase{
267290
"explicit config": {
268-
config: map[string]interface{}{
291+
config: map[string]any{
269292
"network": "tcp",
270293
"address": "127.0.0.1:6379",
271294
"password": "",
@@ -274,27 +297,40 @@ func TestNew(t *testing.T) {
274297
"ssl": false,
275298
},
276299
},
300+
"explicit config with uri": {
301+
config: map[string]any{
302+
"uri": "redis://127.0.0.1:6379/0",
303+
},
304+
},
277305
"implicit config": {
278-
config: map[string]interface{}{},
306+
config: map[string]any{},
279307
},
280308
"bad config address": {
281-
config: map[string]interface{}{"address": 0},
309+
config: map[string]any{"address": 0},
282310
expectedErr: dict.ErrKeyType{
283311
Key: "address",
284312
Value: 0,
285313
T: reflect.TypeOf(""),
286314
},
287315
},
316+
"bad config uri": {
317+
config: map[string]any{"uri": 1},
318+
expectedErr: dict.ErrKeyType{
319+
Key: "uri",
320+
Value: 1,
321+
T: reflect.TypeOf(""),
322+
},
323+
},
288324
"bad config ttl": {
289-
config: map[string]interface{}{"ttl": "fails"},
325+
config: map[string]any{"ttl": "fails"},
290326
expectedErr: dict.ErrKeyType{
291327
Key: "ttl",
292328
Value: "fails",
293329
T: reflect.TypeOf(1),
294330
},
295331
},
296332
"bad address": {
297-
config: map[string]interface{}{
333+
config: map[string]any{
298334
"address": "127.0.0.1:6000",
299335
},
300336
expectedErr: &net.OpError{
@@ -310,7 +346,7 @@ func TestNew(t *testing.T) {
310346
},
311347
},
312348
"bad max_zoom": {
313-
config: map[string]interface{}{
349+
config: map[string]any{
314350
"max_zoom": "2",
315351
},
316352
expectedErr: dict.ErrKeyType{
@@ -320,7 +356,7 @@ func TestNew(t *testing.T) {
320356
},
321357
},
322358
"bad max_zoom 2": {
323-
config: map[string]interface{}{
359+
config: map[string]any{
324360
"max_zoom": -2,
325361
},
326362
expectedErr: dict.ErrKeyType{
@@ -392,7 +428,7 @@ func TestSetGetPurge(t *testing.T) {
392428

393429
testcases := map[string]tcase{
394430
"redis cache hit": {
395-
config: map[string]interface{}{},
431+
config: map[string]any{},
396432
key: cache.Key{
397433
Z: 0,
398434
X: 1,
@@ -402,7 +438,7 @@ func TestSetGetPurge(t *testing.T) {
402438
expectedHit: true,
403439
},
404440
"redis cache miss": {
405-
config: map[string]interface{}{},
441+
config: map[string]any{},
406442
key: cache.Key{
407443
Z: 0,
408444
X: 0,
@@ -475,7 +511,7 @@ func TestSetOverwrite(t *testing.T) {
475511

476512
testcases := map[string]tcase{
477513
"redis overwrite": {
478-
config: map[string]interface{}{},
514+
config: map[string]any{},
479515
key: cache.Key{
480516
Z: 0,
481517
X: 1,
@@ -539,7 +575,7 @@ func TestMaxZoom(t *testing.T) {
539575

540576
tests := map[string]tcase{
541577
"over max zoom": {
542-
config: map[string]interface{}{
578+
config: map[string]any{
543579
"max_zoom": uint(10),
544580
},
545581
key: cache.Key{
@@ -551,7 +587,7 @@ func TestMaxZoom(t *testing.T) {
551587
expectedHit: false,
552588
},
553589
"under max zoom": {
554-
config: map[string]interface{}{
590+
config: map[string]any{
555591
"max_zoom": uint(10),
556592
},
557593
key: cache.Key{
@@ -563,7 +599,7 @@ func TestMaxZoom(t *testing.T) {
563599
expectedHit: true,
564600
},
565601
"equals max zoom": {
566-
config: map[string]interface{}{
602+
config: map[string]any{
567603
"max_zoom": uint(10),
568604
},
569605
key: cache.Key{

0 commit comments

Comments
 (0)