-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
148 lines (125 loc) · 4.44 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"context"
"time"
keelpersistence "github.com/foomo/keel/persistence"
"github.com/google/uuid"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"github.com/foomo/keel"
"github.com/foomo/keel/examples/persistence/mongo/repository"
"github.com/foomo/keel/examples/persistence/mongo/store"
"github.com/foomo/keel/log"
keelmongo "github.com/foomo/keel/persistence/mongo"
)
// docker run -it --rm -p 27017:27017 mongo
func main() {
svr := keel.NewServer()
// get the logger
l := svr.Logger()
cDateTime := &store.DateTimeCodec{}
rb := bson.NewRegistry()
rb.RegisterTypeEncoder(store.TDateTime, cDateTime)
rb.RegisterTypeDecoder(store.TDateTime, cDateTime)
// create persistor
persistor, err := keelmongo.New(
svr.Context(),
"mongodb://localhost:27017/dummy",
// enable telemetry (enabled by default)
keelmongo.WithOtelEnabled(true),
keelmongo.WithClientOptions(
func(clientOptions *options.ClientOptions) {
clientOptions.SetRegistry(rb)
},
),
)
// use log must helper to exit on error
log.Must(l, err, "failed to create persistor")
// ensure to add the persistor to the closers
svr.AddClosers(persistor)
// create repositories
col, err := persistor.Collection(
"dummy",
// define indexes but beware of changes on large dbs
keelmongo.CollectionWithIndexes(
store.EntityIndex,
store.EntityWithVersionsIndex,
),
// define max time for index creation
keelmongo.CollectionWithIndexesMaxTime(time.Second*10),
)
log.Must(l, err, "failed to create collection")
repo := repository.NewDummyRepository(col)
// --- version example ---
// insert entity
newEntity := &store.Dummy{
Entity: store.NewEntity(uuid.New().String()),
}
log.Must(l, repo.Insert(context.Background(), newEntity), "failed to insert")
// fail insert for duplicate entity
l.Info("Try to insert with duplicate key")
if err := repo.Insert(context.Background(), &store.Dummy{
Entity: store.NewEntity(newEntity.ID),
}); mongo.IsDuplicateKeyError(err) {
l.Info("OK: expected error", log.FValue(err.Error()))
} else if err != nil {
l.Error("unexpected error", log.FValue(err.Error()))
} else {
l.Error("unexpected success")
}
// fail insert for duplicate entity
l.Info("Try to upsert with duplicate key")
if err := repo.Upsert(context.Background(), &store.Dummy{
Entity: store.NewEntity(newEntity.ID),
}); mongo.IsDuplicateKeyError(err) {
l.Info("OK: expected error", log.FValue(err.Error()))
} else if err != nil {
l.Error("unexpected error", log.FValue(err.Error()))
} else {
l.Error("unexpected success")
}
l.Info("Try to upsert many with duplicate key")
if err := repo.UpsertMany(context.Background(), []*store.Dummy{{
Entity: store.NewEntity(newEntity.ID),
}}); mongo.IsDuplicateKeyError(err) {
l.Info("OK: expected error", log.FValue(err.Error()))
} else if err != nil {
l.Error("unexpected error", log.FValue(err.Error()))
} else {
l.Error("unexpected success")
}
// get entity x2
l.Info("Try to upsert with dirty write")
newEntityA, err := repo.Get(context.Background(), newEntity.ID)
log.Must(l, err, "failed to load new entity")
newEntityB, err := repo.Get(context.Background(), newEntity.ID)
log.Must(l, err, "failed to load new entity")
// update entity A
log.Must(l, repo.Upsert(context.Background(), newEntityA), "ERROR: failed to load new entity")
// update entity B
if err := repo.Upsert(context.Background(), newEntityB); errors.Is(err, keelpersistence.ErrDirtyWrite) {
l.Info("OK: expected error", log.FValue(err.Error()))
} else if err != nil {
l.Error("unexpected error", log.FValue(err.Error()))
} else {
l.Error("unexpected success")
}
l.Info("Try to upsert many with dirty write")
newEntityA, err = repo.Get(context.Background(), newEntity.ID)
log.Must(l, err, "failed to load new entity")
newEntityB, err = repo.Get(context.Background(), newEntity.ID)
log.Must(l, err, "failed to load new entity")
// update entity A
log.Must(l, repo.UpsertMany(context.Background(), []*store.Dummy{newEntityA}), "ERROR: failed to load new entity")
l.Info("Try to upsert many with dirty write")
if err := repo.UpsertMany(context.Background(), []*store.Dummy{newEntityB}); errors.Is(err, keelpersistence.ErrDirtyWrite) {
l.Info("OK: expected error", log.FValue(err.Error()))
} else if err != nil {
l.Error("unexpected error", log.FValue(err.Error()))
} else {
l.Error("unexpected success")
}
svr.Run()
}