This repository has been archived by the owner on May 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.go
131 lines (114 loc) · 3.7 KB
/
server.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
package server
import (
"context"
"errors"
"fmt"
"math/rand"
"time"
todomgrpb "github.com/giantswarm/giantswarm-todo-app/todo-manager/pkg/proto"
"github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
// initialize mysql gorm driver
_ "github.com/jinzhu/gorm/dialects/mysql"
)
const dbName = "todo"
// TodoManagerServer implements gRPC server for todo manager
type TodoManagerServer struct {
config *Config
db *gorm.DB
}
// NewTodoManagerServer creates a new TodoManagerServer
func NewTodoManagerServer(config *Config) *TodoManagerServer {
driverName := "mysql"
mysqlConnectString := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
config.MysqlUser, config.MysqlPass, config.MysqlHost, dbName)
db, err := gorm.Open(driverName, mysqlConnectString)
if err != nil {
panic(fmt.Sprintf("Failed to connect database: %v", err))
}
db.AutoMigrate(&TodoEntry{})
mgr := &TodoManagerServer{
config: config,
db: db,
}
return mgr
}
// Stop stops the server and frees resources
func (t *TodoManagerServer) Stop() {
t.db.Close()
}
// CreateTodo stores new todo in database
func (t *TodoManagerServer) CreateTodo(ctx context.Context, todo *todomgrpb.Todo) (*todomgrpb.Todo, error) {
dbTodo := FromGrpc(todo)
_, span := trace.StartSpan(ctx, "db-create")
t.db.Create(dbTodo)
span.End()
if dbTodo.ID == 0 {
return nil, errors.New("Error inserting to database")
}
return dbTodo.ToGrpc(), nil
}
// ListTodos lists all todos owned by the user sent in request
func (t *TodoManagerServer) ListTodos(req *todomgrpb.ListTodosReq, srv todomgrpb.TodoManager_ListTodosServer) error {
var todos []TodoEntry
_, span := trace.StartSpan(srv.Context(), "db-list")
log.Info("DB: starting 'list all' query for all the entries of an owner.")
if t.config.EnableFailures {
if num := rand.Int() % 10; num == 0 {
// simulate the DB is really slow
time.Sleep(time.Duration(rand.Int()%3+1) * time.Second)
}
}
t.db.Where("owner = ?", req.Owner).Find(&todos)
span.End()
for _, t := range todos {
todo := t.ToGrpc()
srv.Send(todo)
}
return nil
}
// GetTodo returns todo with specified ID and owner, if it exists
func (t *TodoManagerServer) GetTodo(ctx context.Context, grpcTodo *todomgrpb.TodoIdReq) (*todomgrpb.Todo, error) {
found := TodoEntry{}
_, span := trace.StartSpan(ctx, "db-get")
t.db.First(&found, grpcTodo.GetId())
span.End()
if found.ID == 0 || found.Owner != grpcTodo.GetOwner() {
return nil, errors.New("Todo not found")
}
return found.ToGrpc(), nil
}
// UpdateTodo updates a todo with a specified ID and owner, if it exists
func (t *TodoManagerServer) UpdateTodo(ctx context.Context, grpcTodo *todomgrpb.Todo) (*todomgrpb.Todo, error) {
found := TodoEntry{}
_, span := trace.StartSpan(ctx, "db-update-get")
t.db.First(&found, grpcTodo.GetId())
span.End()
if found.ID == 0 || found.Owner != grpcTodo.GetOwner() {
return nil, errors.New("Todo not found")
}
found.Text = grpcTodo.Text
found.Done = grpcTodo.Done
_, span = trace.StartSpan(ctx, "db-update-save")
t.db.Save(&found)
span.End()
if found.ID == 0 {
return nil, errors.New("Error updating record in DB")
}
return found.ToGrpc(), nil
}
// DeleteTodo deletes a todo with a specified ID and owner, if it exists
func (t *TodoManagerServer) DeleteTodo(ctx context.Context, grpcTodo *todomgrpb.TodoIdReq) (*todomgrpb.DeleteTodoRes, error) {
found := TodoEntry{}
_, span := trace.StartSpan(ctx, "db-update-get")
t.db.First(&found, grpcTodo.GetId())
span.End()
if found.ID == 0 || found.Owner != grpcTodo.GetOwner() {
return nil, errors.New("Todo not found")
}
_, span = trace.StartSpan(ctx, "db-update-delete")
t.db.Delete(&found)
span.End()
return &todomgrpb.DeleteTodoRes{Success: true}, nil
}