From c77487904451667e44539a95afc6aefd8e4559e3 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Wed, 12 May 2021 19:26:23 +0100 Subject: [PATCH] remove the services we won't use --- chats/.gitignore | 2 - chats/Dockerfile | 3 - chats/Makefile | 26 - chats/README.md | 5 - chats/generate.go | 3 - chats/handler/chats.go | 126 -- chats/handler/chats_test.go | 74 -- chats/handler/create_chat.go | 80 -- chats/handler/create_chat_test.go | 62 - chats/handler/create_message.go | 87 -- chats/handler/create_message_test.go | 108 -- chats/handler/list_messages.go | 69 -- chats/handler/list_messages_test.go | 114 -- chats/main.go | 28 - chats/micro.mu | 1 - chats/proto/chats.pb.go | 746 ------------ chats/proto/chats.pb.micro.go | 137 --- chats/proto/chats.proto | 78 -- groups/.gitignore | 2 - groups/Dockerfile | 3 - groups/Makefile | 27 - groups/README.md | 6 - groups/generate.go | 3 - groups/handler/handler.go | 375 ------ groups/handler/handler_test.go | 280 ----- groups/main.go | 24 - groups/micro.mu | 1 - groups/proto/groups.pb.go | 1096 ----------------- groups/proto/groups.pb.micro.go | 209 ---- groups/proto/groups.proto | 81 -- invites/.gitignore | 2 - invites/Dockerfile | 3 - invites/Makefile | 27 - invites/README.md | 6 - invites/examples.json | 57 - invites/generate.go | 3 - invites/handler/invites.go | 347 ------ invites/handler/invites_test.go | 258 ---- invites/main.go | 25 - invites/micro.mu | 1 - invites/proto/invites.pb.go | 716 ----------- invites/proto/invites.pb.micro.go | 152 --- invites/proto/invites.proto | 55 - mail/Makefile | 27 - mail/README.md | 6 - mail/handler/handler.go | 116 -- mail/main.go | 25 - mail/micro.mu | 1 - mail/proto/mail.pb.go | 603 ---------- mail/proto/mail.pb.micro.go | 127 -- mail/proto/mail.proto | 44 - mail/skip | 0 mail/usage.md | 49 - notes/README.md | 6 - notes/handler/handler.go | 161 --- notes/main.go | 22 - notes/micro.mu | 1 - notes/proto/notes.pb.go | 436 ------- notes/proto/notes.pb.micro.go | 236 ---- notes/proto/notes.proto | 48 - notes/skip | 0 notes/usage.md | 42 - seen/.gitignore | 2 - seen/Dockerfile | 3 - seen/Makefile | 27 - seen/README.md | 6 - seen/handler/handler.go | 221 ---- seen/handler/handler_test.go | 250 ---- seen/main.go | 24 - seen/micro.mu | 1 - seen/proto/seen.pb.go | 614 ---------- seen/proto/seen.pb.micro.go | 140 --- seen/proto/seen.proto | 52 - streams/.gitignore | 2 - streams/Makefile | 27 - streams/README.md | 7 - streams/handler/handler.go | 57 - streams/handler/handler_test.go | 43 - streams/handler/publish.go | 34 - streams/handler/publish_test.go | 47 - streams/handler/subscribe.go | 89 -- streams/handler/subscribe_test.go | 228 ---- streams/handler/token.go | 41 - streams/handler/token_test.go | 38 - streams/main.go | 33 - streams/micro.mu | 1 - streams/proto/streams.pb.go | 441 ------- streams/proto/streams.pb.micro.go | 203 ---- streams/proto/streams.proto | 38 - threads/.gitignore | 2 - threads/Dockerfile | 3 - threads/Makefile | 27 - threads/README.md | 6 - threads/generate.go | 3 - threads/handler/create_message.go | 74 -- threads/handler/create_message_test.go | 107 -- threads/handler/create_thread.go | 45 - threads/handler/create_thread_test.go | 58 - threads/handler/delete_thread.go | 41 - threads/handler/delete_thread_test.go | 49 - threads/handler/handler.go | 144 --- threads/handler/handler_test.go | 82 -- threads/handler/list_messages.go | 69 -- threads/handler/list_messages_test.go | 114 -- threads/handler/list_threads.go | 39 - threads/handler/list_threads_test.go | 54 - threads/handler/read_thread.go | 46 - threads/handler/read_thread_test.go | 68 -- threads/handler/recent_messages.go | 62 - threads/handler/recent_messages_test.go | 99 -- threads/handler/update_thread.go | 47 - threads/handler/update_thread_test.go | 65 - threads/main.go | 28 - threads/micro.mu | 1 - threads/proto/threads.pb.go | 1443 ---------------------- threads/proto/threads.pb.micro.go | 234 ---- threads/proto/threads.proto | 115 -- users/.gitignore | 1 - users/Dockerfile | 3 - users/Makefile | 27 - users/README.md | 5 - users/generate.go | 3 - users/handler/create.go | 87 -- users/handler/create_test.go | 128 -- users/handler/delete.go | 44 - users/handler/delete_test.go | 55 - users/handler/handler.go | 88 -- users/handler/handler_test.go | 55 - users/handler/list.go | 36 - users/handler/list_test.go | 66 - users/handler/login.go | 65 - users/handler/login_test.go | 82 -- users/handler/logout.go | 47 - users/handler/logout_test.go | 47 - users/handler/read.go | 41 - users/handler/read_by_email.go | 46 - users/handler/read_by_email_test.go | 88 -- users/handler/read_test.go | 87 -- users/handler/update.go | 87 -- users/handler/update_test.go | 147 --- users/handler/validate.go | 55 - users/handler/validate_test.go | 100 -- users/main.go | 45 - users/micro.mu | 1 - users/proto/users.pb.go | 1454 ----------------------- users/proto/users.pb.micro.go | 236 ---- users/proto/users.proto | 104 -- 147 files changed, 16582 deletions(-) delete mode 100644 chats/.gitignore delete mode 100644 chats/Dockerfile delete mode 100644 chats/Makefile delete mode 100644 chats/README.md delete mode 100644 chats/generate.go delete mode 100644 chats/handler/chats.go delete mode 100644 chats/handler/chats_test.go delete mode 100644 chats/handler/create_chat.go delete mode 100644 chats/handler/create_chat_test.go delete mode 100644 chats/handler/create_message.go delete mode 100644 chats/handler/create_message_test.go delete mode 100644 chats/handler/list_messages.go delete mode 100644 chats/handler/list_messages_test.go delete mode 100644 chats/main.go delete mode 100644 chats/micro.mu delete mode 100644 chats/proto/chats.pb.go delete mode 100644 chats/proto/chats.pb.micro.go delete mode 100644 chats/proto/chats.proto delete mode 100644 groups/.gitignore delete mode 100644 groups/Dockerfile delete mode 100644 groups/Makefile delete mode 100644 groups/README.md delete mode 100644 groups/generate.go delete mode 100644 groups/handler/handler.go delete mode 100644 groups/handler/handler_test.go delete mode 100644 groups/main.go delete mode 100644 groups/micro.mu delete mode 100644 groups/proto/groups.pb.go delete mode 100644 groups/proto/groups.pb.micro.go delete mode 100644 groups/proto/groups.proto delete mode 100644 invites/.gitignore delete mode 100644 invites/Dockerfile delete mode 100644 invites/Makefile delete mode 100644 invites/README.md delete mode 100644 invites/examples.json delete mode 100644 invites/generate.go delete mode 100644 invites/handler/invites.go delete mode 100644 invites/handler/invites_test.go delete mode 100644 invites/main.go delete mode 100644 invites/micro.mu delete mode 100644 invites/proto/invites.pb.go delete mode 100644 invites/proto/invites.pb.micro.go delete mode 100644 invites/proto/invites.proto delete mode 100644 mail/Makefile delete mode 100644 mail/README.md delete mode 100644 mail/handler/handler.go delete mode 100644 mail/main.go delete mode 100644 mail/micro.mu delete mode 100644 mail/proto/mail.pb.go delete mode 100644 mail/proto/mail.pb.micro.go delete mode 100644 mail/proto/mail.proto delete mode 100644 mail/skip delete mode 100644 mail/usage.md delete mode 100644 notes/README.md delete mode 100644 notes/handler/handler.go delete mode 100644 notes/main.go delete mode 100644 notes/micro.mu delete mode 100644 notes/proto/notes.pb.go delete mode 100644 notes/proto/notes.pb.micro.go delete mode 100644 notes/proto/notes.proto delete mode 100644 notes/skip delete mode 100644 notes/usage.md delete mode 100644 seen/.gitignore delete mode 100644 seen/Dockerfile delete mode 100644 seen/Makefile delete mode 100644 seen/README.md delete mode 100644 seen/handler/handler.go delete mode 100644 seen/handler/handler_test.go delete mode 100644 seen/main.go delete mode 100644 seen/micro.mu delete mode 100644 seen/proto/seen.pb.go delete mode 100644 seen/proto/seen.pb.micro.go delete mode 100644 seen/proto/seen.proto delete mode 100644 streams/.gitignore delete mode 100644 streams/Makefile delete mode 100644 streams/README.md delete mode 100644 streams/handler/handler.go delete mode 100644 streams/handler/handler_test.go delete mode 100644 streams/handler/publish.go delete mode 100644 streams/handler/publish_test.go delete mode 100644 streams/handler/subscribe.go delete mode 100644 streams/handler/subscribe_test.go delete mode 100644 streams/handler/token.go delete mode 100644 streams/handler/token_test.go delete mode 100644 streams/main.go delete mode 100644 streams/micro.mu delete mode 100644 streams/proto/streams.pb.go delete mode 100644 streams/proto/streams.pb.micro.go delete mode 100644 streams/proto/streams.proto delete mode 100644 threads/.gitignore delete mode 100644 threads/Dockerfile delete mode 100644 threads/Makefile delete mode 100644 threads/README.md delete mode 100644 threads/generate.go delete mode 100644 threads/handler/create_message.go delete mode 100644 threads/handler/create_message_test.go delete mode 100644 threads/handler/create_thread.go delete mode 100644 threads/handler/create_thread_test.go delete mode 100644 threads/handler/delete_thread.go delete mode 100644 threads/handler/delete_thread_test.go delete mode 100644 threads/handler/handler.go delete mode 100644 threads/handler/handler_test.go delete mode 100644 threads/handler/list_messages.go delete mode 100644 threads/handler/list_messages_test.go delete mode 100644 threads/handler/list_threads.go delete mode 100644 threads/handler/list_threads_test.go delete mode 100644 threads/handler/read_thread.go delete mode 100644 threads/handler/read_thread_test.go delete mode 100644 threads/handler/recent_messages.go delete mode 100644 threads/handler/recent_messages_test.go delete mode 100644 threads/handler/update_thread.go delete mode 100644 threads/handler/update_thread_test.go delete mode 100644 threads/main.go delete mode 100644 threads/micro.mu delete mode 100644 threads/proto/threads.pb.go delete mode 100644 threads/proto/threads.pb.micro.go delete mode 100644 threads/proto/threads.proto delete mode 100644 users/.gitignore delete mode 100644 users/Dockerfile delete mode 100644 users/Makefile delete mode 100644 users/README.md delete mode 100644 users/generate.go delete mode 100644 users/handler/create.go delete mode 100644 users/handler/create_test.go delete mode 100644 users/handler/delete.go delete mode 100644 users/handler/delete_test.go delete mode 100644 users/handler/handler.go delete mode 100644 users/handler/handler_test.go delete mode 100644 users/handler/list.go delete mode 100644 users/handler/list_test.go delete mode 100644 users/handler/login.go delete mode 100644 users/handler/login_test.go delete mode 100644 users/handler/logout.go delete mode 100644 users/handler/logout_test.go delete mode 100644 users/handler/read.go delete mode 100644 users/handler/read_by_email.go delete mode 100644 users/handler/read_by_email_test.go delete mode 100644 users/handler/read_test.go delete mode 100644 users/handler/update.go delete mode 100644 users/handler/update_test.go delete mode 100644 users/handler/validate.go delete mode 100644 users/handler/validate_test.go delete mode 100644 users/main.go delete mode 100644 users/micro.mu delete mode 100644 users/proto/users.pb.go delete mode 100644 users/proto/users.pb.micro.go delete mode 100644 users/proto/users.proto diff --git a/chats/.gitignore b/chats/.gitignore deleted file mode 100644 index 9204471..0000000 --- a/chats/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -chats diff --git a/chats/Dockerfile b/chats/Dockerfile deleted file mode 100644 index bf08280..0000000 --- a/chats/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD chats /chats -ENTRYPOINT [ "/chats" ] diff --git a/chats/Makefile b/chats/Makefile deleted file mode 100644 index 674d8f1..0000000 --- a/chats/Makefile +++ /dev/null @@ -1,26 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=. proto/chats.proto - -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=. proto/chats.proto - @redoc-cli bundle api-chats.json - -.PHONY: build -build: - go build -o chats *.go - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t chats:latest diff --git a/chats/README.md b/chats/README.md deleted file mode 100644 index a6ea550..0000000 --- a/chats/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Chats is a service for direct messaging - -# Chats Service - -The chats service enables direct messaging between one or more parties. diff --git a/chats/generate.go b/chats/generate.go deleted file mode 100644 index 7d9db91..0000000 --- a/chats/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate make proto diff --git a/chats/handler/chats.go b/chats/handler/chats.go deleted file mode 100644 index 72483d9..0000000 --- a/chats/handler/chats.go +++ /dev/null @@ -1,126 +0,0 @@ -package handler - -import ( - "context" - "fmt" - "sort" - "strings" - "time" - - pb "github.com/micro/services/chats/proto" - "github.com/micro/services/pkg/tenant" - - "github.com/micro/micro/v3/service/errors" -) - -var ( - ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") - ErrMissingAuthorID = errors.BadRequest("MISSING_AUTHOR_ID", "Missing Author ID") - ErrMissingText = errors.BadRequest("MISSING_TEXT", "Missing text") - ErrMissingChatID = errors.BadRequest("MISSING_CHAT_ID", "Missing Chat ID") - ErrMissingUserIDs = errors.BadRequest("MISSING_USER_IDs", "Two or more user IDs are required") - ErrNotFound = errors.NotFound("NOT_FOUND", "Chat not found") -) - -type Chats struct { - Time func() time.Time -} - -type Chat struct { - ID string - UserIDs []string - CreatedAt time.Time -} - -type Message struct { - ID string - AuthorID string - ChatID string - Text string - SentAt time.Time -} - -func ParseTime(v string) time.Time { - t, err := time.Parse(time.RFC3339Nano, v) - if err == nil { - return t - } - t, err = time.Parse(time.RFC3339, v) - if err == nil { - return t - } - return time.Time{} -} - -func (m *Message) Serialize() *pb.Message { - return &pb.Message{ - Id: m.ID, - AuthorId: m.AuthorID, - ChatId: m.ChatID, - Text: m.Text, - SentAt: m.SentAt.Format(time.RFC3339Nano), - } -} - -func (c *Chat) Index(ctx context.Context) string { - sort.Strings(c.UserIDs) - users := strings.Join(c.UserIDs, "-") - - key := fmt.Sprintf("chatByUserIDs:%s", users) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (c *Chat) Key(ctx context.Context) string { - key := fmt.Sprintf("chat:%s", c.ID) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (m *Message) Key(ctx context.Context) string { - key := fmt.Sprintf("message:%s:%s", m.ChatID, m.ID) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (m *Message) Index(ctx context.Context) string { - key := fmt.Sprintf("messagesByChatID:%s", m.ChatID) - - if !m.SentAt.IsZero() { - key = fmt.Sprintf("%s:%d", key, m.SentAt.UnixNano()) - - if len(m.ID) > 0 { - key = fmt.Sprintf("%s:%s", key, m.ID) - } - } - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (c *Chat) Serialize() *pb.Chat { - return &pb.Chat{ - Id: c.ID, - UserIds: c.UserIDs, - CreatedAt: c.CreatedAt.Format(time.RFC3339Nano), - } -} diff --git a/chats/handler/chats_test.go b/chats/handler/chats_test.go deleted file mode 100644 index 67d8274..0000000 --- a/chats/handler/chats_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package handler_test - -import ( - "context" - "testing" - "time" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/store" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/chats/handler" - pb "github.com/micro/services/chats/proto" - "github.com/stretchr/testify/assert" -) - -func testHandler(t *testing.T) *handler.Chats { - store.DefaultStore = memory.NewStore() - return &handler.Chats{Time: func() time.Time { return time.Unix(1611327673, 0) }} -} - -func assertChatsMatch(t *testing.T, exp, act *pb.Chat) { - if act == nil { - t.Errorf("Chat not returned") - return - } - - // adapt this check so we can reuse the func in testing create, where we don't know the exact id - // which will be generated - if len(exp.Id) > 0 { - assert.Equal(t, exp.Id, act.Id) - } else { - assert.NotEmpty(t, act.Id) - } - - assert.Equal(t, exp.UserIds, act.UserIds) - - if len(act.CreatedAt) == 0 { - t.Errorf("CreatedAt not set") - return - } - - assert.True(t, exp.CreatedAt == act.CreatedAt) -} - -func assertMessagesMatch(t *testing.T, exp, act *pb.Message) { - if act == nil { - t.Errorf("Message not returned") - return - } - - // adapt these checks so we can reuse the func in testing create, where we don't know the exact id / - // idempotent_id which will be generated - if len(exp.Id) > 0 { - assert.Equal(t, exp.Id, act.Id) - } else { - assert.NotEmpty(t, act.Id) - } - assert.Equal(t, exp.Text, act.Text) - assert.Equal(t, exp.AuthorId, act.AuthorId) - assert.Equal(t, exp.ChatId, act.ChatId) - - if len(act.SentAt) == 0 { - t.Errorf("SentAt not set") - return - } - - assert.True(t, exp.SentAt == act.SentAt) -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - }) -} diff --git a/chats/handler/create_chat.go b/chats/handler/create_chat.go deleted file mode 100644 index 1bb631b..0000000 --- a/chats/handler/create_chat.go +++ /dev/null @@ -1,80 +0,0 @@ -package handler - -import ( - "context" - "sort" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/chats/proto" -) - -// Create a chat between two or more users, if a chat already exists for these users, the existing -// chat will be returned -func (c *Chats) CreateChat(ctx context.Context, req *pb.CreateChatRequest, rsp *pb.CreateChatResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.UserIds) < 2 { - return ErrMissingUserIDs - } - - // sort the user ids - sort.Strings(req.UserIds) - - id := uuid.New().String() - if len(req.Id) > 0 { - id = req.Id - } - - // construct the chat - chat := &Chat{ - ID: id, - CreatedAt: time.Now(), - UserIDs: req.UserIds, - } - - // read the chat by the unique composition of ids - recs, err := store.Read(chat.Key(ctx), store.ReadLimit(1)) - if err == nil && len(recs) == 1 { - // found an existing record - recs[0].Decode(&chat) - rsp.Chat = chat.Serialize() - return nil - } - - // if not found check it exists by user index key - if err == store.ErrNotFound { - recs, err = store.Read(chat.Index(ctx), store.ReadLimit(1)) - if err == nil && len(recs) > 0 { - recs[0].Decode(&chat) - rsp.Chat = chat.Serialize() - return nil - } - } - - // ok otherwise we're creating an entirely new record - newRec := store.NewRecord(chat.Key(ctx), chat) - if err := store.Write(newRec); err != nil { - logger.Errorf("Error creating chat: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // write the user composite key - newRec = store.NewRecord(chat.Index(ctx), chat) - if err := store.Write(newRec); err != nil { - logger.Errorf("Error creating chat: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // return the record - rsp.Chat = chat.Serialize() - - return nil -} diff --git a/chats/handler/create_chat_test.go b/chats/handler/create_chat_test.go deleted file mode 100644 index f3968d7..0000000 --- a/chats/handler/create_chat_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/micro/services/chats/handler" - pb "github.com/micro/services/chats/proto" - "github.com/stretchr/testify/assert" -) - -func TestCreateChat(t *testing.T) { - userIDs := []string{uuid.New().String(), uuid.New().String()} - - tt := []struct { - Name string - UserIDs []string - Error error - }{ - { - Name: "NoUserIDs", - Error: handler.ErrMissingUserIDs, - }, - { - Name: "OneUserID", - UserIDs: userIDs[1:], - Error: handler.ErrMissingUserIDs, - }, - { - Name: "Valid", - UserIDs: userIDs, - }, - { - Name: "Repeat", - UserIDs: userIDs, - }, - } - - var chat *pb.Chat - h := testHandler(t) - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.CreateChatResponse - err := h.CreateChat(microAccountCtx(), &pb.CreateChatRequest{ - UserIds: tc.UserIDs, - }, &rsp) - - assert.Equal(t, tc.Error, err) - if tc.Error != nil { - return - } - - assert.NotNil(t, rsp.Chat) - if chat == nil { - chat = rsp.Chat - } else { - assertChatsMatch(t, chat, rsp.Chat) - } - }) - } -} diff --git a/chats/handler/create_message.go b/chats/handler/create_message.go deleted file mode 100644 index 9161347..0000000 --- a/chats/handler/create_message.go +++ /dev/null @@ -1,87 +0,0 @@ -package handler - -import ( - "context" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/chats/proto" -) - -// Create a message within a chat -func (c *Chats) SendMessage(ctx context.Context, req *pb.SendMessageRequest, rsp *pb.SendMessageResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.AuthorId) == 0 { - return ErrMissingAuthorID - } - if len(req.ChatId) == 0 { - return ErrMissingChatID - } - if len(req.Text) == 0 { - return ErrMissingText - } - - chat := &Chat{ - ID: req.ChatId, - } - - recs, err := store.Read(chat.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading chat: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // create the message - msg := &Message{ - ID: req.Id, - Text: req.Text, - AuthorID: req.AuthorId, - ChatID: req.ChatId, - SentAt: c.Time(), - } - if len(msg.ID) == 0 { - msg.ID = uuid.New().String() - } - - // check if the message already exists - recs, err = store.Read(msg.Key(ctx), store.ReadLimit(1)) - if err == nil && len(recs) == 1 { - // return the existing message - msg = &Message{} - recs[0].Decode(&msg) - rsp.Message = msg.Serialize() - return nil - } - - // if there's an error then return - if err != nil && err != store.ErrNotFound { - logger.Errorf("Error creating message: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // otherwise write the record - if err := store.Write(store.NewRecord(msg.Key(ctx), msg)); err != nil { - logger.Errorf("Error creating message: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // write the time based index - if err := store.Write(store.NewRecord(msg.Index(ctx), msg)); err == nil { - rsp.Message = msg.Serialize() - return nil - } else if err != nil { - logger.Errorf("Error creating message: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - return nil -} diff --git a/chats/handler/create_message_test.go b/chats/handler/create_message_test.go deleted file mode 100644 index 9d4c942..0000000 --- a/chats/handler/create_message_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package handler_test - -import ( - "testing" - "time" - - "github.com/micro/services/chats/handler" - pb "github.com/micro/services/chats/proto" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func TestSendMessage(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateChatResponse - err := h.CreateChat(microAccountCtx(), &pb.CreateChatRequest{ - UserIds: []string{uuid.New().String(), uuid.New().String()}, - }, &cRsp) - if err != nil { - t.Fatalf("Error creating chat: %v", err) - return - } - - iid := uuid.New().String() - tt := []struct { - Name string - AuthorID string - ChatID string - Text string - Error error - ID string - }{ - { - Name: "MissingChatID", - Text: "HelloWorld", - AuthorID: uuid.New().String(), - Error: handler.ErrMissingChatID, - }, - { - Name: "MissingAuthorID", - ChatID: uuid.New().String(), - Text: "HelloWorld", - Error: handler.ErrMissingAuthorID, - }, - { - Name: "MissingText", - ChatID: uuid.New().String(), - AuthorID: uuid.New().String(), - Error: handler.ErrMissingText, - }, - { - Name: "ChatNotFound", - ChatID: uuid.New().String(), - AuthorID: uuid.New().String(), - Text: "HelloWorld", - Error: handler.ErrNotFound, - }, - { - Name: "WithoutID", - ChatID: cRsp.Chat.Id, - AuthorID: uuid.New().String(), - Text: "HelloWorld", - }, - { - Name: "WithID", - ChatID: cRsp.Chat.Id, - AuthorID: "johndoe", - Text: "HelloWorld", - ID: iid, - }, - { - Name: "RepeatID", - ChatID: cRsp.Chat.Id, - AuthorID: "johndoe", - Text: "HelloWorld", - ID: iid, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.SendMessageResponse - err := h.SendMessage(microAccountCtx(), &pb.SendMessageRequest{ - AuthorId: tc.AuthorID, - ChatId: tc.ChatID, - Text: tc.Text, - Id: tc.ID, - }, &rsp) - - assert.Equal(t, tc.Error, err) - if tc.Error != nil { - assert.Nil(t, rsp.Message) - return - } - - assertMessagesMatch(t, &pb.Message{ - AuthorId: tc.AuthorID, - ChatId: tc.ChatID, - SentAt: h.Time().Format(time.RFC3339Nano), - Text: tc.Text, - Id: tc.ID, - }, rsp.Message) - }) - } -} diff --git a/chats/handler/list_messages.go b/chats/handler/list_messages.go deleted file mode 100644 index b4f6ec5..0000000 --- a/chats/handler/list_messages.go +++ /dev/null @@ -1,69 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/chats/proto" -) - -const DefaultLimit = 25 - -// List the messages within a chat in reverse chronological order, using sent_before to -// offset as older messages need to be loaded -func (c *Chats) ListMessages(ctx context.Context, req *pb.ListMessagesRequest, rsp *pb.ListMessagesResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.ChatId) == 0 { - return ErrMissingChatID - } - - message := &Message{ - ChatID: req.ChatId, - } - - // default order is descending - order := store.OrderDesc - if req.Order == "asc" { - order = store.OrderAsc - } - - opts := []store.ReadOption{ - store.ReadPrefix(), - store.ReadOrder(order), - } - - if req.Limit > 0 { - opts = append(opts, store.ReadLimit(uint(req.Limit))) - } else { - opts = append(opts, store.ReadLimit(uint(DefaultLimit))) - } - if req.Offset > 0 { - opts = append(opts, store.ReadOffset(uint(req.Offset))) - } - - // read all the records with the chat ID suffix - recs, err := store.Read(message.Index(ctx), opts...) - if err != nil { - logger.Errorf("Error reading messages: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // return all the messages - for _, rec := range recs { - m := &Message{} - rec.Decode(&m) - if len(m.ID) == 0 || m.ChatID != req.ChatId { - continue - } - rsp.Messages = append(rsp.Messages, m.Serialize()) - } - - return nil -} diff --git a/chats/handler/list_messages_test.go b/chats/handler/list_messages_test.go deleted file mode 100644 index b7b1347..0000000 --- a/chats/handler/list_messages_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package handler_test - -import ( - "sort" - "strconv" - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/services/chats/handler" - pb "github.com/micro/services/chats/proto" - "github.com/stretchr/testify/assert" -) - -func TestListMessages(t *testing.T) { - h := testHandler(t) - h.Time = time.Now - - // seed some data - var chatRsp pb.CreateChatResponse - err := h.CreateChat(microAccountCtx(), &pb.CreateChatRequest{ - UserIds: []string{uuid.New().String(), uuid.New().String()}, - }, &chatRsp) - assert.NoError(t, err) - if err != nil { - return - } - - msgs := make([]*pb.Message, 50) - for i := 0; i < len(msgs); i++ { - var rsp pb.SendMessageResponse - err := h.SendMessage(microAccountCtx(), &pb.SendMessageRequest{ - ChatId: chatRsp.Chat.Id, - AuthorId: uuid.New().String(), - Text: strconv.Itoa(i), - }, &rsp) - assert.NoError(t, err) - msgs[i] = rsp.Message - } - - t.Run("MissingChatID", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingChatID, err) - assert.Nil(t, rsp.Messages) - }) - - t.Run("NoOffset", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ChatId: chatRsp.Chat.Id, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != handler.DefaultLimit { - t.Fatalf("Expected %v messages but got %v", handler.DefaultLimit, len(rsp.Messages)) - return - } - expected := msgs[25:] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) - - t.Run("LimitSet", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ChatId: chatRsp.Chat.Id, - Limit: 10, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 10 { - t.Fatalf("Expected %v messages but got %v", 10, len(rsp.Messages)) - return - } - expected := msgs[40:] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) - - t.Run("OffsetAndLimit", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ChatId: chatRsp.Chat.Id, - Limit: 5, - Offset: 15, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 5 { - t.Fatalf("Expected %v messages but got %v", 5, len(rsp.Messages)) - return - } - expected := msgs[30:35] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) -} - -// sortMessages by the time they were sent -func sortMessages(msgs []*pb.Message) { - sort.Slice(msgs, func(i, j int) bool { - if len(msgs[i].SentAt) == 0 || len(msgs[j].SentAt) == 0 { - return true - } - return handler.ParseTime(msgs[i].SentAt).Before(handler.ParseTime(msgs[j].SentAt)) - }) -} diff --git a/chats/main.go b/chats/main.go deleted file mode 100644 index f260ad2..0000000 --- a/chats/main.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "time" - - "github.com/micro/services/chats/handler" - pb "github.com/micro/services/chats/proto" - - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" -) - -func main() { - // Create service - srv := service.New( - service.Name("chats"), - service.Version("latest"), - ) - - h := &handler.Chats{Time: time.Now} - // Register handler - pb.RegisterChatsHandler(srv.Server(), h) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/chats/micro.mu b/chats/micro.mu deleted file mode 100644 index 69d9005..0000000 --- a/chats/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service chats diff --git a/chats/proto/chats.pb.go b/chats/proto/chats.pb.go deleted file mode 100644 index 273a36f..0000000 --- a/chats/proto/chats.pb.go +++ /dev/null @@ -1,746 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 -// source: proto/chats.proto - -package chats - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Chat struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // unique id of the chat - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // list of users in the chat - UserIds []string `protobuf:"bytes,2,rep,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"` - // RFC3339Nano timestamp - CreatedAt string `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` -} - -func (x *Chat) Reset() { - *x = Chat{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Chat) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Chat) ProtoMessage() {} - -func (x *Chat) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Chat.ProtoReflect.Descriptor instead. -func (*Chat) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{0} -} - -func (x *Chat) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Chat) GetUserIds() []string { - if x != nil { - return x.UserIds - } - return nil -} - -func (x *Chat) GetCreatedAt() string { - if x != nil { - return x.CreatedAt - } - return "" -} - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // unique id of the message - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // user id of the message - AuthorId string `protobuf:"bytes,2,opt,name=author_id,json=authorId,proto3" json:"author_id,omitempty"` - // chat id the message belongs to - ChatId string `protobuf:"bytes,3,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"` - // text within the message - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` - // RFC3339Nano timestamp - SentAt string `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{1} -} - -func (x *Message) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Message) GetAuthorId() string { - if x != nil { - return x.AuthorId - } - return "" -} - -func (x *Message) GetChatId() string { - if x != nil { - return x.ChatId - } - return "" -} - -func (x *Message) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -func (x *Message) GetSentAt() string { - if x != nil { - return x.SentAt - } - return "" -} - -// Create a new chat between mulitple users -type CreateChatRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The chat ID - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // List of users in the chat - UserIds []string `protobuf:"bytes,2,rep,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"` -} - -func (x *CreateChatRequest) Reset() { - *x = CreateChatRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateChatRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateChatRequest) ProtoMessage() {} - -func (x *CreateChatRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateChatRequest.ProtoReflect.Descriptor instead. -func (*CreateChatRequest) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateChatRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *CreateChatRequest) GetUserIds() []string { - if x != nil { - return x.UserIds - } - return nil -} - -type CreateChatResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Chat *Chat `protobuf:"bytes,1,opt,name=chat,proto3" json:"chat,omitempty"` -} - -func (x *CreateChatResponse) Reset() { - *x = CreateChatResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateChatResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateChatResponse) ProtoMessage() {} - -func (x *CreateChatResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateChatResponse.ProtoReflect.Descriptor instead. -func (*CreateChatResponse) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{3} -} - -func (x *CreateChatResponse) GetChat() *Chat { - if x != nil { - return x.Chat - } - return nil -} - -// Send a message to a chat room -type SendMessageRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - ChatId string `protobuf:"bytes,2,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"` - AuthorId string `protobuf:"bytes,3,opt,name=author_id,json=authorId,proto3" json:"author_id,omitempty"` - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` -} - -func (x *SendMessageRequest) Reset() { - *x = SendMessageRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendMessageRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendMessageRequest) ProtoMessage() {} - -func (x *SendMessageRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendMessageRequest.ProtoReflect.Descriptor instead. -func (*SendMessageRequest) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{4} -} - -func (x *SendMessageRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *SendMessageRequest) GetChatId() string { - if x != nil { - return x.ChatId - } - return "" -} - -func (x *SendMessageRequest) GetAuthorId() string { - if x != nil { - return x.AuthorId - } - return "" -} - -func (x *SendMessageRequest) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -type SendMessageResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *SendMessageResponse) Reset() { - *x = SendMessageResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendMessageResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendMessageResponse) ProtoMessage() {} - -func (x *SendMessageResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendMessageResponse.ProtoReflect.Descriptor instead. -func (*SendMessageResponse) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{5} -} - -func (x *SendMessageResponse) GetMessage() *Message { - if x != nil { - return x.Message - } - return nil -} - -// List messages within a chat -type ListMessagesRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // unique id of the chat - ChatId string `protobuf:"bytes,1,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"` - // limit the number of messages - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - // offset for the messages - Offset int64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"` - // order "asc" or "desc" (defaults to reverse chronological) - Order string `protobuf:"bytes,4,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *ListMessagesRequest) Reset() { - *x = ListMessagesRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListMessagesRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListMessagesRequest) ProtoMessage() {} - -func (x *ListMessagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListMessagesRequest.ProtoReflect.Descriptor instead. -func (*ListMessagesRequest) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{6} -} - -func (x *ListMessagesRequest) GetChatId() string { - if x != nil { - return x.ChatId - } - return "" -} - -func (x *ListMessagesRequest) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *ListMessagesRequest) GetOffset() int64 { - if x != nil { - return x.Offset - } - return 0 -} - -func (x *ListMessagesRequest) GetOrder() string { - if x != nil { - return x.Order - } - return "" -} - -type ListMessagesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Messages []*Message `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` -} - -func (x *ListMessagesResponse) Reset() { - *x = ListMessagesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_chats_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListMessagesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListMessagesResponse) ProtoMessage() {} - -func (x *ListMessagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_chats_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListMessagesResponse.ProtoReflect.Descriptor instead. -func (*ListMessagesResponse) Descriptor() ([]byte, []int) { - return file_proto_chats_proto_rawDescGZIP(), []int{7} -} - -func (x *ListMessagesResponse) GetMessages() []*Message { - if x != nil { - return x.Messages - } - return nil -} - -var File_proto_chats_proto protoreflect.FileDescriptor - -var file_proto_chats_proto_rawDesc = []byte{ - 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x63, 0x68, 0x61, 0x74, 0x73, 0x22, 0x50, 0x0a, 0x04, 0x43, 0x68, - 0x61, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x1d, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x7c, 0x0a, 0x07, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x68, 0x61, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x22, 0x3e, 0x0a, 0x11, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0x35, 0x0a, 0x12, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1f, 0x0a, 0x04, 0x63, 0x68, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x52, 0x04, 0x63, 0x68, 0x61, - 0x74, 0x22, 0x6e, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x68, 0x61, 0x74, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, - 0x74, 0x22, 0x3f, 0x0a, 0x13, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x72, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x68, 0x61, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x68, 0x61, 0x74, - 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x42, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, - 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x32, 0xd9, 0x01, 0x0a, 0x05, 0x43, - 0x68, 0x61, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, - 0x61, 0x74, 0x12, 0x18, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, - 0x68, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1a, 0x2e, - 0x63, 0x68, 0x61, 0x74, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x68, 0x61, 0x74, - 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x3b, 0x63, 0x68, 0x61, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_chats_proto_rawDescOnce sync.Once - file_proto_chats_proto_rawDescData = file_proto_chats_proto_rawDesc -) - -func file_proto_chats_proto_rawDescGZIP() []byte { - file_proto_chats_proto_rawDescOnce.Do(func() { - file_proto_chats_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_chats_proto_rawDescData) - }) - return file_proto_chats_proto_rawDescData -} - -var file_proto_chats_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_proto_chats_proto_goTypes = []interface{}{ - (*Chat)(nil), // 0: chats.Chat - (*Message)(nil), // 1: chats.Message - (*CreateChatRequest)(nil), // 2: chats.CreateChatRequest - (*CreateChatResponse)(nil), // 3: chats.CreateChatResponse - (*SendMessageRequest)(nil), // 4: chats.SendMessageRequest - (*SendMessageResponse)(nil), // 5: chats.SendMessageResponse - (*ListMessagesRequest)(nil), // 6: chats.ListMessagesRequest - (*ListMessagesResponse)(nil), // 7: chats.ListMessagesResponse -} -var file_proto_chats_proto_depIdxs = []int32{ - 0, // 0: chats.CreateChatResponse.chat:type_name -> chats.Chat - 1, // 1: chats.SendMessageResponse.message:type_name -> chats.Message - 1, // 2: chats.ListMessagesResponse.messages:type_name -> chats.Message - 2, // 3: chats.Chats.CreateChat:input_type -> chats.CreateChatRequest - 4, // 4: chats.Chats.SendMessage:input_type -> chats.SendMessageRequest - 6, // 5: chats.Chats.ListMessages:input_type -> chats.ListMessagesRequest - 3, // 6: chats.Chats.CreateChat:output_type -> chats.CreateChatResponse - 5, // 7: chats.Chats.SendMessage:output_type -> chats.SendMessageResponse - 7, // 8: chats.Chats.ListMessages:output_type -> chats.ListMessagesResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_proto_chats_proto_init() } -func file_proto_chats_proto_init() { - if File_proto_chats_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_chats_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Chat); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateChatRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateChatResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendMessageRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendMessageResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMessagesRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_chats_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMessagesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_chats_proto_rawDesc, - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_chats_proto_goTypes, - DependencyIndexes: file_proto_chats_proto_depIdxs, - MessageInfos: file_proto_chats_proto_msgTypes, - }.Build() - File_proto_chats_proto = out.File - file_proto_chats_proto_rawDesc = nil - file_proto_chats_proto_goTypes = nil - file_proto_chats_proto_depIdxs = nil -} diff --git a/chats/proto/chats.pb.micro.go b/chats/proto/chats.pb.micro.go deleted file mode 100644 index 3297be0..0000000 --- a/chats/proto/chats.pb.micro.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/chats.proto - -package chats - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Chats service - -func NewChatsEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Chats service - -type ChatsService interface { - // Create a chat between two or more users, if a chat already exists for these users, the existing - // chat will be returned - CreateChat(ctx context.Context, in *CreateChatRequest, opts ...client.CallOption) (*CreateChatResponse, error) - // Create a message within a chat - SendMessage(ctx context.Context, in *SendMessageRequest, opts ...client.CallOption) (*SendMessageResponse, error) - // List the messages within a chat in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - ListMessages(ctx context.Context, in *ListMessagesRequest, opts ...client.CallOption) (*ListMessagesResponse, error) -} - -type chatsService struct { - c client.Client - name string -} - -func NewChatsService(name string, c client.Client) ChatsService { - return &chatsService{ - c: c, - name: name, - } -} - -func (c *chatsService) CreateChat(ctx context.Context, in *CreateChatRequest, opts ...client.CallOption) (*CreateChatResponse, error) { - req := c.c.NewRequest(c.name, "Chats.CreateChat", in) - out := new(CreateChatResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *chatsService) SendMessage(ctx context.Context, in *SendMessageRequest, opts ...client.CallOption) (*SendMessageResponse, error) { - req := c.c.NewRequest(c.name, "Chats.SendMessage", in) - out := new(SendMessageResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *chatsService) ListMessages(ctx context.Context, in *ListMessagesRequest, opts ...client.CallOption) (*ListMessagesResponse, error) { - req := c.c.NewRequest(c.name, "Chats.ListMessages", in) - out := new(ListMessagesResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Chats service - -type ChatsHandler interface { - // Create a chat between two or more users, if a chat already exists for these users, the existing - // chat will be returned - CreateChat(context.Context, *CreateChatRequest, *CreateChatResponse) error - // Create a message within a chat - SendMessage(context.Context, *SendMessageRequest, *SendMessageResponse) error - // List the messages within a chat in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - ListMessages(context.Context, *ListMessagesRequest, *ListMessagesResponse) error -} - -func RegisterChatsHandler(s server.Server, hdlr ChatsHandler, opts ...server.HandlerOption) error { - type chats interface { - CreateChat(ctx context.Context, in *CreateChatRequest, out *CreateChatResponse) error - SendMessage(ctx context.Context, in *SendMessageRequest, out *SendMessageResponse) error - ListMessages(ctx context.Context, in *ListMessagesRequest, out *ListMessagesResponse) error - } - type Chats struct { - chats - } - h := &chatsHandler{hdlr} - return s.Handle(s.NewHandler(&Chats{h}, opts...)) -} - -type chatsHandler struct { - ChatsHandler -} - -func (h *chatsHandler) CreateChat(ctx context.Context, in *CreateChatRequest, out *CreateChatResponse) error { - return h.ChatsHandler.CreateChat(ctx, in, out) -} - -func (h *chatsHandler) SendMessage(ctx context.Context, in *SendMessageRequest, out *SendMessageResponse) error { - return h.ChatsHandler.SendMessage(ctx, in, out) -} - -func (h *chatsHandler) ListMessages(ctx context.Context, in *ListMessagesRequest, out *ListMessagesResponse) error { - return h.ChatsHandler.ListMessages(ctx, in, out) -} diff --git a/chats/proto/chats.proto b/chats/proto/chats.proto deleted file mode 100644 index 41e2890..0000000 --- a/chats/proto/chats.proto +++ /dev/null @@ -1,78 +0,0 @@ -syntax = "proto3"; - -package chats; - -option go_package = "./proto;chats"; - -service Chats { - // Create a chat between two or more users, if a chat already exists for these users, the existing - // chat will be returned - rpc CreateChat(CreateChatRequest) returns (CreateChatResponse); - // Create a message within a chat - rpc SendMessage(SendMessageRequest) returns (SendMessageResponse); - // List the messages within a chat in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - rpc ListMessages(ListMessagesRequest) returns (ListMessagesResponse); -} - -message Chat { - // unique id of the chat - string id = 1; - // list of users in the chat - repeated string user_ids = 2; - // RFC3339 Nano timestamp e.g 2006-01-02T15:04:05.999999999Z07:00 - string created_at = 3; -} - -message Message { - // unique id of the message - string id = 1; - // user id of the message - string author_id = 2; - // chat id the message belongs to - string chat_id = 3; - // text within the message - string text = 4; - // RFC3339 Nano timestamp e.g 2006-01-02T15:04:05.999999999Z07:00 - string sent_at = 5; -} - -// Create a new chat between mulitple users -message CreateChatRequest { - // The chat ID - string id = 1; - // List of users in the chat - repeated string user_ids = 2; -} - -message CreateChatResponse { - Chat chat = 1; -} - -// Send a message to a chat room -message SendMessageRequest { - string id = 1; - string chat_id = 2; - string author_id = 3; - string text = 4; -} - -message SendMessageResponse { - Message message = 1; -} - -// List messages within a chat -message ListMessagesRequest { - // unique id of the chat - string chat_id = 1; - // limit the number of messages - int64 limit = 2; - // offset for the messages - int64 offset = 3; - // order "asc" or "desc" (defaults to reverse chronological) - string order = 4; -} - -message ListMessagesResponse { - repeated Message messages = 1; -} diff --git a/groups/.gitignore b/groups/.gitignore deleted file mode 100644 index a2409d8..0000000 --- a/groups/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -groups diff --git a/groups/Dockerfile b/groups/Dockerfile deleted file mode 100644 index 65aec26..0000000 --- a/groups/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD groups /groups -ENTRYPOINT [ "/groups" ] diff --git a/groups/Makefile b/groups/Makefile deleted file mode 100644 index fc2aeff..0000000 --- a/groups/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/groups.proto - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/groups.proto - @redoc-cli bundle api-groups.json - -.PHONY: build -build: - go build -o groups *.go - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t groups:latest diff --git a/groups/README.md b/groups/README.md deleted file mode 100644 index bd94aaa..0000000 --- a/groups/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Manage group memberships - -# Groups Service - -The group service is a basic CRUD service for group membership management. Create groups, add members and lookup which groups a user is a member of. - diff --git a/groups/generate.go b/groups/generate.go deleted file mode 100644 index 7d9db91..0000000 --- a/groups/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate make proto diff --git a/groups/handler/handler.go b/groups/handler/handler.go deleted file mode 100644 index d3c8201..0000000 --- a/groups/handler/handler.go +++ /dev/null @@ -1,375 +0,0 @@ -package handler - -import ( - "context" - "fmt" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/groups/proto" - "github.com/micro/services/pkg/tenant" -) - -var ( - ErrMissingName = errors.BadRequest("MISSING_NAME", "Missing name") - ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") - ErrMissingIDs = errors.BadRequest("MISSING_IDS", "One or more IDs are required") - ErrMissingGroupID = errors.BadRequest("MISSING_GROUP_ID", "Missing Group ID") - ErrMissingMemberID = errors.BadRequest("MISSING_MEMBER_ID", "Missing Member ID") - ErrNotFound = errors.BadRequest("NOT_FOUND", "No group found with this ID") - ErrStore = errors.InternalServerError("STORE_ERROR", "Error connecting to the store") -) - -type Group struct { - ID string - Name string - Members []string -} - -type Member struct { - ID string - Group string -} - -func (g *Group) Key(ctx context.Context) string { - key := fmt.Sprintf("group:%s", g.ID) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (m *Member) Key(ctx context.Context) string { - key := fmt.Sprintf("member:%s:%s", m.ID, m.Group) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) - -} - -func (g *Group) Serialize() *pb.Group { - memberIDs := make([]string, len(g.Members)) - for i, m := range g.Members { - memberIDs[i] = m - } - return &pb.Group{Id: g.ID, Name: g.Name, MemberIds: memberIDs} -} - -type Groups struct{} - -func (g *Groups) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Name) == 0 { - return ErrMissingName - } - - // create the group object - group := &Group{ID: uuid.New().String(), Name: req.Name} - - // write the group record - if err := store.Write(store.NewRecord(group.Key(ctx), group)); err != nil { - return ErrStore - } - - // return the group - rsp.Group = group.Serialize() - - return nil -} - -func (g *Groups) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Ids) == 0 { - return ErrMissingIDs - } - - // serialize the response - rsp.Groups = make(map[string]*pb.Group) - - for _, id := range req.Ids { - group := &Group{ - ID: id, - } - recs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err != nil { - return ErrStore - } - if len(recs) == 0 { - continue - } - if err := recs[0].Decode(&group); err != nil { - continue - } - rsp.Groups[group.ID] = group.Serialize() - } - - return nil -} - -func (g *Groups) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - if len(req.Name) == 0 { - return ErrMissingName - } - - group := &Group{ID: req.Id} - - recs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - return ErrNotFound - } else if err != nil { - return ErrStore - } - - // decode the record - recs[0].Decode(&group) - - // set the name - group.Name = req.Name - - // save the record - if err := store.Write(store.NewRecord(group.Key(ctx), group)); err != nil { - return ErrStore - } - - // serialize the response - rsp.Group = group.Serialize() - - return nil -} - -func (g *Groups) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - - group := &Group{ID: req.Id} - - // get the group - recs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - return nil - } else if err != nil { - return ErrStore - } - - // decode the record - recs[0].Decode(&group) - - // delete the record - if err := store.Delete(group.Key(ctx)); err == store.ErrNotFound { - return nil - } else if err != nil { - return ErrStore - } - - // delete all the members - for _, memberId := range group.Members { - m := &Member{ - ID: memberId, - } - // delete the member - store.Delete(m.Key(ctx)) - } - - return nil -} - -func (g *Groups) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - - if len(req.MemberId) > 0 { - // only list groups the user is a member of - m := &Member{ID: req.MemberId} - recs, err := store.Read(m.Key(ctx), store.ReadPrefix()) - if err != nil { - return ErrStore - } - - for _, rec := range recs { - m := &Member{ID: req.MemberId} - rec.Decode(&m) - - // get the group - group := &Group{ID: m.Group} - - grecs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err != nil { - return ErrStore - } - grecs[0].Decode(&group) - - rsp.Groups = append(rsp.Groups, group.Serialize()) - } - - return nil - } - - group := &Group{} - - // read all the prefixes - recs, err := store.Read(group.Key(ctx), store.ReadPrefix()) - if err != nil { - return ErrStore - } - - // serialize and return response - for _, rec := range recs { - group := new(Group) - rec.Decode(&group) - rsp.Groups = append(rsp.Groups, group.Serialize()) - } - - return nil -} - -func (g *Groups) AddMember(ctx context.Context, req *pb.AddMemberRequest, rsp *pb.AddMemberResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.GroupId) == 0 { - return ErrMissingGroupID - } - if len(req.MemberId) == 0 { - return ErrMissingMemberID - } - - // read the group - group := &Group{ID: req.GroupId} - - recs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - return ErrNotFound - } else if err != nil { - return ErrStore - } - - // decode the record - recs[0].Decode(group) - - var seen bool - for _, member := range group.Members { - if member == req.MemberId { - seen = true - break - } - } - - // already a member - if seen { - return nil - } - - // add the member - group.Members = append(group.Members, req.MemberId) - - // save the record - if err := store.Write(store.NewRecord(group.Key(ctx), group)); err != nil { - return ErrStore - } - - // add the member record - - m := &Member{ - ID: req.MemberId, - Group: group.ID, - } - - // write the record - if err := store.Write(store.NewRecord(m.Key(ctx), m)); err != nil { - return ErrStore - } - - return nil -} - -func (g *Groups) RemoveMember(ctx context.Context, req *pb.RemoveMemberRequest, rsp *pb.RemoveMemberResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.GroupId) == 0 { - return ErrMissingGroupID - } - if len(req.MemberId) == 0 { - return ErrMissingMemberID - } - - // read the group - group := &Group{ID: req.GroupId} - - // read the gruop - recs, err := store.Read(group.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - return ErrNotFound - } else if err != nil { - return ErrStore - } - - // decode the record - recs[0].Decode(&group) - - // new member id list - var members []string - - for _, member := range group.Members { - if member == req.MemberId { - continue - } - members = append(members, member) - } - - // update the member - group.Members = members - - // save the record - if err := store.Write(store.NewRecord(group.Key(ctx), group)); err != nil { - return ErrStore - } - - // delete the member - m := &Member{ - ID: req.MemberId, - Group: group.ID, - } - if err := store.Delete(m.Key(ctx)); err != nil { - return ErrStore - } - - return nil -} diff --git a/groups/handler/handler_test.go b/groups/handler/handler_test.go deleted file mode 100644 index 9916234..0000000 --- a/groups/handler/handler_test.go +++ /dev/null @@ -1,280 +0,0 @@ -package handler_test - -import ( - "context" - "sort" - "testing" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/store" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/groups/handler" - pb "github.com/micro/services/groups/proto" - "github.com/stretchr/testify/assert" -) - -func testHandler(t *testing.T) *handler.Groups { - store.DefaultStore = memory.NewStore() - return &handler.Groups{} -} -func TestCreate(t *testing.T) { - h := testHandler(t) - - t.Run("MissingName", func(t *testing.T) { - err := h.Create(microAccountCtx(), &pb.CreateRequest{}, &pb.CreateResponse{}) - assert.Equal(t, handler.ErrMissingName, err) - }) - - t.Run("Valid", func(t *testing.T) { - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Doe Family Group", - }, &pb.CreateResponse{}) - assert.NoError(t, err) - }) -} - -func TestUpdate(t *testing.T) { - h := testHandler(t) - - t.Run("MissingID", func(t *testing.T) { - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Name: "Doe Family Group", - }, &pb.UpdateResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - t.Run("MissingName", func(t *testing.T) { - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: uuid.New().String(), - }, &pb.UpdateResponse{}) - assert.Equal(t, handler.ErrMissingName, err) - }) - - t.Run("NotFound", func(t *testing.T) { - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: uuid.New().String(), - Name: "Bar Family Group", - }, &pb.UpdateResponse{}) - assert.Equal(t, handler.ErrNotFound, err) - }) - - t.Run("Valid", func(t *testing.T) { - // create a demo group - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Doe Family Group", - }, &cRsp) - assert.NoError(t, err) - - err = h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp.Group.Id, - Name: "Bar Family Group", - }, &pb.UpdateResponse{}) - assert.NoError(t, err) - - var rRsp pb.ReadResponse - err = h.Read(microAccountCtx(), &pb.ReadRequest{ - Ids: []string{cRsp.Group.Id}, - }, &rRsp) - assert.NoError(t, err) - - g := rRsp.Groups[cRsp.Group.Id] - if g == nil { - t.Errorf("Group not returned") - } else { - assert.Equal(t, "Bar Family Group", g.Name) - } - }) -} - -func TestDelete(t *testing.T) { - h := testHandler(t) - - t.Run("MissingID", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{}, &pb.DeleteResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - t.Run("NotFound", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{ - Id: uuid.New().String(), - }, &pb.DeleteResponse{}) - assert.NoError(t, err) - }) - - // create a demo group - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Doe Family Group", - }, &cRsp) - assert.NoError(t, err) - - t.Run("Valid", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{ - Id: cRsp.Group.Id, - }, &pb.DeleteResponse{}) - assert.NoError(t, err) - - var rRsp pb.ReadResponse - err = h.Read(microAccountCtx(), &pb.ReadRequest{ - Ids: []string{cRsp.Group.Id}, - }, &rRsp) - assert.Nil(t, rRsp.Groups[cRsp.Group.Id]) - }) -} -func TestList(t *testing.T) { - h := testHandler(t) - - // create two demo groups - var cRsp1 pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Alpha Group", - }, &cRsp1) - assert.NoError(t, err) - - var cRsp2 pb.CreateResponse - err = h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Bravo Group", - }, &cRsp2) - assert.NoError(t, err) - - // add a member to the first group - uid := uuid.New().String() - err = h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - GroupId: cRsp1.Group.Id, MemberId: uid, - }, &pb.AddMemberResponse{}) - assert.NoError(t, err) - - t.Run("Unscoped", func(t *testing.T) { - var rsp pb.ListResponse - err = h.List(microAccountCtx(), &pb.ListRequest{}, &rsp) - assert.NoError(t, err) - assert.Lenf(t, rsp.Groups, 2, "Two groups should be returned") - if len(rsp.Groups) != 2 { - return - } - - sort.Slice(rsp.Groups, func(i, j int) bool { - return rsp.Groups[i].Name < rsp.Groups[j].Name - }) - assert.Equal(t, cRsp1.Group.Id, rsp.Groups[0].Id) - assert.Equal(t, cRsp1.Group.Name, rsp.Groups[0].Name) - assert.Len(t, rsp.Groups[0].MemberIds, 1) - assert.Contains(t, rsp.Groups[0].MemberIds, uid) - assert.Equal(t, cRsp2.Group.Id, rsp.Groups[1].Id) - assert.Equal(t, cRsp2.Group.Name, rsp.Groups[1].Name) - assert.Len(t, rsp.Groups[1].MemberIds, 0) - }) - - t.Run("Scoped", func(t *testing.T) { - var rsp pb.ListResponse - err = h.List(microAccountCtx(), &pb.ListRequest{MemberId: uid}, &rsp) - assert.NoError(t, err) - assert.Lenf(t, rsp.Groups, 1, "One group should be returned") - if len(rsp.Groups) != 1 { - return - } - assert.Equal(t, cRsp1.Group.Id, rsp.Groups[0].Id) - assert.Equal(t, cRsp1.Group.Name, rsp.Groups[0].Name) - assert.Len(t, rsp.Groups[0].MemberIds, 1) - assert.Contains(t, rsp.Groups[0].MemberIds, uid) - }) -} - -func TestAddMember(t *testing.T) { - h := testHandler(t) - - t.Run("MissingGroupID", func(t *testing.T) { - err := h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - MemberId: uuid.New().String(), - }, &pb.AddMemberResponse{}) - assert.Equal(t, handler.ErrMissingGroupID, err) - }) - - t.Run("MissingMemberID", func(t *testing.T) { - err := h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - GroupId: uuid.New().String(), - }, &pb.AddMemberResponse{}) - assert.Equal(t, handler.ErrMissingMemberID, err) - }) - - t.Run("GroupNotFound", func(t *testing.T) { - err := h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - GroupId: uuid.New().String(), - MemberId: uuid.New().String(), - }, &pb.AddMemberResponse{}) - assert.Equal(t, handler.ErrNotFound, err) - }) - - // create a test group - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Alpha Group", - }, &cRsp) - assert.NoError(t, err) - - t.Run("Valid", func(t *testing.T) { - err := h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - GroupId: cRsp.Group.Id, - MemberId: uuid.New().String(), - }, &pb.AddMemberResponse{}) - assert.NoError(t, err) - }) - - t.Run("Retry", func(t *testing.T) { - err := h.AddMember(microAccountCtx(), &pb.AddMemberRequest{ - GroupId: cRsp.Group.Id, - MemberId: uuid.New().String(), - }, &pb.AddMemberResponse{}) - assert.NoError(t, err) - }) -} - -func TestRemoveMember(t *testing.T) { - h := testHandler(t) - - t.Run("MissingGroupID", func(t *testing.T) { - err := h.RemoveMember(microAccountCtx(), &pb.RemoveMemberRequest{ - MemberId: uuid.New().String(), - }, &pb.RemoveMemberResponse{}) - assert.Equal(t, handler.ErrMissingGroupID, err) - }) - - t.Run("MissingMemberID", func(t *testing.T) { - err := h.RemoveMember(microAccountCtx(), &pb.RemoveMemberRequest{ - GroupId: uuid.New().String(), - }, &pb.RemoveMemberResponse{}) - assert.Equal(t, handler.ErrMissingMemberID, err) - }) - - // create a test group - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - Name: "Alpha Group", - }, &cRsp) - assert.NoError(t, err) - - t.Run("Valid", func(t *testing.T) { - err := h.RemoveMember(microAccountCtx(), &pb.RemoveMemberRequest{ - GroupId: cRsp.Group.Id, - MemberId: uuid.New().String(), - }, &pb.RemoveMemberResponse{}) - assert.NoError(t, err) - }) - - t.Run("Retry", func(t *testing.T) { - err := h.RemoveMember(microAccountCtx(), &pb.RemoveMemberRequest{ - GroupId: cRsp.Group.Id, - MemberId: uuid.New().String(), - }, &pb.RemoveMemberResponse{}) - assert.NoError(t, err) - }) -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - ID: "someID", - }) -} diff --git a/groups/main.go b/groups/main.go deleted file mode 100644 index 02c2156..0000000 --- a/groups/main.go +++ /dev/null @@ -1,24 +0,0 @@ -package main - -import ( - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/groups/handler" - pb "github.com/micro/services/groups/proto" -) - -func main() { - // Create service - srv := service.New( - service.Name("groups"), - service.Version("latest"), - ) - - // Register handler - pb.RegisterGroupsHandler(srv.Server(), new(handler.Groups)) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/groups/micro.mu b/groups/micro.mu deleted file mode 100644 index 157cef6..0000000 --- a/groups/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service groups diff --git a/groups/proto/groups.pb.go b/groups/proto/groups.pb.go deleted file mode 100644 index 2bf8486..0000000 --- a/groups/proto/groups.pb.go +++ /dev/null @@ -1,1096 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0 -// protoc v3.15.5 -// source: proto/groups.proto - -package groups - -import ( - proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Group struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - MemberIds []string `protobuf:"bytes,3,rep,name=member_ids,json=memberIds,proto3" json:"member_ids,omitempty"` -} - -func (x *Group) Reset() { - *x = Group{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Group) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Group) ProtoMessage() {} - -func (x *Group) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Group.ProtoReflect.Descriptor instead. -func (*Group) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{0} -} - -func (x *Group) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Group) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Group) GetMemberIds() []string { - if x != nil { - return x.MemberIds - } - return nil -} - -type CreateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *CreateRequest) Reset() { - *x = CreateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateRequest) ProtoMessage() {} - -func (x *CreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead. -func (*CreateRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{1} -} - -func (x *CreateRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type CreateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` -} - -func (x *CreateResponse) Reset() { - *x = CreateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateResponse) ProtoMessage() {} - -func (x *CreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateResponse.ProtoReflect.Descriptor instead. -func (*CreateResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateResponse) GetGroup() *Group { - if x != nil { - return x.Group - } - return nil -} - -type ReadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` -} - -func (x *ReadRequest) Reset() { - *x = ReadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadRequest) ProtoMessage() {} - -func (x *ReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. -func (*ReadRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{3} -} - -func (x *ReadRequest) GetIds() []string { - if x != nil { - return x.Ids - } - return nil -} - -type ReadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Groups map[string]*Group `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ReadResponse) Reset() { - *x = ReadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadResponse) ProtoMessage() {} - -func (x *ReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. -func (*ReadResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{4} -} - -func (x *ReadResponse) GetGroups() map[string]*Group { - if x != nil { - return x.Groups - } - return nil -} - -type UpdateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *UpdateRequest) Reset() { - *x = UpdateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateRequest) ProtoMessage() {} - -func (x *UpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead. -func (*UpdateRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{5} -} - -func (x *UpdateRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *UpdateRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type UpdateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` -} - -func (x *UpdateResponse) Reset() { - *x = UpdateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateResponse) ProtoMessage() {} - -func (x *UpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateResponse.ProtoReflect.Descriptor instead. -func (*UpdateResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{6} -} - -func (x *UpdateResponse) GetGroup() *Group { - if x != nil { - return x.Group - } - return nil -} - -type DeleteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteRequest) Reset() { - *x = DeleteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteRequest) ProtoMessage() {} - -func (x *DeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. -func (*DeleteRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{7} -} - -func (x *DeleteRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type DeleteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DeleteResponse) Reset() { - *x = DeleteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteResponse) ProtoMessage() {} - -func (x *DeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{8} -} - -type ListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // passing a member id will restrict the groups to that which the member is part of - MemberId string `protobuf:"bytes,1,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"` -} - -func (x *ListRequest) Reset() { - *x = ListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRequest) ProtoMessage() {} - -func (x *ListRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. -func (*ListRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{9} -} - -func (x *ListRequest) GetMemberId() string { - if x != nil { - return x.MemberId - } - return "" -} - -type ListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Groups []*Group `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty"` -} - -func (x *ListResponse) Reset() { - *x = ListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListResponse) ProtoMessage() {} - -func (x *ListResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. -func (*ListResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{10} -} - -func (x *ListResponse) GetGroups() []*Group { - if x != nil { - return x.Groups - } - return nil -} - -type AddMemberRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - MemberId string `protobuf:"bytes,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"` -} - -func (x *AddMemberRequest) Reset() { - *x = AddMemberRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddMemberRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddMemberRequest) ProtoMessage() {} - -func (x *AddMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddMemberRequest.ProtoReflect.Descriptor instead. -func (*AddMemberRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{11} -} - -func (x *AddMemberRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *AddMemberRequest) GetMemberId() string { - if x != nil { - return x.MemberId - } - return "" -} - -type AddMemberResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *AddMemberResponse) Reset() { - *x = AddMemberResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddMemberResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddMemberResponse) ProtoMessage() {} - -func (x *AddMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddMemberResponse.ProtoReflect.Descriptor instead. -func (*AddMemberResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{12} -} - -type RemoveMemberRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - MemberId string `protobuf:"bytes,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"` -} - -func (x *RemoveMemberRequest) Reset() { - *x = RemoveMemberRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RemoveMemberRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RemoveMemberRequest) ProtoMessage() {} - -func (x *RemoveMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RemoveMemberRequest.ProtoReflect.Descriptor instead. -func (*RemoveMemberRequest) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{13} -} - -func (x *RemoveMemberRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *RemoveMemberRequest) GetMemberId() string { - if x != nil { - return x.MemberId - } - return "" -} - -type RemoveMemberResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *RemoveMemberResponse) Reset() { - *x = RemoveMemberResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_groups_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RemoveMemberResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RemoveMemberResponse) ProtoMessage() {} - -func (x *RemoveMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_groups_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RemoveMemberResponse.ProtoReflect.Descriptor instead. -func (*RemoveMemberResponse) Descriptor() ([]byte, []int) { - return file_proto_groups_proto_rawDescGZIP(), []int{14} -} - -var File_proto_groups_proto protoreflect.FileDescriptor - -var file_proto_groups_proto_rawDesc = []byte{ - 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x4a, 0x0a, 0x05, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0x23, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x35, 0x0a, - 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x23, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x22, 0x1f, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x1a, 0x48, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x33, 0x0a, 0x0d, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x35, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x23, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x1f, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x49, 0x64, 0x22, 0x35, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x4a, 0x0a, 0x10, - 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, - 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, - 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x22, 0x16, 0x0a, 0x14, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa6, 0x03, 0x0a, 0x06, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, - 0x37, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, - 0x12, 0x13, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x15, - 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, - 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x40, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, 0x2e, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1c, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0e, 0x5a, - 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_groups_proto_rawDescOnce sync.Once - file_proto_groups_proto_rawDescData = file_proto_groups_proto_rawDesc -) - -func file_proto_groups_proto_rawDescGZIP() []byte { - file_proto_groups_proto_rawDescOnce.Do(func() { - file_proto_groups_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_groups_proto_rawDescData) - }) - return file_proto_groups_proto_rawDescData -} - -var file_proto_groups_proto_msgTypes = make([]protoimpl.MessageInfo, 16) -var file_proto_groups_proto_goTypes = []interface{}{ - (*Group)(nil), // 0: groups.Group - (*CreateRequest)(nil), // 1: groups.CreateRequest - (*CreateResponse)(nil), // 2: groups.CreateResponse - (*ReadRequest)(nil), // 3: groups.ReadRequest - (*ReadResponse)(nil), // 4: groups.ReadResponse - (*UpdateRequest)(nil), // 5: groups.UpdateRequest - (*UpdateResponse)(nil), // 6: groups.UpdateResponse - (*DeleteRequest)(nil), // 7: groups.DeleteRequest - (*DeleteResponse)(nil), // 8: groups.DeleteResponse - (*ListRequest)(nil), // 9: groups.ListRequest - (*ListResponse)(nil), // 10: groups.ListResponse - (*AddMemberRequest)(nil), // 11: groups.AddMemberRequest - (*AddMemberResponse)(nil), // 12: groups.AddMemberResponse - (*RemoveMemberRequest)(nil), // 13: groups.RemoveMemberRequest - (*RemoveMemberResponse)(nil), // 14: groups.RemoveMemberResponse - nil, // 15: groups.ReadResponse.GroupsEntry -} -var file_proto_groups_proto_depIdxs = []int32{ - 0, // 0: groups.CreateResponse.group:type_name -> groups.Group - 15, // 1: groups.ReadResponse.groups:type_name -> groups.ReadResponse.GroupsEntry - 0, // 2: groups.UpdateResponse.group:type_name -> groups.Group - 0, // 3: groups.ListResponse.groups:type_name -> groups.Group - 0, // 4: groups.ReadResponse.GroupsEntry.value:type_name -> groups.Group - 1, // 5: groups.Groups.Create:input_type -> groups.CreateRequest - 3, // 6: groups.Groups.Read:input_type -> groups.ReadRequest - 5, // 7: groups.Groups.Update:input_type -> groups.UpdateRequest - 7, // 8: groups.Groups.Delete:input_type -> groups.DeleteRequest - 9, // 9: groups.Groups.List:input_type -> groups.ListRequest - 11, // 10: groups.Groups.AddMember:input_type -> groups.AddMemberRequest - 13, // 11: groups.Groups.RemoveMember:input_type -> groups.RemoveMemberRequest - 2, // 12: groups.Groups.Create:output_type -> groups.CreateResponse - 4, // 13: groups.Groups.Read:output_type -> groups.ReadResponse - 6, // 14: groups.Groups.Update:output_type -> groups.UpdateResponse - 8, // 15: groups.Groups.Delete:output_type -> groups.DeleteResponse - 10, // 16: groups.Groups.List:output_type -> groups.ListResponse - 12, // 17: groups.Groups.AddMember:output_type -> groups.AddMemberResponse - 14, // 18: groups.Groups.RemoveMember:output_type -> groups.RemoveMemberResponse - 12, // [12:19] is the sub-list for method output_type - 5, // [5:12] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_proto_groups_proto_init() } -func file_proto_groups_proto_init() { - if File_proto_groups_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_groups_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Group); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddMemberRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddMemberResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveMemberRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_groups_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveMemberResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_groups_proto_rawDesc, - NumEnums: 0, - NumMessages: 16, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_groups_proto_goTypes, - DependencyIndexes: file_proto_groups_proto_depIdxs, - MessageInfos: file_proto_groups_proto_msgTypes, - }.Build() - File_proto_groups_proto = out.File - file_proto_groups_proto_rawDesc = nil - file_proto_groups_proto_goTypes = nil - file_proto_groups_proto_depIdxs = nil -} diff --git a/groups/proto/groups.pb.micro.go b/groups/proto/groups.pb.micro.go deleted file mode 100644 index 23f6157..0000000 --- a/groups/proto/groups.pb.micro.go +++ /dev/null @@ -1,209 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/groups.proto - -package groups - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Groups service - -func NewGroupsEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Groups service - -type GroupsService interface { - // Create a group - Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) - // Read a group using ID - Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) - // Update a groups name - Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) - // Delete a group - Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) - // List all groups - List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) - // AddMember to a group - AddMember(ctx context.Context, in *AddMemberRequest, opts ...client.CallOption) (*AddMemberResponse, error) - // RemoveMember from a group - RemoveMember(ctx context.Context, in *RemoveMemberRequest, opts ...client.CallOption) (*RemoveMemberResponse, error) -} - -type groupsService struct { - c client.Client - name string -} - -func NewGroupsService(name string, c client.Client) GroupsService { - return &groupsService{ - c: c, - name: name, - } -} - -func (c *groupsService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { - req := c.c.NewRequest(c.name, "Groups.Create", in) - out := new(CreateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { - req := c.c.NewRequest(c.name, "Groups.Read", in) - out := new(ReadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) { - req := c.c.NewRequest(c.name, "Groups.Update", in) - out := new(UpdateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { - req := c.c.NewRequest(c.name, "Groups.Delete", in) - out := new(DeleteResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { - req := c.c.NewRequest(c.name, "Groups.List", in) - out := new(ListResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) AddMember(ctx context.Context, in *AddMemberRequest, opts ...client.CallOption) (*AddMemberResponse, error) { - req := c.c.NewRequest(c.name, "Groups.AddMember", in) - out := new(AddMemberResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *groupsService) RemoveMember(ctx context.Context, in *RemoveMemberRequest, opts ...client.CallOption) (*RemoveMemberResponse, error) { - req := c.c.NewRequest(c.name, "Groups.RemoveMember", in) - out := new(RemoveMemberResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Groups service - -type GroupsHandler interface { - // Create a group - Create(context.Context, *CreateRequest, *CreateResponse) error - // Read a group using ID - Read(context.Context, *ReadRequest, *ReadResponse) error - // Update a groups name - Update(context.Context, *UpdateRequest, *UpdateResponse) error - // Delete a group - Delete(context.Context, *DeleteRequest, *DeleteResponse) error - // List all groups - List(context.Context, *ListRequest, *ListResponse) error - // AddMember to a group - AddMember(context.Context, *AddMemberRequest, *AddMemberResponse) error - // RemoveMember from a group - RemoveMember(context.Context, *RemoveMemberRequest, *RemoveMemberResponse) error -} - -func RegisterGroupsHandler(s server.Server, hdlr GroupsHandler, opts ...server.HandlerOption) error { - type groups interface { - Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error - Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error - Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error - Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error - List(ctx context.Context, in *ListRequest, out *ListResponse) error - AddMember(ctx context.Context, in *AddMemberRequest, out *AddMemberResponse) error - RemoveMember(ctx context.Context, in *RemoveMemberRequest, out *RemoveMemberResponse) error - } - type Groups struct { - groups - } - h := &groupsHandler{hdlr} - return s.Handle(s.NewHandler(&Groups{h}, opts...)) -} - -type groupsHandler struct { - GroupsHandler -} - -func (h *groupsHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { - return h.GroupsHandler.Create(ctx, in, out) -} - -func (h *groupsHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { - return h.GroupsHandler.Read(ctx, in, out) -} - -func (h *groupsHandler) Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error { - return h.GroupsHandler.Update(ctx, in, out) -} - -func (h *groupsHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { - return h.GroupsHandler.Delete(ctx, in, out) -} - -func (h *groupsHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { - return h.GroupsHandler.List(ctx, in, out) -} - -func (h *groupsHandler) AddMember(ctx context.Context, in *AddMemberRequest, out *AddMemberResponse) error { - return h.GroupsHandler.AddMember(ctx, in, out) -} - -func (h *groupsHandler) RemoveMember(ctx context.Context, in *RemoveMemberRequest, out *RemoveMemberResponse) error { - return h.GroupsHandler.RemoveMember(ctx, in, out) -} diff --git a/groups/proto/groups.proto b/groups/proto/groups.proto deleted file mode 100644 index a89aaab..0000000 --- a/groups/proto/groups.proto +++ /dev/null @@ -1,81 +0,0 @@ -syntax = "proto3"; - -package groups; -option go_package = "./proto;groups"; - -service Groups { - // Create a group - rpc Create(CreateRequest) returns (CreateResponse); - // Read a group using ID - rpc Read(ReadRequest) returns (ReadResponse); - // Update a groups name - rpc Update(UpdateRequest) returns (UpdateResponse); - // Delete a group - rpc Delete(DeleteRequest) returns (DeleteResponse); - // List all groups - rpc List(ListRequest) returns (ListResponse); - // AddMember to a group - rpc AddMember(AddMemberRequest) returns (AddMemberResponse); - // RemoveMember from a group - rpc RemoveMember(RemoveMemberRequest) returns (RemoveMemberResponse); -} - -message Group { - string id = 1; - string name = 2; - repeated string member_ids = 3; -} - -message CreateRequest { - string name = 1; -} - -message CreateResponse { - Group group = 1; -} - -message ReadRequest { - repeated string ids = 1; -} - -message ReadResponse { - map groups = 1; -} - -message UpdateRequest { - string id = 1; - string name = 2; -} - -message UpdateResponse { - Group group = 1; -} - -message DeleteRequest { - string id = 1; -} - -message DeleteResponse {} - -message ListRequest { - // passing a member id will restrict the groups to that which the member is part of - string member_id = 1; -} - -message ListResponse { - repeated Group groups = 1; -} - -message AddMemberRequest { - string group_id = 1; - string member_id = 2; -} - -message AddMemberResponse {} - -message RemoveMemberRequest { - string group_id = 1; - string member_id = 2; -} - -message RemoveMemberResponse {} diff --git a/invites/.gitignore b/invites/.gitignore deleted file mode 100644 index 4f31144..0000000 --- a/invites/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -invites diff --git a/invites/Dockerfile b/invites/Dockerfile deleted file mode 100644 index 718155b..0000000 --- a/invites/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD invites /invites -ENTRYPOINT [ "/invites" ] diff --git a/invites/Makefile b/invites/Makefile deleted file mode 100644 index be2b0c8..0000000 --- a/invites/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --proto_path=. --micro_out=. --go_out=:. proto/invites.proto - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/invites.proto - @redoc-cli bundle api-invites.json - -.PHONY: build -build: - go build -o invites *.go - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t invites:latest diff --git a/invites/README.md b/invites/README.md deleted file mode 100644 index 76a60ec..0000000 --- a/invites/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Manage and send user and group invites - -# Invites Service - -The invites services allows you to create and manage invites for users and groups by providing invite codes. - diff --git a/invites/examples.json b/invites/examples.json deleted file mode 100644 index 620b4a4..0000000 --- a/invites/examples.json +++ /dev/null @@ -1,57 +0,0 @@ - -{ - "create": [{ - "title": "Create an invite", - "description": "Create an invite for a user for a group", - "request": { - "group_id": "mygroup", - "email": "john@doe.com" - }, - "response": { - "invite": { - "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", - "group_id": "mygroup", - "email": "john@doe.com", - "code": "86285587" - } - } - }], - "read": [{ - "title": "Read an invite", - "description": "Read an invite by code", - "request": { - "code": "86285587" - }, - "response": { - "invite": { - "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", - "group_id": "mygroup", - "email": "john@doe.com", - "code": "86285587" - } - } - }], - "delete": [{ - "title": "Delete an invite", - "description": "Delete an invite by id", - "request": { - "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862" - }, - "response": {} - }], - "list": [{ - "title": "List invites", - "description": "List invites for a group by id", - "request": { - "group_id": "mygroup" - }, - "response": { - "invites": [{ - "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", - "group_id": "myawesomegroup", - "email": "john@doe.com", - "code": "86285587" - }] - } - }] -} diff --git a/invites/generate.go b/invites/generate.go deleted file mode 100644 index 7d9db91..0000000 --- a/invites/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate make proto diff --git a/invites/handler/invites.go b/invites/handler/invites.go deleted file mode 100644 index 6b881ca..0000000 --- a/invites/handler/invites.go +++ /dev/null @@ -1,347 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "fmt" - "math/rand" - "regexp" - "strconv" - "strings" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/invites/proto" - "github.com/micro/services/pkg/tenant" -) - -var ( - ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") - ErrMissingGroupID = errors.BadRequest("MISSING_GROUP_ID", "Missing GroupID") - ErrInvalidEmail = errors.BadRequest("INVALID_EMAIL", "The email provided was invalid") - ErrMissingEmail = errors.BadRequest("MISSING_EMAIL", "Missing Email") - ErrMissingIDAndCode = errors.BadRequest("ID_OR_CODE_REQUIRED", "An email address code is required to read an invite") - ErrMissingGroupIDAndEmail = errors.BadRequest("GROUP_ID_OR_EMAIL_REQUIRED", "An email address or group id is needed to list invites") - ErrInviteNotFound = errors.NotFound("NOT_FOUND", "Invite not found") - - emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") -) - -type Invite struct { - ID string - Email string - GroupID string - Code string -} - -func (i *Invite) Serialize() *pb.Invite { - return &pb.Invite{ - Id: i.ID, - Email: i.Email, - GroupId: i.GroupID, - Code: i.Code, - } -} - -func (i *Invite) Key(ctx context.Context) string { - key := fmt.Sprintf("invite:%s:%s", i.ID, i.Code) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (i *Invite) Index(ctx context.Context) string { - key := fmt.Sprintf("group:%s:%s", i.GroupID, i.Email) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (i *Invite) Marshal() []byte { - b, _ := json.Marshal(i) - return b -} - -func (i *Invite) Unmarshal(b []byte) error { - return json.Unmarshal(b, &i) -} - -type Invites struct{} - -// schema -// Read: id/code -// List: group/email - -// Create an invite -func (i *Invites) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.GroupId) == 0 { - return ErrMissingGroupID - } - if len(req.Email) == 0 { - return ErrMissingEmail - } - if !isEmailValid(req.Email) { - return ErrInvalidEmail - } - - // construct the invite and write to the db - invite := &Invite{ - ID: uuid.New().String(), - Code: generateCode(), - GroupID: req.GroupId, - Email: strings.ToLower(req.Email), - } - - // id/val - key := invite.Key(ctx) - // get group key - gkey := invite.Index(ctx) - - // TODO: Use the micro/micro/v3/service/sync interface to lock - - // write the first record - if err := store.Write(store.NewRecord(key, invite)); err != nil { - logger.Errorf("Error writing to the store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // write the group record - if err := store.Write(store.NewRecord(gkey, invite)); err != nil { - logger.Errorf("Error writing to the store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.Invite = invite.Serialize() - return nil -} - -// Read an invite using ID or code -func (i *Invites) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 && len(req.Code) == 0 { - return ErrMissingIDAndCode - } - - var recs []*store.Record - var err error - - // create a pseudo invite - invite := &Invite{ - ID: req.Id, - Code: req.Code, - } - - if len(req.Id) > 0 && len(req.Code) > 0 { - recs, err = store.Read(invite.Key(ctx), store.ReadLimit(1)) - } else if len(req.Id) > 0 { - recs, err = store.Read(invite.Key(ctx), store.ReadLimit(1), store.ReadPrefix()) - } else if len(req.Code) > 0 { - // create a code suffix key - key := ":" + req.Code - // read all the keys with the given code - // TODO: potential race where if the code is not random - // we read it for the wrong user e.g if two tenants generate the same code - r, lerr := store.Read(key, store.ReadLimit(1), store.ReadSuffix()) - - // now scan for the prefix - prefix := "invite:" - - // additional prefix for the tenant - if t, ok := tenant.FromContext(ctx); ok { - prefix = t + "/" + prefix - } - - // scan for the key we're looking for - for _, rec := range r { - // skip the missing prefix - if !strings.HasPrefix(rec.Key, prefix) { - continue - } - - // skip missing suffix - if !strings.HasSuffix(rec.Key, key) { - continue - } - - // save the record - recs = append(recs, rec) - break - } - - // set the error - // TODO: maybe just process this - err = lerr - } - - // check if there are any records - if err == store.ErrNotFound || len(recs) == 0 { - return ErrInviteNotFound - } - - // check the error - if err != nil { - logger.Errorf("Error reading from the store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // unmarshal the invite - invite.Unmarshal(recs[0].Value) - - // serialize the response - rsp.Invite = invite.Serialize() - return nil -} - -// List invited for a group or specific email -func (i *Invites) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Email) == 0 && len(req.GroupId) == 0 { - return ErrMissingGroupIDAndEmail - } - - invite := &Invite{ - GroupID: req.GroupId, - Email: req.Email, - } - - var recs []*store.Record - var err error - - if len(invite.GroupID) > 0 && len(invite.Email) > 0 { - key := invite.Index(ctx) - recs, err = store.Read(key, store.ReadLimit(1)) - } else if len(invite.GroupID) > 0 { - key := invite.Index(ctx) - recs, err = store.Read(key, store.ReadPrefix()) - } else if len(invite.Email) > 0 { - // create a email suffix key - key := ":" + invite.Email - // read all the keys with the given code - r, lerr := store.Read(key, store.ReadSuffix()) - - // now scan for the prefix - prefix := "group:" - - // additional prefix for the tenant - if t, ok := tenant.FromContext(ctx); ok { - prefix = t + "/" + prefix - } - - // scan for the key we're looking for - for _, rec := range r { - // skip the missing prefix - if !strings.HasPrefix(rec.Key, prefix) { - continue - } - - // skip missing suffix - if !strings.HasSuffix(rec.Key, key) { - continue - } - - // save the record - recs = append(recs, rec) - } - - // set the error - // TODO: maybe just process this - err = lerr - } - - // no records found - if err == store.ErrNotFound { - return nil - } - - // check the error - if err != nil { - logger.Errorf("Error reading from the store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // return response - for _, rec := range recs { - invite := new(Invite) - invite.Unmarshal(rec.Value) - rsp.Invites = append(rsp.Invites, invite.Serialize()) - } - - return nil -} - -// Delete an invite -func (i *Invites) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - - invite := &Invite{ID: req.Id} - key := invite.Key(ctx) - - // check for the existing invite value - recs, err := store.Read(key, store.ReadLimit(1), store.ReadPrefix()) - if err == store.ErrNotFound || len(recs) == 0 { - return nil - } else if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - - // unmarshal the existing invite - invite.Unmarshal(recs[0].Value) - if invite.ID != req.Id { - return nil - } - - // delete the record by id - store.Delete(invite.Key(ctx)) - - // delete the record by group id - store.Delete(invite.Index(ctx)) - - return nil -} - -// isEmailValid checks if the email provided passes the required structure and length. -func isEmailValid(e string) bool { - if len(e) < 3 && len(e) > 254 { - return false - } - return emailRegex.MatchString(e) -} - -// generateCode generates a random 8 digit code -func generateCode() string { - v := rand.Intn(89999999) + 10000000 - return strconv.Itoa(v) -} diff --git a/invites/handler/invites_test.go b/invites/handler/invites_test.go deleted file mode 100644 index dc62ed8..0000000 --- a/invites/handler/invites_test.go +++ /dev/null @@ -1,258 +0,0 @@ -package handler_test - -import ( - "context" - "testing" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/store" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/invites/handler" - pb "github.com/micro/services/invites/proto" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func testHandler(t *testing.T) *handler.Invites { - store.DefaultStore = memory.NewStore() - return &handler.Invites{} -} - -func TestCreate(t *testing.T) { - tt := []struct { - Name string - GroupID string - Email string - Error error - }{ - { - Name: "MissingGroupID", - Email: "john@doe.com", - Error: handler.ErrMissingGroupID, - }, - { - Name: "MissingEmail", - GroupID: uuid.New().String(), - Error: handler.ErrMissingEmail, - }, - { - Name: "InvalidEmail", - GroupID: uuid.New().String(), - Email: "foo.foo.foo", - Error: handler.ErrInvalidEmail, - }, - { - Name: "Valid", - GroupID: "thisisavalidgroupid", - Email: "john@doe.com", - }, - { - Name: "Repeat", - GroupID: "thisisavalidgroupid", - Email: "john@doe.com", - }, - } - - h := testHandler(t) - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - GroupId: tc.GroupID, Email: tc.Email, - }, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.Error != nil { - assert.Nil(t, rsp.Invite) - return - } - - if rsp.Invite == nil { - t.Fatalf("Invite was not returned") - return - } - - assert.NotEmpty(t, rsp.Invite.Id) - assert.NotEmpty(t, rsp.Invite.Code) - assert.Equal(t, tc.GroupID, rsp.Invite.GroupId) - assert.Equal(t, tc.Email, rsp.Invite.Email) - }) - } -} - -func TestRead(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) - assert.NoError(t, err) - if cRsp.Invite == nil { - t.Fatal("No invite returned on create") - return - } - - tt := []struct { - Name string - ID string - Code string - Error error - Invite *pb.Invite - }{ - { - Name: "MissingIDAndCode", - Error: handler.ErrMissingIDAndCode, - }, - { - Name: "NotFoundByID", - ID: uuid.New().String(), - Error: handler.ErrInviteNotFound, - }, - { - Name: "NotFoundByCode", - Code: "12345678", - Error: handler.ErrInviteNotFound, - }, - { - Name: "ValidID", - ID: cRsp.Invite.Id, - Invite: cRsp.Invite, - }, - { - Name: "ValidCode", - Code: cRsp.Invite.Code, - Invite: cRsp.Invite, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.ReadResponse - err := h.Read(microAccountCtx(), &pb.ReadRequest{Id: tc.ID, Code: tc.Code}, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.Invite == nil { - assert.Nil(t, rsp.Invite) - } else { - assertInvitesMatch(t, tc.Invite, rsp.Invite) - } - }) - } -} - -func TestList(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) - assert.NoError(t, err) - if cRsp.Invite == nil { - t.Fatal("No invite returned on create") - return - } - - tt := []struct { - Name string - GroupID string - Email string - Error error - Invite *pb.Invite - }{ - { - Name: "MissingIDAndEmail", - Error: handler.ErrMissingGroupIDAndEmail, - }, - { - Name: "NoResultsForEmail", - Email: "foo@bar.com", - }, - { - Name: "NoResultsForGroupID", - GroupID: uuid.New().String(), - }, - { - Name: "ValidGroupID", - GroupID: cRsp.Invite.GroupId, - Invite: cRsp.Invite, - }, - { - Name: "ValidEmail", - Email: cRsp.Invite.Email, - Invite: cRsp.Invite, - }, - { - Name: "EmailAndGroupID", - Email: cRsp.Invite.Email, - GroupID: uuid.New().String(), - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.ListResponse - err := h.List(microAccountCtx(), &pb.ListRequest{Email: tc.Email, GroupId: tc.GroupID}, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.Invite == nil { - assert.Empty(t, rsp.Invites) - } else { - if len(rsp.Invites) != 1 { - t.Errorf("Incorrect number of invites returned, expected 1 but got %v", len(rsp.Invites)) - return - } - assertInvitesMatch(t, tc.Invite, rsp.Invites[0]) - } - }) - } -} - -func TestDelete(t *testing.T) { - h := testHandler(t) - - t.Run("MissingID", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{}, &pb.DeleteResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - // seed some data - var cRsp pb.CreateResponse - err := h.Create(microAccountCtx(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) - assert.NoError(t, err) - if cRsp.Invite == nil { - t.Fatal("No invite returned on create") - return - } - - t.Run("Valid", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{Id: cRsp.Invite.Id}, &pb.DeleteResponse{}) - assert.NoError(t, err) - - err = h.Read(microAccountCtx(), &pb.ReadRequest{Id: cRsp.Invite.Id}, &pb.ReadResponse{}) - assert.Equal(t, handler.ErrInviteNotFound, err) - }) - - t.Run("Repeat", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{Id: cRsp.Invite.Id}, &pb.DeleteResponse{}) - assert.NoError(t, err) - }) -} - -func assertInvitesMatch(t *testing.T, exp, act *pb.Invite) { - if act == nil { - t.Errorf("No invite returned") - return - } - assert.Equal(t, exp.Id, act.Id) - assert.Equal(t, exp.Code, act.Code) - assert.Equal(t, exp.Email, act.Email) - assert.Equal(t, exp.GroupId, act.GroupId) -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - ID: "someID", - }) -} diff --git a/invites/main.go b/invites/main.go deleted file mode 100644 index 967b3c0..0000000 --- a/invites/main.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "github.com/micro/services/invites/handler" - pb "github.com/micro/services/invites/proto" - - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" -) - -func main() { - // Create service - srv := service.New( - service.Name("invites"), - service.Version("latest"), - ) - - // Register handler - pb.RegisterInvitesHandler(srv.Server(), new(handler.Invites)) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/invites/micro.mu b/invites/micro.mu deleted file mode 100644 index 7b7931e..0000000 --- a/invites/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service invites diff --git a/invites/proto/invites.pb.go b/invites/proto/invites.pb.go deleted file mode 100644 index c9598e3..0000000 --- a/invites/proto/invites.pb.go +++ /dev/null @@ -1,716 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 -// source: proto/invites.proto - -package invites - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Invite struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - GroupId string `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` -} - -func (x *Invite) Reset() { - *x = Invite{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Invite) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Invite) ProtoMessage() {} - -func (x *Invite) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Invite.ProtoReflect.Descriptor instead. -func (*Invite) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{0} -} - -func (x *Invite) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Invite) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *Invite) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *Invite) GetCode() string { - if x != nil { - return x.Code - } - return "" -} - -type CreateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` -} - -func (x *CreateRequest) Reset() { - *x = CreateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateRequest) ProtoMessage() {} - -func (x *CreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead. -func (*CreateRequest) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{1} -} - -func (x *CreateRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *CreateRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -type CreateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Invite *Invite `protobuf:"bytes,1,opt,name=invite,proto3" json:"invite,omitempty"` -} - -func (x *CreateResponse) Reset() { - *x = CreateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateResponse) ProtoMessage() {} - -func (x *CreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateResponse.ProtoReflect.Descriptor instead. -func (*CreateResponse) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateResponse) GetInvite() *Invite { - if x != nil { - return x.Invite - } - return nil -} - -type ReadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` -} - -func (x *ReadRequest) Reset() { - *x = ReadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadRequest) ProtoMessage() {} - -func (x *ReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. -func (*ReadRequest) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{3} -} - -func (x *ReadRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ReadRequest) GetCode() string { - if x != nil { - return x.Code - } - return "" -} - -type ReadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Invite *Invite `protobuf:"bytes,1,opt,name=invite,proto3" json:"invite,omitempty"` -} - -func (x *ReadResponse) Reset() { - *x = ReadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadResponse) ProtoMessage() {} - -func (x *ReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. -func (*ReadResponse) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{4} -} - -func (x *ReadResponse) GetInvite() *Invite { - if x != nil { - return x.Invite - } - return nil -} - -type ListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` -} - -func (x *ListRequest) Reset() { - *x = ListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRequest) ProtoMessage() {} - -func (x *ListRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. -func (*ListRequest) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{5} -} - -func (x *ListRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *ListRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -type ListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Invites []*Invite `protobuf:"bytes,1,rep,name=invites,proto3" json:"invites,omitempty"` -} - -func (x *ListResponse) Reset() { - *x = ListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListResponse) ProtoMessage() {} - -func (x *ListResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. -func (*ListResponse) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{6} -} - -func (x *ListResponse) GetInvites() []*Invite { - if x != nil { - return x.Invites - } - return nil -} - -type DeleteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteRequest) Reset() { - *x = DeleteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteRequest) ProtoMessage() {} - -func (x *DeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. -func (*DeleteRequest) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{7} -} - -func (x *DeleteRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type DeleteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DeleteResponse) Reset() { - *x = DeleteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_invites_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteResponse) ProtoMessage() {} - -func (x *DeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_invites_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return file_proto_invites_proto_rawDescGZIP(), []int{8} -} - -var File_proto_invites_proto protoreflect.FileDescriptor - -var file_proto_invites_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x22, 0x5d, - 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x40, 0x0a, - 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, - 0x39, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x27, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x22, 0x31, 0x0a, 0x0b, 0x52, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x37, 0x0a, - 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, - 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x06, - 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x22, 0x3e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x39, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x22, 0x1f, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe9, 0x01, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x12, 0x39, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x69, 0x6e, 0x76, - 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x52, - 0x65, 0x61, 0x64, 0x12, 0x14, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x69, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x33, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, - 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, - 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, - 0x16, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x69, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_invites_proto_rawDescOnce sync.Once - file_proto_invites_proto_rawDescData = file_proto_invites_proto_rawDesc -) - -func file_proto_invites_proto_rawDescGZIP() []byte { - file_proto_invites_proto_rawDescOnce.Do(func() { - file_proto_invites_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_invites_proto_rawDescData) - }) - return file_proto_invites_proto_rawDescData -} - -var file_proto_invites_proto_msgTypes = make([]protoimpl.MessageInfo, 9) -var file_proto_invites_proto_goTypes = []interface{}{ - (*Invite)(nil), // 0: invites.Invite - (*CreateRequest)(nil), // 1: invites.CreateRequest - (*CreateResponse)(nil), // 2: invites.CreateResponse - (*ReadRequest)(nil), // 3: invites.ReadRequest - (*ReadResponse)(nil), // 4: invites.ReadResponse - (*ListRequest)(nil), // 5: invites.ListRequest - (*ListResponse)(nil), // 6: invites.ListResponse - (*DeleteRequest)(nil), // 7: invites.DeleteRequest - (*DeleteResponse)(nil), // 8: invites.DeleteResponse -} -var file_proto_invites_proto_depIdxs = []int32{ - 0, // 0: invites.CreateResponse.invite:type_name -> invites.Invite - 0, // 1: invites.ReadResponse.invite:type_name -> invites.Invite - 0, // 2: invites.ListResponse.invites:type_name -> invites.Invite - 1, // 3: invites.Invites.Create:input_type -> invites.CreateRequest - 3, // 4: invites.Invites.Read:input_type -> invites.ReadRequest - 5, // 5: invites.Invites.List:input_type -> invites.ListRequest - 7, // 6: invites.Invites.Delete:input_type -> invites.DeleteRequest - 2, // 7: invites.Invites.Create:output_type -> invites.CreateResponse - 4, // 8: invites.Invites.Read:output_type -> invites.ReadResponse - 6, // 9: invites.Invites.List:output_type -> invites.ListResponse - 8, // 10: invites.Invites.Delete:output_type -> invites.DeleteResponse - 7, // [7:11] is the sub-list for method output_type - 3, // [3:7] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_proto_invites_proto_init() } -func file_proto_invites_proto_init() { - if File_proto_invites_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_invites_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Invite); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_invites_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_invites_proto_rawDesc, - NumEnums: 0, - NumMessages: 9, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_invites_proto_goTypes, - DependencyIndexes: file_proto_invites_proto_depIdxs, - MessageInfos: file_proto_invites_proto_msgTypes, - }.Build() - File_proto_invites_proto = out.File - file_proto_invites_proto_rawDesc = nil - file_proto_invites_proto_goTypes = nil - file_proto_invites_proto_depIdxs = nil -} diff --git a/invites/proto/invites.pb.micro.go b/invites/proto/invites.pb.micro.go deleted file mode 100644 index 2590923..0000000 --- a/invites/proto/invites.pb.micro.go +++ /dev/null @@ -1,152 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/invites.proto - -package invites - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Invites service - -func NewInvitesEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Invites service - -type InvitesService interface { - // Create an invite - Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) - // Read an invite using ID or code - Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) - // List invited for a group or specific email - List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) - // Delete an invite - Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) -} - -type invitesService struct { - c client.Client - name string -} - -func NewInvitesService(name string, c client.Client) InvitesService { - return &invitesService{ - c: c, - name: name, - } -} - -func (c *invitesService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { - req := c.c.NewRequest(c.name, "Invites.Create", in) - out := new(CreateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *invitesService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { - req := c.c.NewRequest(c.name, "Invites.Read", in) - out := new(ReadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *invitesService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { - req := c.c.NewRequest(c.name, "Invites.List", in) - out := new(ListResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *invitesService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { - req := c.c.NewRequest(c.name, "Invites.Delete", in) - out := new(DeleteResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Invites service - -type InvitesHandler interface { - // Create an invite - Create(context.Context, *CreateRequest, *CreateResponse) error - // Read an invite using ID or code - Read(context.Context, *ReadRequest, *ReadResponse) error - // List invited for a group or specific email - List(context.Context, *ListRequest, *ListResponse) error - // Delete an invite - Delete(context.Context, *DeleteRequest, *DeleteResponse) error -} - -func RegisterInvitesHandler(s server.Server, hdlr InvitesHandler, opts ...server.HandlerOption) error { - type invites interface { - Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error - Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error - List(ctx context.Context, in *ListRequest, out *ListResponse) error - Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error - } - type Invites struct { - invites - } - h := &invitesHandler{hdlr} - return s.Handle(s.NewHandler(&Invites{h}, opts...)) -} - -type invitesHandler struct { - InvitesHandler -} - -func (h *invitesHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { - return h.InvitesHandler.Create(ctx, in, out) -} - -func (h *invitesHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { - return h.InvitesHandler.Read(ctx, in, out) -} - -func (h *invitesHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { - return h.InvitesHandler.List(ctx, in, out) -} - -func (h *invitesHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { - return h.InvitesHandler.Delete(ctx, in, out) -} diff --git a/invites/proto/invites.proto b/invites/proto/invites.proto deleted file mode 100644 index 40dd1c9..0000000 --- a/invites/proto/invites.proto +++ /dev/null @@ -1,55 +0,0 @@ -syntax = "proto3"; - -package invites; -option go_package = "./proto;invites"; - -service Invites { - // Create an invite - rpc Create(CreateRequest) returns (CreateResponse); - // Read an invite using ID or code - rpc Read(ReadRequest) returns (ReadResponse); - // List invited for a group or specific email - rpc List(ListRequest) returns (ListResponse); - // Delete an invite - rpc Delete(DeleteRequest) returns (DeleteResponse); -} - -message Invite { - string id = 1; - string group_id = 2; - string email = 3; - string code = 4; -} - -message CreateRequest { - string group_id = 1; - string email = 2; -} - -message CreateResponse { - Invite invite = 1; -} - -message ReadRequest { - string id = 1; - string code = 2; -} - -message ReadResponse { - Invite invite = 1; -} - -message ListRequest { - string group_id = 1; - string email = 2; -} - -message ListResponse { - repeated Invite invites = 1; -} - -message DeleteRequest { - string id = 1; -} - -message DeleteResponse {} diff --git a/mail/Makefile b/mail/Makefile deleted file mode 100644 index d6b85f8..0000000 --- a/mail/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/mail.proto - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/mail.proto - @redoc-cli bundle api-mail.json - -.PHONY: build -build: - go build -o mail *.go - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t mail:latest diff --git a/mail/README.md b/mail/README.md deleted file mode 100644 index f579feb..0000000 --- a/mail/README.md +++ /dev/null @@ -1,6 +0,0 @@ -An inbox for your messages - -# Mail Service - -The mail service is a simplified service for sending mail, much like email where the messages stay on the server. - diff --git a/mail/handler/handler.go b/mail/handler/handler.go deleted file mode 100644 index b3a10c4..0000000 --- a/mail/handler/handler.go +++ /dev/null @@ -1,116 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "strings" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/mail/proto" -) - -const ( - messagePrefix = "message" - joinKey = "/" -) - -type Mail struct{} - -// Send a message -func (m *Mail) Send(ctx context.Context, req *pb.SendRequest, rsp *pb.SendResponse) error { - // validate the request - if len(req.To) == 0 { - return errors.BadRequest("mail.Send.MissingTo", "Missing to") - } - if len(req.From) == 0 { - return errors.BadRequest("mail.Send.MissingFrom", "Missing from") - } - if len(req.Text) == 0 { - return errors.BadRequest("mail.Send.MissingText", "Missing text") - } - - // construct the message and marshal it to json - msg := &pb.Message{ - Id: uuid.New().String(), - To: req.To, - From: req.From, - Subject: req.Subject, - Text: req.Text, - SentAt: time.Now().Unix(), - } - bytes, err := json.Marshal(msg) - if err != nil { - return errors.BadRequest("mail.Send.Unknown", "Error encoding message") - } - - // write the message to the store under the recipients key - key := strings.Join([]string{messagePrefix, req.To, msg.Id}, joinKey) - if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil { - return errors.BadRequest("mail.Send.Unknown", "Error writing to the store") - } - - // write the message to the store under the id (so it can be looked up without needing to know - // the users id) - key = strings.Join([]string{messagePrefix, msg.Id}, joinKey) - if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil { - return errors.BadRequest("mail.Send.Unknown", "Error writing to the store") - } - - return nil -} - -// List mail for a user -func (m *Mail) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { - // validate the request - if len(req.User) == 0 { - return errors.BadRequest("mail.List.MissingUser", "Missing user") - } - - // query the store for any mail sent to the user - prefix := strings.Join([]string{messagePrefix, req.User}, joinKey) - recs, err := store.Read(prefix, store.ReadPrefix()) - if err != nil { - return errors.BadRequest("mail.List.Unknown", "Error reading from the store") - } - - // serialize the result - rsp.Mail = make([]*pb.Message, len(recs)) - for i, r := range recs { - var msg pb.Message - if err := json.Unmarshal(r.Value, &msg); err != nil { - return errors.BadRequest("mail.List.Unknown", "Error decoding message") - } - rsp.Mail[i] = &msg - } - - return nil -} - -// Read a message -func (m *Mail) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { - // validate the request - if len(req.Id) == 0 { - return errors.BadRequest("mail.Read.MissingUser", "Missing user") - } - - // query the store - key := strings.Join([]string{messagePrefix, req.Id}, joinKey) - recs, err := store.Read(key) - if err == store.ErrNotFound { - return errors.NotFound("message.Read.InvalidID", "Message not found with ID") - } else if err != nil { - return errors.BadRequest("mail.Read.Unknown", "Error reading from the store") - } - - // serialize the response - var msg pb.Message - if err := json.Unmarshal(recs[0].Value, &msg); err != nil { - return errors.BadRequest("mail.Read.Unknown", "Error decoding message") - } - rsp.Message = &msg - - return nil -} diff --git a/mail/main.go b/mail/main.go deleted file mode 100644 index 10c9680..0000000 --- a/mail/main.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" - - "github.com/micro/services/mail/handler" - pb "github.com/micro/services/mail/proto" -) - -func main() { - // Create the service - srv := service.New( - service.Name("mail"), - service.Version("latest"), - ) - - // Register the handler against the server - pb.RegisterMailHandler(srv.Server(), new(handler.Mail)) - - // Run the service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/mail/micro.mu b/mail/micro.mu deleted file mode 100644 index d72aedf..0000000 --- a/mail/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service mail \ No newline at end of file diff --git a/mail/proto/mail.pb.go b/mail/proto/mail.pb.go deleted file mode 100644 index 5cdb182..0000000 --- a/mail/proto/mail.pb.go +++ /dev/null @@ -1,603 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0 -// protoc v3.15.5 -// source: proto/mail.proto - -package mail - -import ( - proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` - From string `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Text string `protobuf:"bytes,5,opt,name=text,proto3" json:"text,omitempty"` - SentAt int64 `protobuf:"varint,6,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{0} -} - -func (x *Message) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Message) GetTo() string { - if x != nil { - return x.To - } - return "" -} - -func (x *Message) GetFrom() string { - if x != nil { - return x.From - } - return "" -} - -func (x *Message) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Message) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -func (x *Message) GetSentAt() int64 { - if x != nil { - return x.SentAt - } - return 0 -} - -type SendRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - To string `protobuf:"bytes,1,opt,name=to,proto3" json:"to,omitempty"` - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` -} - -func (x *SendRequest) Reset() { - *x = SendRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendRequest) ProtoMessage() {} - -func (x *SendRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendRequest.ProtoReflect.Descriptor instead. -func (*SendRequest) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{1} -} - -func (x *SendRequest) GetTo() string { - if x != nil { - return x.To - } - return "" -} - -func (x *SendRequest) GetFrom() string { - if x != nil { - return x.From - } - return "" -} - -func (x *SendRequest) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *SendRequest) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -type SendResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *SendResponse) Reset() { - *x = SendResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendResponse) ProtoMessage() {} - -func (x *SendResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendResponse.ProtoReflect.Descriptor instead. -func (*SendResponse) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{2} -} - -type ListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` -} - -func (x *ListRequest) Reset() { - *x = ListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRequest) ProtoMessage() {} - -func (x *ListRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. -func (*ListRequest) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{3} -} - -func (x *ListRequest) GetUser() string { - if x != nil { - return x.User - } - return "" -} - -type ListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Mail []*Message `protobuf:"bytes,1,rep,name=mail,proto3" json:"mail,omitempty"` -} - -func (x *ListResponse) Reset() { - *x = ListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListResponse) ProtoMessage() {} - -func (x *ListResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. -func (*ListResponse) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{4} -} - -func (x *ListResponse) GetMail() []*Message { - if x != nil { - return x.Mail - } - return nil -} - -type ReadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *ReadRequest) Reset() { - *x = ReadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadRequest) ProtoMessage() {} - -func (x *ReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. -func (*ReadRequest) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{5} -} - -func (x *ReadRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type ReadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *ReadResponse) Reset() { - *x = ReadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_mail_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadResponse) ProtoMessage() {} - -func (x *ReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_mail_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. -func (*ReadResponse) Descriptor() ([]byte, []int) { - return file_proto_mail_proto_rawDescGZIP(), []int{6} -} - -func (x *ReadResponse) GetMessage() *Message { - if x != nil { - return x.Message - } - return nil -} - -var File_proto_mail_proto protoreflect.FileDescriptor - -var file_proto_mail_proto_rawDesc = []byte{ - 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x84, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, - 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x22, - 0x5f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, - 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, - 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x21, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x22, 0x31, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x1d, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x37, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x93, - 0x01, 0x0a, 0x04, 0x4d, 0x61, 0x69, 0x6c, 0x12, 0x2d, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, - 0x11, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x11, - 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x12, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x11, 0x2e, - 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x12, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0c, 0x5a, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x61, - 0x69, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_mail_proto_rawDescOnce sync.Once - file_proto_mail_proto_rawDescData = file_proto_mail_proto_rawDesc -) - -func file_proto_mail_proto_rawDescGZIP() []byte { - file_proto_mail_proto_rawDescOnce.Do(func() { - file_proto_mail_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_mail_proto_rawDescData) - }) - return file_proto_mail_proto_rawDescData -} - -var file_proto_mail_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_proto_mail_proto_goTypes = []interface{}{ - (*Message)(nil), // 0: mail.Message - (*SendRequest)(nil), // 1: mail.SendRequest - (*SendResponse)(nil), // 2: mail.SendResponse - (*ListRequest)(nil), // 3: mail.ListRequest - (*ListResponse)(nil), // 4: mail.ListResponse - (*ReadRequest)(nil), // 5: mail.ReadRequest - (*ReadResponse)(nil), // 6: mail.ReadResponse -} -var file_proto_mail_proto_depIdxs = []int32{ - 0, // 0: mail.ListResponse.mail:type_name -> mail.Message - 0, // 1: mail.ReadResponse.message:type_name -> mail.Message - 1, // 2: mail.Mail.Send:input_type -> mail.SendRequest - 3, // 3: mail.Mail.List:input_type -> mail.ListRequest - 5, // 4: mail.Mail.Read:input_type -> mail.ReadRequest - 2, // 5: mail.Mail.Send:output_type -> mail.SendResponse - 4, // 6: mail.Mail.List:output_type -> mail.ListResponse - 6, // 7: mail.Mail.Read:output_type -> mail.ReadResponse - 5, // [5:8] is the sub-list for method output_type - 2, // [2:5] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_proto_mail_proto_init() } -func file_proto_mail_proto_init() { - if File_proto_mail_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_mail_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_mail_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_mail_proto_rawDesc, - NumEnums: 0, - NumMessages: 7, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_mail_proto_goTypes, - DependencyIndexes: file_proto_mail_proto_depIdxs, - MessageInfos: file_proto_mail_proto_msgTypes, - }.Build() - File_proto_mail_proto = out.File - file_proto_mail_proto_rawDesc = nil - file_proto_mail_proto_goTypes = nil - file_proto_mail_proto_depIdxs = nil -} diff --git a/mail/proto/mail.pb.micro.go b/mail/proto/mail.pb.micro.go deleted file mode 100644 index cf76573..0000000 --- a/mail/proto/mail.pb.micro.go +++ /dev/null @@ -1,127 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/mail.proto - -package mail - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Mail service - -func NewMailEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Mail service - -type MailService interface { - Send(ctx context.Context, in *SendRequest, opts ...client.CallOption) (*SendResponse, error) - List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) - Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) -} - -type mailService struct { - c client.Client - name string -} - -func NewMailService(name string, c client.Client) MailService { - return &mailService{ - c: c, - name: name, - } -} - -func (c *mailService) Send(ctx context.Context, in *SendRequest, opts ...client.CallOption) (*SendResponse, error) { - req := c.c.NewRequest(c.name, "Mail.Send", in) - out := new(SendResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *mailService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { - req := c.c.NewRequest(c.name, "Mail.List", in) - out := new(ListResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *mailService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { - req := c.c.NewRequest(c.name, "Mail.Read", in) - out := new(ReadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Mail service - -type MailHandler interface { - Send(context.Context, *SendRequest, *SendResponse) error - List(context.Context, *ListRequest, *ListResponse) error - Read(context.Context, *ReadRequest, *ReadResponse) error -} - -func RegisterMailHandler(s server.Server, hdlr MailHandler, opts ...server.HandlerOption) error { - type mail interface { - Send(ctx context.Context, in *SendRequest, out *SendResponse) error - List(ctx context.Context, in *ListRequest, out *ListResponse) error - Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error - } - type Mail struct { - mail - } - h := &mailHandler{hdlr} - return s.Handle(s.NewHandler(&Mail{h}, opts...)) -} - -type mailHandler struct { - MailHandler -} - -func (h *mailHandler) Send(ctx context.Context, in *SendRequest, out *SendResponse) error { - return h.MailHandler.Send(ctx, in, out) -} - -func (h *mailHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { - return h.MailHandler.List(ctx, in, out) -} - -func (h *mailHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { - return h.MailHandler.Read(ctx, in, out) -} diff --git a/mail/proto/mail.proto b/mail/proto/mail.proto deleted file mode 100644 index 1a46afe..0000000 --- a/mail/proto/mail.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package mail; -option go_package = "./proto;mail"; - -service Mail { - rpc Send(SendRequest) returns (SendResponse); - rpc List(ListRequest) returns (ListResponse); - rpc Read(ReadRequest) returns (ReadResponse); -} - -message Message { - string id = 1; - string to = 2; - string from = 3; - string subject = 4; - string text = 5; - int64 sent_at = 6; -} - -message SendRequest { - string to = 1; - string from = 2; - string subject = 3; - string text = 4; -} - -message SendResponse {} - -message ListRequest { - string user = 1; -} - -message ListResponse { - repeated Message mail = 1; -} - -message ReadRequest { - string id = 1; -} - -message ReadResponse { - Message message = 1; -} diff --git a/mail/skip b/mail/skip deleted file mode 100644 index e69de29..0000000 diff --git a/mail/usage.md b/mail/usage.md deleted file mode 100644 index 802508e..0000000 --- a/mail/usage.md +++ /dev/null @@ -1,49 +0,0 @@ -The mail service is a simplified service for sending mail, much like email. - -# Mail Service - -## Send a message - -### CLI - -```bash -> micro mail send --to=John --from=Barry --subject=HelloWorld --text="Hello John" -``` - -## List the mail a user has received - -### CLI - -```bash -> micro mail list --user=John -{ - "mail": [ - { - "id": "78efd836-ca51-4163-af43-65985f7c6587", - "to": "John", - "from": "Barry", - "subject": "HelloWorld", - "text": "Hello John", - "sent_at": "1602777240" - } - ] -} -``` - -## Lookup an individual email by ID - -### CLI - -```bash -> micro mail read --id=78efd836-ca51-4163-af43-65985f7c6587 -{ - "message": { - "id": "78efd836-ca51-4163-af43-65985f7c6587", - "to": "John", - "from": "Barry", - "subject": "HelloWorld", - "text": "Hello John", - "sent_at": "1602777240" - } -} -``` \ No newline at end of file diff --git a/notes/README.md b/notes/README.md deleted file mode 100644 index 803ca03..0000000 --- a/notes/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Store your notes and todos - -# Notes Service - -The notes service offers basic storage of notes and todo lists. - diff --git a/notes/handler/handler.go b/notes/handler/handler.go deleted file mode 100644 index 75f5402..0000000 --- a/notes/handler/handler.go +++ /dev/null @@ -1,161 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "io" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/notes/proto" -) - -const storePrefix = "notes/" - -// New returns an initialized notes handler -func New() pb.NotesHandler { - return new(handler) -} - -type handler struct{} - -// List all the notes -func (h *handler) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { - // query the store - recs, err := store.Read(storePrefix, store.ReadPrefix()) - if err != nil { - logger.Errorf("Error reading notes from the store: %v", err) - return errors.InternalServerError("notes.List.Unknown", "Error reading from the store") - } - - // serialize the response - rsp.Notes = make([]*pb.Note, len(recs)) - for i, r := range recs { - var note pb.Note - if err := json.Unmarshal(r.Value, ¬e); err != nil { - logger.Errorf("Error unmarshaling note: %v", err) - return errors.InternalServerError("notes.List.Unknown", "Error unmarshaling note") - } - rsp.Notes[i] = ¬e - } - - return nil -} - -// Create a note -func (h *handler) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { - // validate the request - if len(req.Title) == 0 { - return errors.BadRequest("notes.Create.MissingTitle", "Missing title") - } - - // construct the note - note := &pb.Note{ - Id: uuid.New().String(), - Created: time.Now().Unix(), - Title: req.Title, - Text: req.Text, - } - - // marshal the note to bytes - bytes, err := json.Marshal(note) - if err != nil { - logger.Errorf("Error marshaling note: %v", err) - return errors.InternalServerError("notes.Create.Unknown", "Error marshaling note") - } - - // write to the store - key := storePrefix + note.Id - if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil { - logger.Errorf("Error writing to store: %v", err) - return errors.InternalServerError("notes.Create.Unknown", "Error writing to store") - } - - // return the id - rsp.Id = note.Id - return nil -} - -// Delete a note -func (h *handler) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error { - // validate the request - if len(req.Id) == 0 { - return errors.BadRequest("notes.Delete.MissingID", "Missing id") - } - - // delete the note from the store - if err := store.Delete(storePrefix + req.Id); err == store.ErrNotFound { - return errors.NotFound("notes.Delete.InvalidID", "Note not found with this ID") - } else if err != nil { - logger.Errorf("Error deleting from the store: %v", err) - return errors.InternalServerError("notes.Delete.Unknown", "Error deleting from the store") - } - - return nil -} - -// Update a note -func (h *handler) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error { - // validate the request - if len(req.Id) == 0 { - return errors.BadRequest("notes.Update.MissingID", "Missing id") - } - if len(req.Title) == 0 { - return errors.BadRequest("notes.Update.MissingTitle", "Missing title") - } - - // read the note from the store - recs, err := store.Read(storePrefix + req.Id) - if err == store.ErrNotFound { - return errors.NotFound("notes.Update.InvalidID", "Note not found with this ID") - } else if err != nil { - logger.Errorf("Error reading from the store: %v", err) - return errors.InternalServerError("notes.Update.Unknown", "Error reading from the store") - } - - // unmarshal the note - var note pb.Note - if err := json.Unmarshal(recs[0].Value, ¬e); err != nil { - logger.Errorf("Error unmarshaling note: %v", err) - return errors.InternalServerError("notes.Update.Unknown", "Error unmarshaling note") - } - - // assign the new title and text - note.Title = req.Title - note.Text = req.Text - - // marshal the note to bytes - bytes, err := json.Marshal(note) - if err != nil { - logger.Errorf("Error marshaling note: %v", err) - return errors.InternalServerError("notes.Update.Unknown", "Error marshaling note") - } - - // write to the store - key := storePrefix + note.Id - if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil { - logger.Errorf("Error writing to store: %v", err) - return errors.InternalServerError("notes.Update.Unknown", "Error writing to store") - } - - return nil -} - -// UpdateStream updates a note every time an update is sent on the stream -func (h *handler) UpdateStream(ctx context.Context, stream pb.Notes_UpdateStreamStream) error { - for { - uReq, err := stream.Recv() - if err == io.EOF { - return nil - } else if err != nil { - return errors.InternalServerError("notes.UpdateStream.Unknown", "Error reading from stream") - } - - if err := h.Update(ctx, uReq, nil); err != nil { - return err - } - } -} diff --git a/notes/main.go b/notes/main.go deleted file mode 100644 index aa8e2b9..0000000 --- a/notes/main.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" - - "github.com/micro/services/notes/handler" - pb "github.com/micro/services/notes/proto" -) - -func main() { - srv := service.New( - service.Name("notes"), - service.Version("latest"), - ) - - pb.RegisterNotesHandler(srv.Server(), handler.New()) - - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/notes/micro.mu b/notes/micro.mu deleted file mode 100644 index 12035d6..0000000 --- a/notes/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service notes diff --git a/notes/proto/notes.pb.go b/notes/proto/notes.pb.go deleted file mode 100644 index c3f9465..0000000 --- a/notes/proto/notes.pb.go +++ /dev/null @@ -1,436 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: notes/proto/notes.proto - -package notes - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -type Note struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Created int64 `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"` - Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Note) Reset() { *m = Note{} } -func (m *Note) String() string { return proto.CompactTextString(m) } -func (*Note) ProtoMessage() {} -func (*Note) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{0} -} - -func (m *Note) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Note.Unmarshal(m, b) -} -func (m *Note) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Note.Marshal(b, m, deterministic) -} -func (m *Note) XXX_Merge(src proto.Message) { - xxx_messageInfo_Note.Merge(m, src) -} -func (m *Note) XXX_Size() int { - return xxx_messageInfo_Note.Size(m) -} -func (m *Note) XXX_DiscardUnknown() { - xxx_messageInfo_Note.DiscardUnknown(m) -} - -var xxx_messageInfo_Note proto.InternalMessageInfo - -func (m *Note) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *Note) GetCreated() int64 { - if m != nil { - return m.Created - } - return 0 -} - -func (m *Note) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *Note) GetText() string { - if m != nil { - return m.Text - } - return "" -} - -type CreateRequest struct { - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateRequest) Reset() { *m = CreateRequest{} } -func (m *CreateRequest) String() string { return proto.CompactTextString(m) } -func (*CreateRequest) ProtoMessage() {} -func (*CreateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{1} -} - -func (m *CreateRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateRequest.Unmarshal(m, b) -} -func (m *CreateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateRequest.Marshal(b, m, deterministic) -} -func (m *CreateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateRequest.Merge(m, src) -} -func (m *CreateRequest) XXX_Size() int { - return xxx_messageInfo_CreateRequest.Size(m) -} -func (m *CreateRequest) XXX_DiscardUnknown() { - xxx_messageInfo_CreateRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateRequest proto.InternalMessageInfo - -func (m *CreateRequest) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *CreateRequest) GetText() string { - if m != nil { - return m.Text - } - return "" -} - -type CreateResponse struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateResponse) Reset() { *m = CreateResponse{} } -func (m *CreateResponse) String() string { return proto.CompactTextString(m) } -func (*CreateResponse) ProtoMessage() {} -func (*CreateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{2} -} - -func (m *CreateResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateResponse.Unmarshal(m, b) -} -func (m *CreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateResponse.Marshal(b, m, deterministic) -} -func (m *CreateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateResponse.Merge(m, src) -} -func (m *CreateResponse) XXX_Size() int { - return xxx_messageInfo_CreateResponse.Size(m) -} -func (m *CreateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CreateResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateResponse proto.InternalMessageInfo - -func (m *CreateResponse) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -type UpdateRequest struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` - Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *UpdateRequest) Reset() { *m = UpdateRequest{} } -func (m *UpdateRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateRequest) ProtoMessage() {} -func (*UpdateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{3} -} - -func (m *UpdateRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_UpdateRequest.Unmarshal(m, b) -} -func (m *UpdateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_UpdateRequest.Marshal(b, m, deterministic) -} -func (m *UpdateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateRequest.Merge(m, src) -} -func (m *UpdateRequest) XXX_Size() int { - return xxx_messageInfo_UpdateRequest.Size(m) -} -func (m *UpdateRequest) XXX_DiscardUnknown() { - xxx_messageInfo_UpdateRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_UpdateRequest proto.InternalMessageInfo - -func (m *UpdateRequest) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *UpdateRequest) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *UpdateRequest) GetText() string { - if m != nil { - return m.Text - } - return "" -} - -type UpdateResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *UpdateResponse) Reset() { *m = UpdateResponse{} } -func (m *UpdateResponse) String() string { return proto.CompactTextString(m) } -func (*UpdateResponse) ProtoMessage() {} -func (*UpdateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{4} -} - -func (m *UpdateResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_UpdateResponse.Unmarshal(m, b) -} -func (m *UpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_UpdateResponse.Marshal(b, m, deterministic) -} -func (m *UpdateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateResponse.Merge(m, src) -} -func (m *UpdateResponse) XXX_Size() int { - return xxx_messageInfo_UpdateResponse.Size(m) -} -func (m *UpdateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_UpdateResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_UpdateResponse proto.InternalMessageInfo - -type DeleteRequest struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } -func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteRequest) ProtoMessage() {} -func (*DeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{5} -} - -func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteRequest.Unmarshal(m, b) -} -func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic) -} -func (m *DeleteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteRequest.Merge(m, src) -} -func (m *DeleteRequest) XXX_Size() int { - return xxx_messageInfo_DeleteRequest.Size(m) -} -func (m *DeleteRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo - -func (m *DeleteRequest) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -type DeleteResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteResponse) Reset() { *m = DeleteResponse{} } -func (m *DeleteResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteResponse) ProtoMessage() {} -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{6} -} - -func (m *DeleteResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteResponse.Unmarshal(m, b) -} -func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic) -} -func (m *DeleteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteResponse.Merge(m, src) -} -func (m *DeleteResponse) XXX_Size() int { - return xxx_messageInfo_DeleteResponse.Size(m) -} -func (m *DeleteResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo - -type ListRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ListRequest) Reset() { *m = ListRequest{} } -func (m *ListRequest) String() string { return proto.CompactTextString(m) } -func (*ListRequest) ProtoMessage() {} -func (*ListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{7} -} - -func (m *ListRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ListRequest.Unmarshal(m, b) -} -func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic) -} -func (m *ListRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ListRequest.Merge(m, src) -} -func (m *ListRequest) XXX_Size() int { - return xxx_messageInfo_ListRequest.Size(m) -} -func (m *ListRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ListRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ListRequest proto.InternalMessageInfo - -type ListResponse struct { - Notes []*Note `protobuf:"bytes,1,rep,name=notes,proto3" json:"notes,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ListResponse) Reset() { *m = ListResponse{} } -func (m *ListResponse) String() string { return proto.CompactTextString(m) } -func (*ListResponse) ProtoMessage() {} -func (*ListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7f19915b807268a5, []int{8} -} - -func (m *ListResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ListResponse.Unmarshal(m, b) -} -func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic) -} -func (m *ListResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ListResponse.Merge(m, src) -} -func (m *ListResponse) XXX_Size() int { - return xxx_messageInfo_ListResponse.Size(m) -} -func (m *ListResponse) XXX_DiscardUnknown() { - xxx_messageInfo_ListResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_ListResponse proto.InternalMessageInfo - -func (m *ListResponse) GetNotes() []*Note { - if m != nil { - return m.Notes - } - return nil -} - -func init() { - proto.RegisterType((*Note)(nil), "notes.Note") - proto.RegisterType((*CreateRequest)(nil), "notes.CreateRequest") - proto.RegisterType((*CreateResponse)(nil), "notes.CreateResponse") - proto.RegisterType((*UpdateRequest)(nil), "notes.UpdateRequest") - proto.RegisterType((*UpdateResponse)(nil), "notes.UpdateResponse") - proto.RegisterType((*DeleteRequest)(nil), "notes.DeleteRequest") - proto.RegisterType((*DeleteResponse)(nil), "notes.DeleteResponse") - proto.RegisterType((*ListRequest)(nil), "notes.ListRequest") - proto.RegisterType((*ListResponse)(nil), "notes.ListResponse") -} - -func init() { proto.RegisterFile("notes/proto/notes.proto", fileDescriptor_7f19915b807268a5) } - -var fileDescriptor_7f19915b807268a5 = []byte{ - // 344 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcf, 0x4a, 0xc3, 0x40, - 0x10, 0xc6, 0xc9, 0x9f, 0x56, 0x9c, 0x36, 0x45, 0xd6, 0x8a, 0xa1, 0x17, 0x63, 0x4e, 0x01, 0xb1, - 0xc1, 0x8a, 0x07, 0x11, 0x2f, 0xea, 0x45, 0x10, 0x0f, 0x11, 0x2f, 0xbd, 0xb5, 0xc9, 0xa0, 0x0b, - 0x6d, 0x37, 0x66, 0xa7, 0xe2, 0xc3, 0xf8, 0xb0, 0x92, 0xdd, 0x24, 0xcd, 0xd6, 0x7a, 0xf0, 0x36, - 0xdf, 0xec, 0xfc, 0x66, 0x76, 0xbe, 0x5d, 0x38, 0x5e, 0x09, 0x42, 0x19, 0xe7, 0x85, 0x20, 0x11, - 0xab, 0x78, 0xac, 0x62, 0xd6, 0x51, 0x22, 0x9c, 0x82, 0xfb, 0x2c, 0x08, 0xd9, 0x00, 0x6c, 0x9e, - 0xf9, 0x56, 0x60, 0x45, 0xfb, 0x89, 0xcd, 0x33, 0xe6, 0xc3, 0x5e, 0x5a, 0xe0, 0x8c, 0x30, 0xf3, - 0xed, 0xc0, 0x8a, 0x9c, 0xa4, 0x96, 0x6c, 0x08, 0x1d, 0xe2, 0xb4, 0x40, 0xdf, 0x51, 0xc5, 0x5a, - 0x30, 0x06, 0x2e, 0xe1, 0x17, 0xf9, 0xae, 0x4a, 0xaa, 0x38, 0xbc, 0x06, 0xef, 0x5e, 0x41, 0x09, - 0x7e, 0xac, 0x51, 0xd2, 0x06, 0xb5, 0x76, 0xa1, 0x76, 0x0b, 0x0d, 0x60, 0x50, 0xa3, 0x32, 0x17, - 0x2b, 0xf9, 0xeb, 0x82, 0xe1, 0x23, 0x78, 0xaf, 0x79, 0xd6, 0x6a, 0xbe, 0xbd, 0x41, 0x33, 0xcc, - 0xde, 0x35, 0xcc, 0x69, 0x0d, 0x3b, 0x80, 0x41, 0xdd, 0x4a, 0x0f, 0x0b, 0x4f, 0xc0, 0x7b, 0xc0, - 0x05, 0xfe, 0xd9, 0xbc, 0x44, 0xea, 0x82, 0x0a, 0xf1, 0xa0, 0xf7, 0xc4, 0x25, 0x55, 0x40, 0x78, - 0x01, 0x7d, 0x2d, 0xab, 0xeb, 0x9f, 0x82, 0x36, 0xdc, 0xb7, 0x02, 0x27, 0xea, 0x4d, 0x7a, 0x63, - 0xfd, 0x16, 0xa5, 0xf7, 0x89, 0x3e, 0x99, 0x7c, 0xdb, 0xd0, 0x29, 0xb5, 0x64, 0x31, 0xb8, 0x25, - 0xcc, 0x58, 0x55, 0xd5, 0x6a, 0x3c, 0x3a, 0x34, 0x72, 0x55, 0xf7, 0x2b, 0xe8, 0x6a, 0xbb, 0xd8, - 0xb0, 0x3a, 0x36, 0x8c, 0x1f, 0x1d, 0x6d, 0x65, 0x37, 0x98, 0xde, 0xa2, 0xc1, 0x8c, 0xad, 0x1b, - 0xcc, 0x5c, 0xb5, 0xc4, 0xb4, 0x5f, 0x0d, 0x66, 0xbc, 0x44, 0x83, 0x99, 0xa6, 0xb2, 0x5b, 0xe8, - 0xeb, 0xcc, 0x0b, 0x15, 0x38, 0x5b, 0xfe, 0x0b, 0x8e, 0xac, 0xbb, 0xf3, 0xe9, 0xd9, 0x1b, 0xa7, - 0xf7, 0xf5, 0x7c, 0x9c, 0x8a, 0x65, 0xbc, 0xe4, 0x69, 0x21, 0x62, 0x89, 0xc5, 0x27, 0x4f, 0x51, - 0xc6, 0xad, 0x5f, 0x7e, 0xa3, 0xe2, 0x79, 0x57, 0x89, 0xcb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x31, 0xee, 0xed, 0xda, 0x01, 0x03, 0x00, 0x00, -} diff --git a/notes/proto/notes.pb.micro.go b/notes/proto/notes.pb.micro.go deleted file mode 100644 index 16c319d..0000000 --- a/notes/proto/notes.pb.micro.go +++ /dev/null @@ -1,236 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: notes/proto/notes.proto - -package notes - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Notes service - -func NewNotesEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Notes service - -type NotesService interface { - List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) - Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) - Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) - Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) - UpdateStream(ctx context.Context, opts ...client.CallOption) (Notes_UpdateStreamService, error) -} - -type notesService struct { - c client.Client - name string -} - -func NewNotesService(name string, c client.Client) NotesService { - return ¬esService{ - c: c, - name: name, - } -} - -func (c *notesService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { - req := c.c.NewRequest(c.name, "Notes.List", in) - out := new(ListResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *notesService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { - req := c.c.NewRequest(c.name, "Notes.Create", in) - out := new(CreateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *notesService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { - req := c.c.NewRequest(c.name, "Notes.Delete", in) - out := new(DeleteResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *notesService) Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) { - req := c.c.NewRequest(c.name, "Notes.Update", in) - out := new(UpdateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *notesService) UpdateStream(ctx context.Context, opts ...client.CallOption) (Notes_UpdateStreamService, error) { - req := c.c.NewRequest(c.name, "Notes.UpdateStream", &UpdateRequest{}) - stream, err := c.c.Stream(ctx, req, opts...) - if err != nil { - return nil, err - } - return ¬esServiceUpdateStream{stream}, nil -} - -type Notes_UpdateStreamService interface { - Context() context.Context - SendMsg(interface{}) error - RecvMsg(interface{}) error - CloseAndRecv() (*UpdateResponse, error) - Send(*UpdateRequest) error -} - -type notesServiceUpdateStream struct { - stream client.Stream -} - -func (x *notesServiceUpdateStream) CloseAndRecv() (*UpdateResponse, error) { - if err := x.stream.Close(); err != nil { - return nil, err - } - r := new(UpdateResponse) - err := x.RecvMsg(r) - return r, err -} - -func (x *notesServiceUpdateStream) Context() context.Context { - return x.stream.Context() -} - -func (x *notesServiceUpdateStream) SendMsg(m interface{}) error { - return x.stream.Send(m) -} - -func (x *notesServiceUpdateStream) RecvMsg(m interface{}) error { - return x.stream.Recv(m) -} - -func (x *notesServiceUpdateStream) Send(m *UpdateRequest) error { - return x.stream.Send(m) -} - -// Server API for Notes service - -type NotesHandler interface { - List(context.Context, *ListRequest, *ListResponse) error - Create(context.Context, *CreateRequest, *CreateResponse) error - Delete(context.Context, *DeleteRequest, *DeleteResponse) error - Update(context.Context, *UpdateRequest, *UpdateResponse) error - UpdateStream(context.Context, Notes_UpdateStreamStream) error -} - -func RegisterNotesHandler(s server.Server, hdlr NotesHandler, opts ...server.HandlerOption) error { - type notes interface { - List(ctx context.Context, in *ListRequest, out *ListResponse) error - Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error - Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error - Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error - UpdateStream(ctx context.Context, stream server.Stream) error - } - type Notes struct { - notes - } - h := ¬esHandler{hdlr} - return s.Handle(s.NewHandler(&Notes{h}, opts...)) -} - -type notesHandler struct { - NotesHandler -} - -func (h *notesHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { - return h.NotesHandler.List(ctx, in, out) -} - -func (h *notesHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { - return h.NotesHandler.Create(ctx, in, out) -} - -func (h *notesHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { - return h.NotesHandler.Delete(ctx, in, out) -} - -func (h *notesHandler) Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error { - return h.NotesHandler.Update(ctx, in, out) -} - -func (h *notesHandler) UpdateStream(ctx context.Context, stream server.Stream) error { - return h.NotesHandler.UpdateStream(ctx, ¬esUpdateStreamStream{stream}) -} - -type Notes_UpdateStreamStream interface { - Context() context.Context - SendMsg(interface{}) error - RecvMsg(interface{}) error - SendAndClose(*UpdateResponse) error - Recv() (*UpdateRequest, error) -} - -type notesUpdateStreamStream struct { - stream server.Stream -} - -func (x *notesUpdateStreamStream) SendAndClose(in *UpdateResponse) error { - if err := x.SendMsg(in); err != nil { - return err - } - return x.stream.Close() -} - -func (x *notesUpdateStreamStream) Context() context.Context { - return x.stream.Context() -} - -func (x *notesUpdateStreamStream) SendMsg(m interface{}) error { - return x.stream.Send(m) -} - -func (x *notesUpdateStreamStream) RecvMsg(m interface{}) error { - return x.stream.Recv(m) -} - -func (x *notesUpdateStreamStream) Recv() (*UpdateRequest, error) { - m := new(UpdateRequest) - if err := x.stream.Recv(m); err != nil { - return nil, err - } - return m, nil -} diff --git a/notes/proto/notes.proto b/notes/proto/notes.proto deleted file mode 100644 index 5fadf30..0000000 --- a/notes/proto/notes.proto +++ /dev/null @@ -1,48 +0,0 @@ -syntax = "proto3"; - -package notes; -option go_package = "./proto;notes"; - -service Notes { - rpc List(ListRequest) returns (ListResponse); - rpc Create(CreateRequest) returns (CreateResponse); - rpc Delete(DeleteRequest) returns (DeleteResponse); - rpc Update(UpdateRequest) returns (UpdateResponse); - rpc UpdateStream(stream UpdateRequest) returns (UpdateResponse); -} - -message Note { - string id = 1; - int64 created = 2; - string title = 3; - string text = 4; -} - -message CreateRequest { - string title = 1; - string text = 2; -} - -message CreateResponse { - string id = 1; -} - -message UpdateRequest { - string id = 1; - string title = 2; - string text = 3; -} - -message UpdateResponse {} - -message DeleteRequest { - string id = 1; -} - -message DeleteResponse {} - -message ListRequest {} - -message ListResponse { - repeated Note notes = 1; -} diff --git a/notes/skip b/notes/skip deleted file mode 100644 index e69de29..0000000 diff --git a/notes/usage.md b/notes/usage.md deleted file mode 100644 index 1fa74ee..0000000 --- a/notes/usage.md +++ /dev/null @@ -1,42 +0,0 @@ -Notes service is an RPC service which offers CRUD for notes. It demonstrates usage of the store, errors and logger pacakges. - -# Notes Service - -## Create a note - -```bash -micro notes create --title="HelloWorld" --text="MyFirstNote" -{ - "id": "6d3fa5c0-6e79-4418-a72a-c1650efb65d2" -} -``` - -## Update a note - -```bash -micro notes update --id=6d3fa5c0-6e79-4418-a72a-c1650efb65d2 --title="HelloWorld" --text="MyFirstNote (v2)" -{} -``` - -## List notes - -```bash -micro notes list -{ - "notes": [ - { - "id": "6d3fa5c0-6e79-4418-a72a-c1650efb65d2", - "created": "1602849877", - "title": "HelloWorld", - "text": "MyFirstNote (v2)" - } - ] -} -``` - -## Delete a note - -```bash -micro notes delete --id=6d3fa5c0-6e79-4418-a72a-c1650efb65d2 -{} -``` diff --git a/seen/.gitignore b/seen/.gitignore deleted file mode 100644 index 49b4681..0000000 --- a/seen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -seen diff --git a/seen/Dockerfile b/seen/Dockerfile deleted file mode 100644 index abf9e36..0000000 --- a/seen/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD seen /seen -ENTRYPOINT [ "/seen" ] diff --git a/seen/Makefile b/seen/Makefile deleted file mode 100644 index 663f2f1..0000000 --- a/seen/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --proto_path=. --micro_out=. --go_out=:. proto/seen.proto - -.PHONY: build -build: - go build -o seen *.go - -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/seen.proto - @redoc-cli bundle api-seen.json - - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t seen:latest diff --git a/seen/README.md b/seen/README.md deleted file mode 100644 index 096d7cb..0000000 --- a/seen/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Seen is a service to keep track of which resources a user has seen (read). For example, it can be used to keep track of what notifications have been seen by a user, or what messages they've read in a chat. - - -# Seen Service - -The seen service is a service to keep track of which resources a user has seen (read). diff --git a/seen/handler/handler.go b/seen/handler/handler.go deleted file mode 100644 index 156ad1b..0000000 --- a/seen/handler/handler.go +++ /dev/null @@ -1,221 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - "github.com/micro/services/pkg/tenant" - pb "github.com/micro/services/seen/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -var ( - ErrMissingUserID = errors.BadRequest("MISSING_USER_ID", "Missing UserID") - ErrMissingResourceID = errors.BadRequest("MISSING_RESOURCE_ID", "Missing ResourceID") - ErrMissingResourceIDs = errors.BadRequest("MISSING_RESOURCE_IDS", "Missing ResourceIDs") - ErrMissingResourceType = errors.BadRequest("MISSING_RESOURCE_TYPE", "Missing ResourceType") - ErrStore = errors.InternalServerError("STORE_ERROR", "Error connecting to the store") -) - -type Seen struct{} - -type Record struct { - ID string - UserID string - ResourceID string - ResourceType string - Timestamp time.Time -} - -func (r *Record) Key(ctx context.Context) string { - key := fmt.Sprintf("%s:%s:%s", r.UserID, r.ResourceType, r.ResourceID) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (r *Record) Marshal() []byte { - b, _ := json.Marshal(r) - return b -} - -func (r *Record) Unmarshal(b []byte) error { - return json.Unmarshal(b, &r) -} - -// Set a resource as seen by a user. If no timestamp is provided, the current time is used. -func (s *Seen) Set(ctx context.Context, req *pb.SetRequest, rsp *pb.SetResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.UserId) == 0 { - return ErrMissingUserID - } - if len(req.ResourceId) == 0 { - return ErrMissingResourceID - } - if len(req.ResourceType) == 0 { - return ErrMissingResourceType - } - - // default the timestamp - if req.Timestamp == nil { - req.Timestamp = timestamppb.New(time.Now()) - } - - // find the resource - instance := &Record{ - UserID: req.UserId, - ResourceID: req.ResourceId, - ResourceType: req.ResourceType, - } - - _, err := store.Read(instance.Key(ctx), store.ReadLimit(1)) - if err == store.ErrNotFound { - instance.ID = uuid.New().String() - } else if err != nil { - logger.Errorf("Error with store: %v", err) - return ErrStore - } - - // update the resource - instance.Timestamp = req.Timestamp.AsTime() - - if err := store.Write(&store.Record{ - Key: instance.Key(ctx), - Value: instance.Marshal(), - }); err != nil { - logger.Errorf("Error with store: %v", err) - return ErrStore - } - - return nil -} - -// Unset a resource as seen, used in cases where a user viewed a resource but wants to override -// this so they remember to action it in the future, e.g. "Mark this as unread". -func (s *Seen) Unset(ctx context.Context, req *pb.UnsetRequest, rsp *pb.UnsetResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.UserId) == 0 { - return ErrMissingUserID - } - if len(req.ResourceId) == 0 { - return ErrMissingResourceID - } - if len(req.ResourceType) == 0 { - return ErrMissingResourceType - } - - instance := &Record{ - UserID: req.UserId, - ResourceID: req.ResourceId, - ResourceType: req.ResourceType, - } - - // delete the object from the store - if err := store.Delete(instance.Key(ctx)); err != nil { - logger.Errorf("Error with store: %v", err) - return ErrStore - } - - return nil -} - -// Read returns the timestamps at which various resources were seen by a user. If no timestamp -// is returned for a given resource_id, it indicates that resource has not yet been seen by the -// user. -func (s *Seen) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.UserId) == 0 { - return ErrMissingUserID - } - if len(req.ResourceIds) == 0 { - return ErrMissingResourceIDs - } - if len(req.ResourceType) == 0 { - return ErrMissingResourceType - } - - rec := &Record{ - UserID: req.UserId, - ResourceType: req.ResourceType, - } - - var recs []*store.Record - var err error - - // get the records for the resource type - if len(req.ResourceIds) == 1 { - // read the key itself - rec.ResourceID = req.ResourceIds[0] - // gen key - key := rec.Key(ctx) - // get the record - recs, err = store.Read(key, store.ReadLimit(1)) - } else { - // create a key prefix - key := rec.Key(ctx) - // otherwise read the prefix - recs, err = store.Read(key, store.ReadPrefix()) - } - - if err == store.ErrNotFound { - return nil - } else if err != nil { - logger.Errorf("Error with store: %v", err) - return ErrStore - } - - // make an id map - ids := make(map[string]bool) - - for _, id := range req.ResourceIds { - ids[id] = true - } - - // make the map - rsp.Timestamps = make(map[string]*timestamppb.Timestamp) - - // range over records for the user/resource type - // TODO: add some sort of filter query in store - for _, rec := range recs { - // get id - parts := strings.Split(rec.Key, ":") - id := parts[2] - - fmt.Println("checking record", rec.Key, id) - - if ok := ids[id]; !ok { - continue - } - - // add the timestamp for the record - r := new(Record) - r.Unmarshal(rec.Value) - rsp.Timestamps[id] = timestamppb.New(r.Timestamp) - } - - return nil -} diff --git a/seen/handler/handler_test.go b/seen/handler/handler_test.go deleted file mode 100644 index cab8273..0000000 --- a/seen/handler/handler_test.go +++ /dev/null @@ -1,250 +0,0 @@ -package handler_test - -import ( - "context" - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/store" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/seen/handler" - pb "github.com/micro/services/seen/proto" - "github.com/stretchr/testify/assert" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func testHandler(t *testing.T) *handler.Seen { - store.DefaultStore = memory.NewStore() - return &handler.Seen{} -} - -func TestSet(t *testing.T) { - tt := []struct { - Name string - UserID string - ResourceType string - ResourceID string - Timestamp *timestamppb.Timestamp - Error error - }{ - { - Name: "MissingUserID", - ResourceType: "message", - ResourceID: uuid.New().String(), - Error: handler.ErrMissingUserID, - }, - { - Name: "MissingResourceID", - UserID: uuid.New().String(), - ResourceType: "message", - Error: handler.ErrMissingResourceID, - }, - { - Name: "MissingResourceType", - UserID: uuid.New().String(), - ResourceID: uuid.New().String(), - Error: handler.ErrMissingResourceType, - }, - { - Name: "WithTimetamp", - UserID: uuid.New().String(), - ResourceID: uuid.New().String(), - ResourceType: "message", - Timestamp: timestamppb.New(time.Now().Add(time.Minute * -5)), - }, - { - Name: "WithoutTimetamp", - UserID: uuid.New().String(), - ResourceID: uuid.New().String(), - ResourceType: "message", - }, - { - Name: "WithUpdatedTimetamp", - UserID: uuid.New().String(), - ResourceID: uuid.New().String(), - ResourceType: "message", - Timestamp: timestamppb.New(time.Now().Add(time.Minute * -3)), - }, - } - - h := testHandler(t) - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - err := h.Set(microAccountCtx(), &pb.SetRequest{ - UserId: tc.UserID, - ResourceId: tc.ResourceID, - ResourceType: tc.ResourceType, - Timestamp: tc.Timestamp, - }, &pb.SetResponse{}) - - assert.Equal(t, tc.Error, err) - }) - } -} -func TestUnset(t *testing.T) { - // seed some test data - h := testHandler(t) - seed := &pb.SetRequest{ - UserId: uuid.New().String(), - ResourceId: uuid.New().String(), - ResourceType: "message", - } - err := h.Set(microAccountCtx(), seed, &pb.SetResponse{}) - assert.NoError(t, err) - - tt := []struct { - Name string - UserID string - ResourceType string - ResourceID string - Error error - }{ - { - Name: "MissingUserID", - ResourceType: "message", - ResourceID: uuid.New().String(), - Error: handler.ErrMissingUserID, - }, - { - Name: "MissingResourceID", - UserID: uuid.New().String(), - ResourceType: "message", - Error: handler.ErrMissingResourceID, - }, - { - Name: "MissingResourceType", - UserID: uuid.New().String(), - ResourceID: uuid.New().String(), - Error: handler.ErrMissingResourceType, - }, - { - Name: "Exists", - UserID: seed.UserId, - ResourceID: seed.ResourceId, - ResourceType: seed.ResourceType, - }, - { - Name: "Repeat", - UserID: seed.UserId, - ResourceID: seed.ResourceId, - ResourceType: seed.ResourceType, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - err := h.Unset(microAccountCtx(), &pb.UnsetRequest{ - UserId: tc.UserID, - ResourceId: tc.ResourceID, - ResourceType: tc.ResourceType, - }, &pb.UnsetResponse{}) - - assert.Equal(t, tc.Error, err) - }) - } -} - -func TestRead(t *testing.T) { - tn := time.Now() - h := testHandler(t) - - // seed some test data - td := []struct { - UserID string - ResourceID string - ResourceType string - Timestamp *timestamppb.Timestamp - }{ - { - UserID: "user-1", - ResourceID: "message-1", - ResourceType: "message", - Timestamp: timestamppb.New(tn.Add(time.Minute * -10)), - }, - { - UserID: "user-1", - ResourceID: "message-1", - ResourceType: "message", - Timestamp: timestamppb.New(tn), - }, - { - UserID: "user-1", - ResourceID: "message-2", - ResourceType: "message", - Timestamp: timestamppb.New(tn.Add(time.Minute * -10)), - }, - { - UserID: "user-1", - ResourceID: "notification-1", - ResourceType: "notification", - Timestamp: timestamppb.New(tn.Add(time.Minute * -10)), - }, - { - UserID: "user-2", - ResourceID: "message-3", - ResourceType: "message", - Timestamp: timestamppb.New(tn.Add(time.Minute * -10)), - }, - } - for _, d := range td { - assert.NoError(t, h.Set(microAccountCtx(), &pb.SetRequest{ - UserId: d.UserID, - ResourceId: d.ResourceID, - ResourceType: d.ResourceType, - Timestamp: d.Timestamp, - }, &pb.SetResponse{})) - } - - // check only the requested values are returned - var rsp pb.ReadResponse - err := h.Read(microAccountCtx(), &pb.ReadRequest{ - UserId: "user-1", - ResourceType: "message", - ResourceIds: []string{"message-1", "message-2", "message-3"}, - }, &rsp) - assert.NoError(t, err) - assert.Len(t, rsp.Timestamps, 2) - - if v := rsp.Timestamps["message-1"]; v != nil { - assert.Equal(t, microSecondTime(v.AsTime()), microSecondTime(tn)) - } else { - t.Errorf("Expected a timestamp for message-1") - } - - if v := rsp.Timestamps["message-2"]; v != nil { - assert.Equal(t, microSecondTime(v.AsTime()), microSecondTime(tn.Add(time.Minute*-10).UTC())) - } else { - t.Errorf("Expected a timestamp for message-2") - } - - // unsetting a resource should remove it from the list - err = h.Unset(microAccountCtx(), &pb.UnsetRequest{ - UserId: "user-1", - ResourceId: "message-2", - ResourceType: "message", - }, &pb.UnsetResponse{}) - assert.NoError(t, err) - - rsp = pb.ReadResponse{} - err = h.Read(microAccountCtx(), &pb.ReadRequest{ - UserId: "user-1", - ResourceType: "message", - ResourceIds: []string{"message-1", "message-2", "message-3"}, - }, &rsp) - assert.NoError(t, err) - assert.Len(t, rsp.Timestamps, 1) - -} - -// postgres has a resolution of 100microseconds so just test that it's accurate to the second -func microSecondTime(tt time.Time) time.Time { - return time.Unix(tt.Unix(), int64(tt.Nanosecond()-tt.Nanosecond()%1000)).UTC() -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - }) -} diff --git a/seen/main.go b/seen/main.go deleted file mode 100644 index 41d9f46..0000000 --- a/seen/main.go +++ /dev/null @@ -1,24 +0,0 @@ -package main - -import ( - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/seen/handler" - pb "github.com/micro/services/seen/proto" -) - -func main() { - // Create service - srv := service.New( - service.Name("seen"), - service.Version("latest"), - ) - - // Register handler - pb.RegisterSeenHandler(srv.Server(), new(handler.Seen)) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/seen/micro.mu b/seen/micro.mu deleted file mode 100644 index 74056f4..0000000 --- a/seen/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service seen diff --git a/seen/proto/seen.pb.go b/seen/proto/seen.pb.go deleted file mode 100644 index b0fe897..0000000 --- a/seen/proto/seen.pb.go +++ /dev/null @@ -1,614 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0 -// protoc v3.15.5 -// source: proto/seen.proto - -package seen - -import ( - proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Resource struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *Resource) Reset() { - *x = Resource{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Resource) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Resource) ProtoMessage() {} - -func (x *Resource) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Resource.ProtoReflect.Descriptor instead. -func (*Resource) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{0} -} - -func (x *Resource) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Resource) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type SetRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ResourceType string `protobuf:"bytes,2,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` - ResourceId string `protobuf:"bytes,3,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"` - Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` -} - -func (x *SetRequest) Reset() { - *x = SetRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SetRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetRequest) ProtoMessage() {} - -func (x *SetRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SetRequest.ProtoReflect.Descriptor instead. -func (*SetRequest) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{1} -} - -func (x *SetRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SetRequest) GetResourceType() string { - if x != nil { - return x.ResourceType - } - return "" -} - -func (x *SetRequest) GetResourceId() string { - if x != nil { - return x.ResourceId - } - return "" -} - -func (x *SetRequest) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -type SetResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *SetResponse) Reset() { - *x = SetResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SetResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetResponse) ProtoMessage() {} - -func (x *SetResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SetResponse.ProtoReflect.Descriptor instead. -func (*SetResponse) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{2} -} - -type UnsetRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ResourceType string `protobuf:"bytes,2,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` - ResourceId string `protobuf:"bytes,3,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"` -} - -func (x *UnsetRequest) Reset() { - *x = UnsetRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnsetRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnsetRequest) ProtoMessage() {} - -func (x *UnsetRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnsetRequest.ProtoReflect.Descriptor instead. -func (*UnsetRequest) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{3} -} - -func (x *UnsetRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *UnsetRequest) GetResourceType() string { - if x != nil { - return x.ResourceType - } - return "" -} - -func (x *UnsetRequest) GetResourceId() string { - if x != nil { - return x.ResourceId - } - return "" -} - -type UnsetResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *UnsetResponse) Reset() { - *x = UnsetResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnsetResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnsetResponse) ProtoMessage() {} - -func (x *UnsetResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnsetResponse.ProtoReflect.Descriptor instead. -func (*UnsetResponse) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{4} -} - -type ReadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ResourceType string `protobuf:"bytes,2,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` - ResourceIds []string `protobuf:"bytes,3,rep,name=resource_ids,json=resourceIds,proto3" json:"resource_ids,omitempty"` -} - -func (x *ReadRequest) Reset() { - *x = ReadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadRequest) ProtoMessage() {} - -func (x *ReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. -func (*ReadRequest) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{5} -} - -func (x *ReadRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *ReadRequest) GetResourceType() string { - if x != nil { - return x.ResourceType - } - return "" -} - -func (x *ReadRequest) GetResourceIds() []string { - if x != nil { - return x.ResourceIds - } - return nil -} - -type ReadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Timestamps map[string]*timestamppb.Timestamp `protobuf:"bytes,1,rep,name=timestamps,proto3" json:"timestamps,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ReadResponse) Reset() { - *x = ReadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_seen_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadResponse) ProtoMessage() {} - -func (x *ReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_seen_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. -func (*ReadResponse) Descriptor() ([]byte, []int) { - return file_proto_seen_proto_rawDescGZIP(), []int{6} -} - -func (x *ReadResponse) GetTimestamps() map[string]*timestamppb.Timestamp { - if x != nil { - return x.Timestamps - } - return nil -} - -var File_proto_seen_proto protoreflect.FileDescriptor - -var file_proto_seen_proto_rawDesc = []byte{ - 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x04, 0x73, 0x65, 0x65, 0x6e, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xa5, 0x01, 0x0a, 0x0a, 0x53, 0x65, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x6d, 0x0a, 0x0c, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x22, - 0x0f, 0x0a, 0x0d, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x6e, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, - 0x22, 0xad, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x73, 0x1a, 0x59, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x32, 0x93, 0x01, 0x0a, 0x04, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x03, 0x53, 0x65, 0x74, - 0x12, 0x10, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x12, 0x12, - 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, - 0x11, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0c, 0x5a, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, - 0x73, 0x65, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_seen_proto_rawDescOnce sync.Once - file_proto_seen_proto_rawDescData = file_proto_seen_proto_rawDesc -) - -func file_proto_seen_proto_rawDescGZIP() []byte { - file_proto_seen_proto_rawDescOnce.Do(func() { - file_proto_seen_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_seen_proto_rawDescData) - }) - return file_proto_seen_proto_rawDescData -} - -var file_proto_seen_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_proto_seen_proto_goTypes = []interface{}{ - (*Resource)(nil), // 0: seen.Resource - (*SetRequest)(nil), // 1: seen.SetRequest - (*SetResponse)(nil), // 2: seen.SetResponse - (*UnsetRequest)(nil), // 3: seen.UnsetRequest - (*UnsetResponse)(nil), // 4: seen.UnsetResponse - (*ReadRequest)(nil), // 5: seen.ReadRequest - (*ReadResponse)(nil), // 6: seen.ReadResponse - nil, // 7: seen.ReadResponse.TimestampsEntry - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp -} -var file_proto_seen_proto_depIdxs = []int32{ - 8, // 0: seen.SetRequest.timestamp:type_name -> google.protobuf.Timestamp - 7, // 1: seen.ReadResponse.timestamps:type_name -> seen.ReadResponse.TimestampsEntry - 8, // 2: seen.ReadResponse.TimestampsEntry.value:type_name -> google.protobuf.Timestamp - 1, // 3: seen.Seen.Set:input_type -> seen.SetRequest - 3, // 4: seen.Seen.Unset:input_type -> seen.UnsetRequest - 5, // 5: seen.Seen.Read:input_type -> seen.ReadRequest - 2, // 6: seen.Seen.Set:output_type -> seen.SetResponse - 4, // 7: seen.Seen.Unset:output_type -> seen.UnsetResponse - 6, // 8: seen.Seen.Read:output_type -> seen.ReadResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_proto_seen_proto_init() } -func file_proto_seen_proto_init() { - if File_proto_seen_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_seen_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Resource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnsetRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnsetResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_seen_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_seen_proto_rawDesc, - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_seen_proto_goTypes, - DependencyIndexes: file_proto_seen_proto_depIdxs, - MessageInfos: file_proto_seen_proto_msgTypes, - }.Build() - File_proto_seen_proto = out.File - file_proto_seen_proto_rawDesc = nil - file_proto_seen_proto_goTypes = nil - file_proto_seen_proto_depIdxs = nil -} diff --git a/seen/proto/seen.pb.micro.go b/seen/proto/seen.pb.micro.go deleted file mode 100644 index a556dbe..0000000 --- a/seen/proto/seen.pb.micro.go +++ /dev/null @@ -1,140 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/seen.proto - -package seen - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - _ "google.golang.org/protobuf/types/known/timestamppb" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Seen service - -func NewSeenEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Seen service - -type SeenService interface { - // Set a resource as seen by a user. If no timestamp is provided, the current time is used. - Set(ctx context.Context, in *SetRequest, opts ...client.CallOption) (*SetResponse, error) - // Unset a resource as seen, used in cases where a user viewed a resource but wants to override - // this so they remember to action it in the future, e.g. "Mark this as unread". - Unset(ctx context.Context, in *UnsetRequest, opts ...client.CallOption) (*UnsetResponse, error) - // Read returns the timestamps at which various resources were seen by a user. If no timestamp - // is returned for a given resource_id, it indicates that resource has not yet been seen by the - // user. - Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) -} - -type seenService struct { - c client.Client - name string -} - -func NewSeenService(name string, c client.Client) SeenService { - return &seenService{ - c: c, - name: name, - } -} - -func (c *seenService) Set(ctx context.Context, in *SetRequest, opts ...client.CallOption) (*SetResponse, error) { - req := c.c.NewRequest(c.name, "Seen.Set", in) - out := new(SetResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *seenService) Unset(ctx context.Context, in *UnsetRequest, opts ...client.CallOption) (*UnsetResponse, error) { - req := c.c.NewRequest(c.name, "Seen.Unset", in) - out := new(UnsetResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *seenService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { - req := c.c.NewRequest(c.name, "Seen.Read", in) - out := new(ReadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Seen service - -type SeenHandler interface { - // Set a resource as seen by a user. If no timestamp is provided, the current time is used. - Set(context.Context, *SetRequest, *SetResponse) error - // Unset a resource as seen, used in cases where a user viewed a resource but wants to override - // this so they remember to action it in the future, e.g. "Mark this as unread". - Unset(context.Context, *UnsetRequest, *UnsetResponse) error - // Read returns the timestamps at which various resources were seen by a user. If no timestamp - // is returned for a given resource_id, it indicates that resource has not yet been seen by the - // user. - Read(context.Context, *ReadRequest, *ReadResponse) error -} - -func RegisterSeenHandler(s server.Server, hdlr SeenHandler, opts ...server.HandlerOption) error { - type seen interface { - Set(ctx context.Context, in *SetRequest, out *SetResponse) error - Unset(ctx context.Context, in *UnsetRequest, out *UnsetResponse) error - Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error - } - type Seen struct { - seen - } - h := &seenHandler{hdlr} - return s.Handle(s.NewHandler(&Seen{h}, opts...)) -} - -type seenHandler struct { - SeenHandler -} - -func (h *seenHandler) Set(ctx context.Context, in *SetRequest, out *SetResponse) error { - return h.SeenHandler.Set(ctx, in, out) -} - -func (h *seenHandler) Unset(ctx context.Context, in *UnsetRequest, out *UnsetResponse) error { - return h.SeenHandler.Unset(ctx, in, out) -} - -func (h *seenHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { - return h.SeenHandler.Read(ctx, in, out) -} diff --git a/seen/proto/seen.proto b/seen/proto/seen.proto deleted file mode 100644 index 82c9acd..0000000 --- a/seen/proto/seen.proto +++ /dev/null @@ -1,52 +0,0 @@ -syntax = "proto3"; - -package seen; -option go_package = "./proto;seen"; -import "google/protobuf/timestamp.proto"; - -// Seen is a service to keep track of which resources a user has seen (read). For example, it can -// be used to keep track of what notifications have been seen by a user, or what messages they've -// read in a chat. -service Seen { - // Set a resource as seen by a user. If no timestamp is provided, the current time is used. - rpc Set(SetRequest) returns (SetResponse); - // Unset a resource as seen, used in cases where a user viewed a resource but wants to override - // this so they remember to action it in the future, e.g. "Mark this as unread". - rpc Unset(UnsetRequest) returns (UnsetResponse); - // Read returns the timestamps at which various resources were seen by a user. If no timestamp - // is returned for a given resource_id, it indicates that resource has not yet been seen by the - // user. - rpc Read(ReadRequest) returns (ReadResponse); -} - -message Resource { - string type = 1; - string id = 2; -} - -message SetRequest { - string user_id = 1; - string resource_type = 2; - string resource_id = 3; - google.protobuf.Timestamp timestamp = 4; -} - -message SetResponse {} - -message UnsetRequest { - string user_id = 1; - string resource_type = 2; - string resource_id = 3; -} - -message UnsetResponse {} - -message ReadRequest { - string user_id = 1; - string resource_type = 2; - repeated string resource_ids = 3; -} - -message ReadResponse { - map timestamps = 1; -} diff --git a/streams/.gitignore b/streams/.gitignore deleted file mode 100644 index 4a47005..0000000 --- a/streams/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -streams diff --git a/streams/Makefile b/streams/Makefile deleted file mode 100644 index 1a31997..0000000 --- a/streams/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --proto_path=. --micro_out=. --go_out=:. proto/streams.proto - -.PHONY: build -build: - go build -o streams *.go - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/streams.proto - @redoc-cli bundle api-streams.json - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t streams:latest diff --git a/streams/README.md b/streams/README.md deleted file mode 100644 index 4e68eea..0000000 --- a/streams/README.md +++ /dev/null @@ -1,7 +0,0 @@ -PubSub streaming and websockets - -# Streams Service - -The streams service provides an event stream, designed for sending messages from a server to mutliple -clients connecting via Websockets. The Token RPC should be called to generate a token for each client, -the clients should then subscribe using the Subscribe RPC. diff --git a/streams/handler/handler.go b/streams/handler/handler.go deleted file mode 100644 index 04c060e..0000000 --- a/streams/handler/handler.go +++ /dev/null @@ -1,57 +0,0 @@ -package handler - -import ( - "fmt" - "time" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/events" - "github.com/micro/services/pkg/cache" - "github.com/nats-io/nats-streaming-server/util" -) - -var ( - TokenTTL = time.Minute - ErrMissingTopic = errors.BadRequest("MISSING_TOPIC", "Missing topic") - ErrInvalidTopic = errors.BadRequest("MISSING_TOPIC", "Invalid topic") - ErrMissingToken = errors.BadRequest("MISSING_TOKEN", "Missing token") - ErrMissingMessage = errors.BadRequest("MISSING_MESSAGE", "Missing message") - ErrInvalidToken = errors.Forbidden("INVALID_TOKEN", "Invalid token") - ErrExpiredToken = errors.Forbidden("EXPIRED_TOKEN", "Token expired") - ErrForbiddenTopic = errors.Forbidden("FORBIDDEN_TOPIC", "Token has not have permission to subscribe to this topic") -) - -type Token struct { - Token string - Topic string - Account string - ExpiresAt time.Time -} - -type Streams struct { - Cache cache.Cache - Events events.Stream - Time func() time.Time -} - -func getAccount(acc *auth.Account) string { - owner := acc.Metadata["apikey_owner"] - if len(owner) == 0 { - owner = acc.ID - } - return fmt.Sprintf("%s.%s", acc.Issuer, owner) -} - -// fmtTopic returns a topic string with namespace prefix -func fmtTopic(acc *auth.Account, topic string) string { - return fmt.Sprintf("%s.%s", getAccount(acc), topic) -} - -// validateTopicInput validates that topic is alphanumeric -func validateTopicInput(topic string) error { - if !util.IsChannelNameValid(topic, false) { - return ErrInvalidTopic - } - return nil -} diff --git a/streams/handler/handler_test.go b/streams/handler/handler_test.go deleted file mode 100644 index ba99ee3..0000000 --- a/streams/handler/handler_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package handler_test - -import ( - "testing" - "time" - - "github.com/micro/micro/v3/service/events" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/pkg/cache" - "github.com/micro/services/streams/handler" -) - -func testHandler(t *testing.T) *handler.Streams { - h := &handler.Streams{ - Cache: cache.New(memory.NewStore()), - Events: new(eventsMock), - Time: func() time.Time { - return time.Unix(1612787045, 0) - }, - } - return h -} - -type eventsMock struct { - PublishCount int - PublishTopic string - PublishMessage interface{} - - ConsumeTopic string - ConsumeChan <-chan events.Event -} - -func (e *eventsMock) Publish(topic string, msg interface{}, opts ...events.PublishOption) error { - e.PublishCount++ - e.PublishTopic = topic - e.PublishMessage = msg - return nil -} - -func (e *eventsMock) Consume(topic string, opts ...events.ConsumeOption) (<-chan events.Event, error) { - e.ConsumeTopic = topic - return e.ConsumeChan, nil -} diff --git a/streams/handler/publish.go b/streams/handler/publish.go deleted file mode 100644 index f013014..0000000 --- a/streams/handler/publish.go +++ /dev/null @@ -1,34 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/streams/proto" -) - -func (s *Streams) Publish(ctx context.Context, req *pb.Message, rsp *pb.PublishResponse) error { - // validate the request - if len(req.Topic) == 0 { - return ErrMissingTopic - } - if err := validateTopicInput(req.Topic); err != nil { - return err - } - if len(req.Message) == 0 { - return ErrMissingMessage - } - - topic := req.Topic - - // in the event we have an account we use multi-tenancy - acc, ok := auth.AccountFromContext(ctx) - if ok { - topic = fmtTopic(acc, req.Topic) - } - - // publish the message - logger.Infof("Publishing message to topic: %v", req.Topic) - return s.Events.Publish(topic, req.Message) -} diff --git a/streams/handler/publish_test.go b/streams/handler/publish_test.go deleted file mode 100644 index 38aa3fa..0000000 --- a/streams/handler/publish_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler_test - -import ( - "context" - "strings" - "testing" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/services/streams/handler" - pb "github.com/micro/services/streams/proto" - "github.com/stretchr/testify/assert" -) - -func TestPublish(t *testing.T) { - msg := "{\"foo\":\"bar\"}" - topic := strings.ReplaceAll(uuid.New().String(), "-", "") - - t.Run("MissingTopic", func(t *testing.T) { - h := testHandler(t) - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Publish(ctx, &pb.Message{Message: msg}, &pb.PublishResponse{}) - assert.Equal(t, handler.ErrMissingTopic, err) - assert.Zero(t, h.Events.(*eventsMock).PublishCount) - }) - - t.Run("MissingMessage", func(t *testing.T) { - h := testHandler(t) - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Publish(ctx, &pb.Message{Topic: topic}, &pb.PublishResponse{}) - assert.Equal(t, handler.ErrMissingMessage, err) - assert.Zero(t, h.Events.(*eventsMock).PublishCount) - }) - - t.Run("ValidMessage", func(t *testing.T) { - h := testHandler(t) - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo", ID: "foo-id"}) - err := h.Publish(ctx, &pb.Message{ - Topic: topic, Message: msg, - }, &pb.PublishResponse{}) - assert.NoError(t, err) - assert.Equal(t, 1, h.Events.(*eventsMock).PublishCount) - assert.Equal(t, msg, h.Events.(*eventsMock).PublishMessage) - // topic is prefixed with acc issuer to implement multitenancy - assert.Equal(t, "foo.foo-id."+topic, h.Events.(*eventsMock).PublishTopic) - }) -} diff --git a/streams/handler/subscribe.go b/streams/handler/subscribe.go deleted file mode 100644 index d9d9dcc..0000000 --- a/streams/handler/subscribe.go +++ /dev/null @@ -1,89 +0,0 @@ -package handler - -import ( - "context" - "fmt" - "io" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/events" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/streams/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func (s *Streams) Subscribe(ctx context.Context, req *pb.SubscribeRequest, stream pb.Streams_SubscribeStream) error { - logger.Infof("Received subscribe request. Topic: '%v', Token: '%v'", req.Topic, req.Token) - - // validate the request - if len(req.Token) == 0 { - return ErrMissingToken - } - if len(req.Topic) == 0 { - return ErrMissingTopic - } - if err := validateTopicInput(req.Topic); err != nil { - return err - } - - // find the token and check to see if it has expired - var token Token - if err := s.Cache.Get("token:"+req.Token, &token); err == store.ErrNotFound { - return ErrInvalidToken - } else if err != nil { - logger.Errorf("Error reading token from store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error reading token from database") - } - if token.ExpiresAt.Before(s.Time()) { - return ErrExpiredToken - } - - // if the token was scoped to a channel, ensure the channel is the one being requested - if len(token.Topic) > 0 && token.Topic != req.Topic { - return ErrForbiddenTopic - } - - var topic string - - // attempt to create a unique topic for the account - acc, ok := auth.AccountFromContext(ctx) - if ok { - topic = fmtTopic(acc, req.Topic) - } else if len(token.Account) > 0 { - // use the account in the token if present - topic = fmt.Sprintf("%s.%s", token.Account, token.Topic) - } else { - topic = req.Topic - } - - // start the subscription - logger.Infof("Subscribing to %v via queue %v", req.Topic, token.Token) - - evChan, err := s.Events.Consume(topic, events.WithGroup(token.Token)) - if err != nil { - logger.Errorf("Error connecting to events stream: %v", err) - return errors.InternalServerError("EVENTS_ERROR", "Error connecting to events stream") - } - - for { - msg, ok := <-evChan - if !ok { - return nil - } - - logger.Infof("Sending message to subscriber %v", token.Topic) - pbMsg := &pb.Message{ - Topic: req.Topic, // use req.Topic not msg.Topic because topic is munged for multitenancy - Message: string(msg.Payload), - SentAt: timestamppb.New(msg.Timestamp), - } - - if err := stream.Send(pbMsg); err == io.EOF { - return nil - } else if err != nil { - return err - } - } -} diff --git a/streams/handler/subscribe_test.go b/streams/handler/subscribe_test.go deleted file mode 100644 index 60f5ac6..0000000 --- a/streams/handler/subscribe_test.go +++ /dev/null @@ -1,228 +0,0 @@ -package handler_test - -import ( - "context" - "sync" - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/events" - "github.com/micro/services/streams/handler" - pb "github.com/micro/services/streams/proto" - "github.com/stretchr/testify/assert" -) - -func TestSubscribe(t *testing.T) { - t.Run("MissingToken", func(t *testing.T) { - h := testHandler(t) - s := new(streamMock) - - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "helloworld", - }, s) - - assert.Equal(t, handler.ErrMissingToken, err) - assert.Empty(t, s.Messages) - }) - - t.Run("MissingTopic", func(t *testing.T) { - h := testHandler(t) - s := new(streamMock) - - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Subscribe(ctx, &pb.SubscribeRequest{ - Token: uuid.New().String(), - }, s) - - assert.Equal(t, handler.ErrMissingTopic, err) - assert.Empty(t, s.Messages) - }) - - t.Run("InvalidToken", func(t *testing.T) { - h := testHandler(t) - s := new(streamMock) - - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "helloworld", - Token: uuid.New().String(), - }, s) - - assert.Equal(t, handler.ErrInvalidToken, err) - assert.Empty(t, s.Messages) - }) - - t.Run("ExpiredToken", func(t *testing.T) { - h := testHandler(t) - - var tRsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{ - Topic: "helloworld", - }, &tRsp) - assert.NoError(t, err) - - ct := h.Time() - h.Time = func() time.Time { return ct.Add(handler.TokenTTL * 2) } - s := new(streamMock) - err = h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "helloworld", - Token: tRsp.Token, - }, s) - - assert.Equal(t, handler.ErrExpiredToken, err) - assert.Empty(t, s.Messages) - }) - - t.Run("ForbiddenTopic", func(t *testing.T) { - h := testHandler(t) - - var tRsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{ - Topic: "helloworldx", - }, &tRsp) - assert.NoError(t, err) - - s := new(streamMock) - err = h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "helloworld", - Token: tRsp.Token, - }, s) - - assert.Equal(t, handler.ErrForbiddenTopic, err) - assert.Empty(t, s.Messages) - }) - - t.Run("Valid", func(t *testing.T) { - defer func() { - if i := recover(); i != nil { - t.Logf("%+v", i) - } - }() - h := testHandler(t) - c := make(chan events.Event) - h.Events.(*eventsMock).ConsumeChan = c - - var tRsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{ID: "foo", Issuer: "my-ns"}) - err := h.Token(ctx, &pb.TokenRequest{ - Topic: "helloworld", - }, &tRsp) - assert.NoError(t, err) - - s := &streamMock{Messages: []*pb.Message{}} - wg := sync.WaitGroup{} - wg.Add(1) - var subsErr error - go func() { - defer wg.Done() - subsErr = h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "helloworld", - Token: tRsp.Token, - }, s) - }() - - e1 := events.Event{ - ID: uuid.New().String(), - Topic: "helloworld", - Timestamp: h.Time().Add(time.Second * -2), - Payload: []byte("abc"), - } - e2 := events.Event{ - ID: uuid.New().String(), - Topic: "helloworld", - Timestamp: h.Time().Add(time.Second * -1), - Payload: []byte("123"), - } - - timeout := time.NewTimer(time.Millisecond * 100).C - select { - case <-timeout: - t.Fatal("Events not consumed from stream") - return - case c <- e1: - t.Log("Event1 consumed") - } - select { - case <-timeout: - t.Fatal("Events not consumed from stream") - return - case c <- e2: - t.Log("Event2 consumed") - } - - close(c) - wg.Wait() - assert.NoError(t, subsErr) - assert.Equal(t, "my-ns.foo.helloworld", h.Events.(*eventsMock).ConsumeTopic) - - // sleep to wait for the subscribe loop to push the message to the stream - //time.Sleep(1 * time.Second) - if len(s.Messages) != 2 { - t.Fatalf("Expected 2 messages, got %v", len(s.Messages)) - return - } - - assert.Equal(t, e1.Topic, s.Messages[0].Topic) - assert.Equal(t, string(e1.Payload), s.Messages[0].Message) - assert.True(t, e1.Timestamp.Equal(s.Messages[0].SentAt.AsTime())) - - assert.Equal(t, e2.Topic, s.Messages[1].Topic) - assert.Equal(t, string(e2.Payload), s.Messages[1].Message) - assert.True(t, e2.Timestamp.Equal(s.Messages[1].SentAt.AsTime())) - }) - - /* - t.Run("TokenForDifferentIssuer", func(t *testing.T) { - h := testHandler(t) - - var tRsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{ - Topic: "tokfordiff", - }, &tRsp) - assert.NoError(t, err) - - s := new(streamMock) - ctx = auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "bar"}) - err = h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "tokfordiff", - Token: tRsp.Token, - }, s) - assert.Equal(t, handler.ErrInvalidToken, err) - assert.Empty(t, s.Messages) - }) - */ - t.Run("BadTopic", func(t *testing.T) { - h := testHandler(t) - - var tRsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{}, &tRsp) - assert.NoError(t, err) - - s := new(streamMock) - ctx = auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "bar"}) - err = h.Subscribe(ctx, &pb.SubscribeRequest{ - Topic: "tok-for/diff", - Token: tRsp.Token, - }, s) - assert.Equal(t, handler.ErrInvalidTopic, err) - assert.Empty(t, s.Messages) - }) - -} - -type streamMock struct { - Messages []*pb.Message - pb.Streams_SubscribeStream -} - -func (x *streamMock) Send(m *pb.Message) error { - x.Messages = append(x.Messages, m) - return nil -} diff --git a/streams/handler/token.go b/streams/handler/token.go deleted file mode 100644 index 42467bb..0000000 --- a/streams/handler/token.go +++ /dev/null @@ -1,41 +0,0 @@ -package handler - -import ( - "context" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/streams/proto" -) - -func (s *Streams) Token(ctx context.Context, req *pb.TokenRequest, rsp *pb.TokenResponse) error { - if len(req.Topic) > 0 { - if err := validateTopicInput(req.Topic); err != nil { - return err - } - } - - var account string - if acc, ok := auth.AccountFromContext(ctx); ok { - account = getAccount(acc) - } - - // construct the token and write it to the database - t := Token{ - Token: uuid.New().String(), - ExpiresAt: s.Time().Add(TokenTTL), - Topic: req.Topic, - Account: account, - } - - if err := s.Cache.Put("token:"+t.Token, t, t.ExpiresAt); err != nil { - logger.Errorf("Error creating token in store: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error writing token to database") - } - - // return the token in the response - rsp.Token = t.Token - return nil -} diff --git a/streams/handler/token_test.go b/streams/handler/token_test.go deleted file mode 100644 index 945c843..0000000 --- a/streams/handler/token_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package handler_test - -import ( - "context" - "testing" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/services/streams/handler" - pb "github.com/micro/services/streams/proto" - "github.com/stretchr/testify/assert" -) - -func TestToken(t *testing.T) { - h := testHandler(t) - - t.Run("WithoutTopic", func(t *testing.T) { - var rsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{}, &rsp) - assert.NoError(t, err) - assert.NotEmpty(t, rsp.Token) - }) - - t.Run("WithTopic", func(t *testing.T) { - var rsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{Topic: "helloworld"}, &rsp) - assert.NoError(t, err) - assert.NotEmpty(t, rsp.Token) - }) - - t.Run("WithBadTopic", func(t *testing.T) { - var rsp pb.TokenResponse - ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"}) - err := h.Token(ctx, &pb.TokenRequest{Topic: "helloworld/1"}, &rsp) - assert.Equal(t, handler.ErrInvalidTopic, err) - }) -} diff --git a/streams/main.go b/streams/main.go deleted file mode 100644 index 17169ee..0000000 --- a/streams/main.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "time" - - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/events" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/cache" - "github.com/micro/services/streams/handler" - pb "github.com/micro/services/streams/proto" -) - -func main() { - // Create service - srv := service.New( - service.Name("streams"), - ) - - h := &handler.Streams{ - Cache: cache.DefaultCache, - Events: events.DefaultStream, - Time: time.Now, - } - - // Register handler - pb.RegisterStreamsHandler(srv.Server(), h) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/streams/micro.mu b/streams/micro.mu deleted file mode 100644 index c961f25..0000000 --- a/streams/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service streams diff --git a/streams/proto/streams.pb.go b/streams/proto/streams.pb.go deleted file mode 100644 index 5aaf330..0000000 --- a/streams/proto/streams.pb.go +++ /dev/null @@ -1,441 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.5 -// source: proto/streams.proto - -package streams - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PublishResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *PublishResponse) Reset() { - *x = PublishResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_streams_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PublishResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PublishResponse) ProtoMessage() {} - -func (x *PublishResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_streams_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PublishResponse.ProtoReflect.Descriptor instead. -func (*PublishResponse) Descriptor() ([]byte, []int) { - return file_proto_streams_proto_rawDescGZIP(), []int{0} -} - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - SentAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_streams_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_proto_streams_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_proto_streams_proto_rawDescGZIP(), []int{1} -} - -func (x *Message) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -func (x *Message) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -func (x *Message) GetSentAt() *timestamppb.Timestamp { - if x != nil { - return x.SentAt - } - return nil -} - -type SubscribeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // topic the user wishes to subscribe to, required - Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` - // tokens should be provided if the user is not proving an API key on the request (e.g. in cases - // where the stream is being consumed directly from the frontend via websockets). tokens can be - // generated using the Token RPC - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *SubscribeRequest) Reset() { - *x = SubscribeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_streams_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SubscribeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SubscribeRequest) ProtoMessage() {} - -func (x *SubscribeRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_streams_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SubscribeRequest.ProtoReflect.Descriptor instead. -func (*SubscribeRequest) Descriptor() ([]byte, []int) { - return file_proto_streams_proto_rawDescGZIP(), []int{2} -} - -func (x *SubscribeRequest) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -func (x *SubscribeRequest) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -type TokenRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // the topic the token should be restricted to, if no topic is required the token can be used to - // subscribe to any topic - Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` -} - -func (x *TokenRequest) Reset() { - *x = TokenRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_streams_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TokenRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TokenRequest) ProtoMessage() {} - -func (x *TokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_streams_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TokenRequest.ProtoReflect.Descriptor instead. -func (*TokenRequest) Descriptor() ([]byte, []int) { - return file_proto_streams_proto_rawDescGZIP(), []int{3} -} - -func (x *TokenRequest) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -type TokenResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *TokenResponse) Reset() { - *x = TokenResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_streams_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TokenResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TokenResponse) ProtoMessage() {} - -func (x *TokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_streams_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TokenResponse.ProtoReflect.Descriptor instead. -func (*TokenResponse) Descriptor() ([]byte, []int) { - return file_proto_streams_proto_rawDescGZIP(), []int{4} -} - -func (x *TokenResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -var File_proto_streams_proto protoreflect.FileDescriptor - -var file_proto_streams_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x1f, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x11, 0x0a, 0x0f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x6e, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x70, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, - 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, - 0x41, 0x74, 0x22, 0x3e, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0x24, 0x0a, 0x0c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x22, 0x25, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, - 0xba, 0x01, 0x0a, 0x07, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x10, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, - 0x30, 0x01, 0x12, 0x38, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x15, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x11, 0x5a, 0x0f, - 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_streams_proto_rawDescOnce sync.Once - file_proto_streams_proto_rawDescData = file_proto_streams_proto_rawDesc -) - -func file_proto_streams_proto_rawDescGZIP() []byte { - file_proto_streams_proto_rawDescOnce.Do(func() { - file_proto_streams_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_streams_proto_rawDescData) - }) - return file_proto_streams_proto_rawDescData -} - -var file_proto_streams_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_proto_streams_proto_goTypes = []interface{}{ - (*PublishResponse)(nil), // 0: streams.PublishResponse - (*Message)(nil), // 1: streams.Message - (*SubscribeRequest)(nil), // 2: streams.SubscribeRequest - (*TokenRequest)(nil), // 3: streams.TokenRequest - (*TokenResponse)(nil), // 4: streams.TokenResponse - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp -} -var file_proto_streams_proto_depIdxs = []int32{ - 5, // 0: streams.Message.sent_at:type_name -> google.protobuf.Timestamp - 1, // 1: streams.Streams.Publish:input_type -> streams.Message - 2, // 2: streams.Streams.Subscribe:input_type -> streams.SubscribeRequest - 3, // 3: streams.Streams.Token:input_type -> streams.TokenRequest - 0, // 4: streams.Streams.Publish:output_type -> streams.PublishResponse - 1, // 5: streams.Streams.Subscribe:output_type -> streams.Message - 4, // 6: streams.Streams.Token:output_type -> streams.TokenResponse - 4, // [4:7] is the sub-list for method output_type - 1, // [1:4] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_proto_streams_proto_init() } -func file_proto_streams_proto_init() { - if File_proto_streams_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_streams_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PublishResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_streams_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_streams_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SubscribeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_streams_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TokenRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_streams_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TokenResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_streams_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_streams_proto_goTypes, - DependencyIndexes: file_proto_streams_proto_depIdxs, - MessageInfos: file_proto_streams_proto_msgTypes, - }.Build() - File_proto_streams_proto = out.File - file_proto_streams_proto_rawDesc = nil - file_proto_streams_proto_goTypes = nil - file_proto_streams_proto_depIdxs = nil -} diff --git a/streams/proto/streams.pb.micro.go b/streams/proto/streams.pb.micro.go deleted file mode 100644 index 33110a9..0000000 --- a/streams/proto/streams.pb.micro.go +++ /dev/null @@ -1,203 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/streams.proto - -package streams - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - _ "google.golang.org/protobuf/types/known/timestamppb" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Streams service - -func NewStreamsEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Streams service - -type StreamsService interface { - Publish(ctx context.Context, in *Message, opts ...client.CallOption) (*PublishResponse, error) - Subscribe(ctx context.Context, in *SubscribeRequest, opts ...client.CallOption) (Streams_SubscribeService, error) - Token(ctx context.Context, in *TokenRequest, opts ...client.CallOption) (*TokenResponse, error) -} - -type streamsService struct { - c client.Client - name string -} - -func NewStreamsService(name string, c client.Client) StreamsService { - return &streamsService{ - c: c, - name: name, - } -} - -func (c *streamsService) Publish(ctx context.Context, in *Message, opts ...client.CallOption) (*PublishResponse, error) { - req := c.c.NewRequest(c.name, "Streams.Publish", in) - out := new(PublishResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *streamsService) Subscribe(ctx context.Context, in *SubscribeRequest, opts ...client.CallOption) (Streams_SubscribeService, error) { - req := c.c.NewRequest(c.name, "Streams.Subscribe", &SubscribeRequest{}) - stream, err := c.c.Stream(ctx, req, opts...) - if err != nil { - return nil, err - } - if err := stream.Send(in); err != nil { - return nil, err - } - return &streamsServiceSubscribe{stream}, nil -} - -type Streams_SubscribeService interface { - Context() context.Context - SendMsg(interface{}) error - RecvMsg(interface{}) error - Close() error - Recv() (*Message, error) -} - -type streamsServiceSubscribe struct { - stream client.Stream -} - -func (x *streamsServiceSubscribe) Close() error { - return x.stream.Close() -} - -func (x *streamsServiceSubscribe) Context() context.Context { - return x.stream.Context() -} - -func (x *streamsServiceSubscribe) SendMsg(m interface{}) error { - return x.stream.Send(m) -} - -func (x *streamsServiceSubscribe) RecvMsg(m interface{}) error { - return x.stream.Recv(m) -} - -func (x *streamsServiceSubscribe) Recv() (*Message, error) { - m := new(Message) - err := x.stream.Recv(m) - if err != nil { - return nil, err - } - return m, nil -} - -func (c *streamsService) Token(ctx context.Context, in *TokenRequest, opts ...client.CallOption) (*TokenResponse, error) { - req := c.c.NewRequest(c.name, "Streams.Token", in) - out := new(TokenResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Streams service - -type StreamsHandler interface { - Publish(context.Context, *Message, *PublishResponse) error - Subscribe(context.Context, *SubscribeRequest, Streams_SubscribeStream) error - Token(context.Context, *TokenRequest, *TokenResponse) error -} - -func RegisterStreamsHandler(s server.Server, hdlr StreamsHandler, opts ...server.HandlerOption) error { - type streams interface { - Publish(ctx context.Context, in *Message, out *PublishResponse) error - Subscribe(ctx context.Context, stream server.Stream) error - Token(ctx context.Context, in *TokenRequest, out *TokenResponse) error - } - type Streams struct { - streams - } - h := &streamsHandler{hdlr} - return s.Handle(s.NewHandler(&Streams{h}, opts...)) -} - -type streamsHandler struct { - StreamsHandler -} - -func (h *streamsHandler) Publish(ctx context.Context, in *Message, out *PublishResponse) error { - return h.StreamsHandler.Publish(ctx, in, out) -} - -func (h *streamsHandler) Subscribe(ctx context.Context, stream server.Stream) error { - m := new(SubscribeRequest) - if err := stream.Recv(m); err != nil { - return err - } - return h.StreamsHandler.Subscribe(ctx, m, &streamsSubscribeStream{stream}) -} - -type Streams_SubscribeStream interface { - Context() context.Context - SendMsg(interface{}) error - RecvMsg(interface{}) error - Close() error - Send(*Message) error -} - -type streamsSubscribeStream struct { - stream server.Stream -} - -func (x *streamsSubscribeStream) Close() error { - return x.stream.Close() -} - -func (x *streamsSubscribeStream) Context() context.Context { - return x.stream.Context() -} - -func (x *streamsSubscribeStream) SendMsg(m interface{}) error { - return x.stream.Send(m) -} - -func (x *streamsSubscribeStream) RecvMsg(m interface{}) error { - return x.stream.Recv(m) -} - -func (x *streamsSubscribeStream) Send(m *Message) error { - return x.stream.Send(m) -} - -func (h *streamsHandler) Token(ctx context.Context, in *TokenRequest, out *TokenResponse) error { - return h.StreamsHandler.Token(ctx, in, out) -} diff --git a/streams/proto/streams.proto b/streams/proto/streams.proto deleted file mode 100644 index e6c385a..0000000 --- a/streams/proto/streams.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package streams; -option go_package = "./proto;streams"; -import "google/protobuf/timestamp.proto"; - -service Streams { - rpc Publish(Message) returns (PublishResponse) {} - rpc Subscribe(SubscribeRequest) returns (stream Message) {} - rpc Token(TokenRequest) returns (TokenResponse) {} -} - -message PublishResponse {} - -message Message { - string topic = 1; - string message = 2; - google.protobuf.Timestamp sent_at = 3; -} - -message SubscribeRequest { - // topic the user wishes to subscribe to, required - string topic = 1; - // tokens should be provided if the user is not proving an API key on the request (e.g. in cases - // where the stream is being consumed directly from the frontend via websockets). tokens can be - // generated using the Token RPC - string token = 2; -} - -message TokenRequest { - // the topic the token should be restricted to, if no topic is required the token can be used to - // subscribe to any topic - string topic = 1; -} - -message TokenResponse { - string token = 1; -} diff --git a/threads/.gitignore b/threads/.gitignore deleted file mode 100644 index 4a47005..0000000 --- a/threads/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -streams diff --git a/threads/Dockerfile b/threads/Dockerfile deleted file mode 100644 index d30a523..0000000 --- a/threads/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD threads /threads -ENTRYPOINT [ "/threads" ] diff --git a/threads/Makefile b/threads/Makefile deleted file mode 100644 index 867300b..0000000 --- a/threads/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --proto_path=. --micro_out=. --go_out=:. proto/threads.proto - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/threads.proto - @redoc-cli bundle api-threads.json - -.PHONY: build -build: - go build -o threads *.go - -.PHONY: test -test: - go test -v ./... -cover - -.PHONY: docker -docker: - docker build . -t threads:latest diff --git a/threads/README.md b/threads/README.md deleted file mode 100644 index 8063519..0000000 --- a/threads/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Threaded conversations - -# Threads Service - -Threads provides threaded conversations as a service grouped by topics. - diff --git a/threads/generate.go b/threads/generate.go deleted file mode 100644 index 7d9db91..0000000 --- a/threads/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate make proto diff --git a/threads/handler/create_message.go b/threads/handler/create_message.go deleted file mode 100644 index 68df605..0000000 --- a/threads/handler/create_message.go +++ /dev/null @@ -1,74 +0,0 @@ -package handler - -import ( - "context" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// Create a message within a thread -func (s *Threads) CreateMessage(ctx context.Context, req *pb.CreateMessageRequest, rsp *pb.CreateMessageResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.AuthorId) == 0 { - return ErrMissingAuthorID - } - if len(req.ThreadId) == 0 { - return ErrMissingThreadID - } - if len(req.Text) == 0 { - return ErrMissingText - } - - // lookup the thread - conv := Thread{ID: req.ThreadId} - - if err := model.Read(ctx, &conv); err == model.ErrNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // create the message - msg := &Message{ - ID: req.Id, - SentAt: s.Time(), - Text: req.Text, - AuthorID: req.AuthorId, - ThreadID: req.ThreadId, - } - if len(msg.ID) == 0 { - msg.ID = uuid.New().String() - } - - if err := model.Create(ctx, msg); err == nil { - rsp.Message = msg.Serialize() - return nil - } else if err != model.ErrAlreadyExists { - logger.Errorf("Error creating message: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // a message already exists with this id - existing := &Message{ID: msg.ID, ThreadID: req.ThreadId} - - if err := model.Read(ctx, existing); err == model.ErrNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error creating message: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // return the message - rsp.Message = existing.Serialize() - return nil -} diff --git a/threads/handler/create_message_test.go b/threads/handler/create_message_test.go deleted file mode 100644 index 6e18a9e..0000000 --- a/threads/handler/create_message_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func TestCreateMessage(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "HelloWorld", GroupId: uuid.New().String(), - }, &cRsp) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - - iid := uuid.New().String() - tt := []struct { - Name string - AuthorID string - ThreadID string - ID string - Text string - Error error - }{ - { - Name: "MissingThreadID", - Text: "HelloWorld", - AuthorID: uuid.New().String(), - Error: handler.ErrMissingThreadID, - }, - { - Name: "MissingAuthorID", - ThreadID: uuid.New().String(), - Text: "HelloWorld", - Error: handler.ErrMissingAuthorID, - }, - { - Name: "MissingText", - ThreadID: uuid.New().String(), - AuthorID: uuid.New().String(), - Error: handler.ErrMissingText, - }, - { - Name: "ThreadNotFound", - ThreadID: uuid.New().String(), - AuthorID: uuid.New().String(), - Text: "HelloWorld", - Error: handler.ErrNotFound, - }, - { - Name: "NoID", - ThreadID: cRsp.Thread.Id, - AuthorID: uuid.New().String(), - Text: "HelloWorld", - }, - { - Name: "WithID", - ThreadID: cRsp.Thread.Id, - Text: "HelloWorld", - AuthorID: "johndoe", - ID: iid, - }, - { - Name: "RepeatID", - ThreadID: cRsp.Thread.Id, - Text: "HelloWorld", - AuthorID: "johndoe", - ID: iid, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.CreateMessageResponse - err := h.CreateMessage(microAccountCtx(), &pb.CreateMessageRequest{ - AuthorId: tc.AuthorID, - ThreadId: tc.ThreadID, - Text: tc.Text, - Id: tc.ID, - }, &rsp) - - assert.Equal(t, tc.Error, err) - if tc.Error != nil { - assert.Nil(t, rsp.Message) - return - } - - assertMessagesMatch(t, &pb.Message{ - Id: tc.ID, - AuthorId: tc.AuthorID, - ThreadId: tc.ThreadID, - SentAt: handler.FormatTime(h.Time()), - Text: tc.Text, - }, rsp.Message) - }) - } -} diff --git a/threads/handler/create_thread.go b/threads/handler/create_thread.go deleted file mode 100644 index 6894f6d..0000000 --- a/threads/handler/create_thread.go +++ /dev/null @@ -1,45 +0,0 @@ -package handler - -import ( - "context" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// Create a thread -func (s *Threads) CreateThread(ctx context.Context, req *pb.CreateThreadRequest, rsp *pb.CreateThreadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.GroupId) == 0 { - return ErrMissingGroupID - } - if len(req.Topic) == 0 { - return ErrMissingTopic - } - - // write the thread to the database - thread := &Thread{ - ID: uuid.New().String(), - Topic: req.Topic, - GroupID: req.GroupId, - CreatedAt: s.Time(), - } - - // write the thread to the database - if err := model.Create(ctx, thread); err != nil { - logger.Errorf("Error creating thread: %v", err) - return err - } - - // serialize the response - rsp.Thread = thread.Serialize() - return nil -} diff --git a/threads/handler/create_thread_test.go b/threads/handler/create_thread_test.go deleted file mode 100644 index 9340494..0000000 --- a/threads/handler/create_thread_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func TestCreateThread(t *testing.T) { - tt := []struct { - Name string - GroupID string - Topic string - Error error - }{ - { - Name: "MissingGroupID", - Topic: "HelloWorld", - Error: handler.ErrMissingGroupID, - }, - { - Name: "MissingTopic", - GroupID: uuid.New().String(), - Error: handler.ErrMissingTopic, - }, - { - Name: "Valid", - GroupID: uuid.New().String(), - Topic: "HelloWorld", - }, - } - - h := testHandler(t) - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: tc.Topic, GroupId: tc.GroupID, - }, &rsp) - - assert.Equal(t, tc.Error, err) - if tc.Error != nil { - assert.Nil(t, rsp.Thread) - return - } - - assertThreadsMatch(t, &pb.Thread{ - CreatedAt: handler.FormatTime(h.Time()), - GroupId: tc.GroupID, - Topic: tc.Topic, - }, rsp.Thread) - }) - } -} diff --git a/threads/handler/delete_thread.go b/threads/handler/delete_thread.go deleted file mode 100644 index d03ac82..0000000 --- a/threads/handler/delete_thread.go +++ /dev/null @@ -1,41 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// Delete a thread and all the messages within -func (s *Threads) DeleteThread(ctx context.Context, req *pb.DeleteThreadRequest, rsp *pb.DeleteThreadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - - thread := Thread{ID: req.Id} - - // delete the thread - if err := model.Delete(ctx, &thread); err != nil { - logger.Errorf("Error deleting thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - message := Message{ThreadID: req.Id} - - // delete the messages - if err := model.Delete(ctx, &message); err != nil { - logger.Errorf("Error deleting messages: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - return nil -} diff --git a/threads/handler/delete_thread_test.go b/threads/handler/delete_thread_test.go deleted file mode 100644 index 6cf81e0..0000000 --- a/threads/handler/delete_thread_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func TestDeleteThread(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "HelloWorld", GroupId: uuid.New().String(), - }, &cRsp) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - - t.Run("MissingID", func(t *testing.T) { - err := h.DeleteThread(microAccountCtx(), &pb.DeleteThreadRequest{}, &pb.DeleteThreadResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - t.Run("Valid", func(t *testing.T) { - err := h.DeleteThread(microAccountCtx(), &pb.DeleteThreadRequest{ - Id: cRsp.Thread.Id, - }, &pb.DeleteThreadResponse{}) - assert.NoError(t, err) - - err = h.ReadThread(microAccountCtx(), &pb.ReadThreadRequest{ - Id: cRsp.Thread.Id, - }, &pb.ReadThreadResponse{}) - assert.Equal(t, handler.ErrNotFound, err) - }) - - t.Run("Retry", func(t *testing.T) { - err := h.DeleteThread(microAccountCtx(), &pb.DeleteThreadRequest{ - Id: cRsp.Thread.Id, - }, &pb.DeleteThreadResponse{}) - assert.NoError(t, err) - }) -} diff --git a/threads/handler/handler.go b/threads/handler/handler.go deleted file mode 100644 index b2bf248..0000000 --- a/threads/handler/handler.go +++ /dev/null @@ -1,144 +0,0 @@ -package handler - -import ( - "context" - "fmt" - "time" - - "github.com/micro/micro/v3/service/errors" - "github.com/micro/services/pkg/tenant" - pb "github.com/micro/services/threads/proto" -) - -var ( - ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") - ErrMissingGroupID = errors.BadRequest("MISSING_GROUP_ID", "Missing GroupID") - ErrMissingTopic = errors.BadRequest("MISSING_TOPIC", "Missing Topic") - ErrMissingAuthorID = errors.BadRequest("MISSING_AUTHOR_ID", "Missing Author ID") - ErrMissingText = errors.BadRequest("MISSING_TEXT", "Missing text") - ErrMissingThreadID = errors.BadRequest("MISSING_CONVERSATION_ID", "Missing Thread ID") - ErrMissingThreadIDs = errors.BadRequest("MISSING_CONVERSATION_IDS", "One or more Thread IDs are required") - ErrNotFound = errors.NotFound("NOT_FOUND", "Thread not found") -) - -type Threads struct { - Time func() time.Time -} - -type Message struct { - ID string - AuthorID string - ThreadID string - Text string - SentAt time.Time -} - -func (m *Message) Serialize() *pb.Message { - return &pb.Message{ - Id: m.ID, - AuthorId: m.AuthorID, - ThreadId: m.ThreadID, - Text: m.Text, - SentAt: m.SentAt.Format(time.RFC3339Nano), - } -} - -type Thread struct { - ID string - GroupID string - Topic string - CreatedAt time.Time -} - -func (c *Thread) Serialize() *pb.Thread { - return &pb.Thread{ - Id: c.ID, - GroupId: c.GroupID, - Topic: c.Topic, - CreatedAt: c.CreatedAt.Format(time.RFC3339Nano), - } -} - -func ParseTime(v string) time.Time { - t, err := time.Parse(time.RFC3339Nano, v) - if err == nil { - return t - } - t, err = time.Parse(time.RFC3339, v) - if err == nil { - return t - } - return time.Time{} -} - -func FormatTime(t time.Time) string { - return t.Format(time.RFC3339Nano) -} - -func (t *Thread) Key(ctx context.Context) string { - if len(t.ID) == 0 { - return "" - } - - key := fmt.Sprintf("thread:%s", t.ID) - - tnt, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", tnt, key) -} - -func (t *Thread) Index(ctx context.Context) string { - key := fmt.Sprintf("threadsByGroupID:%s:%s", t.GroupID, t.ID) - - tnt, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", tnt, key) -} - -func (t *Thread) Value() interface{} { - return t -} - -func (m *Message) Key(ctx context.Context) string { - if len(m.ID) == 0 { - return "" - } - - key := fmt.Sprintf("message:%s:%s", m.ID, m.ThreadID) - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (m *Message) Index(ctx context.Context) string { - key := fmt.Sprintf("messagesByThreadID:%s", m.ThreadID) - - if !m.SentAt.IsZero() { - key = fmt.Sprintf("%s:%d", key, m.SentAt.UnixNano()) - - if len(m.ID) > 0 { - key = fmt.Sprintf("%s:%s", key, m.ID) - } - } - - t, ok := tenant.FromContext(ctx) - if !ok { - return key - } - - return fmt.Sprintf("%s/%s", t, key) -} - -func (m *Message) Value() interface{} { - return m -} diff --git a/threads/handler/handler_test.go b/threads/handler/handler_test.go deleted file mode 100644 index f30cc53..0000000 --- a/threads/handler/handler_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package handler_test - -import ( - "context" - "testing" - "time" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/store" - "github.com/micro/micro/v3/service/store/memory" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func testHandler(t *testing.T) *handler.Threads { - store.DefaultStore = memory.NewStore() - return &handler.Threads{Time: func() time.Time { return time.Unix(1611327673, 0) }} -} - -func assertThreadsMatch(t *testing.T, exp, act *pb.Thread) { - if act == nil { - t.Errorf("Thread not returned") - return - } - - // adapt this check so we can reuse the func in testing create, where we don't know the exact id - // which will be generated - if len(exp.Id) > 0 { - assert.Equal(t, exp.Id, act.Id) - } else { - assert.NotEmpty(t, act.Id) - } - - assert.Equal(t, exp.Topic, act.Topic) - assert.Equal(t, exp.GroupId, act.GroupId) - - if act.CreatedAt == "" { - t.Errorf("CreatedAt not set") - return - } - - assert.True(t, microSecondTime(exp.CreatedAt).Equal(microSecondTime(act.CreatedAt))) -} - -func assertMessagesMatch(t *testing.T, exp, act *pb.Message) { - if act == nil { - t.Errorf("Message not returned") - return - } - - // adapt this check so we can reuse the func in testing create, where we don't know the exact id - // which will be generated - if len(exp.Id) > 0 { - assert.Equal(t, exp.Id, act.Id) - } else { - assert.NotEmpty(t, act.Id) - } - - assert.Equal(t, exp.Text, act.Text) - assert.Equal(t, exp.AuthorId, act.AuthorId) - assert.Equal(t, exp.ThreadId, act.ThreadId) - - if act.SentAt == "" { - t.Errorf("SentAt not set") - return - } - - assert.True(t, microSecondTime(exp.SentAt).Equal(microSecondTime(act.SentAt))) -} - -// postgres has a resolution of 100microseconds so just test that it's accurate to the second -func microSecondTime(t string) time.Time { - tt := handler.ParseTime(t) - return time.Unix(tt.Unix(), int64(tt.Nanosecond()-tt.Nanosecond()%1000)) -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - }) -} diff --git a/threads/handler/list_messages.go b/threads/handler/list_messages.go deleted file mode 100644 index 7452c49..0000000 --- a/threads/handler/list_messages.go +++ /dev/null @@ -1,69 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/micro/v3/service/store" - pb "github.com/micro/services/threads/proto" -) - -const DefaultLimit = 25 - -// List the messages within a thread in reverse chronological order, using sent_before to -// offset as older messages need to be loaded -func (s *Threads) ListMessages(ctx context.Context, req *pb.ListMessagesRequest, rsp *pb.ListMessagesResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.ThreadId) == 0 { - return ErrMissingThreadID - } - - // default order is descending - order := store.OrderDesc - if req.Order == "asc" { - order = store.OrderAsc - } - - opts := []store.ReadOption{ - store.ReadPrefix(), - store.ReadOrder(order), - } - - if req.Limit > 0 { - opts = append(opts, store.ReadLimit(uint(req.Limit))) - } else { - opts = append(opts, store.ReadLimit(uint(DefaultLimit))) - } - if req.Offset > 0 { - opts = append(opts, store.ReadOffset(uint(req.Offset))) - } - - message := &Message{ - ThreadID: req.ThreadId, - } - - // read all the records with the chat ID suffix - recs, err := store.Read(message.Index(ctx), opts...) - if err != nil { - logger.Errorf("Error reading messages: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // return all the messages - for _, rec := range recs { - m := &Message{} - rec.Decode(&m) - if len(m.ID) == 0 || m.ThreadID != req.ThreadId { - continue - } - rsp.Messages = append(rsp.Messages, m.Serialize()) - } - - return nil -} diff --git a/threads/handler/list_messages_test.go b/threads/handler/list_messages_test.go deleted file mode 100644 index 9040563..0000000 --- a/threads/handler/list_messages_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package handler_test - -import ( - "sort" - "strconv" - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func TestListMessages(t *testing.T) { - h := testHandler(t) - h.Time = time.Now - - // seed some data - var convRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "TestListMessages", GroupId: uuid.New().String(), - }, &convRsp) - assert.NoError(t, err) - if err != nil { - return - } - - msgs := make([]*pb.Message, 50) - for i := 0; i < len(msgs); i++ { - var rsp pb.CreateMessageResponse - err := h.CreateMessage(microAccountCtx(), &pb.CreateMessageRequest{ - ThreadId: convRsp.Thread.Id, - AuthorId: uuid.New().String(), - Text: strconv.Itoa(i), - }, &rsp) - assert.NoError(t, err) - msgs[i] = rsp.Message - } - - t.Run("MissingThreadID", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingThreadID, err) - assert.Nil(t, rsp.Messages) - }) - - t.Run("NoOffset", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ThreadId: convRsp.Thread.Id, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != handler.DefaultLimit { - t.Fatalf("Expected %v messages but got %v", handler.DefaultLimit, len(rsp.Messages)) - return - } - expected := msgs[25:] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) - - t.Run("LimitSet", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ThreadId: convRsp.Thread.Id, - Limit: 10, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 10 { - t.Fatalf("Expected %v messages but got %v", 10, len(rsp.Messages)) - return - } - expected := msgs[40:] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) - - t.Run("OffsetAndLimit", func(t *testing.T) { - var rsp pb.ListMessagesResponse - err := h.ListMessages(microAccountCtx(), &pb.ListMessagesRequest{ - ThreadId: convRsp.Thread.Id, - Limit: 5, - Offset: 30, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 5 { - t.Fatalf("Expected %v messages but got %v", 5, len(rsp.Messages)) - return - } - expected := msgs[15:20] - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) -} - -// sortMessages by the time they were sent -func sortMessages(msgs []*pb.Message) { - sort.Slice(msgs, func(i, j int) bool { - if msgs[i].SentAt == "" || msgs[j].SentAt == "" { - return true - } - return handler.ParseTime(msgs[i].SentAt).Before(handler.ParseTime(msgs[j].SentAt)) - }) -} diff --git a/threads/handler/list_threads.go b/threads/handler/list_threads.go deleted file mode 100644 index bcdf9f5..0000000 --- a/threads/handler/list_threads.go +++ /dev/null @@ -1,39 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// List all the threads for a group -func (s *Threads) ListThreads(ctx context.Context, req *pb.ListThreadsRequest, rsp *pb.ListThreadsResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.GroupId) == 0 { - return ErrMissingGroupID - } - - var threads []*Thread - thread := &Thread{GroupID: req.GroupId} - - // get all the threads - if err := model.List(ctx, thread, &threads, model.Query{}); err != nil { - logger.Errorf("Error reading thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // return the response - for _, thread := range threads { - rsp.Threads = append(rsp.Threads, thread.Serialize()) - } - - return nil -} diff --git a/threads/handler/list_threads_test.go b/threads/handler/list_threads_test.go deleted file mode 100644 index 2eaeabb..0000000 --- a/threads/handler/list_threads_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func TestListThreads(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp1 pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "HelloWorld", GroupId: uuid.New().String(), - }, &cRsp1) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - var cRsp2 pb.CreateThreadResponse - err = h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "FooBar", GroupId: uuid.New().String(), - }, &cRsp2) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - - t.Run("MissingGroupID", func(t *testing.T) { - var rsp pb.ListThreadsResponse - err := h.ListThreads(microAccountCtx(), &pb.ListThreadsRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingGroupID, err) - assert.Nil(t, rsp.Threads) - }) - - t.Run("Valid", func(t *testing.T) { - var rsp pb.ListThreadsResponse - err := h.ListThreads(microAccountCtx(), &pb.ListThreadsRequest{ - GroupId: cRsp1.Thread.GroupId, - }, &rsp) - - assert.NoError(t, err) - if len(rsp.Threads) != 1 { - t.Fatalf("Expected 1 thread to be returned, got %v", len(rsp.Threads)) - return - } - - assertThreadsMatch(t, cRsp1.Thread, rsp.Threads[0]) - }) -} diff --git a/threads/handler/read_thread.go b/threads/handler/read_thread.go deleted file mode 100644 index 93b8f99..0000000 --- a/threads/handler/read_thread.go +++ /dev/null @@ -1,46 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// Read a thread using its ID, can filter using group ID if provided -func (s *Threads) ReadThread(ctx context.Context, req *pb.ReadThreadRequest, rsp *pb.ReadThreadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - - // construct the query - thread := &Thread{ID: req.Id} - - var err error - - if len(req.GroupId) > 0 { - thread.GroupID = req.GroupId - err = model.ReadIndex(ctx, thread) - } else { - err = model.Read(ctx, thread) - } - - if err == model.ErrNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // serialize the response - rsp.Thread = thread.Serialize() - return nil -} diff --git a/threads/handler/read_thread_test.go b/threads/handler/read_thread_test.go deleted file mode 100644 index b4f2706..0000000 --- a/threads/handler/read_thread_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func TestReadThread(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "HelloWorld", GroupId: uuid.New().String(), - }, &cRsp) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - - tt := []struct { - Name string - ID string - GroupID string - Error error - Result *pb.Thread - }{ - { - Name: "MissingID", - Error: handler.ErrMissingID, - }, - { - Name: "IncorrectID", - ID: uuid.New().String(), - Error: handler.ErrNotFound, - }, - { - Name: "FoundUsingIDOnly", - ID: cRsp.Thread.Id, - Result: cRsp.Thread, - }, - { - Name: "IncorrectGroupID", - ID: cRsp.Thread.Id, - Error: handler.ErrNotFound, - GroupID: uuid.New().String(), - }, - } - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.ReadThreadResponse - err := h.ReadThread(microAccountCtx(), &pb.ReadThreadRequest{ - Id: tc.ID, GroupId: tc.GroupID, - }, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.Result == nil { - assert.Nil(t, rsp.Thread) - } else { - assertThreadsMatch(t, tc.Result, rsp.Thread) - } - }) - } -} diff --git a/threads/handler/recent_messages.go b/threads/handler/recent_messages.go deleted file mode 100644 index 97df589..0000000 --- a/threads/handler/recent_messages.go +++ /dev/null @@ -1,62 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// RecentMessages returns the most recent messages in a group of threads. By default the -// most messages retrieved per thread is 25, however this can be overriden using the -// limit_per_thread option -func (s *Threads) RecentMessages(ctx context.Context, req *pb.RecentMessagesRequest, rsp *pb.RecentMessagesResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.ThreadIds) == 0 { - return ErrMissingThreadIDs - } - - limit := uint(DefaultLimit) - if req.LimitPerThread > 0 { - limit = uint(req.LimitPerThread) - } - - // if group id is present then list threads by group - if len(req.GroupId) > 0 && len(req.ThreadIds) == 0 { - var threads []*Thread - thread := &Thread{GroupID: req.GroupId} - if err := model.List(ctx, thread, &threads, model.Query{}); err != nil { - logger.Errorf("Error reading threads: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // create the thread ids - for _, thread := range threads { - req.ThreadIds = append(req.ThreadIds, thread.ID) - } - } - - for _, thread := range req.ThreadIds { - q := model.Query{Limit: limit, Order: "desc"} - m := &Message{ThreadID: thread} - var messages []*Message - - if err := model.List(ctx, m, &messages, q); err != nil { - logger.Errorf("Error reading messages: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - for _, msg := range messages { - rsp.Messages = append(rsp.Messages, msg.Serialize()) - } - } - - return nil -} diff --git a/threads/handler/recent_messages_test.go b/threads/handler/recent_messages_test.go deleted file mode 100644 index 4e8954d..0000000 --- a/threads/handler/recent_messages_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package handler_test - -import ( - "fmt" - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func TestRecentMessages(t *testing.T) { - h := testHandler(t) - h.Time = time.Now - - // seed some data - ids := make([]string, 3) - convos := make(map[string][]*pb.Message, 3) - for i := 0; i < 3; i++ { - var convRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "TestRecentMessages", GroupId: uuid.New().String(), - }, &convRsp) - assert.NoError(t, err) - if err != nil { - return - } - - convos[convRsp.Thread.Id] = make([]*pb.Message, 50) - ids[i] = convRsp.Thread.Id - - for j := 0; j < 50; j++ { - var rsp pb.CreateMessageResponse - err := h.CreateMessage(microAccountCtx(), &pb.CreateMessageRequest{ - ThreadId: convRsp.Thread.Id, - AuthorId: uuid.New().String(), - Text: fmt.Sprintf("Thread %v, Message %v", i, j), - }, &rsp) - assert.NoError(t, err) - convos[convRsp.Thread.Id][j] = rsp.Message - } - } - - t.Run("MissingThreadIDs", func(t *testing.T) { - var rsp pb.RecentMessagesResponse - err := h.RecentMessages(microAccountCtx(), &pb.RecentMessagesRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingThreadIDs, err) - assert.Nil(t, rsp.Messages) - }) - - t.Run("LimitSet", func(t *testing.T) { - var rsp pb.RecentMessagesResponse - err := h.RecentMessages(microAccountCtx(), &pb.RecentMessagesRequest{ - ThreadIds: ids, - LimitPerThread: 10, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 30 { - t.Fatalf("Expected %v messages but got %v", 30, len(rsp.Messages)) - return - } - var expected []*pb.Message - for _, msgs := range convos { - expected = append(expected, msgs[40:]...) - } - sortMessages(expected) - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) - - t.Run("NoLimitSet", func(t *testing.T) { - reducedIDs := ids[:2] - - var rsp pb.RecentMessagesResponse - err := h.RecentMessages(microAccountCtx(), &pb.RecentMessagesRequest{ - ThreadIds: reducedIDs, - }, &rsp) - assert.NoError(t, err) - - if len(rsp.Messages) != 50 { - t.Fatalf("Expected %v messages but got %v", 50, len(rsp.Messages)) - return - } - var expected []*pb.Message - for _, id := range reducedIDs { - expected = append(expected, convos[id][25:]...) - } - sortMessages(expected) - sortMessages(rsp.Messages) - for i, msg := range rsp.Messages { - assertMessagesMatch(t, expected[i], msg) - } - }) -} diff --git a/threads/handler/update_thread.go b/threads/handler/update_thread.go deleted file mode 100644 index 39a8eab..0000000 --- a/threads/handler/update_thread.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/pkg/model" - pb "github.com/micro/services/threads/proto" -) - -// Update a threads topic -func (s *Threads) UpdateThread(ctx context.Context, req *pb.UpdateThreadRequest, rsp *pb.UpdateThreadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - if len(req.Topic) == 0 { - return ErrMissingTopic - } - - t := &Thread{ID: req.Id} - - if err := model.Read(ctx, t); err == model.ErrNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // update the thread - t.Topic = req.Topic - if err := model.Update(ctx, t); err != nil { - logger.Errorf("Error updating thread: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to database") - } - - // serialize the result - rsp.Thread = t.Serialize() - - return nil -} diff --git a/threads/handler/update_thread_test.go b/threads/handler/update_thread_test.go deleted file mode 100644 index 424e610..0000000 --- a/threads/handler/update_thread_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - "github.com/stretchr/testify/assert" -) - -func TestUpdateThread(t *testing.T) { - h := testHandler(t) - - // seed some data - var cRsp pb.CreateThreadResponse - err := h.CreateThread(microAccountCtx(), &pb.CreateThreadRequest{ - Topic: "HelloWorld", GroupId: uuid.New().String(), - }, &cRsp) - if err != nil { - t.Fatalf("Error creating thread: %v", err) - return - } - - t.Run("MissingID", func(t *testing.T) { - err := h.UpdateThread(microAccountCtx(), &pb.UpdateThreadRequest{ - Topic: "NewTopic", - }, &pb.UpdateThreadResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - t.Run("MissingTopic", func(t *testing.T) { - err := h.UpdateThread(microAccountCtx(), &pb.UpdateThreadRequest{ - Id: uuid.New().String(), - }, &pb.UpdateThreadResponse{}) - assert.Equal(t, handler.ErrMissingTopic, err) - }) - - t.Run("InvalidID", func(t *testing.T) { - err := h.UpdateThread(microAccountCtx(), &pb.UpdateThreadRequest{ - Id: uuid.New().String(), - Topic: "NewTopic", - }, &pb.UpdateThreadResponse{}) - assert.Equal(t, handler.ErrNotFound, err) - }) - - t.Run("Valid", func(t *testing.T) { - err := h.UpdateThread(microAccountCtx(), &pb.UpdateThreadRequest{ - Id: cRsp.Thread.Id, - Topic: "NewTopic", - }, &pb.UpdateThreadResponse{}) - assert.NoError(t, err) - - var rsp pb.ReadThreadResponse - err = h.ReadThread(microAccountCtx(), &pb.ReadThreadRequest{ - Id: cRsp.Thread.Id, - }, &rsp) - assert.NoError(t, err) - if rsp.Thread == nil { - t.Fatal("No thread returned") - return - } - assert.Equal(t, "NewTopic", rsp.Thread.Topic) - }) -} diff --git a/threads/main.go b/threads/main.go deleted file mode 100644 index 2d57b8f..0000000 --- a/threads/main.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "time" - - "github.com/micro/services/threads/handler" - pb "github.com/micro/services/threads/proto" - - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/logger" -) - -func main() { - // Create service - srv := service.New( - service.Name("threads"), - service.Version("latest"), - ) - - h := &handler.Threads{Time: time.Now} - // Register handler - pb.RegisterThreadsHandler(srv.Server(), h) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/threads/micro.mu b/threads/micro.mu deleted file mode 100644 index 2921d5e..0000000 --- a/threads/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service threads diff --git a/threads/proto/threads.pb.go b/threads/proto/threads.pb.go deleted file mode 100644 index 7954bc9..0000000 --- a/threads/proto/threads.pb.go +++ /dev/null @@ -1,1443 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 -// source: proto/threads.proto - -package threads - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Thread struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - GroupId string `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` - CreatedAt string `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` -} - -func (x *Thread) Reset() { - *x = Thread{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Thread) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Thread) ProtoMessage() {} - -func (x *Thread) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Thread.ProtoReflect.Descriptor instead. -func (*Thread) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{0} -} - -func (x *Thread) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Thread) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *Thread) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -func (x *Thread) GetCreatedAt() string { - if x != nil { - return x.CreatedAt - } - return "" -} - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - AuthorId string `protobuf:"bytes,2,opt,name=author_id,json=authorId,proto3" json:"author_id,omitempty"` - ThreadId string `protobuf:"bytes,3,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` - SentAt string `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{1} -} - -func (x *Message) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Message) GetAuthorId() string { - if x != nil { - return x.AuthorId - } - return "" -} - -func (x *Message) GetThreadId() string { - if x != nil { - return x.ThreadId - } - return "" -} - -func (x *Message) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -func (x *Message) GetSentAt() string { - if x != nil { - return x.SentAt - } - return "" -} - -type CreateThreadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` -} - -func (x *CreateThreadRequest) Reset() { - *x = CreateThreadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateThreadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateThreadRequest) ProtoMessage() {} - -func (x *CreateThreadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateThreadRequest.ProtoReflect.Descriptor instead. -func (*CreateThreadRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateThreadRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *CreateThreadRequest) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -type CreateThreadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Thread *Thread `protobuf:"bytes,1,opt,name=thread,proto3" json:"thread,omitempty"` -} - -func (x *CreateThreadResponse) Reset() { - *x = CreateThreadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateThreadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateThreadResponse) ProtoMessage() {} - -func (x *CreateThreadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateThreadResponse.ProtoReflect.Descriptor instead. -func (*CreateThreadResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{3} -} - -func (x *CreateThreadResponse) GetThread() *Thread { - if x != nil { - return x.Thread - } - return nil -} - -type ReadThreadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - GroupId string `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` -} - -func (x *ReadThreadRequest) Reset() { - *x = ReadThreadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadThreadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadThreadRequest) ProtoMessage() {} - -func (x *ReadThreadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadThreadRequest.ProtoReflect.Descriptor instead. -func (*ReadThreadRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{4} -} - -func (x *ReadThreadRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ReadThreadRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -type ReadThreadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Thread *Thread `protobuf:"bytes,1,opt,name=thread,proto3" json:"thread,omitempty"` -} - -func (x *ReadThreadResponse) Reset() { - *x = ReadThreadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadThreadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadThreadResponse) ProtoMessage() {} - -func (x *ReadThreadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadThreadResponse.ProtoReflect.Descriptor instead. -func (*ReadThreadResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{5} -} - -func (x *ReadThreadResponse) GetThread() *Thread { - if x != nil { - return x.Thread - } - return nil -} - -type ListThreadsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` -} - -func (x *ListThreadsRequest) Reset() { - *x = ListThreadsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListThreadsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListThreadsRequest) ProtoMessage() {} - -func (x *ListThreadsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListThreadsRequest.ProtoReflect.Descriptor instead. -func (*ListThreadsRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{6} -} - -func (x *ListThreadsRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -type ListThreadsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Threads []*Thread `protobuf:"bytes,1,rep,name=threads,proto3" json:"threads,omitempty"` -} - -func (x *ListThreadsResponse) Reset() { - *x = ListThreadsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListThreadsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListThreadsResponse) ProtoMessage() {} - -func (x *ListThreadsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListThreadsResponse.ProtoReflect.Descriptor instead. -func (*ListThreadsResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{7} -} - -func (x *ListThreadsResponse) GetThreads() []*Thread { - if x != nil { - return x.Threads - } - return nil -} - -type UpdateThreadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` -} - -func (x *UpdateThreadRequest) Reset() { - *x = UpdateThreadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateThreadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateThreadRequest) ProtoMessage() {} - -func (x *UpdateThreadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateThreadRequest.ProtoReflect.Descriptor instead. -func (*UpdateThreadRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{8} -} - -func (x *UpdateThreadRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *UpdateThreadRequest) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -type UpdateThreadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Thread *Thread `protobuf:"bytes,1,opt,name=thread,proto3" json:"thread,omitempty"` -} - -func (x *UpdateThreadResponse) Reset() { - *x = UpdateThreadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateThreadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateThreadResponse) ProtoMessage() {} - -func (x *UpdateThreadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateThreadResponse.ProtoReflect.Descriptor instead. -func (*UpdateThreadResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{9} -} - -func (x *UpdateThreadResponse) GetThread() *Thread { - if x != nil { - return x.Thread - } - return nil -} - -type DeleteThreadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteThreadRequest) Reset() { - *x = DeleteThreadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteThreadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteThreadRequest) ProtoMessage() {} - -func (x *DeleteThreadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteThreadRequest.ProtoReflect.Descriptor instead. -func (*DeleteThreadRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{10} -} - -func (x *DeleteThreadRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type DeleteThreadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DeleteThreadResponse) Reset() { - *x = DeleteThreadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteThreadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteThreadResponse) ProtoMessage() {} - -func (x *DeleteThreadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteThreadResponse.ProtoReflect.Descriptor instead. -func (*DeleteThreadResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{11} -} - -type CreateMessageRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - ThreadId string `protobuf:"bytes,2,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` - AuthorId string `protobuf:"bytes,3,opt,name=author_id,json=authorId,proto3" json:"author_id,omitempty"` - Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` -} - -func (x *CreateMessageRequest) Reset() { - *x = CreateMessageRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateMessageRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateMessageRequest) ProtoMessage() {} - -func (x *CreateMessageRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateMessageRequest.ProtoReflect.Descriptor instead. -func (*CreateMessageRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{12} -} - -func (x *CreateMessageRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *CreateMessageRequest) GetThreadId() string { - if x != nil { - return x.ThreadId - } - return "" -} - -func (x *CreateMessageRequest) GetAuthorId() string { - if x != nil { - return x.AuthorId - } - return "" -} - -func (x *CreateMessageRequest) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -type CreateMessageResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *CreateMessageResponse) Reset() { - *x = CreateMessageResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateMessageResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateMessageResponse) ProtoMessage() {} - -func (x *CreateMessageResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateMessageResponse.ProtoReflect.Descriptor instead. -func (*CreateMessageResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{13} -} - -func (x *CreateMessageResponse) GetMessage() *Message { - if x != nil { - return x.Message - } - return nil -} - -type ListMessagesRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - Offset int64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"` - Order string `protobuf:"bytes,4,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *ListMessagesRequest) Reset() { - *x = ListMessagesRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListMessagesRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListMessagesRequest) ProtoMessage() {} - -func (x *ListMessagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListMessagesRequest.ProtoReflect.Descriptor instead. -func (*ListMessagesRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{14} -} - -func (x *ListMessagesRequest) GetThreadId() string { - if x != nil { - return x.ThreadId - } - return "" -} - -func (x *ListMessagesRequest) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *ListMessagesRequest) GetOffset() int64 { - if x != nil { - return x.Offset - } - return 0 -} - -func (x *ListMessagesRequest) GetOrder() string { - if x != nil { - return x.Order - } - return "" -} - -type ListMessagesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Messages []*Message `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` -} - -func (x *ListMessagesResponse) Reset() { - *x = ListMessagesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListMessagesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListMessagesResponse) ProtoMessage() {} - -func (x *ListMessagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListMessagesResponse.ProtoReflect.Descriptor instead. -func (*ListMessagesResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{15} -} - -func (x *ListMessagesResponse) GetMessages() []*Message { - if x != nil { - return x.Messages - } - return nil -} - -type RecentMessagesRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - ThreadIds []string `protobuf:"bytes,2,rep,name=thread_ids,json=threadIds,proto3" json:"thread_ids,omitempty"` - LimitPerThread int64 `protobuf:"varint,3,opt,name=limit_per_thread,json=limitPerThread,proto3" json:"limit_per_thread,omitempty"` -} - -func (x *RecentMessagesRequest) Reset() { - *x = RecentMessagesRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RecentMessagesRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RecentMessagesRequest) ProtoMessage() {} - -func (x *RecentMessagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RecentMessagesRequest.ProtoReflect.Descriptor instead. -func (*RecentMessagesRequest) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{16} -} - -func (x *RecentMessagesRequest) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *RecentMessagesRequest) GetThreadIds() []string { - if x != nil { - return x.ThreadIds - } - return nil -} - -func (x *RecentMessagesRequest) GetLimitPerThread() int64 { - if x != nil { - return x.LimitPerThread - } - return 0 -} - -type RecentMessagesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Messages []*Message `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` -} - -func (x *RecentMessagesResponse) Reset() { - *x = RecentMessagesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_threads_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RecentMessagesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RecentMessagesResponse) ProtoMessage() {} - -func (x *RecentMessagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_threads_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RecentMessagesResponse.ProtoReflect.Descriptor instead. -func (*RecentMessagesResponse) Descriptor() ([]byte, []int) { - return file_proto_threads_proto_rawDescGZIP(), []int{17} -} - -func (x *RecentMessagesResponse) GetMessages() []*Message { - if x != nil { - return x.Messages - } - return nil -} - -var File_proto_threads_proto protoreflect.FileDescriptor - -var file_proto_threads_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x22, 0x68, - 0x0a, 0x06, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x80, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x49, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, - 0x78, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x22, 0x46, 0x0a, 0x13, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x70, 0x69, 0x63, 0x22, 0x3f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x06, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x22, 0x3e, 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x54, 0x68, 0x72, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x12, 0x52, 0x65, 0x61, 0x64, 0x54, 0x68, 0x72, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x73, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x06, 0x74, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x22, 0x2f, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, - 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x49, 0x64, 0x22, 0x40, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x72, 0x65, - 0x61, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x07, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x70, 0x69, 0x63, 0x22, 0x3f, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x06, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x22, 0x25, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x16, 0x0a, 0x14, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x74, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x43, 0x0a, 0x15, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x76, - 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, - 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x44, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, - 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x7b, 0x0a, 0x15, - 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x49, 0x64, 0x73, 0x12, - 0x28, 0x0a, 0x10, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x50, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x46, 0x0a, 0x16, 0x52, 0x65, 0x63, - 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x32, 0xf1, 0x04, 0x0a, 0x07, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x4b, 0x0a, - 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x2e, - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x68, - 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x52, 0x65, - 0x61, 0x64, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, - 0x64, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, - 0x64, 0x12, 0x1c, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, - 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1c, - 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, - 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x68, 0x72, - 0x65, 0x61, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, - 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x52, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2e, 0x52, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x3b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_threads_proto_rawDescOnce sync.Once - file_proto_threads_proto_rawDescData = file_proto_threads_proto_rawDesc -) - -func file_proto_threads_proto_rawDescGZIP() []byte { - file_proto_threads_proto_rawDescOnce.Do(func() { - file_proto_threads_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_threads_proto_rawDescData) - }) - return file_proto_threads_proto_rawDescData -} - -var file_proto_threads_proto_msgTypes = make([]protoimpl.MessageInfo, 18) -var file_proto_threads_proto_goTypes = []interface{}{ - (*Thread)(nil), // 0: threads.Thread - (*Message)(nil), // 1: threads.Message - (*CreateThreadRequest)(nil), // 2: threads.CreateThreadRequest - (*CreateThreadResponse)(nil), // 3: threads.CreateThreadResponse - (*ReadThreadRequest)(nil), // 4: threads.ReadThreadRequest - (*ReadThreadResponse)(nil), // 5: threads.ReadThreadResponse - (*ListThreadsRequest)(nil), // 6: threads.ListThreadsRequest - (*ListThreadsResponse)(nil), // 7: threads.ListThreadsResponse - (*UpdateThreadRequest)(nil), // 8: threads.UpdateThreadRequest - (*UpdateThreadResponse)(nil), // 9: threads.UpdateThreadResponse - (*DeleteThreadRequest)(nil), // 10: threads.DeleteThreadRequest - (*DeleteThreadResponse)(nil), // 11: threads.DeleteThreadResponse - (*CreateMessageRequest)(nil), // 12: threads.CreateMessageRequest - (*CreateMessageResponse)(nil), // 13: threads.CreateMessageResponse - (*ListMessagesRequest)(nil), // 14: threads.ListMessagesRequest - (*ListMessagesResponse)(nil), // 15: threads.ListMessagesResponse - (*RecentMessagesRequest)(nil), // 16: threads.RecentMessagesRequest - (*RecentMessagesResponse)(nil), // 17: threads.RecentMessagesResponse -} -var file_proto_threads_proto_depIdxs = []int32{ - 0, // 0: threads.CreateThreadResponse.thread:type_name -> threads.Thread - 0, // 1: threads.ReadThreadResponse.thread:type_name -> threads.Thread - 0, // 2: threads.ListThreadsResponse.threads:type_name -> threads.Thread - 0, // 3: threads.UpdateThreadResponse.thread:type_name -> threads.Thread - 1, // 4: threads.CreateMessageResponse.message:type_name -> threads.Message - 1, // 5: threads.ListMessagesResponse.messages:type_name -> threads.Message - 1, // 6: threads.RecentMessagesResponse.messages:type_name -> threads.Message - 2, // 7: threads.Threads.CreateThread:input_type -> threads.CreateThreadRequest - 4, // 8: threads.Threads.ReadThread:input_type -> threads.ReadThreadRequest - 8, // 9: threads.Threads.UpdateThread:input_type -> threads.UpdateThreadRequest - 10, // 10: threads.Threads.DeleteThread:input_type -> threads.DeleteThreadRequest - 6, // 11: threads.Threads.ListThreads:input_type -> threads.ListThreadsRequest - 12, // 12: threads.Threads.CreateMessage:input_type -> threads.CreateMessageRequest - 14, // 13: threads.Threads.ListMessages:input_type -> threads.ListMessagesRequest - 16, // 14: threads.Threads.RecentMessages:input_type -> threads.RecentMessagesRequest - 3, // 15: threads.Threads.CreateThread:output_type -> threads.CreateThreadResponse - 5, // 16: threads.Threads.ReadThread:output_type -> threads.ReadThreadResponse - 9, // 17: threads.Threads.UpdateThread:output_type -> threads.UpdateThreadResponse - 11, // 18: threads.Threads.DeleteThread:output_type -> threads.DeleteThreadResponse - 7, // 19: threads.Threads.ListThreads:output_type -> threads.ListThreadsResponse - 13, // 20: threads.Threads.CreateMessage:output_type -> threads.CreateMessageResponse - 15, // 21: threads.Threads.ListMessages:output_type -> threads.ListMessagesResponse - 17, // 22: threads.Threads.RecentMessages:output_type -> threads.RecentMessagesResponse - 15, // [15:23] is the sub-list for method output_type - 7, // [7:15] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name -} - -func init() { file_proto_threads_proto_init() } -func file_proto_threads_proto_init() { - if File_proto_threads_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_threads_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Thread); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateThreadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateThreadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadThreadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadThreadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListThreadsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListThreadsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateThreadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateThreadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteThreadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteThreadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMessageRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMessageResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMessagesRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMessagesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RecentMessagesRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_threads_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RecentMessagesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_threads_proto_rawDesc, - NumEnums: 0, - NumMessages: 18, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_threads_proto_goTypes, - DependencyIndexes: file_proto_threads_proto_depIdxs, - MessageInfos: file_proto_threads_proto_msgTypes, - }.Build() - File_proto_threads_proto = out.File - file_proto_threads_proto_rawDesc = nil - file_proto_threads_proto_goTypes = nil - file_proto_threads_proto_depIdxs = nil -} diff --git a/threads/proto/threads.pb.micro.go b/threads/proto/threads.pb.micro.go deleted file mode 100644 index 8e89571..0000000 --- a/threads/proto/threads.pb.micro.go +++ /dev/null @@ -1,234 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/threads.proto - -package threads - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Threads service - -func NewThreadsEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Threads service - -type ThreadsService interface { - // Create a thread - CreateThread(ctx context.Context, in *CreateThreadRequest, opts ...client.CallOption) (*CreateThreadResponse, error) - // Read a thread using its ID, can filter using group ID if provided - ReadThread(ctx context.Context, in *ReadThreadRequest, opts ...client.CallOption) (*ReadThreadResponse, error) - // Update a threads topic - UpdateThread(ctx context.Context, in *UpdateThreadRequest, opts ...client.CallOption) (*UpdateThreadResponse, error) - // Delete a thread and all the messages within - DeleteThread(ctx context.Context, in *DeleteThreadRequest, opts ...client.CallOption) (*DeleteThreadResponse, error) - // List all the threads for a group - ListThreads(ctx context.Context, in *ListThreadsRequest, opts ...client.CallOption) (*ListThreadsResponse, error) - // Create a message within a thread - CreateMessage(ctx context.Context, in *CreateMessageRequest, opts ...client.CallOption) (*CreateMessageResponse, error) - // List the messages within a thread in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - ListMessages(ctx context.Context, in *ListMessagesRequest, opts ...client.CallOption) (*ListMessagesResponse, error) - // RecentMessages returns the most recent messages in a group of threads. By default the - // most messages retrieved per thread is 25, however this can be overriden using the - // limit_per_thread option - RecentMessages(ctx context.Context, in *RecentMessagesRequest, opts ...client.CallOption) (*RecentMessagesResponse, error) -} - -type threadsService struct { - c client.Client - name string -} - -func NewThreadsService(name string, c client.Client) ThreadsService { - return &threadsService{ - c: c, - name: name, - } -} - -func (c *threadsService) CreateThread(ctx context.Context, in *CreateThreadRequest, opts ...client.CallOption) (*CreateThreadResponse, error) { - req := c.c.NewRequest(c.name, "Threads.CreateThread", in) - out := new(CreateThreadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) ReadThread(ctx context.Context, in *ReadThreadRequest, opts ...client.CallOption) (*ReadThreadResponse, error) { - req := c.c.NewRequest(c.name, "Threads.ReadThread", in) - out := new(ReadThreadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) UpdateThread(ctx context.Context, in *UpdateThreadRequest, opts ...client.CallOption) (*UpdateThreadResponse, error) { - req := c.c.NewRequest(c.name, "Threads.UpdateThread", in) - out := new(UpdateThreadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) DeleteThread(ctx context.Context, in *DeleteThreadRequest, opts ...client.CallOption) (*DeleteThreadResponse, error) { - req := c.c.NewRequest(c.name, "Threads.DeleteThread", in) - out := new(DeleteThreadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) ListThreads(ctx context.Context, in *ListThreadsRequest, opts ...client.CallOption) (*ListThreadsResponse, error) { - req := c.c.NewRequest(c.name, "Threads.ListThreads", in) - out := new(ListThreadsResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) CreateMessage(ctx context.Context, in *CreateMessageRequest, opts ...client.CallOption) (*CreateMessageResponse, error) { - req := c.c.NewRequest(c.name, "Threads.CreateMessage", in) - out := new(CreateMessageResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) ListMessages(ctx context.Context, in *ListMessagesRequest, opts ...client.CallOption) (*ListMessagesResponse, error) { - req := c.c.NewRequest(c.name, "Threads.ListMessages", in) - out := new(ListMessagesResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *threadsService) RecentMessages(ctx context.Context, in *RecentMessagesRequest, opts ...client.CallOption) (*RecentMessagesResponse, error) { - req := c.c.NewRequest(c.name, "Threads.RecentMessages", in) - out := new(RecentMessagesResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Threads service - -type ThreadsHandler interface { - // Create a thread - CreateThread(context.Context, *CreateThreadRequest, *CreateThreadResponse) error - // Read a thread using its ID, can filter using group ID if provided - ReadThread(context.Context, *ReadThreadRequest, *ReadThreadResponse) error - // Update a threads topic - UpdateThread(context.Context, *UpdateThreadRequest, *UpdateThreadResponse) error - // Delete a thread and all the messages within - DeleteThread(context.Context, *DeleteThreadRequest, *DeleteThreadResponse) error - // List all the threads for a group - ListThreads(context.Context, *ListThreadsRequest, *ListThreadsResponse) error - // Create a message within a thread - CreateMessage(context.Context, *CreateMessageRequest, *CreateMessageResponse) error - // List the messages within a thread in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - ListMessages(context.Context, *ListMessagesRequest, *ListMessagesResponse) error - // RecentMessages returns the most recent messages in a group of threads. By default the - // most messages retrieved per thread is 25, however this can be overriden using the - // limit_per_thread option - RecentMessages(context.Context, *RecentMessagesRequest, *RecentMessagesResponse) error -} - -func RegisterThreadsHandler(s server.Server, hdlr ThreadsHandler, opts ...server.HandlerOption) error { - type threads interface { - CreateThread(ctx context.Context, in *CreateThreadRequest, out *CreateThreadResponse) error - ReadThread(ctx context.Context, in *ReadThreadRequest, out *ReadThreadResponse) error - UpdateThread(ctx context.Context, in *UpdateThreadRequest, out *UpdateThreadResponse) error - DeleteThread(ctx context.Context, in *DeleteThreadRequest, out *DeleteThreadResponse) error - ListThreads(ctx context.Context, in *ListThreadsRequest, out *ListThreadsResponse) error - CreateMessage(ctx context.Context, in *CreateMessageRequest, out *CreateMessageResponse) error - ListMessages(ctx context.Context, in *ListMessagesRequest, out *ListMessagesResponse) error - RecentMessages(ctx context.Context, in *RecentMessagesRequest, out *RecentMessagesResponse) error - } - type Threads struct { - threads - } - h := &threadsHandler{hdlr} - return s.Handle(s.NewHandler(&Threads{h}, opts...)) -} - -type threadsHandler struct { - ThreadsHandler -} - -func (h *threadsHandler) CreateThread(ctx context.Context, in *CreateThreadRequest, out *CreateThreadResponse) error { - return h.ThreadsHandler.CreateThread(ctx, in, out) -} - -func (h *threadsHandler) ReadThread(ctx context.Context, in *ReadThreadRequest, out *ReadThreadResponse) error { - return h.ThreadsHandler.ReadThread(ctx, in, out) -} - -func (h *threadsHandler) UpdateThread(ctx context.Context, in *UpdateThreadRequest, out *UpdateThreadResponse) error { - return h.ThreadsHandler.UpdateThread(ctx, in, out) -} - -func (h *threadsHandler) DeleteThread(ctx context.Context, in *DeleteThreadRequest, out *DeleteThreadResponse) error { - return h.ThreadsHandler.DeleteThread(ctx, in, out) -} - -func (h *threadsHandler) ListThreads(ctx context.Context, in *ListThreadsRequest, out *ListThreadsResponse) error { - return h.ThreadsHandler.ListThreads(ctx, in, out) -} - -func (h *threadsHandler) CreateMessage(ctx context.Context, in *CreateMessageRequest, out *CreateMessageResponse) error { - return h.ThreadsHandler.CreateMessage(ctx, in, out) -} - -func (h *threadsHandler) ListMessages(ctx context.Context, in *ListMessagesRequest, out *ListMessagesResponse) error { - return h.ThreadsHandler.ListMessages(ctx, in, out) -} - -func (h *threadsHandler) RecentMessages(ctx context.Context, in *RecentMessagesRequest, out *RecentMessagesResponse) error { - return h.ThreadsHandler.RecentMessages(ctx, in, out) -} diff --git a/threads/proto/threads.proto b/threads/proto/threads.proto deleted file mode 100644 index e9b6c67..0000000 --- a/threads/proto/threads.proto +++ /dev/null @@ -1,115 +0,0 @@ -syntax = "proto3"; - -package threads; - -option go_package = "./proto;threads"; - -service Threads { - // Create a thread - rpc CreateThread(CreateThreadRequest) returns (CreateThreadResponse); - // Read a thread using its ID, can filter using group ID if provided - rpc ReadThread(ReadThreadRequest) returns (ReadThreadResponse); - // Update a threads topic - rpc UpdateThread(UpdateThreadRequest) returns (UpdateThreadResponse); - // Delete a thread and all the messages within - rpc DeleteThread(DeleteThreadRequest) returns (DeleteThreadResponse); - // List all the threads for a group - rpc ListThreads(ListThreadsRequest) returns (ListThreadsResponse); - // Create a message within a thread - rpc CreateMessage(CreateMessageRequest) returns (CreateMessageResponse); - // List the messages within a thread in reverse chronological order, using sent_before to - // offset as older messages need to be loaded - rpc ListMessages(ListMessagesRequest) returns (ListMessagesResponse); - // RecentMessages returns the most recent messages in a group of threads. By default the - // most messages retrieved per thread is 25, however this can be overriden using the - // limit_per_thread option - rpc RecentMessages(RecentMessagesRequest) returns (RecentMessagesResponse); -} - -message Thread { - string id = 1; - string group_id = 2; - string topic = 3; - string created_at = 4; -} - -message Message { - string id = 1; - string author_id = 2; - string thread_id = 3; - string text = 4; - string sent_at = 5; -} - -message CreateThreadRequest { - string group_id = 1; - string topic = 2; -} - -message CreateThreadResponse { - Thread thread = 1; -} - -message ReadThreadRequest { - string id = 1; - string group_id = 2; -} - -message ReadThreadResponse { - Thread thread = 1; -} - -message ListThreadsRequest { - string group_id = 1; -} - -message ListThreadsResponse { - repeated Thread threads = 1; -} - -message UpdateThreadRequest { - string id = 1; - string topic = 2; -} - -message UpdateThreadResponse { - Thread thread = 1; -} - -message DeleteThreadRequest { - string id = 1; -} - -message DeleteThreadResponse {} - -message CreateMessageRequest { - string id = 1; - string thread_id = 2; - string author_id = 3; - string text = 4; -} - -message CreateMessageResponse { - Message message = 1; -} - -message ListMessagesRequest { - string thread_id = 1; - int64 limit = 2; - int64 offset = 3; - string order = 4; -} - -message ListMessagesResponse { - repeated Message messages = 1; -} - -message RecentMessagesRequest { - string group_id = 1; - repeated string thread_ids = 2; - int64 limit_per_thread = 3; -} - -message RecentMessagesResponse { - repeated Message messages = 1; -} diff --git a/users/.gitignore b/users/.gitignore deleted file mode 100644 index ae22583..0000000 --- a/users/.gitignore +++ /dev/null @@ -1 +0,0 @@ -users diff --git a/users/Dockerfile b/users/Dockerfile deleted file mode 100644 index 5a4c6b4..0000000 --- a/users/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD users /users -ENTRYPOINT [ "/users" ] diff --git a/users/Makefile b/users/Makefile deleted file mode 100644 index 8e5347f..0000000 --- a/users/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -GOPATH:=$(shell go env GOPATH) -.PHONY: init -init: - go get -u github.com/golang/protobuf/proto - go get -u github.com/golang/protobuf/protoc-gen-go - go get github.com/micro/micro/v3/cmd/protoc-gen-micro -.PHONY: proto -proto: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/users.proto - -.PHONY: docs -docs: - protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/users.proto - @redoc-cli bundle api-users.json - -.PHONY: build -build: - go build -o users *.go - -.PHONY: test -test: - go test -v -p 1 ./... - -.PHONY: docker -docker: - docker build . -t users:latest diff --git a/users/README.md b/users/README.md deleted file mode 100644 index 160b2a1..0000000 --- a/users/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Usage management and authentication - -# Users Service - -The user service provides user management, storage and authentication. diff --git a/users/generate.go b/users/generate.go deleted file mode 100644 index 7d9db91..0000000 --- a/users/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate make proto diff --git a/users/handler/create.go b/users/handler/create.go deleted file mode 100644 index d15b22f..0000000 --- a/users/handler/create.go +++ /dev/null @@ -1,87 +0,0 @@ -package handler - -import ( - "context" - "regexp" - "strings" - "time" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Create a user -func (u *Users) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - - // validate the request - if len(req.FirstName) == 0 { - return ErrMissingFirstName - } - if len(req.LastName) == 0 { - return ErrMissingLastName - } - if len(req.Email) == 0 { - return ErrMissingEmail - } - if !isEmailValid(req.Email) { - return ErrInvalidEmail - } - if len(req.Password) < 8 { - return ErrInvalidPassword - } - - // hash and salt the password using bcrypt - phash, err := hashAndSalt(req.Password) - if err != nil { - logger.Errorf("Error hashing and salting password: %v", err) - return errors.InternalServerError("HASHING_ERROR", "Error hashing password") - } - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - return db.Transaction(func(tx *gorm.DB) error { - // write the user to the database - user := &User{ - ID: uuid.New().String(), - FirstName: req.FirstName, - LastName: req.LastName, - Email: strings.ToLower(req.Email), - Password: phash, - } - err = tx.Create(user).Error - - if err != nil { - if match, _ := regexp.MatchString(`idx_[\S]+_users_email`, err.Error()); match { - return ErrDuplicateEmail - } - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // generate a token for the user - token := Token{ - UserID: user.ID, - Key: uuid.New().String(), - ExpiresAt: u.Time().Add(time.Hour * 24 * 7), - } - if err := tx.Create(&token).Error; err != nil { - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.User = user.Serialize() - rsp.Token = token.Key - return nil - }) -} diff --git a/users/handler/create_test.go b/users/handler/create_test.go deleted file mode 100644 index a098aec..0000000 --- a/users/handler/create_test.go +++ /dev/null @@ -1,128 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestCreate(t *testing.T) { - tt := []struct { - Name string - FirstName string - LastName string - Email string - Password string - Error error - }{ - { - Name: "MissingFirstName", - LastName: "Doe", - Email: "john@doe.com", - Password: "password", - Error: handler.ErrMissingFirstName, - }, - { - Name: "MissingLastName", - FirstName: "John", - Email: "john@doe.com", - Password: "password", - Error: handler.ErrMissingLastName, - }, - { - Name: "MissingEmail", - FirstName: "John", - LastName: "Doe", - Password: "password", - Error: handler.ErrMissingEmail, - }, - { - Name: "InvalidEmail", - FirstName: "John", - LastName: "Doe", - Password: "password", - Email: "foo.foo.foo", - Error: handler.ErrInvalidEmail, - }, - { - Name: "InvalidPassword", - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "pwd", - Error: handler.ErrInvalidPassword, - }, - } - - // test the validations - h := testHandler(t) - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - err := h.Create(microAccountCtx(), &pb.CreateRequest{ - FirstName: tc.FirstName, - LastName: tc.LastName, - Email: tc.Email, - Password: tc.Password, - }, &pb.CreateResponse{}) - assert.Equal(t, tc.Error, err) - }) - } - - t.Run("Valid", func(t *testing.T) { - var rsp pb.CreateResponse - req := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &req, &rsp) - - assert.NoError(t, err) - u := rsp.User - if u == nil { - t.Fatalf("No user returned") - } - assert.NotEmpty(t, u.Id) - assert.Equal(t, req.FirstName, u.FirstName) - assert.Equal(t, req.LastName, u.LastName) - assert.Equal(t, req.Email, u.Email) - assert.NotEmpty(t, rsp.Token) - }) - - t.Run("DuplicateEmail", func(t *testing.T) { - var rsp pb.CreateResponse - req := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &req, &rsp) - assert.Equal(t, handler.ErrDuplicateEmail, err) - assert.Nil(t, rsp.User) - }) - - t.Run("DifferentEmail", func(t *testing.T) { - var rsp pb.CreateResponse - req := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "johndoe@gmail.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &req, &rsp) - - assert.NoError(t, err) - u := rsp.User - if u == nil { - t.Fatalf("No user returned") - } - assert.NotEmpty(t, u.Id) - assert.Equal(t, req.FirstName, u.FirstName) - assert.Equal(t, req.LastName, u.LastName) - assert.Equal(t, req.Email, u.Email) - }) -} diff --git a/users/handler/delete.go b/users/handler/delete.go deleted file mode 100644 index 5eb8043..0000000 --- a/users/handler/delete.go +++ /dev/null @@ -1,44 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Delete a user -func (u *Users) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - - // delete the users tokens - return db.Transaction(func(tx *gorm.DB) error { - if err := tx.Delete(&Token{}, &Token{UserID: req.Id}).Error; err != nil { - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // delete from the database - if err := tx.Delete(&User{}, &User{ID: req.Id}).Error; err != nil { - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - return nil - }) -} diff --git a/users/handler/delete_test.go b/users/handler/delete_test.go deleted file mode 100644 index a2215f5..0000000 --- a/users/handler/delete_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestDelete(t *testing.T) { - h := testHandler(t) - - t.Run("MissingID", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{}, &pb.DeleteResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - // create some mock data - var cRsp pb.CreateResponse - cReq := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq, &cRsp) - assert.NoError(t, err) - if cRsp.User == nil { - t.Fatal("No user returned") - return - } - - t.Run("Valid", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{ - Id: cRsp.User.Id, - }, &pb.DeleteResponse{}) - assert.NoError(t, err) - - // check it was actually deleted - var rsp pb.ReadResponse - err = h.Read(microAccountCtx(), &pb.ReadRequest{ - Ids: []string{cRsp.User.Id}, - }, &rsp) - assert.NoError(t, err) - assert.Nil(t, rsp.Users[cRsp.User.Id]) - }) - - t.Run("Retry", func(t *testing.T) { - err := h.Delete(microAccountCtx(), &pb.DeleteRequest{ - Id: cRsp.User.Id, - }, &pb.DeleteResponse{}) - assert.NoError(t, err) - }) -} diff --git a/users/handler/handler.go b/users/handler/handler.go deleted file mode 100644 index 568180f..0000000 --- a/users/handler/handler.go +++ /dev/null @@ -1,88 +0,0 @@ -package handler - -import ( - "regexp" - "time" - - "github.com/micro/micro/v3/service/errors" - gorm2 "github.com/micro/services/pkg/gorm" - pb "github.com/micro/services/users/proto" - "golang.org/x/crypto/bcrypt" -) - -var ( - ErrMissingFirstName = errors.BadRequest("MISSING_FIRST_NAME", "Missing first name") - ErrMissingLastName = errors.BadRequest("MISSING_LAST_NAME", "Missing last name") - ErrMissingEmail = errors.BadRequest("MISSING_EMAIL", "Missing email") - ErrDuplicateEmail = errors.BadRequest("DUPLICATE_EMAIL", "A user with this email address already exists") - ErrInvalidEmail = errors.BadRequest("INVALID_EMAIL", "The email provided is invalid") - ErrInvalidPassword = errors.BadRequest("INVALID_PASSWORD", "Password must be at least 8 characters long") - ErrMissingEmails = errors.BadRequest("MISSING_EMAILS", "One or more emails are required") - ErrMissingIDs = errors.BadRequest("MISSING_IDS", "One or more ids are required") - ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") - ErrMissingToken = errors.BadRequest("MISSING_TOKEN", "Missing token") - ErrIncorrectPassword = errors.BadRequest("INCORRECT_PASSWORD", "Incorrect password") - ErrTokenExpired = errors.BadRequest("TOKEN_EXPIRED", "Token has expired") - ErrInvalidToken = errors.BadRequest("INVALID_TOKEN", "Token is invalid") - ErrNotFound = errors.NotFound("NOT_FOUND", "User not found") - - emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") - tokenTTL = time.Hour * 7 * 24 -) - -type User struct { - ID string - FirstName string - LastName string - Email string `gorm:"uniqueIndex"` - Password string - CreatedAt time.Time - Tokens []Token -} - -func (u *User) Serialize() *pb.User { - return &pb.User{ - Id: u.ID, - FirstName: u.FirstName, - LastName: u.LastName, - Email: u.Email, - } -} - -type Token struct { - Key string `gorm:"primaryKey"` - CreatedAt time.Time - ExpiresAt time.Time - UserID string - User User -} - -type Users struct { - gorm2.Helper - Time func() time.Time -} - -func NewHandler(t func() time.Time) *Users { - return &Users{Time: t} -} - -// isEmailValid checks if the email provided passes the required structure and length. -func isEmailValid(e string) bool { - if len(e) < 3 && len(e) > 254 { - return false - } - return emailRegex.MatchString(e) -} - -func hashAndSalt(pwd string) (string, error) { - hash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost) - if err != nil { - return "", err - } - return string(hash), nil -} - -func passwordsMatch(hashed string, plain string) bool { - err := bcrypt.CompareHashAndPassword([]byte(hashed), []byte(plain)) - return err == nil -} diff --git a/users/handler/handler_test.go b/users/handler/handler_test.go deleted file mode 100644 index 3dfbad7..0000000 --- a/users/handler/handler_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package handler_test - -import ( - "context" - "database/sql" - "os" - "testing" - "time" - - "github.com/micro/micro/v3/service/auth" - "github.com/stretchr/testify/assert" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - - _ "github.com/jackc/pgx/v4/stdlib" -) - -func testHandler(t *testing.T) *handler.Users { - // connect to the database - addr := os.Getenv("POSTGRES_URL") - if len(addr) == 0 { - addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable" - } - sqlDB, err := sql.Open("pgx", addr) - if err != nil { - t.Fatalf("Failed to open connection to DB %s", err) - } - // clean any data from a previous run - if _, err := sqlDB.Exec(`DROP TABLE IF EXISTS "micro_someID_users", "micro_someID_tokens" CASCADE`); err != nil { - t.Fatalf("Error cleaning database: %v", err) - } - - h := handler.NewHandler(time.Now) - h.DBConn(sqlDB).Migrations(&handler.User{}, &handler.Token{}) - return h -} - -func assertUsersMatch(t *testing.T, exp, act *pb.User) { - if act == nil { - t.Error("No user returned") - return - } - assert.Equal(t, exp.Id, act.Id) - assert.Equal(t, exp.FirstName, act.FirstName) - assert.Equal(t, exp.LastName, act.LastName) - assert.Equal(t, exp.Email, act.Email) -} - -func microAccountCtx() context.Context { - return auth.ContextWithAccount(context.TODO(), &auth.Account{ - Issuer: "micro", - ID: "someID", - }) -} diff --git a/users/handler/list.go b/users/handler/list.go deleted file mode 100644 index 8ecc225..0000000 --- a/users/handler/list.go +++ /dev/null @@ -1,36 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" -) - -// List all users -func (u *Users) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // query the database - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - var users []User - if err := db.Model(&User{}).Find(&users).Error; err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.Users = make([]*pb.User, len(users)) - for i, u := range users { - rsp.Users[i] = u.Serialize() - } - return nil -} diff --git a/users/handler/list_test.go b/users/handler/list_test.go deleted file mode 100644 index f9aaa82..0000000 --- a/users/handler/list_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package handler_test - -import ( - "testing" - - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestList(t *testing.T) { - h := testHandler(t) - - // create some mock data - var cRsp1 pb.CreateResponse - cReq1 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq1, &cRsp1) - assert.NoError(t, err) - if cRsp1.User == nil { - t.Fatal("No user returned") - return - } - - var cRsp2 pb.CreateResponse - cReq2 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "johndoe@gmail.com", - Password: "passwordabc", - } - err = h.Create(microAccountCtx(), &cReq2, &cRsp2) - assert.NoError(t, err) - if cRsp2.User == nil { - t.Fatal("No user returned") - return - } - - var rsp pb.ListResponse - err = h.List(microAccountCtx(), &pb.ListRequest{}, &rsp) - assert.NoError(t, err) - if rsp.Users == nil { - t.Error("No users returned") - return - } - - var u1Found, u2Found bool - for _, u := range rsp.Users { - switch u.Id { - case cRsp1.User.Id: - assertUsersMatch(t, cRsp1.User, u) - u1Found = true - case cRsp2.User.Id: - assertUsersMatch(t, cRsp2.User, u) - u2Found = true - default: - t.Fatal("Unexpected user returned") - return - } - } - assert.True(t, u1Found) - assert.True(t, u2Found) -} diff --git a/users/handler/login.go b/users/handler/login.go deleted file mode 100644 index c275d9a..0000000 --- a/users/handler/login.go +++ /dev/null @@ -1,65 +0,0 @@ -package handler - -import ( - "context" - - "github.com/google/uuid" - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Login using email and password returns the users profile and a token -func (u *Users) Login(ctx context.Context, req *pb.LoginRequest, rsp *pb.LoginResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Email) == 0 { - return ErrMissingEmail - } - if len(req.Password) == 0 { - return ErrInvalidPassword - } - - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - - return db.Transaction(func(tx *gorm.DB) error { - // lookup the user - var user User - if err := tx.Where(&User{Email: req.Email}).First(&user).Error; err == gorm.ErrRecordNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // compare the passwords - if !passwordsMatch(user.Password, req.Password) { - return ErrIncorrectPassword - } - - // generate a token for the user - token := Token{ - UserID: user.ID, - Key: uuid.New().String(), - ExpiresAt: u.Time().Add(tokenTTL), - } - if err := tx.Create(&token).Error; err != nil { - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.Token = token.Key - rsp.User = user.Serialize() - return nil - }) -} diff --git a/users/handler/login_test.go b/users/handler/login_test.go deleted file mode 100644 index 4fd4afe..0000000 --- a/users/handler/login_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestLogin(t *testing.T) { - h := testHandler(t) - - // create some mock data - var cRsp pb.CreateResponse - cReq := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq, &cRsp) - assert.NoError(t, err) - if cRsp.User == nil { - t.Fatal("No user returned") - return - } - - tt := []struct { - Name string - Email string - Password string - Error error - User *pb.User - }{ - { - Name: "MissingEmail", - Password: "passwordabc", - Error: handler.ErrMissingEmail, - }, - { - Name: "MissingPassword", - Email: "john@doe.com", - Error: handler.ErrInvalidPassword, - }, - { - Name: "UserNotFound", - Email: "foo@bar.com", - Password: "passwordabc", - Error: handler.ErrNotFound, - }, - { - Name: "IncorrectPassword", - Email: "john@doe.com", - Password: "passwordabcdef", - Error: handler.ErrIncorrectPassword, - }, - { - Name: "Valid", - Email: "john@doe.com", - Password: "passwordabc", - User: cRsp.User, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - var rsp pb.LoginResponse - err := h.Login(microAccountCtx(), &pb.LoginRequest{ - Email: tc.Email, Password: tc.Password, - }, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.User != nil { - assertUsersMatch(t, tc.User, rsp.User) - assert.NotEmpty(t, rsp.Token) - } else { - assert.Nil(t, tc.User) - } - }) - } -} diff --git a/users/handler/logout.go b/users/handler/logout.go deleted file mode 100644 index e3f5b47..0000000 --- a/users/handler/logout.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Logout expires all tokens for the user -func (u *Users) Logout(ctx context.Context, req *pb.LogoutRequest, rsp *pb.LogoutResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - return db.Transaction(func(tx *gorm.DB) error { - // lookup the user - var user User - if err := tx.Where(&User{ID: req.Id}).Preload("Tokens").First(&user).Error; err == gorm.ErrRecordNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // delete the tokens - if err := tx.Delete(user.Tokens).Error; err != nil { - logger.Errorf("Error deleting from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - return nil - }) -} diff --git a/users/handler/logout_test.go b/users/handler/logout_test.go deleted file mode 100644 index e15f6ae..0000000 --- a/users/handler/logout_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestLogout(t *testing.T) { - h := testHandler(t) - - t.Run("MissingUserID", func(t *testing.T) { - err := h.Logout(microAccountCtx(), &pb.LogoutRequest{}, &pb.LogoutResponse{}) - assert.Equal(t, handler.ErrMissingID, err) - }) - - t.Run("UserNotFound", func(t *testing.T) { - err := h.Logout(microAccountCtx(), &pb.LogoutRequest{Id: uuid.New().String()}, &pb.LogoutResponse{}) - assert.Equal(t, handler.ErrNotFound, err) - }) - - t.Run("Valid", func(t *testing.T) { - // create some mock data - var cRsp pb.CreateResponse - cReq := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq, &cRsp) - assert.NoError(t, err) - if cRsp.User == nil { - t.Fatal("No user returned") - return - } - - err = h.Logout(microAccountCtx(), &pb.LogoutRequest{Id: cRsp.User.Id}, &pb.LogoutResponse{}) - assert.NoError(t, err) - - err = h.Validate(microAccountCtx(), &pb.ValidateRequest{Token: cRsp.Token}, &pb.ValidateResponse{}) - assert.Error(t, err) - }) -} diff --git a/users/handler/read.go b/users/handler/read.go deleted file mode 100644 index 20aa7fc..0000000 --- a/users/handler/read.go +++ /dev/null @@ -1,41 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" -) - -// Read users using ID -func (u *Users) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Ids) == 0 { - return ErrMissingIDs - } - - // query the database - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - var users []User - if err := db.Model(&User{}).Where("id IN (?)", req.Ids).Find(&users).Error; err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.Users = make(map[string]*pb.User, len(users)) - for _, u := range users { - rsp.Users[u.ID] = u.Serialize() - } - return nil -} diff --git a/users/handler/read_by_email.go b/users/handler/read_by_email.go deleted file mode 100644 index adee532..0000000 --- a/users/handler/read_by_email.go +++ /dev/null @@ -1,46 +0,0 @@ -package handler - -import ( - "context" - "strings" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" -) - -// Read users using email -func (u *Users) ReadByEmail(ctx context.Context, req *pb.ReadByEmailRequest, rsp *pb.ReadByEmailResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Emails) == 0 { - return ErrMissingEmails - } - emails := make([]string, len(req.Emails)) - for i, e := range req.Emails { - emails[i] = strings.ToLower(e) - } - - // query the database - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - var users []User - if err := db.Model(&User{}).Where("lower(email) IN (?)", emails).Find(&users).Error; err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.Users = make(map[string]*pb.User, len(users)) - for _, u := range users { - rsp.Users[u.Email] = u.Serialize() - } - return nil -} diff --git a/users/handler/read_by_email_test.go b/users/handler/read_by_email_test.go deleted file mode 100644 index d468342..0000000 --- a/users/handler/read_by_email_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package handler_test - -import ( - "strings" - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestReadByEmail(t *testing.T) { - h := testHandler(t) - - t.Run("MissingEmails", func(t *testing.T) { - var rsp pb.ReadByEmailResponse - err := h.ReadByEmail(microAccountCtx(), &pb.ReadByEmailRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingEmails, err) - assert.Nil(t, rsp.Users) - }) - - t.Run("NotFound", func(t *testing.T) { - var rsp pb.ReadByEmailResponse - err := h.ReadByEmail(microAccountCtx(), &pb.ReadByEmailRequest{Emails: []string{"foo"}}, &rsp) - assert.Nil(t, err) - if rsp.Users == nil { - t.Fatal("Expected the users object to not be nil") - } - assert.Nil(t, rsp.Users["foo"]) - }) - - // create some mock data - var rsp1 pb.CreateResponse - req1 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &req1, &rsp1) - assert.NoError(t, err) - if rsp1.User == nil { - t.Fatal("No user returned") - return - } - - var rsp2 pb.CreateResponse - req2 := pb.CreateRequest{ - FirstName: "Apple", - LastName: "Tree", - Email: "apple@tree.com", - Password: "passwordabc", - } - err = h.Create(microAccountCtx(), &req2, &rsp2) - assert.NoError(t, err) - if rsp2.User == nil { - t.Fatal("No user returned") - return - } - - // test the read - var rsp pb.ReadByEmailResponse - err = h.ReadByEmail(microAccountCtx(), &pb.ReadByEmailRequest{ - Emails: []string{rsp1.User.Email, strings.ToUpper(rsp2.User.Email)}, - }, &rsp) - assert.NoError(t, err) - - if rsp.Users == nil { - t.Fatal("Users not returned") - return - } - assert.NotNil(t, rsp.Users[rsp1.User.Email]) - assert.NotNil(t, rsp.Users[rsp2.User.Email]) - - // check the users match - if u := rsp.Users[rsp1.User.Email]; u != nil { - assert.Equal(t, rsp1.User.Id, u.Id) - assert.Equal(t, rsp1.User.FirstName, u.FirstName) - assert.Equal(t, rsp1.User.LastName, u.LastName) - assert.Equal(t, rsp1.User.Email, u.Email) - } - if u := rsp.Users[rsp2.User.Email]; u != nil { - assert.Equal(t, rsp2.User.Id, u.Id) - assert.Equal(t, rsp2.User.FirstName, u.FirstName) - assert.Equal(t, rsp2.User.LastName, u.LastName) - assert.Equal(t, rsp2.User.Email, u.Email) - } -} diff --git a/users/handler/read_test.go b/users/handler/read_test.go deleted file mode 100644 index 167ac75..0000000 --- a/users/handler/read_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestRead(t *testing.T) { - h := testHandler(t) - - t.Run("MissingIDs", func(t *testing.T) { - var rsp pb.ReadResponse - err := h.Read(microAccountCtx(), &pb.ReadRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingIDs, err) - assert.Nil(t, rsp.Users) - }) - - t.Run("NotFound", func(t *testing.T) { - var rsp pb.ReadResponse - err := h.Read(microAccountCtx(), &pb.ReadRequest{Ids: []string{"foo"}}, &rsp) - assert.Nil(t, err) - if rsp.Users == nil { - t.Fatal("Expected the users object to not be nil") - } - assert.Nil(t, rsp.Users["foo"]) - }) - - // create some mock data - var rsp1 pb.CreateResponse - req1 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &req1, &rsp1) - assert.NoError(t, err) - if rsp1.User == nil { - t.Fatal("No user returned") - return - } - - var rsp2 pb.CreateResponse - req2 := pb.CreateRequest{ - FirstName: "Apple", - LastName: "Tree", - Email: "apple@tree.com", - Password: "passwordabc", - } - err = h.Create(microAccountCtx(), &req2, &rsp2) - assert.NoError(t, err) - if rsp2.User == nil { - t.Fatal("No user returned") - return - } - - // test the read - var rsp pb.ReadResponse - err = h.Read(microAccountCtx(), &pb.ReadRequest{ - Ids: []string{rsp1.User.Id, rsp2.User.Id}, - }, &rsp) - assert.NoError(t, err) - - if rsp.Users == nil { - t.Fatal("Users not returned") - return - } - assert.NotNil(t, rsp.Users[rsp1.User.Id]) - assert.NotNil(t, rsp.Users[rsp2.User.Id]) - - // check the users match - if u := rsp.Users[rsp1.User.Id]; u != nil { - assert.Equal(t, rsp1.User.Id, u.Id) - assert.Equal(t, rsp1.User.FirstName, u.FirstName) - assert.Equal(t, rsp1.User.LastName, u.LastName) - assert.Equal(t, rsp1.User.Email, u.Email) - } - if u := rsp.Users[rsp2.User.Id]; u != nil { - assert.Equal(t, rsp2.User.Id, u.Id) - assert.Equal(t, rsp2.User.FirstName, u.FirstName) - assert.Equal(t, rsp2.User.LastName, u.LastName) - assert.Equal(t, rsp2.User.Email, u.Email) - } -} diff --git a/users/handler/update.go b/users/handler/update.go deleted file mode 100644 index 3c566ab..0000000 --- a/users/handler/update.go +++ /dev/null @@ -1,87 +0,0 @@ -package handler - -import ( - "context" - "regexp" - "strings" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Update a user -func (u *Users) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Id) == 0 { - return ErrMissingID - } - if req.FirstName != nil && len(req.FirstName.Value) == 0 { - return ErrMissingFirstName - } - if req.LastName != nil && len(req.LastName.Value) == 0 { - return ErrMissingLastName - } - if req.Email != nil && len(req.Email.Value) == 0 { - return ErrMissingEmail - } - if req.Email != nil && !isEmailValid(req.Email.Value) { - return ErrInvalidEmail - } - if req.Password != nil && len(req.Password.Value) < 8 { - return ErrInvalidEmail - } - - // lookup the user - var user User - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - if err := db.Where(&User{ID: req.Id}).First(&user).Error; err == gorm.ErrRecordNotFound { - return ErrNotFound - } else if err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // assign the updated values - if req.FirstName != nil { - user.FirstName = req.FirstName.Value - } - if req.LastName != nil { - user.LastName = req.LastName.Value - } - if req.Email != nil { - user.Email = strings.ToLower(req.Email.Value) - } - if req.Password != nil { - p, err := hashAndSalt(req.Password.Value) - if err != nil { - logger.Errorf("Error hasing and salting password: %v", err) - return errors.InternalServerError("HASHING_ERROR", "Error hashing password") - } - user.Password = p - } - - // write the user to the database - err = db.Save(user).Error - if err != nil { - if match, _ := regexp.MatchString(`idx_[\S]+_users_email`, err.Error()); match { - return ErrDuplicateEmail - } - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the user - rsp.User = user.Serialize() - return nil -} diff --git a/users/handler/update_test.go b/users/handler/update_test.go deleted file mode 100644 index c0ce6e5..0000000 --- a/users/handler/update_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package handler_test - -import ( - "testing" - - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -func TestUpdate(t *testing.T) { - h := testHandler(t) - - t.Run("MissingID", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{}, &rsp) - assert.Equal(t, handler.ErrMissingID, err) - assert.Nil(t, rsp.User) - }) - - t.Run("NotFound", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{Id: "foo"}, &rsp) - assert.Equal(t, handler.ErrNotFound, err) - assert.Nil(t, rsp.User) - }) - - // create some mock data - var cRsp1 pb.CreateResponse - cReq1 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq1, &cRsp1) - assert.NoError(t, err) - if cRsp1.User == nil { - t.Fatal("No user returned") - return - } - - var cRsp2 pb.CreateResponse - cReq2 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "johndoe@gmail.com", - Password: "passwordabc", - } - err = h.Create(microAccountCtx(), &cReq2, &cRsp2) - assert.NoError(t, err) - if cRsp2.User == nil { - t.Fatal("No user returned") - return - } - - t.Run("BlankFirstName", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, FirstName: &wrapperspb.StringValue{}, - }, &rsp) - assert.Equal(t, handler.ErrMissingFirstName, err) - assert.Nil(t, rsp.User) - }) - - t.Run("BlankLastName", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, LastName: &wrapperspb.StringValue{}, - }, &rsp) - assert.Equal(t, handler.ErrMissingLastName, err) - assert.Nil(t, rsp.User) - }) - - t.Run("BlankLastName", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, LastName: &wrapperspb.StringValue{}, - }, &rsp) - assert.Equal(t, handler.ErrMissingLastName, err) - assert.Nil(t, rsp.User) - }) - - t.Run("BlankEmail", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, Email: &wrapperspb.StringValue{}, - }, &rsp) - assert.Equal(t, handler.ErrMissingEmail, err) - assert.Nil(t, rsp.User) - }) - - t.Run("InvalidEmail", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, Email: &wrapperspb.StringValue{Value: "foo.bar"}, - }, &rsp) - assert.Equal(t, handler.ErrInvalidEmail, err) - assert.Nil(t, rsp.User) - }) - - t.Run("EmailAlreadyExists", func(t *testing.T) { - var rsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &pb.UpdateRequest{ - Id: cRsp1.User.Id, Email: &wrapperspb.StringValue{Value: cRsp2.User.Email}, - }, &rsp) - assert.Equal(t, handler.ErrDuplicateEmail, err) - assert.Nil(t, rsp.User) - }) - - t.Run("Valid", func(t *testing.T) { - uReq := pb.UpdateRequest{ - Id: cRsp1.User.Id, - Email: &wrapperspb.StringValue{Value: "foobar@gmail.com"}, - FirstName: &wrapperspb.StringValue{Value: "Foo"}, - LastName: &wrapperspb.StringValue{Value: "Bar"}, - } - var uRsp pb.UpdateResponse - err := h.Update(microAccountCtx(), &uReq, &uRsp) - assert.NoError(t, err) - if uRsp.User == nil { - t.Error("No user returned") - return - } - assert.Equal(t, cRsp1.User.Id, uRsp.User.Id) - assert.Equal(t, uReq.Email.Value, uRsp.User.Email) - assert.Equal(t, uReq.FirstName.Value, uRsp.User.FirstName) - assert.Equal(t, uReq.LastName.Value, uRsp.User.LastName) - }) - - t.Run("UpdatePassword", func(t *testing.T) { - uReq := pb.UpdateRequest{ - Id: cRsp2.User.Id, - Password: &wrapperspb.StringValue{Value: "helloworld"}, - } - err := h.Update(microAccountCtx(), &uReq, &pb.UpdateResponse{}) - assert.NoError(t, err) - - lReq := pb.LoginRequest{ - Email: cRsp2.User.Email, - Password: "helloworld", - } - err = h.Login(microAccountCtx(), &lReq, &pb.LoginResponse{}) - assert.NoError(t, err) - }) -} diff --git a/users/handler/validate.go b/users/handler/validate.go deleted file mode 100644 index 01306e4..0000000 --- a/users/handler/validate.go +++ /dev/null @@ -1,55 +0,0 @@ -package handler - -import ( - "context" - - "github.com/micro/micro/v3/service/auth" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/users/proto" - "gorm.io/gorm" -) - -// Validate a token, each time a token is validated it extends its lifetime for another week -func (u *Users) Validate(ctx context.Context, req *pb.ValidateRequest, rsp *pb.ValidateResponse) error { - _, ok := auth.AccountFromContext(ctx) - if !ok { - errors.Unauthorized("UNAUTHORIZED", "Unauthorized") - } - // validate the request - if len(req.Token) == 0 { - return ErrMissingToken - } - - db, err := u.GetDBConn(ctx) - if err != nil { - logger.Errorf("Error connecting to DB: %v", err) - return errors.InternalServerError("DB_ERROR", "Error connecting to DB") - } - return db.Transaction(func(tx *gorm.DB) error { - // lookup the token - var token Token - if err := tx.Where(&Token{Key: req.Token}).Preload("User").First(&token).Error; err == gorm.ErrRecordNotFound { - return ErrInvalidToken - } else if err != nil { - logger.Errorf("Error reading from the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // ensure the token is valid - if u.Time().After(token.ExpiresAt) { - return ErrTokenExpired - } - - // extend the token for another lifetime - token.ExpiresAt = u.Time().Add(tokenTTL) - if err := tx.Save(&token).Error; err != nil { - logger.Errorf("Error writing to the database: %v", err) - return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") - } - - // serialize the response - rsp.User = token.User.Serialize() - return nil - }) -} diff --git a/users/handler/validate_test.go b/users/handler/validate_test.go deleted file mode 100644 index bbf82b8..0000000 --- a/users/handler/validate_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package handler_test - -import ( - "testing" - "time" - - "github.com/google/uuid" - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - "github.com/stretchr/testify/assert" -) - -func TestValidate(t *testing.T) { - h := testHandler(t) - - // create some mock data - var cRsp1 pb.CreateResponse - cReq1 := pb.CreateRequest{ - FirstName: "John", - LastName: "Doe", - Email: "john@doe.com", - Password: "passwordabc", - } - err := h.Create(microAccountCtx(), &cReq1, &cRsp1) - assert.NoError(t, err) - if cRsp1.User == nil { - t.Fatal("No user returned") - return - } - - var cRsp2 pb.CreateResponse - cReq2 := pb.CreateRequest{ - FirstName: "Barry", - LastName: "Doe", - Email: "barry@doe.com", - Password: "passwordabc", - } - err = h.Create(microAccountCtx(), &cReq2, &cRsp2) - assert.NoError(t, err) - if cRsp2.User == nil { - t.Fatal("No user returned") - return - } - - tt := []struct { - Name string - Token string - Time func() time.Time - Error error - User *pb.User - }{ - { - Name: "MissingToken", - Error: handler.ErrMissingToken, - }, - { - Name: "InvalidToken", - Error: handler.ErrInvalidToken, - Token: uuid.New().String(), - }, - { - Name: "ExpiredToken", - Error: handler.ErrTokenExpired, - Token: cRsp1.Token, - Time: func() time.Time { return time.Now().Add(time.Hour * 24 * 8) }, - }, - { - Name: "ValidToken", - User: cRsp2.User, - Token: cRsp2.Token, - Time: func() time.Time { return time.Now().Add(time.Hour * 24 * 3) }, - }, - { - Name: "RefreshedToken", - User: cRsp2.User, - Token: cRsp2.Token, - Time: func() time.Time { return time.Now().Add(time.Hour * 24 * 8) }, - }, - } - - for _, tc := range tt { - t.Run(tc.Name, func(t *testing.T) { - if tc.Time == nil { - h.Time = time.Now - } else { - h.Time = tc.Time - } - - var rsp pb.ValidateResponse - err := h.Validate(microAccountCtx(), &pb.ValidateRequest{Token: tc.Token}, &rsp) - assert.Equal(t, tc.Error, err) - - if tc.User != nil { - assertUsersMatch(t, tc.User, rsp.User) - } else { - assert.Nil(t, tc.User) - } - }) - } -} diff --git a/users/main.go b/users/main.go deleted file mode 100644 index b1d24ab..0000000 --- a/users/main.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "database/sql" - "time" - - "github.com/micro/micro/v3/service" - "github.com/micro/micro/v3/service/config" - "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/users/handler" - pb "github.com/micro/services/users/proto" - - _ "github.com/jackc/pgx/v4/stdlib" -) - -var dbAddress = "postgresql://postgres:postgres@localhost:5432/users?sslmode=disable" - -func main() { - // Create service - srv := service.New( - service.Name("users"), - service.Version("latest"), - ) - - // Connect to the database - cfg, err := config.Get("users.database") - if err != nil { - logger.Fatalf("Error loading config: %v", err) - } - addr := cfg.String(dbAddress) - - // Register handler - sqlDB, err := sql.Open("pgx", addr) - if err != nil { - logger.Fatalf("Failed to open connection to DB %s", err) - } - h := handler.NewHandler(time.Now) - h.DBConn(sqlDB).Migrations(&handler.User{}, &handler.Token{}) - pb.RegisterUsersHandler(srv.Server(), h) - - // Run service - if err := srv.Run(); err != nil { - logger.Fatal(err) - } -} diff --git a/users/micro.mu b/users/micro.mu deleted file mode 100644 index 3f68786..0000000 --- a/users/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service users diff --git a/users/proto/users.pb.go b/users/proto/users.pb.go deleted file mode 100644 index 97a217d..0000000 --- a/users/proto/users.pb.go +++ /dev/null @@ -1,1454 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.5 -// source: proto/users.proto - -package users - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type User struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - FirstName string `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"` - LastName string `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"` - Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` -} - -func (x *User) Reset() { - *x = User{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *User) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*User) ProtoMessage() {} - -func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use User.ProtoReflect.Descriptor instead. -func (*User) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{0} -} - -func (x *User) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *User) GetFirstName() string { - if x != nil { - return x.FirstName - } - return "" -} - -func (x *User) GetLastName() string { - if x != nil { - return x.LastName - } - return "" -} - -func (x *User) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -type CreateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - FirstName string `protobuf:"bytes,1,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"` - LastName string `protobuf:"bytes,2,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"` - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` -} - -func (x *CreateRequest) Reset() { - *x = CreateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateRequest) ProtoMessage() {} - -func (x *CreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead. -func (*CreateRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{1} -} - -func (x *CreateRequest) GetFirstName() string { - if x != nil { - return x.FirstName - } - return "" -} - -func (x *CreateRequest) GetLastName() string { - if x != nil { - return x.LastName - } - return "" -} - -func (x *CreateRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *CreateRequest) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -type CreateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *CreateResponse) Reset() { - *x = CreateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateResponse) ProtoMessage() {} - -func (x *CreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateResponse.ProtoReflect.Descriptor instead. -func (*CreateResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateResponse) GetUser() *User { - if x != nil { - return x.User - } - return nil -} - -func (x *CreateResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -type ReadRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` -} - -func (x *ReadRequest) Reset() { - *x = ReadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadRequest) ProtoMessage() {} - -func (x *ReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. -func (*ReadRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{3} -} - -func (x *ReadRequest) GetIds() []string { - if x != nil { - return x.Ids - } - return nil -} - -type ReadResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Users map[string]*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ReadResponse) Reset() { - *x = ReadResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadResponse) ProtoMessage() {} - -func (x *ReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. -func (*ReadResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{4} -} - -func (x *ReadResponse) GetUsers() map[string]*User { - if x != nil { - return x.Users - } - return nil -} - -type ReadByEmailRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Emails []string `protobuf:"bytes,1,rep,name=emails,proto3" json:"emails,omitempty"` -} - -func (x *ReadByEmailRequest) Reset() { - *x = ReadByEmailRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadByEmailRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadByEmailRequest) ProtoMessage() {} - -func (x *ReadByEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadByEmailRequest.ProtoReflect.Descriptor instead. -func (*ReadByEmailRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{5} -} - -func (x *ReadByEmailRequest) GetEmails() []string { - if x != nil { - return x.Emails - } - return nil -} - -type ReadByEmailResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Users map[string]*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ReadByEmailResponse) Reset() { - *x = ReadByEmailResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReadByEmailResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReadByEmailResponse) ProtoMessage() {} - -func (x *ReadByEmailResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReadByEmailResponse.ProtoReflect.Descriptor instead. -func (*ReadByEmailResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{6} -} - -func (x *ReadByEmailResponse) GetUsers() map[string]*User { - if x != nil { - return x.Users - } - return nil -} - -type UpdateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - FirstName *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"` - LastName *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"` - Email *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` - Password *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=password,proto3" json:"password,omitempty"` -} - -func (x *UpdateRequest) Reset() { - *x = UpdateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateRequest) ProtoMessage() {} - -func (x *UpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead. -func (*UpdateRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{7} -} - -func (x *UpdateRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *UpdateRequest) GetFirstName() *wrapperspb.StringValue { - if x != nil { - return x.FirstName - } - return nil -} - -func (x *UpdateRequest) GetLastName() *wrapperspb.StringValue { - if x != nil { - return x.LastName - } - return nil -} - -func (x *UpdateRequest) GetEmail() *wrapperspb.StringValue { - if x != nil { - return x.Email - } - return nil -} - -func (x *UpdateRequest) GetPassword() *wrapperspb.StringValue { - if x != nil { - return x.Password - } - return nil -} - -type UpdateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` -} - -func (x *UpdateResponse) Reset() { - *x = UpdateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateResponse) ProtoMessage() {} - -func (x *UpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateResponse.ProtoReflect.Descriptor instead. -func (*UpdateResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{8} -} - -func (x *UpdateResponse) GetUser() *User { - if x != nil { - return x.User - } - return nil -} - -type DeleteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteRequest) Reset() { - *x = DeleteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteRequest) ProtoMessage() {} - -func (x *DeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. -func (*DeleteRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{9} -} - -func (x *DeleteRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type DeleteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DeleteResponse) Reset() { - *x = DeleteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteResponse) ProtoMessage() {} - -func (x *DeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{10} -} - -type ListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ListRequest) Reset() { - *x = ListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRequest) ProtoMessage() {} - -func (x *ListRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. -func (*ListRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{11} -} - -type ListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` -} - -func (x *ListResponse) Reset() { - *x = ListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListResponse) ProtoMessage() {} - -func (x *ListResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. -func (*ListResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{12} -} - -func (x *ListResponse) GetUsers() []*User { - if x != nil { - return x.Users - } - return nil -} - -type LoginRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` -} - -func (x *LoginRequest) Reset() { - *x = LoginRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LoginRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LoginRequest) ProtoMessage() {} - -func (x *LoginRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead. -func (*LoginRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{13} -} - -func (x *LoginRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *LoginRequest) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -type LoginResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *LoginResponse) Reset() { - *x = LoginResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LoginResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LoginResponse) ProtoMessage() {} - -func (x *LoginResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead. -func (*LoginResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{14} -} - -func (x *LoginResponse) GetUser() *User { - if x != nil { - return x.User - } - return nil -} - -func (x *LoginResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -type LogoutRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *LogoutRequest) Reset() { - *x = LogoutRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LogoutRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LogoutRequest) ProtoMessage() {} - -func (x *LogoutRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. -func (*LogoutRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{15} -} - -func (x *LogoutRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type LogoutResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LogoutResponse) Reset() { - *x = LogoutResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LogoutResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LogoutResponse) ProtoMessage() {} - -func (x *LogoutResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead. -func (*LogoutResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{16} -} - -type ValidateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *ValidateRequest) Reset() { - *x = ValidateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ValidateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ValidateRequest) ProtoMessage() {} - -func (x *ValidateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ValidateRequest.ProtoReflect.Descriptor instead. -func (*ValidateRequest) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{17} -} - -func (x *ValidateRequest) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -type ValidateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` -} - -func (x *ValidateResponse) Reset() { - *x = ValidateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_users_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ValidateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ValidateResponse) ProtoMessage() {} - -func (x *ValidateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_users_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ValidateResponse.ProtoReflect.Descriptor instead. -func (*ValidateResponse) Descriptor() ([]byte, []int) { - return file_proto_users_proto_rawDescGZIP(), []int{18} -} - -func (x *ValidateResponse) GetUser() *User { - if x != nil { - return x.User - } - return nil -} - -var File_proto_users_proto protoreflect.FileDescriptor - -var file_proto_users_proto_rawDesc = []byte{ - 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x68, 0x0a, 0x04, 0x55, 0x73, - 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x7d, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x22, 0x47, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1f, 0x0a, 0x0b, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, - 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x8b, 0x01, - 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, - 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x1a, 0x45, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2c, 0x0a, 0x12, 0x52, - 0x65, 0x61, 0x64, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x13, 0x52, 0x65, - 0x61, 0x64, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x42, 0x79, 0x45, - 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x45, - 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x85, 0x02, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x32, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x38, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x31, 0x0a, - 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x22, 0x1f, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x31, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x46, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, - 0x1f, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x22, 0x10, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x33, 0x0a, 0x10, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x32, 0x8e, 0x04, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x12, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x13, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x42, 0x79, - 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, - 0x61, 0x64, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x42, 0x79, 0x45, - 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, - 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x12, 0x14, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x31, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x13, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x14, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x4c, 0x6f, 0x67, - 0x6f, 0x75, 0x74, 0x12, 0x14, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, - 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_users_proto_rawDescOnce sync.Once - file_proto_users_proto_rawDescData = file_proto_users_proto_rawDesc -) - -func file_proto_users_proto_rawDescGZIP() []byte { - file_proto_users_proto_rawDescOnce.Do(func() { - file_proto_users_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_users_proto_rawDescData) - }) - return file_proto_users_proto_rawDescData -} - -var file_proto_users_proto_msgTypes = make([]protoimpl.MessageInfo, 21) -var file_proto_users_proto_goTypes = []interface{}{ - (*User)(nil), // 0: users.User - (*CreateRequest)(nil), // 1: users.CreateRequest - (*CreateResponse)(nil), // 2: users.CreateResponse - (*ReadRequest)(nil), // 3: users.ReadRequest - (*ReadResponse)(nil), // 4: users.ReadResponse - (*ReadByEmailRequest)(nil), // 5: users.ReadByEmailRequest - (*ReadByEmailResponse)(nil), // 6: users.ReadByEmailResponse - (*UpdateRequest)(nil), // 7: users.UpdateRequest - (*UpdateResponse)(nil), // 8: users.UpdateResponse - (*DeleteRequest)(nil), // 9: users.DeleteRequest - (*DeleteResponse)(nil), // 10: users.DeleteResponse - (*ListRequest)(nil), // 11: users.ListRequest - (*ListResponse)(nil), // 12: users.ListResponse - (*LoginRequest)(nil), // 13: users.LoginRequest - (*LoginResponse)(nil), // 14: users.LoginResponse - (*LogoutRequest)(nil), // 15: users.LogoutRequest - (*LogoutResponse)(nil), // 16: users.LogoutResponse - (*ValidateRequest)(nil), // 17: users.ValidateRequest - (*ValidateResponse)(nil), // 18: users.ValidateResponse - nil, // 19: users.ReadResponse.UsersEntry - nil, // 20: users.ReadByEmailResponse.UsersEntry - (*wrapperspb.StringValue)(nil), // 21: google.protobuf.StringValue -} -var file_proto_users_proto_depIdxs = []int32{ - 0, // 0: users.CreateResponse.user:type_name -> users.User - 19, // 1: users.ReadResponse.users:type_name -> users.ReadResponse.UsersEntry - 20, // 2: users.ReadByEmailResponse.users:type_name -> users.ReadByEmailResponse.UsersEntry - 21, // 3: users.UpdateRequest.first_name:type_name -> google.protobuf.StringValue - 21, // 4: users.UpdateRequest.last_name:type_name -> google.protobuf.StringValue - 21, // 5: users.UpdateRequest.email:type_name -> google.protobuf.StringValue - 21, // 6: users.UpdateRequest.password:type_name -> google.protobuf.StringValue - 0, // 7: users.UpdateResponse.user:type_name -> users.User - 0, // 8: users.ListResponse.users:type_name -> users.User - 0, // 9: users.LoginResponse.user:type_name -> users.User - 0, // 10: users.ValidateResponse.user:type_name -> users.User - 0, // 11: users.ReadResponse.UsersEntry.value:type_name -> users.User - 0, // 12: users.ReadByEmailResponse.UsersEntry.value:type_name -> users.User - 1, // 13: users.Users.Create:input_type -> users.CreateRequest - 3, // 14: users.Users.Read:input_type -> users.ReadRequest - 5, // 15: users.Users.ReadByEmail:input_type -> users.ReadByEmailRequest - 7, // 16: users.Users.Update:input_type -> users.UpdateRequest - 9, // 17: users.Users.Delete:input_type -> users.DeleteRequest - 11, // 18: users.Users.List:input_type -> users.ListRequest - 13, // 19: users.Users.Login:input_type -> users.LoginRequest - 15, // 20: users.Users.Logout:input_type -> users.LogoutRequest - 17, // 21: users.Users.Validate:input_type -> users.ValidateRequest - 2, // 22: users.Users.Create:output_type -> users.CreateResponse - 4, // 23: users.Users.Read:output_type -> users.ReadResponse - 6, // 24: users.Users.ReadByEmail:output_type -> users.ReadByEmailResponse - 8, // 25: users.Users.Update:output_type -> users.UpdateResponse - 10, // 26: users.Users.Delete:output_type -> users.DeleteResponse - 12, // 27: users.Users.List:output_type -> users.ListResponse - 14, // 28: users.Users.Login:output_type -> users.LoginResponse - 16, // 29: users.Users.Logout:output_type -> users.LogoutResponse - 18, // 30: users.Users.Validate:output_type -> users.ValidateResponse - 22, // [22:31] is the sub-list for method output_type - 13, // [13:22] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name -} - -func init() { file_proto_users_proto_init() } -func file_proto_users_proto_init() { - if File_proto_users_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_users_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*User); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadByEmailRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadByEmailResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoginRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoginResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LogoutRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LogoutResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_users_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_users_proto_rawDesc, - NumEnums: 0, - NumMessages: 21, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_users_proto_goTypes, - DependencyIndexes: file_proto_users_proto_depIdxs, - MessageInfos: file_proto_users_proto_msgTypes, - }.Build() - File_proto_users_proto = out.File - file_proto_users_proto_rawDesc = nil - file_proto_users_proto_goTypes = nil - file_proto_users_proto_depIdxs = nil -} diff --git a/users/proto/users.pb.micro.go b/users/proto/users.pb.micro.go deleted file mode 100644 index a966811..0000000 --- a/users/proto/users.pb.micro.go +++ /dev/null @@ -1,236 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/users.proto - -package users - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - _ "google.golang.org/protobuf/types/known/wrapperspb" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Users service - -func NewUsersEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Users service - -type UsersService interface { - Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) - Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) - ReadByEmail(ctx context.Context, in *ReadByEmailRequest, opts ...client.CallOption) (*ReadByEmailResponse, error) - Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) - Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) - List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) - // Login using email and password returns the users profile and a token - Login(ctx context.Context, in *LoginRequest, opts ...client.CallOption) (*LoginResponse, error) - // Logout expires all tokens for the user - Logout(ctx context.Context, in *LogoutRequest, opts ...client.CallOption) (*LogoutResponse, error) - // Validate a token, each time a token is validated it extends its lifetime for another week - Validate(ctx context.Context, in *ValidateRequest, opts ...client.CallOption) (*ValidateResponse, error) -} - -type usersService struct { - c client.Client - name string -} - -func NewUsersService(name string, c client.Client) UsersService { - return &usersService{ - c: c, - name: name, - } -} - -func (c *usersService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { - req := c.c.NewRequest(c.name, "Users.Create", in) - out := new(CreateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { - req := c.c.NewRequest(c.name, "Users.Read", in) - out := new(ReadResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) ReadByEmail(ctx context.Context, in *ReadByEmailRequest, opts ...client.CallOption) (*ReadByEmailResponse, error) { - req := c.c.NewRequest(c.name, "Users.ReadByEmail", in) - out := new(ReadByEmailResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) { - req := c.c.NewRequest(c.name, "Users.Update", in) - out := new(UpdateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { - req := c.c.NewRequest(c.name, "Users.Delete", in) - out := new(DeleteResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { - req := c.c.NewRequest(c.name, "Users.List", in) - out := new(ListResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Login(ctx context.Context, in *LoginRequest, opts ...client.CallOption) (*LoginResponse, error) { - req := c.c.NewRequest(c.name, "Users.Login", in) - out := new(LoginResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Logout(ctx context.Context, in *LogoutRequest, opts ...client.CallOption) (*LogoutResponse, error) { - req := c.c.NewRequest(c.name, "Users.Logout", in) - out := new(LogoutResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *usersService) Validate(ctx context.Context, in *ValidateRequest, opts ...client.CallOption) (*ValidateResponse, error) { - req := c.c.NewRequest(c.name, "Users.Validate", in) - out := new(ValidateResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Users service - -type UsersHandler interface { - Create(context.Context, *CreateRequest, *CreateResponse) error - Read(context.Context, *ReadRequest, *ReadResponse) error - ReadByEmail(context.Context, *ReadByEmailRequest, *ReadByEmailResponse) error - Update(context.Context, *UpdateRequest, *UpdateResponse) error - Delete(context.Context, *DeleteRequest, *DeleteResponse) error - List(context.Context, *ListRequest, *ListResponse) error - // Login using email and password returns the users profile and a token - Login(context.Context, *LoginRequest, *LoginResponse) error - // Logout expires all tokens for the user - Logout(context.Context, *LogoutRequest, *LogoutResponse) error - // Validate a token, each time a token is validated it extends its lifetime for another week - Validate(context.Context, *ValidateRequest, *ValidateResponse) error -} - -func RegisterUsersHandler(s server.Server, hdlr UsersHandler, opts ...server.HandlerOption) error { - type users interface { - Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error - Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error - ReadByEmail(ctx context.Context, in *ReadByEmailRequest, out *ReadByEmailResponse) error - Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error - Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error - List(ctx context.Context, in *ListRequest, out *ListResponse) error - Login(ctx context.Context, in *LoginRequest, out *LoginResponse) error - Logout(ctx context.Context, in *LogoutRequest, out *LogoutResponse) error - Validate(ctx context.Context, in *ValidateRequest, out *ValidateResponse) error - } - type Users struct { - users - } - h := &usersHandler{hdlr} - return s.Handle(s.NewHandler(&Users{h}, opts...)) -} - -type usersHandler struct { - UsersHandler -} - -func (h *usersHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { - return h.UsersHandler.Create(ctx, in, out) -} - -func (h *usersHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { - return h.UsersHandler.Read(ctx, in, out) -} - -func (h *usersHandler) ReadByEmail(ctx context.Context, in *ReadByEmailRequest, out *ReadByEmailResponse) error { - return h.UsersHandler.ReadByEmail(ctx, in, out) -} - -func (h *usersHandler) Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error { - return h.UsersHandler.Update(ctx, in, out) -} - -func (h *usersHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { - return h.UsersHandler.Delete(ctx, in, out) -} - -func (h *usersHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { - return h.UsersHandler.List(ctx, in, out) -} - -func (h *usersHandler) Login(ctx context.Context, in *LoginRequest, out *LoginResponse) error { - return h.UsersHandler.Login(ctx, in, out) -} - -func (h *usersHandler) Logout(ctx context.Context, in *LogoutRequest, out *LogoutResponse) error { - return h.UsersHandler.Logout(ctx, in, out) -} - -func (h *usersHandler) Validate(ctx context.Context, in *ValidateRequest, out *ValidateResponse) error { - return h.UsersHandler.Validate(ctx, in, out) -} diff --git a/users/proto/users.proto b/users/proto/users.proto deleted file mode 100644 index e0fc885..0000000 --- a/users/proto/users.proto +++ /dev/null @@ -1,104 +0,0 @@ -syntax = "proto3"; - -package users; -option go_package = "./proto;users"; -import "google/protobuf/wrappers.proto"; - -service Users { - rpc Create(CreateRequest) returns (CreateResponse) {} - rpc Read(ReadRequest) returns (ReadResponse) {} - rpc ReadByEmail(ReadByEmailRequest) returns (ReadByEmailResponse) {} - rpc Update(UpdateRequest) returns (UpdateResponse) {} - rpc Delete(DeleteRequest) returns (DeleteResponse) {} - rpc List(ListRequest) returns (ListResponse) {} - - // Login using email and password returns the users profile and a token - rpc Login(LoginRequest) returns (LoginResponse) {} - // Logout expires all tokens for the user - rpc Logout(LogoutRequest) returns (LogoutResponse) {} - // Validate a token, each time a token is validated it extends its lifetime for another week - rpc Validate(ValidateRequest) returns (ValidateResponse) {} -} - -message User { - string id = 1; - string first_name = 2; - string last_name = 3; - string email = 4; -} - -message CreateRequest { - string first_name = 1; - string last_name = 2; - string email = 3; - string password = 4; -} - -message CreateResponse { - User user = 1; - string token = 2; -} - -message ReadRequest { - repeated string ids = 1; -} - -message ReadResponse { - map users = 1; -} - -message ReadByEmailRequest { - repeated string emails = 1; -} - -message ReadByEmailResponse { - map users = 1; -} - -message UpdateRequest { - string id = 1; - google.protobuf.StringValue first_name = 2; - google.protobuf.StringValue last_name = 3; - google.protobuf.StringValue email = 4; - google.protobuf.StringValue password = 5; -} - -message UpdateResponse { - User user = 1; -} - -message DeleteRequest { - string id = 1; -} - -message DeleteResponse {} - -message ListRequest {} - -message ListResponse { - repeated User users = 1; -} - -message LoginRequest { - string email = 1; - string password = 2; -} - -message LoginResponse { - User user = 1; - string token = 2; -} - -message LogoutRequest { - string id = 1; -} - -message LogoutResponse {} - -message ValidateRequest { - string token = 1; -} - -message ValidateResponse { - User user = 1; -}