Multitenant streams api (#72)

This commit is contained in:
Dominic Wong
2021-03-18 17:21:41 +00:00
committed by GitHub
parent 28ad626d91
commit 8dfe49f813
87 changed files with 1890 additions and 1064 deletions

View File

@@ -5,6 +5,21 @@ jobs:
test:
name: Test repo
runs-on: ubuntu-latest
container: node:10.18-jessie
services:
postgres:
image: postgres:12.4
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DATABASE: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Set up Go 1.13
uses: actions/setup-go@v1
@@ -23,4 +38,5 @@ jobs:
id: tests
env:
IN_TRAVIS_CI: yes
POSTGRES_URL: postgresql://postgres:postgres@postgres:5432/postgres?sslmode=disable
run: go test -v -p 1 ./...

View File

@@ -11,7 +11,7 @@ proto:
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=. proto/chats.proto
@redoc-cli bundle api-chats.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,6 +1,7 @@
package handler_test
import (
"os"
"testing"
"time"
@@ -8,27 +9,32 @@ import (
pb "github.com/micro/services/chats/proto"
"github.com/stretchr/testify/assert"
"github.com/golang/protobuf/ptypes/timestamp"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func testHandler(t *testing.T) *handler.Chats {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/chats?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS chats, messages CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&handler.Chat{}, &handler.Message{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE chats, messages CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Chats{DB: db, Time: func() time.Time { return time.Unix(1611327673, 0) }}
}
@@ -53,7 +59,13 @@ func assertChatsMatch(t *testing.T, exp, act *pb.Chat) {
return
}
assert.True(t, exp.CreatedAt.AsTime().Equal(act.CreatedAt.AsTime()))
assert.True(t, microSecondTime(exp.CreatedAt).Equal(microSecondTime(act.CreatedAt)))
}
// postgres has a resolution of 100microseconds so just test that it's accurate to the second
func microSecondTime(t *timestamp.Timestamp) time.Time {
tt:=t.AsTime()
return time.Unix(tt.Unix(), int64( tt.Nanosecond() - tt.Nanosecond() % 1000))
}
func assertMessagesMatch(t *testing.T, exp, act *pb.Message) {
@@ -77,6 +89,5 @@ func assertMessagesMatch(t *testing.T, exp, act *pb.Message) {
t.Errorf("SentAt not set")
return
}
assert.True(t, exp.SentAt.AsTime().Equal(act.SentAt.AsTime()))
assert.True(t, microSecondTime(exp.SentAt).Equal(microSecondTime(act.SentAt)))
}

View File

@@ -1,16 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.11.4
// protoc-gen-go v1.25.0
// protoc v3.15.5
// source: proto/chats.proto
package chats
import (
timestamp "github.com/golang/protobuf/ptypes/timestamp"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
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"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
reflect "reflect"
sync "sync"
)
@@ -22,14 +23,18 @@ const (
_ = 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 Chat struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
UserIds []string `protobuf:"bytes,2,rep,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"`
CreatedAt *timestamp.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
UserIds []string `protobuf:"bytes,2,rep,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"`
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
}
func (x *Chat) Reset() {
@@ -78,7 +83,7 @@ func (x *Chat) GetUserIds() []string {
return nil
}
func (x *Chat) GetCreatedAt() *timestamp.Timestamp {
func (x *Chat) GetCreatedAt() *timestamppb.Timestamp {
if x != nil {
return x.CreatedAt
}
@@ -90,11 +95,11 @@ type Message struct {
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"`
ChatId string `protobuf:"bytes,3,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"`
SentAt *timestamp.Timestamp `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`
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"`
ChatId string `protobuf:"bytes,3,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"`
SentAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`
}
func (x *Message) Reset() {
@@ -157,7 +162,7 @@ func (x *Message) GetText() string {
return ""
}
func (x *Message) GetSentAt() *timestamp.Timestamp {
func (x *Message) GetSentAt() *timestamppb.Timestamp {
if x != nil {
return x.SentAt
}
@@ -381,9 +386,9 @@ type ListMessagesRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ChatId string `protobuf:"bytes,1,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
SentBefore *timestamp.Timestamp `protobuf:"bytes,2,opt,name=sent_before,json=sentBefore,proto3" json:"sent_before,omitempty"`
Limit *wrappers.Int32Value `protobuf:"bytes,3,opt,name=limit,proto3" json:"limit,omitempty"`
ChatId string `protobuf:"bytes,1,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
SentBefore *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=sent_before,json=sentBefore,proto3" json:"sent_before,omitempty"`
Limit *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=limit,proto3" json:"limit,omitempty"`
}
func (x *ListMessagesRequest) Reset() {
@@ -425,14 +430,14 @@ func (x *ListMessagesRequest) GetChatId() string {
return ""
}
func (x *ListMessagesRequest) GetSentBefore() *timestamp.Timestamp {
func (x *ListMessagesRequest) GetSentBefore() *timestamppb.Timestamp {
if x != nil {
return x.SentBefore
}
return nil
}
func (x *ListMessagesRequest) GetLimit() *wrappers.Int32Value {
func (x *ListMessagesRequest) GetLimit() *wrapperspb.Int32Value {
if x != nil {
return x.Limit
}
@@ -583,8 +588,8 @@ var file_proto_chats_proto_goTypes = []interface{}{
(*CreateMessageResponse)(nil), // 5: chats.CreateMessageResponse
(*ListMessagesRequest)(nil), // 6: chats.ListMessagesRequest
(*ListMessagesResponse)(nil), // 7: chats.ListMessagesResponse
(*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*wrappers.Int32Value)(nil), // 9: google.protobuf.Int32Value
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*wrapperspb.Int32Value)(nil), // 9: google.protobuf.Int32Value
}
var file_proto_chats_proto_depIdxs = []int32{
8, // 0: chats.Chat.created_at:type_name -> google.protobuf.Timestamp

View File

@@ -6,8 +6,8 @@ package chats
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/timestamppb"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -129,7 +129,7 @@ func main() {
}
// get latest version from github
getVersions := exec.Command("npm", "show", "@micro/services", "time", "--json")
getVersions := exec.Command("npm", "show", "@micro/services", "--time", "--json")
getVersions.Dir = tsPath
outp, err := getVersions.CombinedOutput()
@@ -137,15 +137,20 @@ func main() {
fmt.Println("Failed to get versions of NPM package", string(outp))
os.Exit(1)
}
versions := map[string]interface{}{}
err = json.Unmarshal(outp, &versions)
if err != nil {
fmt.Println("Failed to unmarshal versions", string(outp))
os.Exit(1)
type npmVers struct {
Versions []string `json:"versions"`
}
npmOutput := &npmVers{}
var latest *semver.Version
if len(outp) > 0 {
err = json.Unmarshal(outp, npmOutput)
if err != nil {
fmt.Println("Failed to unmarshal versions", string(outp))
os.Exit(1)
}
}
var latest *semver.Version
for version, _ := range versions {
for _, version := range npmOutput.Versions {
v, err := semver.NewVersion(version)
if err != nil {
fmt.Println("Failed to parse semver", err)
@@ -158,6 +163,9 @@ func main() {
latest = v
}
}
if latest == nil {
latest, _ = semver.NewVersion("0.0.0")
}
newV := latest.IncPatch()
// bump package to latest version

View File

@@ -7,16 +7,16 @@ init:
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/codes.proto
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/codes.proto
.PHONY: build
build:
go build -o codes *.go
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/codes.proto
@redoc-cli bundle api-codes.json
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/codes.proto
@redoc-cli bundle api-protobuf.json
.PHONY: test
test:

View File

@@ -1,6 +1,7 @@
package handler_test
import (
"os"
"testing"
"time"
@@ -11,7 +12,12 @@ import (
func testHandler(t *testing.T) *handler.Codes {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/codes?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}

View File

@@ -1,16 +1,15 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.23.0
// protoc v3.13.0
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/codes.proto
package codes
import (
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
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"
)
@@ -22,17 +21,13 @@ const (
_ = 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 CreateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` // e.g. phone number or email being verified
ExpiresAt *timestamp.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` // expiry time for the code, default 5 minutes
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` // e.g. phone number or email being verified
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` // expiry time for the code, default 5 minutes
}
func (x *CreateRequest) Reset() {
@@ -74,7 +69,7 @@ func (x *CreateRequest) GetIdentity() string {
return ""
}
func (x *CreateRequest) GetExpiresAt() *timestamp.Timestamp {
func (x *CreateRequest) GetExpiresAt() *timestamppb.Timestamp {
if x != nil {
return x.ExpiresAt
}
@@ -249,8 +244,8 @@ var file_proto_codes_proto_rawDesc = []byte{
0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x14, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x56,
0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63,
0x6f, 0x64, 0x65, 0x73, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x42, 0x0d, 0x5a, 0x0b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x6f, 0x64,
0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x73, 0x65, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63,
0x6f, 0x64, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -267,11 +262,11 @@ func file_proto_codes_proto_rawDescGZIP() []byte {
var file_proto_codes_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_proto_codes_proto_goTypes = []interface{}{
(*CreateRequest)(nil), // 0: codes.CreateRequest
(*CreateResponse)(nil), // 1: codes.CreateResponse
(*VerifyRequest)(nil), // 2: codes.VerifyRequest
(*VerifyResponse)(nil), // 3: codes.VerifyResponse
(*timestamp.Timestamp)(nil), // 4: google.protobuf.Timestamp
(*CreateRequest)(nil), // 0: codes.CreateRequest
(*CreateResponse)(nil), // 1: codes.CreateResponse
(*VerifyRequest)(nil), // 2: codes.VerifyRequest
(*VerifyResponse)(nil), // 3: codes.VerifyResponse
(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
}
var file_proto_codes_proto_depIdxs = []int32{
4, // 0: codes.CreateRequest.expires_at:type_name -> google.protobuf.Timestamp

View File

@@ -6,7 +6,7 @@ package codes
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "google.golang.org/protobuf/types/known/timestamppb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package codes;
option go_package = "proto;codes";
option go_package = "./proto;codes";
import "google/protobuf/timestamp.proto";
service Codes {
@@ -23,4 +23,4 @@ message VerifyRequest {
string identity = 2;
}
message VerifyResponse {}
message VerifyResponse {}

View File

@@ -1,290 +1,459 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.15.5
// source: proto/comments.proto
package comments
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
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 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
// 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 Comment struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Post string `protobuf:"bytes,2,opt,name=post,proto3" json:"post,omitempty"`
Author string `protobuf:"bytes,3,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
Created int64 `protobuf:"varint,5,opt,name=created,proto3" json:"created,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Post string `protobuf:"bytes,2,opt,name=post,proto3" json:"post,omitempty"`
Author string `protobuf:"bytes,3,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
Created int64 `protobuf:"varint,5,opt,name=created,proto3" json:"created,omitempty"`
}
func (m *Comment) Reset() { *m = Comment{} }
func (m *Comment) String() string { return proto.CompactTextString(m) }
func (*Comment) ProtoMessage() {}
func (x *Comment) Reset() {
*x = Comment{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_comments_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Comment) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Comment) ProtoMessage() {}
func (x *Comment) ProtoReflect() protoreflect.Message {
mi := &file_proto_comments_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 Comment.ProtoReflect.Descriptor instead.
func (*Comment) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{0}
return file_proto_comments_proto_rawDescGZIP(), []int{0}
}
func (m *Comment) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Comment.Unmarshal(m, b)
}
func (m *Comment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Comment.Marshal(b, m, deterministic)
}
func (m *Comment) XXX_Merge(src proto.Message) {
xxx_messageInfo_Comment.Merge(m, src)
}
func (m *Comment) XXX_Size() int {
return xxx_messageInfo_Comment.Size(m)
}
func (m *Comment) XXX_DiscardUnknown() {
xxx_messageInfo_Comment.DiscardUnknown(m)
}
var xxx_messageInfo_Comment proto.InternalMessageInfo
func (m *Comment) GetId() string {
if m != nil {
return m.Id
func (x *Comment) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (m *Comment) GetPost() string {
if m != nil {
return m.Post
func (x *Comment) GetPost() string {
if x != nil {
return x.Post
}
return ""
}
func (m *Comment) GetAuthor() string {
if m != nil {
return m.Author
func (x *Comment) GetAuthor() string {
if x != nil {
return x.Author
}
return ""
}
func (m *Comment) GetMessage() string {
if m != nil {
return m.Message
func (x *Comment) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
func (m *Comment) GetCreated() int64 {
if m != nil {
return m.Created
func (x *Comment) GetCreated() int64 {
if x != nil {
return x.Created
}
return 0
}
type NewRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// post id
Post string `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"`
// message to leave
Author string `protobuf:"bytes,2,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Author string `protobuf:"bytes,2,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
}
func (m *NewRequest) Reset() { *m = NewRequest{} }
func (m *NewRequest) String() string { return proto.CompactTextString(m) }
func (*NewRequest) ProtoMessage() {}
func (x *NewRequest) Reset() {
*x = NewRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_comments_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NewRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewRequest) ProtoMessage() {}
func (x *NewRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_comments_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 NewRequest.ProtoReflect.Descriptor instead.
func (*NewRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{1}
return file_proto_comments_proto_rawDescGZIP(), []int{1}
}
func (m *NewRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewRequest.Unmarshal(m, b)
}
func (m *NewRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewRequest.Marshal(b, m, deterministic)
}
func (m *NewRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewRequest.Merge(m, src)
}
func (m *NewRequest) XXX_Size() int {
return xxx_messageInfo_NewRequest.Size(m)
}
func (m *NewRequest) XXX_DiscardUnknown() {
xxx_messageInfo_NewRequest.DiscardUnknown(m)
}
var xxx_messageInfo_NewRequest proto.InternalMessageInfo
func (m *NewRequest) GetPost() string {
if m != nil {
return m.Post
func (x *NewRequest) GetPost() string {
if x != nil {
return x.Post
}
return ""
}
func (m *NewRequest) GetAuthor() string {
if m != nil {
return m.Author
func (x *NewRequest) GetAuthor() string {
if x != nil {
return x.Author
}
return ""
}
func (m *NewRequest) GetMessage() string {
if m != nil {
return m.Message
func (x *NewRequest) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type NewResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (m *NewResponse) Reset() { *m = NewResponse{} }
func (m *NewResponse) String() string { return proto.CompactTextString(m) }
func (*NewResponse) ProtoMessage() {}
func (x *NewResponse) Reset() {
*x = NewResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_comments_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NewResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewResponse) ProtoMessage() {}
func (x *NewResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_comments_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 NewResponse.ProtoReflect.Descriptor instead.
func (*NewResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{2}
return file_proto_comments_proto_rawDescGZIP(), []int{2}
}
func (m *NewResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewResponse.Unmarshal(m, b)
}
func (m *NewResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewResponse.Marshal(b, m, deterministic)
}
func (m *NewResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewResponse.Merge(m, src)
}
func (m *NewResponse) XXX_Size() int {
return xxx_messageInfo_NewResponse.Size(m)
}
func (m *NewResponse) XXX_DiscardUnknown() {
xxx_messageInfo_NewResponse.DiscardUnknown(m)
}
var xxx_messageInfo_NewResponse proto.InternalMessageInfo
type ListRequest struct {
Post string `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Post string `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"`
}
func (m *ListRequest) Reset() { *m = ListRequest{} }
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
func (*ListRequest) ProtoMessage() {}
func (x *ListRequest) Reset() {
*x = ListRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_comments_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_comments_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 fileDescriptor_44070930b213c2b7, []int{3}
return file_proto_comments_proto_rawDescGZIP(), []int{3}
}
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
func (m *ListRequest) GetPost() string {
if m != nil {
return m.Post
func (x *ListRequest) GetPost() string {
if x != nil {
return x.Post
}
return ""
}
type ListResponse struct {
Comments []*Comment `protobuf:"bytes,1,rep,name=comments,proto3" json:"comments,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Comments []*Comment `protobuf:"bytes,1,rep,name=comments,proto3" json:"comments,omitempty"`
}
func (m *ListResponse) Reset() { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage() {}
func (x *ListResponse) Reset() {
*x = ListResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_comments_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_comments_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 fileDescriptor_44070930b213c2b7, []int{4}
return file_proto_comments_proto_rawDescGZIP(), []int{4}
}
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) GetComments() []*Comment {
if m != nil {
return m.Comments
func (x *ListResponse) GetComments() []*Comment {
if x != nil {
return x.Comments
}
return nil
}
func init() {
proto.RegisterType((*Comment)(nil), "comments.Comment")
proto.RegisterType((*NewRequest)(nil), "comments.NewRequest")
proto.RegisterType((*NewResponse)(nil), "comments.NewResponse")
proto.RegisterType((*ListRequest)(nil), "comments.ListRequest")
proto.RegisterType((*ListResponse)(nil), "comments.ListResponse")
var File_proto_comments_proto protoreflect.FileDescriptor
var file_proto_comments_proto_rawDesc = []byte{
0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73,
0x22, 0x79, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70,
0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12,
0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01,
0x28, 0x03, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x52, 0x0a, 0x0a, 0x4e,
0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x16, 0x0a,
0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
0x0d, 0x0a, 0x0b, 0x4e, 0x65, 0x77, 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, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x73,
0x74, 0x22, 0x3d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x2d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43,
0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73,
0x32, 0x79, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x03,
0x4e, 0x65, 0x77, 0x12, 0x14, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4e,
0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x37, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
func init() {
proto.RegisterFile("proto/comments.proto", fileDescriptor_44070930b213c2b7)
var (
file_proto_comments_proto_rawDescOnce sync.Once
file_proto_comments_proto_rawDescData = file_proto_comments_proto_rawDesc
)
func file_proto_comments_proto_rawDescGZIP() []byte {
file_proto_comments_proto_rawDescOnce.Do(func() {
file_proto_comments_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_comments_proto_rawDescData)
})
return file_proto_comments_proto_rawDescData
}
var fileDescriptor_44070930b213c2b7 = []byte{
// 253 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x51, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x25, 0x71, 0x68, 0xcb, 0x05, 0x90, 0x38, 0x95, 0xca, 0xea, 0x04, 0x9e, 0xba, 0x50, 0xa4,
0x82, 0xc4, 0xc4, 0xc4, 0x8a, 0x18, 0xfc, 0x07, 0xa1, 0x3d, 0x41, 0x87, 0xd4, 0x21, 0xe7, 0x0a,
0xf5, 0xef, 0x71, 0x1d, 0x3b, 0x0d, 0x11, 0x74, 0xbb, 0xf7, 0xee, 0xdd, 0xbd, 0xf3, 0x33, 0x8c,
0xab, 0xda, 0x58, 0x73, 0xbf, 0x34, 0x65, 0x49, 0x1b, 0xcb, 0x73, 0x0f, 0x71, 0x14, 0xb1, 0xda,
0xc1, 0xf0, 0xa5, 0xa9, 0xf1, 0x12, 0xd2, 0xf5, 0x4a, 0x26, 0x37, 0xc9, 0xec, 0x4c, 0xbb, 0x0a,
0x11, 0xb2, 0xca, 0xb0, 0x95, 0xa9, 0x67, 0x7c, 0x8d, 0x13, 0x18, 0x14, 0x5b, 0xfb, 0x69, 0x6a,
0x29, 0x3c, 0x1b, 0x10, 0x4a, 0x18, 0x96, 0xc4, 0x5c, 0x7c, 0x90, 0xcc, 0x7c, 0x23, 0xc2, 0x7d,
0x67, 0x59, 0x53, 0x61, 0x69, 0x25, 0x4f, 0x5d, 0x47, 0xe8, 0x08, 0x95, 0x06, 0x78, 0xa3, 0x6f,
0x4d, 0x5f, 0x5b, 0x72, 0x9b, 0xa3, 0x5b, 0xf2, 0xa7, 0x5b, 0xfa, 0x9f, 0x9b, 0xf8, 0xe5, 0xa6,
0x2e, 0x20, 0xf7, 0x3b, 0xb9, 0x32, 0x1b, 0x26, 0x75, 0x0b, 0xf9, 0xeb, 0x9a, 0xed, 0x11, 0x0f,
0xf5, 0x0c, 0xe7, 0x8d, 0xa4, 0x19, 0xc1, 0x3b, 0x68, 0xc3, 0x71, 0x3a, 0x31, 0xcb, 0x17, 0x57,
0xf3, 0x36, 0xbd, 0x10, 0x95, 0x6e, 0x25, 0x8b, 0x1d, 0x8c, 0x02, 0xc9, 0xf8, 0x08, 0xc2, 0x99,
0xe3, 0xf8, 0xa0, 0x3f, 0xbc, 0x6f, 0x7a, 0xdd, 0x63, 0xc3, 0x85, 0x27, 0xf8, 0x04, 0xd9, 0xfe,
0x00, 0xec, 0x08, 0x3a, 0x37, 0x4f, 0x27, 0x7d, 0x3a, 0x0e, 0xbe, 0x0f, 0xfc, 0x5f, 0x3e, 0xfc,
0x04, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x0c, 0xe5, 0xcc, 0xe3, 0x01, 0x00, 0x00,
var file_proto_comments_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proto_comments_proto_goTypes = []interface{}{
(*Comment)(nil), // 0: comments.Comment
(*NewRequest)(nil), // 1: comments.NewRequest
(*NewResponse)(nil), // 2: comments.NewResponse
(*ListRequest)(nil), // 3: comments.ListRequest
(*ListResponse)(nil), // 4: comments.ListResponse
}
var file_proto_comments_proto_depIdxs = []int32{
0, // 0: comments.ListResponse.comments:type_name -> comments.Comment
1, // 1: comments.Comments.New:input_type -> comments.NewRequest
3, // 2: comments.Comments.List:input_type -> comments.ListRequest
2, // 3: comments.Comments.New:output_type -> comments.NewResponse
4, // 4: comments.Comments.List:output_type -> comments.ListResponse
3, // [3:5] is the sub-list for method output_type
1, // [1:3] 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_comments_proto_init() }
func file_proto_comments_proto_init() {
if File_proto_comments_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_comments_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Comment); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_comments_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_comments_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_comments_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_comments_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
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_comments_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_comments_proto_goTypes,
DependencyIndexes: file_proto_comments_proto_depIdxs,
MessageInfos: file_proto_comments_proto_msgTypes,
}.Build()
File_proto_comments_proto = out.File
file_proto_comments_proto_rawDesc = nil
file_proto_comments_proto_goTypes = nil
file_proto_comments_proto_depIdxs = nil
}

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package comments;
option go_package = "proto;comments";
option go_package = "./proto;comments";
service Comments {
rpc New(NewRequest) returns (NewResponse) {}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/datastore.proto
package datastore

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package datastore;
option go_package = "proto;datastore";
option go_package = "./proto;datastore";
// These endpoints are experimental and will likely change,
// especially related to indexes.
@@ -109,4 +109,4 @@ message CreateIndexRequest {
message CreateIndexResponse {
}
}

View File

@@ -14,7 +14,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/etas.proto
@redoc-cli bundle api-etas.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,16 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/etas.proto
package etas
import (
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
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"
)
@@ -114,7 +114,7 @@ type Route struct {
Waypoints []*Point `protobuf:"bytes,2,rep,name=waypoints,proto3" json:"waypoints,omitempty"`
// start time specifies the time the vehicle will arrive at the pickup. If no value is provided,
// the current time will be used
StartTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
StartTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
}
func (x *Route) Reset() {
@@ -163,7 +163,7 @@ func (x *Route) GetWaypoints() []*Point {
return nil
}
func (x *Route) GetStartTime() *timestamp.Timestamp {
func (x *Route) GetStartTime() *timestamppb.Timestamp {
if x != nil {
return x.StartTime
}
@@ -224,8 +224,8 @@ type ETA struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
EstimatedArrivalTime *timestamp.Timestamp `protobuf:"bytes,1,opt,name=estimated_arrival_time,json=estimatedArrivalTime,proto3" json:"estimated_arrival_time,omitempty"`
EstimatedDepartureTime *timestamp.Timestamp `protobuf:"bytes,2,opt,name=estimated_departure_time,json=estimatedDepartureTime,proto3" json:"estimated_departure_time,omitempty"`
EstimatedArrivalTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=estimated_arrival_time,json=estimatedArrivalTime,proto3" json:"estimated_arrival_time,omitempty"`
EstimatedDepartureTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=estimated_departure_time,json=estimatedDepartureTime,proto3" json:"estimated_departure_time,omitempty"`
}
func (x *ETA) Reset() {
@@ -260,14 +260,14 @@ func (*ETA) Descriptor() ([]byte, []int) {
return file_proto_etas_proto_rawDescGZIP(), []int{3}
}
func (x *ETA) GetEstimatedArrivalTime() *timestamp.Timestamp {
func (x *ETA) GetEstimatedArrivalTime() *timestamppb.Timestamp {
if x != nil {
return x.EstimatedArrivalTime
}
return nil
}
func (x *ETA) GetEstimatedDepartureTime() *timestamp.Timestamp {
func (x *ETA) GetEstimatedDepartureTime() *timestamppb.Timestamp {
if x != nil {
return x.EstimatedDepartureTime
}
@@ -337,12 +337,12 @@ func file_proto_etas_proto_rawDescGZIP() []byte {
var file_proto_etas_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proto_etas_proto_goTypes = []interface{}{
(*Point)(nil), // 0: etas.Point
(*Route)(nil), // 1: etas.Route
(*Response)(nil), // 2: etas.Response
(*ETA)(nil), // 3: etas.ETA
nil, // 4: etas.Response.PointsEntry
(*timestamp.Timestamp)(nil), // 5: google.protobuf.Timestamp
(*Point)(nil), // 0: etas.Point
(*Route)(nil), // 1: etas.Route
(*Response)(nil), // 2: etas.Response
(*ETA)(nil), // 3: etas.ETA
nil, // 4: etas.Response.PointsEntry
(*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp
}
var file_proto_etas_proto_depIdxs = []int32{
0, // 0: etas.Route.pickup:type_name -> etas.Point

View File

@@ -6,7 +6,7 @@ package etas
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "google.golang.org/protobuf/types/known/timestamppb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package etas;
option go_package = "proto;etas";
option go_package = "./proto;etas";
import "google/protobuf/timestamp.proto";
@@ -41,4 +41,4 @@ message Response {
message ETA {
google.protobuf.Timestamp estimated_arrival_time = 1;
google.protobuf.Timestamp estimated_departure_time = 2;
}
}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/feeds.proto
package feeds

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package feeds;
option go_package = "proto;feeds";
option go_package = "./proto;feeds";
service Feeds {
rpc Add(AddRequest) returns (AddResponse) {}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/files.proto
package files

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package files;
option go_package = "proto;files";
option go_package = "./proto;files";
service Files {
rpc Save(SaveRequest) returns (SaveResponse) {}
@@ -48,4 +48,4 @@ message ListRequest {
message ListResponse {
repeated File files = 1;
}
}

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/geocoding.proto
@redoc-cli bundle api-geocoding.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,16 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/geocoding.proto
package geocoding
import (
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
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"
)
@@ -126,8 +126,8 @@ type Coordinates struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Latitude *wrappers.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
Latitude *wrapperspb.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrapperspb.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
}
func (x *Coordinates) Reset() {
@@ -162,14 +162,14 @@ func (*Coordinates) Descriptor() ([]byte, []int) {
return file_proto_geocoding_proto_rawDescGZIP(), []int{1}
}
func (x *Coordinates) GetLatitude() *wrappers.DoubleValue {
func (x *Coordinates) GetLatitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Latitude
}
return nil
}
func (x *Coordinates) GetLongitude() *wrappers.DoubleValue {
func (x *Coordinates) GetLongitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Longitude
}
@@ -230,9 +230,9 @@ func file_proto_geocoding_proto_rawDescGZIP() []byte {
var file_proto_geocoding_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_geocoding_proto_goTypes = []interface{}{
(*Address)(nil), // 0: geocoding.Address
(*Coordinates)(nil), // 1: geocoding.Coordinates
(*wrappers.DoubleValue)(nil), // 2: google.protobuf.DoubleValue
(*Address)(nil), // 0: geocoding.Address
(*Coordinates)(nil), // 1: geocoding.Coordinates
(*wrapperspb.DoubleValue)(nil), // 2: google.protobuf.DoubleValue
}
var file_proto_geocoding_proto_depIdxs = []int32{
2, // 0: geocoding.Coordinates.latitude:type_name -> google.protobuf.DoubleValue

View File

@@ -6,7 +6,7 @@ package geocoding
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package geocoding;
option go_package = "proto;geocoding";
option go_package = "./proto;geocoding";
import "google/protobuf/wrappers.proto";
@@ -25,4 +25,4 @@ message Address {
message Coordinates {
google.protobuf.DoubleValue latitude = 1;
google.protobuf.DoubleValue longitude = 2;
}
}

6
go.mod
View File

@@ -7,12 +7,12 @@ require (
github.com/PuerkitoBio/goquery v1.6.1
github.com/SlyMarbo/rss v1.0.1
github.com/getkin/kin-openapi v0.26.0
github.com/golang/protobuf v1.4.3
github.com/golang/protobuf v1.5.1
github.com/google/uuid v1.1.2
github.com/gosimple/slug v1.9.0
github.com/hailocab/go-geoindex v0.0.0-20160127134810-64631bfe9711
github.com/micro/dev v0.0.0-20201117163752-d3cfc9788dfa
github.com/micro/micro/v3 v3.1.1-0.20210301204023-e0e966d08c06
github.com/micro/micro/v3 v3.1.2-0.20210311170414-40583563ada6
github.com/miekg/dns v1.1.31 // indirect
github.com/stoewer/go-strcase v1.2.0
github.com/stretchr/testify v1.6.1
@@ -23,7 +23,7 @@ require (
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
google.golang.org/genproto v0.0.0-20201001141541-efaab9d3c4f7 // indirect
google.golang.org/grpc v1.32.0 // indirect
google.golang.org/protobuf v1.25.0
google.golang.org/protobuf v1.26.0
googlemaps.github.io/maps v1.3.1
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
gorm.io/driver/postgres v1.0.6

51
go.sum
View File

@@ -74,17 +74,23 @@ github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkN
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/caddyserver/certmagic v0.10.6 h1:sCya6FmfaN74oZE46kqfaFOVoROD/mF36rTQfjN7TZc=
github.com/caddyserver/certmagic v0.10.6/go.mod h1:Y8jcUBctgk/IhpAzlHKfimZNyXCkfGgRTC0orl8gROQ=
github.com/cenkalti/backoff/v4 v4.0.0 h1:6VeaLF9aI+MAUQ95106HwWzYZgJJpZ4stumjj6RFYAU=
github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY=
github.com/cloudflare/cloudflare-go v0.10.9 h1:d8KOgLpYiC+Xq3T4tuO+/goM+RZvuO+T4pojuv8giL8=
github.com/cloudflare/cloudflare-go v0.10.9/go.mod h1:5TrsWH+3f4NV6WjtS5QFp+DifH81rph40gU374Sh0dQ=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -104,21 +110,25 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch/v5 v5.0.0 h1:dKTrUeykyQwKb/kx7Z+4ukDs6l+4L41HqG1XHnhX7WE=
github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getkin/kin-openapi v0.26.0 h1:xKIW5Z5wAfutxGBH+rr9qu0Ywfb/E1bPWkYLKRYfEuU=
github.com/getkin/kin-openapi v0.26.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v3 v3.4.0 h1:deB9NkelA+TfjGHVw8J7iKl/rMtffcGMWSMmptvMv0A=
github.com/go-acme/lego/v3 v3.4.0/go.mod h1:xYbLDuxq3Hy4bMUT1t9JIuz6GWIWb3m5X+TeTHYaT7M=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@@ -133,13 +143,16 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.3/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -163,6 +176,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -172,7 +188,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo=
github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
@@ -196,8 +214,10 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -207,8 +227,10 @@ github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hailocab/go-geoindex v0.0.0-20160127134810-64631bfe9711 h1:Oi8hPOZX0gaM2sPVXse2bMpfOjP47a7O61YuB6Z4sGk=
github.com/hailocab/go-geoindex v0.0.0-20160127134810-64631bfe9711/go.mod h1:+v2qJ3UZe4q2GfgZO4od004F/cMgJbmPSs7dD/ZMUkY=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
@@ -238,6 +260,7 @@ github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
@@ -292,22 +315,26 @@ github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b/go.mod h1:HMcgvsgd0Fjj
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA=
github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ=
@@ -323,18 +350,15 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/micro/dev v0.0.0-20201117163752-d3cfc9788dfa h1:1BoFPE4/NTF7WKLZWsEFImOsN143QAU7Dkw9J2/qFXA=
github.com/micro/dev v0.0.0-20201117163752-d3cfc9788dfa/go.mod h1:j/8E+ezN/ij7a9BXBHMKmLayFfUW1O4h/Owdv67B0X0=
github.com/micro/micro/v3 v3.0.0-beta.6.0.20201016094841-ca8ffd563b2b/go.mod h1:RPJTp9meQAppzW/9jgQtfJmPpRJAySVPbz9uur4B3Ko=
github.com/micro/micro/v3 v3.0.5-0.20210202220323-c0f344d21cc6 h1:lK6mPBqHUIDjcRIUWSwsjKUkug1HSqK1J+FmGSHVYjQ=
github.com/micro/micro/v3 v3.0.5-0.20210202220323-c0f344d21cc6/go.mod h1:+WoC+lHuRy8FIgJlNuLkhpmsFbylYb0vYcEgMpKT4Z4=
github.com/micro/micro/v3 v3.0.5-0.20210205114115-75aad3b94f08 h1:HPklGdPFUPQAG5YMQi1n8R3LBqhlWj0SzVz2W9EdwAo=
github.com/micro/micro/v3 v3.0.5-0.20210205114115-75aad3b94f08/go.mod h1:+WoC+lHuRy8FIgJlNuLkhpmsFbylYb0vYcEgMpKT4Z4=
github.com/micro/micro/v3 v3.1.1-0.20210301204023-e0e966d08c06 h1:Kiegspe4Ea6hwyVWbDD6zf/DXpiVyyB2XgZuxAXGwtA=
github.com/micro/micro/v3 v3.1.1-0.20210301204023-e0e966d08c06/go.mod h1:+cr/21X4agxmBxMuztg/LOFrNBk9xLVJNq4UofWNWic=
github.com/micro/micro/v3 v3.1.2-0.20210311170414-40583563ada6 h1:uilKEf27gjxx/ZL0wdRGsKmjZJtm/PNEyG/RT4L0pzw=
github.com/micro/micro/v3 v3.1.2-0.20210311170414-40583563ada6/go.mod h1:+cr/21X4agxmBxMuztg/LOFrNBk9xLVJNq4UofWNWic=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
@@ -349,9 +373,11 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
@@ -359,12 +385,15 @@ github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.3/go.mod h1:YZeBtGzYYEsCHp2LST/u/0NDwGkRoBtmn1cIWCJiS6M=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
@@ -412,9 +441,12 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516 h1:ofR1ZdrNSkiWcMsRrubK9tb2/SlZVWttAfqUjJi6QYc=
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -438,6 +470,7 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw=
github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
@@ -451,10 +484,12 @@ github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
github.com/xanzy/go-gitlab v0.35.1 h1:jJSgT0NxjCvrSZf7Gvn2NxxV9xAYkTjYrKW8XwWhrfY=
github.com/xanzy/go-gitlab v0.35.1/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -760,6 +795,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
googlemaps.github.io/maps v1.3.1 h1:VYFiLFgZyDVFYjPKLedOWxjmrwuaJFAc4EhqGNZfX40=
googlemaps.github.io/maps v1.3.1/go.mod h1:cCq0JKYAnnCRSdiaBi7Ex9CW15uxIAk7oPi8V/xEh6s=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@@ -780,6 +818,7 @@ gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiV
gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y=
gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=

View File

@@ -2,6 +2,7 @@ package handler_test
import (
"context"
"os"
"sort"
"testing"
@@ -15,21 +16,25 @@ import (
func testHandler(t *testing.T) *handler.Groups {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/groups?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS groups, memberships CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&handler.Group{}, &handler.Membership{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE groups CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Groups{DB: db}
}
func TestCreate(t *testing.T) {

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/groups.proto
package groups

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package groups;
option go_package = "proto;groups";
option go_package = "./proto;groups";
service Groups {
// Create a group
@@ -78,4 +78,4 @@ message RemoveMemberRequest {
string member_id = 2;
}
message RemoveMemberResponse {}
message RemoveMemberResponse {}

View File

@@ -1,123 +1,211 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/services/helloworld/proto/helloworld.proto
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/helloworld.proto
package helloworld
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// 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
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 Request struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Request) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
mi := &file_proto_helloworld_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 Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
return fileDescriptor_db677fb74c3ffc82, []int{0}
return file_proto_helloworld_proto_rawDescGZIP(), []int{0}
}
func (m *Request) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Request.Unmarshal(m, b)
}
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
}
func (m *Request) XXX_Merge(src proto.Message) {
xxx_messageInfo_Request.Merge(m, src)
}
func (m *Request) XXX_Size() int {
return xxx_messageInfo_Request.Size(m)
}
func (m *Request) XXX_DiscardUnknown() {
xxx_messageInfo_Request.DiscardUnknown(m)
}
var xxx_messageInfo_Request proto.InternalMessageInfo
func (m *Request) GetName() string {
if m != nil {
return m.Name
func (x *Request) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type Response struct {
Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (x *Response) Reset() {
*x = Response{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_helloworld_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Response) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Response) ProtoMessage() {}
func (x *Response) ProtoReflect() protoreflect.Message {
mi := &file_proto_helloworld_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 Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
return fileDescriptor_db677fb74c3ffc82, []int{1}
return file_proto_helloworld_proto_rawDescGZIP(), []int{1}
}
func (m *Response) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Response.Unmarshal(m, b)
}
func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Response.Marshal(b, m, deterministic)
}
func (m *Response) XXX_Merge(src proto.Message) {
xxx_messageInfo_Response.Merge(m, src)
}
func (m *Response) XXX_Size() int {
return xxx_messageInfo_Response.Size(m)
}
func (m *Response) XXX_DiscardUnknown() {
xxx_messageInfo_Response.DiscardUnknown(m)
}
var xxx_messageInfo_Response proto.InternalMessageInfo
func (m *Response) GetMsg() string {
if m != nil {
return m.Msg
func (x *Response) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
func init() {
proto.RegisterType((*Request)(nil), "helloworld.Request")
proto.RegisterType((*Response)(nil), "helloworld.Response")
var File_proto_helloworld_proto protoreflect.FileDescriptor
var file_proto_helloworld_proto_rawDesc = []byte{
0x0a, 0x16, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72,
0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,
0x6f, 0x72, 0x6c, 0x64, 0x22, 0x1d, 0x0a, 0x07, 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, 0x1c, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73,
0x67, 0x32, 0x41, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x12,
0x33, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x13, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,
0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68,
0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x14, 0x5a, 0x12, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b,
0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
func init() {
proto.RegisterFile("github.com/micro/services/helloworld/proto/helloworld.proto", fileDescriptor_db677fb74c3ffc82)
var (
file_proto_helloworld_proto_rawDescOnce sync.Once
file_proto_helloworld_proto_rawDescData = file_proto_helloworld_proto_rawDesc
)
func file_proto_helloworld_proto_rawDescGZIP() []byte {
file_proto_helloworld_proto_rawDescOnce.Do(func() {
file_proto_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_helloworld_proto_rawDescData)
})
return file_proto_helloworld_proto_rawDescData
}
var fileDescriptor_db677fb74c3ffc82 = []byte{
// 163 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4e, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xcd, 0x4c, 0x2e, 0xca, 0xd7, 0x2f, 0x4e, 0x2d,
0x2a, 0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0xcf, 0x48, 0xcd, 0xc9, 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49,
0xd1, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x47, 0x12, 0xd0, 0x03, 0x0b, 0x08, 0x71, 0x21, 0x44, 0x94,
0x64, 0xb9, 0xd8, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12,
0x73, 0x53, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x25, 0x19, 0x2e, 0x8e, 0xa0,
0xd4, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0x21, 0x01, 0x2e, 0xe6, 0xdc, 0xe2, 0x74, 0xa8, 0x34,
0x88, 0x69, 0xe4, 0xc8, 0xc5, 0xe5, 0x01, 0x37, 0x4a, 0xc8, 0x98, 0x8b, 0xc5, 0x39, 0x31, 0x27,
0x47, 0x48, 0x58, 0x0f, 0xc9, 0x46, 0xa8, 0xe1, 0x52, 0x22, 0xa8, 0x82, 0x10, 0x23, 0x95, 0x18,
0x92, 0xd8, 0xc0, 0x4e, 0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x03, 0x31, 0x86, 0xda, 0xd1,
0x00, 0x00, 0x00,
var file_proto_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_helloworld_proto_goTypes = []interface{}{
(*Request)(nil), // 0: helloworld.Request
(*Response)(nil), // 1: helloworld.Response
}
var file_proto_helloworld_proto_depIdxs = []int32{
0, // 0: helloworld.Helloworld.Call:input_type -> helloworld.Request
1, // 1: helloworld.Helloworld.Call:output_type -> helloworld.Response
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_proto_helloworld_proto_init() }
func file_proto_helloworld_proto_init() {
if File_proto_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Response); 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_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_helloworld_proto_goTypes,
DependencyIndexes: file_proto_helloworld_proto_depIdxs,
MessageInfos: file_proto_helloworld_proto_msgTypes,
}.Build()
File_proto_helloworld_proto = out.File
file_proto_helloworld_proto_rawDesc = nil
file_proto_helloworld_proto_goTypes = nil
file_proto_helloworld_proto_depIdxs = nil
}

View File

@@ -1,5 +1,5 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/services/helloworld/proto/helloworld.proto
// source: proto/helloworld.proto
package helloworld

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package helloworld;
option go_package = "proto;helloworld";
option go_package = "./proto;helloworld";
service Helloworld {
rpc Call(Request) returns (Response) {}

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/invites.proto
@redoc-cli bundle api-invites.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -2,12 +2,12 @@ package handler_test
import (
"context"
"os"
"testing"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/micro/services/invites/handler"
pb "github.com/micro/services/invites/proto"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
@@ -17,21 +17,25 @@ import (
func testHandler(t *testing.T) *handler.Invites {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/invites?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS invites CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&handler.Invite{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE invites CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Invites{DB: db}
}

View File

@@ -1,16 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/invites.proto
package invites
import (
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
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"
)
@@ -204,8 +204,8 @@ type ReadRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id *wrappers.StringValue `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Code *wrappers.StringValue `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
Id *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Code *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
}
func (x *ReadRequest) Reset() {
@@ -240,14 +240,14 @@ func (*ReadRequest) Descriptor() ([]byte, []int) {
return file_proto_invites_proto_rawDescGZIP(), []int{3}
}
func (x *ReadRequest) GetId() *wrappers.StringValue {
func (x *ReadRequest) GetId() *wrapperspb.StringValue {
if x != nil {
return x.Id
}
return nil
}
func (x *ReadRequest) GetCode() *wrappers.StringValue {
func (x *ReadRequest) GetCode() *wrapperspb.StringValue {
if x != nil {
return x.Code
}
@@ -306,8 +306,8 @@ type ListRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
GroupId *wrappers.StringValue `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
Email *wrappers.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
GroupId *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
Email *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
}
func (x *ListRequest) Reset() {
@@ -342,14 +342,14 @@ func (*ListRequest) Descriptor() ([]byte, []int) {
return file_proto_invites_proto_rawDescGZIP(), []int{5}
}
func (x *ListRequest) GetGroupId() *wrappers.StringValue {
func (x *ListRequest) GetGroupId() *wrapperspb.StringValue {
if x != nil {
return x.GroupId
}
return nil
}
func (x *ListRequest) GetEmail() *wrappers.StringValue {
func (x *ListRequest) GetEmail() *wrapperspb.StringValue {
if x != nil {
return x.Email
}
@@ -567,16 +567,16 @@ func file_proto_invites_proto_rawDescGZIP() []byte {
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
(*wrappers.StringValue)(nil), // 9: google.protobuf.StringValue
(*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
(*wrapperspb.StringValue)(nil), // 9: google.protobuf.StringValue
}
var file_proto_invites_proto_depIdxs = []int32{
0, // 0: invites.CreateResponse.invite:type_name -> invites.Invite

View File

@@ -6,7 +6,7 @@ package invites
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package invites;
option go_package = "proto;invites";
option go_package = "./proto;invites";
import "google/protobuf/wrappers.proto";
service Invites {
@@ -53,4 +53,4 @@ message DeleteRequest {
string id = 1;
}
message DeleteResponse {}
message DeleteResponse {}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/location.proto
// The location service stores GPS points for tracking purposes

View File

@@ -1,6 +1,6 @@
syntax = "proto3";
option go_package = "proto;location";
option go_package = "./proto;location";
// The location service stores GPS points for tracking purposes
// and provides endpoints to query those points.

View File

@@ -1,386 +1,603 @@
// 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 (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
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 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
// 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 {
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"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
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 (m *Message) Reset() { *m = Message{} }
func (m *Message) String() string { return proto.CompactTextString(m) }
func (*Message) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{0}
return file_proto_mail_proto_rawDescGZIP(), []int{0}
}
func (m *Message) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Message.Unmarshal(m, b)
}
func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Message.Marshal(b, m, deterministic)
}
func (m *Message) XXX_Merge(src proto.Message) {
xxx_messageInfo_Message.Merge(m, src)
}
func (m *Message) XXX_Size() int {
return xxx_messageInfo_Message.Size(m)
}
func (m *Message) XXX_DiscardUnknown() {
xxx_messageInfo_Message.DiscardUnknown(m)
}
var xxx_messageInfo_Message proto.InternalMessageInfo
func (m *Message) GetId() string {
if m != nil {
return m.Id
func (x *Message) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (m *Message) GetTo() string {
if m != nil {
return m.To
func (x *Message) GetTo() string {
if x != nil {
return x.To
}
return ""
}
func (m *Message) GetFrom() string {
if m != nil {
return m.From
func (x *Message) GetFrom() string {
if x != nil {
return x.From
}
return ""
}
func (m *Message) GetSubject() string {
if m != nil {
return m.Subject
func (x *Message) GetSubject() string {
if x != nil {
return x.Subject
}
return ""
}
func (m *Message) GetText() string {
if m != nil {
return m.Text
func (x *Message) GetText() string {
if x != nil {
return x.Text
}
return ""
}
func (m *Message) GetSentAt() int64 {
if m != nil {
return m.SentAt
func (x *Message) GetSentAt() int64 {
if x != nil {
return x.SentAt
}
return 0
}
type SendRequest struct {
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"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
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 (m *SendRequest) Reset() { *m = SendRequest{} }
func (m *SendRequest) String() string { return proto.CompactTextString(m) }
func (*SendRequest) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{1}
return file_proto_mail_proto_rawDescGZIP(), []int{1}
}
func (m *SendRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendRequest.Unmarshal(m, b)
}
func (m *SendRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SendRequest.Marshal(b, m, deterministic)
}
func (m *SendRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SendRequest.Merge(m, src)
}
func (m *SendRequest) XXX_Size() int {
return xxx_messageInfo_SendRequest.Size(m)
}
func (m *SendRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SendRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SendRequest proto.InternalMessageInfo
func (m *SendRequest) GetTo() string {
if m != nil {
return m.To
func (x *SendRequest) GetTo() string {
if x != nil {
return x.To
}
return ""
}
func (m *SendRequest) GetFrom() string {
if m != nil {
return m.From
func (x *SendRequest) GetFrom() string {
if x != nil {
return x.From
}
return ""
}
func (m *SendRequest) GetSubject() string {
if m != nil {
return m.Subject
func (x *SendRequest) GetSubject() string {
if x != nil {
return x.Subject
}
return ""
}
func (m *SendRequest) GetText() string {
if m != nil {
return m.Text
func (x *SendRequest) GetText() string {
if x != nil {
return x.Text
}
return ""
}
type SendResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (m *SendResponse) Reset() { *m = SendResponse{} }
func (m *SendResponse) String() string { return proto.CompactTextString(m) }
func (*SendResponse) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{2}
return file_proto_mail_proto_rawDescGZIP(), []int{2}
}
func (m *SendResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendResponse.Unmarshal(m, b)
}
func (m *SendResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SendResponse.Marshal(b, m, deterministic)
}
func (m *SendResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SendResponse.Merge(m, src)
}
func (m *SendResponse) XXX_Size() int {
return xxx_messageInfo_SendResponse.Size(m)
}
func (m *SendResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SendResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SendResponse proto.InternalMessageInfo
type ListRequest struct {
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
}
func (m *ListRequest) Reset() { *m = ListRequest{} }
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
func (*ListRequest) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{3}
return file_proto_mail_proto_rawDescGZIP(), []int{3}
}
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
func (m *ListRequest) GetUser() string {
if m != nil {
return m.User
func (x *ListRequest) GetUser() string {
if x != nil {
return x.User
}
return ""
}
type ListResponse struct {
Mail []*Message `protobuf:"bytes,1,rep,name=mail,proto3" json:"mail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Mail []*Message `protobuf:"bytes,1,rep,name=mail,proto3" json:"mail,omitempty"`
}
func (m *ListResponse) Reset() { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{4}
return file_proto_mail_proto_rawDescGZIP(), []int{4}
}
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) GetMail() []*Message {
if m != nil {
return m.Mail
func (x *ListResponse) GetMail() []*Message {
if x != nil {
return x.Mail
}
return nil
}
type ReadRequest 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:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (m *ReadRequest) Reset() { *m = ReadRequest{} }
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
func (*ReadRequest) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{5}
return file_proto_mail_proto_rawDescGZIP(), []int{5}
}
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReadRequest.Unmarshal(m, b)
}
func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic)
}
func (m *ReadRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadRequest.Merge(m, src)
}
func (m *ReadRequest) XXX_Size() int {
return xxx_messageInfo_ReadRequest.Size(m)
}
func (m *ReadRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ReadRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ReadRequest proto.InternalMessageInfo
func (m *ReadRequest) GetId() string {
if m != nil {
return m.Id
func (x *ReadRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
type ReadResponse struct {
Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (m *ReadResponse) Reset() { *m = ReadResponse{} }
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
func (*ReadResponse) ProtoMessage() {}
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 fileDescriptor_92689585a3f577ba, []int{6}
return file_proto_mail_proto_rawDescGZIP(), []int{6}
}
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReadResponse.Unmarshal(m, b)
}
func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic)
}
func (m *ReadResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadResponse.Merge(m, src)
}
func (m *ReadResponse) XXX_Size() int {
return xxx_messageInfo_ReadResponse.Size(m)
}
func (m *ReadResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ReadResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ReadResponse proto.InternalMessageInfo
func (m *ReadResponse) GetMessage() *Message {
if m != nil {
return m.Message
func (x *ReadResponse) GetMessage() *Message {
if x != nil {
return x.Message
}
return nil
}
func init() {
proto.RegisterType((*Message)(nil), "mail.Message")
proto.RegisterType((*SendRequest)(nil), "mail.SendRequest")
proto.RegisterType((*SendResponse)(nil), "mail.SendResponse")
proto.RegisterType((*ListRequest)(nil), "mail.ListRequest")
proto.RegisterType((*ListResponse)(nil), "mail.ListResponse")
proto.RegisterType((*ReadRequest)(nil), "mail.ReadRequest")
proto.RegisterType((*ReadResponse)(nil), "mail.ReadResponse")
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,
}
func init() { proto.RegisterFile("proto/mail.proto", fileDescriptor_92689585a3f577ba) }
var (
file_proto_mail_proto_rawDescOnce sync.Once
file_proto_mail_proto_rawDescData = file_proto_mail_proto_rawDesc
)
var fileDescriptor_92689585a3f577ba = []byte{
// 317 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xb1, 0x4e, 0xc3, 0x30,
0x14, 0x94, 0x13, 0xd3, 0x88, 0x97, 0x50, 0x81, 0x17, 0x2c, 0x24, 0xa4, 0xd6, 0x0b, 0x59, 0x52,
0x44, 0x19, 0x18, 0x98, 0x60, 0xa6, 0x4b, 0xd8, 0x58, 0xaa, 0x94, 0x18, 0x14, 0xd4, 0xc4, 0x25,
0x7e, 0x91, 0xf8, 0x00, 0xfe, 0x80, 0x1f, 0x46, 0xb6, 0x63, 0x61, 0xd4, 0x6e, 0x77, 0xef, 0x9d,
0x7d, 0xbe, 0x93, 0xe1, 0x74, 0xd7, 0x2b, 0x54, 0xd7, 0x6d, 0xd5, 0x6c, 0x17, 0x16, 0x32, 0x6a,
0xb0, 0xf8, 0x26, 0x90, 0xac, 0xa4, 0xd6, 0xd5, 0xbb, 0x64, 0x53, 0x88, 0x9a, 0x9a, 0x93, 0x19,
0xc9, 0x8f, 0xcb, 0xa8, 0xa9, 0x0d, 0x47, 0xc5, 0x23, 0xc7, 0x51, 0x31, 0x06, 0xf4, 0xad, 0x57,
0x2d, 0x8f, 0xed, 0xc4, 0x62, 0xc6, 0x21, 0xd1, 0xc3, 0xe6, 0x43, 0xbe, 0x22, 0xa7, 0x76, 0xec,
0xa9, 0x51, 0xa3, 0xfc, 0x42, 0x7e, 0xe4, 0xd4, 0x06, 0xb3, 0x73, 0x48, 0xb4, 0xec, 0x70, 0x5d,
0x21, 0x9f, 0xcc, 0x48, 0x1e, 0x97, 0x13, 0x43, 0x1f, 0x50, 0xac, 0x21, 0x7d, 0x96, 0x5d, 0x5d,
0xca, 0xcf, 0x41, 0x6a, 0x1c, 0x9d, 0xc9, 0x9e, 0x73, 0x74, 0xd8, 0x39, 0x3e, 0xec, 0x4c, 0xff,
0x9c, 0xc5, 0x14, 0x32, 0x67, 0xa0, 0x77, 0xaa, 0xd3, 0x52, 0xcc, 0x21, 0x7d, 0x6a, 0x34, 0x7a,
0x43, 0x06, 0x74, 0xd0, 0xb2, 0x1f, 0x2d, 0x2d, 0x16, 0x37, 0x90, 0x39, 0x89, 0x3b, 0xc2, 0xe6,
0x60, 0x2b, 0xe3, 0x64, 0x16, 0xe7, 0xe9, 0xf2, 0x64, 0x61, 0xbb, 0x1c, 0xbb, 0x2b, 0x5d, 0x9b,
0x97, 0x90, 0x96, 0xb2, 0x0a, 0x63, 0x84, 0x85, 0x8a, 0x3b, 0xc8, 0xdc, 0x7a, 0xbc, 0xf1, 0x0a,
0x92, 0xd6, 0x9d, 0xb7, 0xa2, 0xbd, 0x4b, 0xfd, 0x76, 0xf9, 0x43, 0x80, 0xae, 0xaa, 0x66, 0xcb,
0x0a, 0xa0, 0x26, 0x06, 0x3b, 0x73, 0xc2, 0xa0, 0xb3, 0x0b, 0x16, 0x8e, 0x46, 0x83, 0x02, 0xa8,
0x89, 0xe0, 0xe5, 0x41, 0x62, 0x2f, 0xff, 0x97, 0xb0, 0x00, 0x6a, 0xde, 0xe7, 0xe5, 0x41, 0x14,
0x2f, 0x0f, 0x9f, 0xff, 0x98, 0xbd, 0x80, 0xfd, 0x4a, 0xf7, 0x66, 0xb5, 0x99, 0x58, 0x7c, 0xfb,
0x1b, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xb1, 0x5f, 0x20, 0x6a, 0x02, 0x00, 0x00,
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
}

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package mail;
option go_package = "proto;mail";
option go_package = "./proto;mail";
service Mail {
rpc Send(SendRequest) returns (SendResponse);
@@ -41,4 +41,4 @@ message ReadRequest {
message ReadResponse {
Message message = 1;
}
}

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package notes;
option go_package = "proto;notes";
option go_package = "./proto;notes";
service Notes {
rpc List(ListRequest) returns (ListResponse);
@@ -45,4 +45,4 @@ message ListRequest {}
message ListResponse {
repeated Note notes = 1;
}
}

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/places.proto
@redoc-cli bundle api-places.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -93,7 +93,7 @@ func (l *Places) Last(ctx context.Context, req *pb.LastRequest, rsp *pb.ListResp
}
// query the database
q := l.DB.Raw("SELECT DISTINCT ON (place_id) place_id, timestamp, latitude, longitude FROM places WHERE place_id IN (?) ORDER BY place_id, timestamp DESC", req.Ids)
q := l.DB.Raw("SELECT DISTINCT ON (place_id) place_id, timestamp, latitude, longitude FROM locations WHERE place_id IN (?) ORDER BY place_id, timestamp DESC", req.Ids)
var locs []*model.Location
if err := q.Find(&locs).Error; err != nil {
logger.Errorf("Error reading from the database: %v", err)

View File

@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/google/uuid"
geo "github.com/hailocab/go-geoindex"
"github.com/stretchr/testify/assert"
@@ -22,29 +23,29 @@ import (
func testHandler(t *testing.T) pb.PlacesHandler {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/places?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS locations CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&model.Location{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE places CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Places{DB: db, Geoindex: geo.NewPointsIndex(geo.Km(0.1))}
}
func TestSave(t *testing.T) {
if v := os.Getenv("IN_TRAVIS_CI"); v == "yes" {
return
}
tt := []struct {
Name string
Places []*pb.Location
@@ -116,9 +117,6 @@ func TestSave(t *testing.T) {
}
func TestLast(t *testing.T) {
if v := os.Getenv("IN_TRAVIS_CI"); v == "yes" {
return
}
h := testHandler(t)
t.Run("MissingIDs", func(t *testing.T) {
@@ -134,24 +132,25 @@ func TestLast(t *testing.T) {
assert.NoError(t, err)
assert.Empty(t, rsp.Places)
})
tn := time.Now()
// generate some example data to work with
loc1 := &pb.Location{
Latitude: &wrapperspb.DoubleValue{Value: 51.5007},
Longitude: &wrapperspb.DoubleValue{Value: 0.1246},
Timestamp: timestamppb.New(time.Now()),
Timestamp: timestamppb.New(tn),
Id: "a",
}
loc2 := &pb.Location{
Latitude: &wrapperspb.DoubleValue{Value: 51.6007},
Longitude: &wrapperspb.DoubleValue{Value: 0.1546},
Timestamp: timestamppb.New(time.Now()),
Timestamp: timestamppb.New(tn.Add(1 * time.Microsecond)),
Id: "b",
}
loc3 := &pb.Location{
Latitude: &wrapperspb.DoubleValue{Value: 52.6007},
Longitude: &wrapperspb.DoubleValue{Value: 0.2546},
Timestamp: timestamppb.New(time.Now()),
Timestamp: timestamppb.New(tn.Add(2 * time.Microsecond)),
Id: loc2.Id,
}
err := h.Save(context.TODO(), &pb.SaveRequest{
@@ -162,7 +161,7 @@ func TestLast(t *testing.T) {
t.Run("OneUser", func(t *testing.T) {
var rsp pb.ListResponse
err := h.Last(context.Background(), &pb.LastRequest{
Ids: []string{loc2.Id},
Ids: []string{loc3.Id},
}, &rsp)
assert.NoError(t, err)
@@ -172,8 +171,9 @@ func TestLast(t *testing.T) {
assert.Equal(t, loc3.Id, rsp.Places[0].Id)
assert.Equal(t, loc3.Latitude.Value, rsp.Places[0].Latitude.Value)
assert.Equal(t, loc3.Longitude.Value, rsp.Places[0].Longitude.Value)
assert.Equal(t, loc3.Timestamp.AsTime(), rsp.Places[0].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc3.Timestamp), microSecondTime(rsp.Places[0].Timestamp))
})
t.Run("ManyUser", func(t *testing.T) {
var rsp pb.ListResponse
err := h.Last(context.Background(), &pb.LastRequest{
@@ -193,19 +193,16 @@ func TestLast(t *testing.T) {
assert.Equal(t, loc1.Id, rsp.Places[1].Id)
assert.Equal(t, loc1.Latitude.Value, rsp.Places[1].Latitude.Value)
assert.Equal(t, loc1.Longitude.Value, rsp.Places[1].Longitude.Value)
assert.Equal(t, loc1.Timestamp.AsTime(), rsp.Places[1].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc1.Timestamp), microSecondTime(rsp.Places[1].Timestamp))
assert.Equal(t, loc3.Id, rsp.Places[0].Id)
assert.Equal(t, loc3.Latitude.Value, rsp.Places[0].Latitude.Value)
assert.Equal(t, loc3.Longitude.Value, rsp.Places[0].Longitude.Value)
assert.Equal(t, loc3.Timestamp.AsTime(), rsp.Places[0].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc3.Timestamp), microSecondTime(rsp.Places[0].Timestamp))
})
}
func TestNear(t *testing.T) {
if v := os.Getenv("IN_TRAVIS_CI"); v == "yes" {
return
}
lat := &wrapperspb.DoubleValue{Value: 51.510357}
lng := &wrapperspb.DoubleValue{Value: -0.116773}
rad := &wrapperspb.DoubleValue{Value: 2.0}
@@ -401,9 +398,6 @@ func TestNear(t *testing.T) {
}
func TestRead(t *testing.T) {
if v := os.Getenv("IN_TRAVIS_CI"); v == "yes" {
return
}
h := testHandler(t)
baseTime := time.Now().Add(time.Hour * -24)
@@ -482,12 +476,12 @@ func TestRead(t *testing.T) {
assert.Equal(t, loc2.Id, rsp.Places[0].Id)
assert.Equal(t, loc2.Latitude.Value, rsp.Places[0].Latitude.Value)
assert.Equal(t, loc2.Longitude.Value, rsp.Places[0].Longitude.Value)
assert.Equal(t, loc2.Timestamp.AsTime(), rsp.Places[0].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc2.Timestamp), microSecondTime(rsp.Places[0].Timestamp))
assert.Equal(t, loc3.Id, rsp.Places[1].Id)
assert.Equal(t, loc3.Latitude.Value, rsp.Places[1].Latitude.Value)
assert.Equal(t, loc3.Longitude.Value, rsp.Places[1].Longitude.Value)
assert.Equal(t, loc3.Timestamp.AsTime(), rsp.Places[1].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc3.Timestamp), microSecondTime(rsp.Places[1].Timestamp))
})
t.Run("OnePlaceIDReducedTime", func(t *testing.T) {
@@ -505,7 +499,7 @@ func TestRead(t *testing.T) {
assert.Equal(t, loc2.Id, rsp.Places[0].Id)
assert.Equal(t, loc2.Latitude.Value, rsp.Places[0].Latitude.Value)
assert.Equal(t, loc2.Longitude.Value, rsp.Places[0].Longitude.Value)
assert.Equal(t, loc2.Timestamp.AsTime(), rsp.Places[0].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc2.Timestamp), microSecondTime(rsp.Places[0].Timestamp))
})
t.Run("TwoPlaceIDs", func(t *testing.T) {
@@ -523,11 +517,17 @@ func TestRead(t *testing.T) {
assert.Equal(t, loc1.Id, rsp.Places[0].Id)
assert.Equal(t, loc1.Latitude.Value, rsp.Places[0].Latitude.Value)
assert.Equal(t, loc1.Longitude.Value, rsp.Places[0].Longitude.Value)
assert.Equal(t, loc1.Timestamp.AsTime(), rsp.Places[0].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc1.Timestamp), microSecondTime(rsp.Places[0].Timestamp))
assert.Equal(t, loc2.Id, rsp.Places[1].Id)
assert.Equal(t, loc2.Latitude.Value, rsp.Places[1].Latitude.Value)
assert.Equal(t, loc2.Longitude.Value, rsp.Places[1].Longitude.Value)
assert.Equal(t, loc2.Timestamp.AsTime(), rsp.Places[1].Timestamp.AsTime())
assert.Equal(t, microSecondTime(loc2.Timestamp), microSecondTime(rsp.Places[1].Timestamp))
})
}
// postgres has a resolution of 100microseconds so just test that it's accurate to the second
func microSecondTime(t *timestamp.Timestamp) time.Time {
tt := t.AsTime()
return time.Unix(tt.Unix(), int64(tt.Nanosecond()-tt.Nanosecond()%1000))
}

View File

@@ -1,17 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/places.proto
package places
import (
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
reflect "reflect"
sync "sync"
)
@@ -23,21 +22,17 @@ const (
_ = 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 Location 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"`
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Timestamp *timestamp.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Latitude *wrappers.DoubleValue `protobuf:"bytes,5,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrappers.DoubleValue `protobuf:"bytes,6,opt,name=longitude,proto3" json:"longitude,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Latitude *wrapperspb.DoubleValue `protobuf:"bytes,5,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrapperspb.DoubleValue `protobuf:"bytes,6,opt,name=longitude,proto3" json:"longitude,omitempty"`
}
func (x *Location) Reset() {
@@ -93,21 +88,21 @@ func (x *Location) GetMetadata() map[string]string {
return nil
}
func (x *Location) GetTimestamp() *timestamp.Timestamp {
func (x *Location) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
return nil
}
func (x *Location) GetLatitude() *wrappers.DoubleValue {
func (x *Location) GetLatitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Latitude
}
return nil
}
func (x *Location) GetLongitude() *wrappers.DoubleValue {
func (x *Location) GetLongitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Longitude
}
@@ -298,10 +293,10 @@ type NearRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Latitude *wrappers.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
Latitude *wrapperspb.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrapperspb.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
// radius to search within, units km
Radius *wrappers.DoubleValue `protobuf:"bytes,3,opt,name=radius,proto3" json:"radius,omitempty"`
Radius *wrapperspb.DoubleValue `protobuf:"bytes,3,opt,name=radius,proto3" json:"radius,omitempty"`
}
func (x *NearRequest) Reset() {
@@ -336,21 +331,21 @@ func (*NearRequest) Descriptor() ([]byte, []int) {
return file_proto_places_proto_rawDescGZIP(), []int{5}
}
func (x *NearRequest) GetLatitude() *wrappers.DoubleValue {
func (x *NearRequest) GetLatitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Latitude
}
return nil
}
func (x *NearRequest) GetLongitude() *wrappers.DoubleValue {
func (x *NearRequest) GetLongitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Longitude
}
return nil
}
func (x *NearRequest) GetRadius() *wrappers.DoubleValue {
func (x *NearRequest) GetRadius() *wrapperspb.DoubleValue {
if x != nil {
return x.Radius
}
@@ -362,9 +357,9 @@ type ReadRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"`
After *timestamp.Timestamp `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"`
Before *timestamp.Timestamp `protobuf:"bytes,3,opt,name=before,proto3" json:"before,omitempty"`
Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"`
After *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"`
Before *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=before,proto3" json:"before,omitempty"`
}
func (x *ReadRequest) Reset() {
@@ -406,14 +401,14 @@ func (x *ReadRequest) GetIds() []string {
return nil
}
func (x *ReadRequest) GetAfter() *timestamp.Timestamp {
func (x *ReadRequest) GetAfter() *timestamppb.Timestamp {
if x != nil {
return x.After
}
return nil
}
func (x *ReadRequest) GetBefore() *timestamp.Timestamp {
func (x *ReadRequest) GetBefore() *timestamppb.Timestamp {
if x != nil {
return x.Before
}
@@ -494,8 +489,9 @@ var file_proto_places_proto_rawDesc = []byte{
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x04, 0x52, 0x65, 0x61,
0x64, 0x12, 0x13, 0x2e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x10,
0x5a, 0x0e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -512,16 +508,16 @@ func file_proto_places_proto_rawDescGZIP() []byte {
var file_proto_places_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_proto_places_proto_goTypes = []interface{}{
(*Location)(nil), // 0: places.Location
(*SaveRequest)(nil), // 1: places.SaveRequest
(*SaveResponse)(nil), // 2: places.SaveResponse
(*LastRequest)(nil), // 3: places.LastRequest
(*ListResponse)(nil), // 4: places.ListResponse
(*NearRequest)(nil), // 5: places.NearRequest
(*ReadRequest)(nil), // 6: places.ReadRequest
nil, // 7: places.Location.MetadataEntry
(*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*wrappers.DoubleValue)(nil), // 9: google.protobuf.DoubleValue
(*Location)(nil), // 0: places.Location
(*SaveRequest)(nil), // 1: places.SaveRequest
(*SaveResponse)(nil), // 2: places.SaveResponse
(*LastRequest)(nil), // 3: places.LastRequest
(*ListResponse)(nil), // 4: places.ListResponse
(*NearRequest)(nil), // 5: places.NearRequest
(*ReadRequest)(nil), // 6: places.ReadRequest
nil, // 7: places.Location.MetadataEntry
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*wrapperspb.DoubleValue)(nil), // 9: google.protobuf.DoubleValue
}
var file_proto_places_proto_depIdxs = []int32{
7, // 0: places.Location.metadata:type_name -> places.Location.MetadataEntry

View File

@@ -6,8 +6,8 @@ package places
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/timestamppb"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,6 +1,7 @@
syntax = "proto3";
package places;
option go_package = "./proto;places";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/posts.proto
package posts

View File

@@ -2,6 +2,8 @@ syntax = "proto3";
package posts;
option go_package = "./proto;posts";
service Posts {
// Index returns the posts index without content
rpc Index(IndexRequest) returns (IndexResponse) {}

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/routing.proto
@redoc-cli bundle api-routing.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,16 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/routing.proto
package routing
import (
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
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"
)
@@ -31,8 +31,8 @@ type Point struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Latitude *wrappers.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
Latitude *wrapperspb.DoubleValue `protobuf:"bytes,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
Longitude *wrapperspb.DoubleValue `protobuf:"bytes,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
}
func (x *Point) Reset() {
@@ -67,14 +67,14 @@ func (*Point) Descriptor() ([]byte, []int) {
return file_proto_routing_proto_rawDescGZIP(), []int{0}
}
func (x *Point) GetLatitude() *wrappers.DoubleValue {
func (x *Point) GetLatitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Latitude
}
return nil
}
func (x *Point) GetLongitude() *wrappers.DoubleValue {
func (x *Point) GetLongitude() *wrapperspb.DoubleValue {
if x != nil {
return x.Longitude
}
@@ -231,10 +231,10 @@ func file_proto_routing_proto_rawDescGZIP() []byte {
var file_proto_routing_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proto_routing_proto_goTypes = []interface{}{
(*Point)(nil), // 0: routing.Point
(*RouteRequest)(nil), // 1: routing.RouteRequest
(*RouteResponse)(nil), // 2: routing.RouteResponse
(*wrappers.DoubleValue)(nil), // 3: google.protobuf.DoubleValue
(*Point)(nil), // 0: routing.Point
(*RouteRequest)(nil), // 1: routing.RouteRequest
(*RouteResponse)(nil), // 2: routing.RouteResponse
(*wrapperspb.DoubleValue)(nil), // 3: google.protobuf.DoubleValue
}
var file_proto_routing_proto_depIdxs = []int32{
3, // 0: routing.Point.latitude:type_name -> google.protobuf.DoubleValue

View File

@@ -6,7 +6,7 @@ package routing
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package routing;
option go_package = "proto;routing";
option go_package = "./proto;routing";
import "google/protobuf/wrappers.proto";
@@ -21,4 +21,4 @@ message RouteRequest {
message RouteResponse {
repeated Point waypoints = 1;
}
}

View File

@@ -13,6 +13,11 @@ proto:
build:
go build -o seen *.go
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/seen.proto
@redoc-cli bundle api-protobuf.json
.PHONY: test
test:
go test -v ./... -cover

View File

@@ -2,6 +2,7 @@ package handler_test
import (
"context"
"os"
"testing"
"time"
@@ -16,7 +17,11 @@ import (
func testHandler(t *testing.T) *handler.Seen {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5433/postgres?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
@@ -222,13 +227,13 @@ func TestRead(t *testing.T) {
assert.Len(t, rsp.Timestamps, 2)
if v := rsp.Timestamps["message-1"]; v != nil {
assert.True(t, v.AsTime().Equal(tn))
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.True(t, v.AsTime().Equal(tn.Add(time.Minute*-10)))
assert.Equal(t, microSecondTime(v.AsTime()), microSecondTime(tn.Add(time.Minute*-10).UTC()))
} else {
t.Errorf("Expected a timestamp for message-2")
}
@@ -249,4 +254,10 @@ func TestRead(t *testing.T) {
}, &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()
}

View File

@@ -1,16 +1,16 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.23.0
// protoc v3.13.0
// protoc-gen-go v1.25.0
// protoc v3.15.5
// source: proto/seen.proto
package seen
import (
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
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"
)
@@ -86,10 +86,10 @@ type SetRequest struct {
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 *timestamp.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
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() {
@@ -145,7 +145,7 @@ func (x *SetRequest) GetResourceId() string {
return ""
}
func (x *SetRequest) GetTimestamp() *timestamp.Timestamp {
func (x *SetRequest) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
@@ -359,7 +359,7 @@ type ReadResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Timestamps map[string]*timestamp.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"`
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() {
@@ -394,7 +394,7 @@ func (*ReadResponse) Descriptor() ([]byte, []int) {
return file_proto_seen_proto_rawDescGZIP(), []int{6}
}
func (x *ReadResponse) GetTimestamps() map[string]*timestamp.Timestamp {
func (x *ReadResponse) GetTimestamps() map[string]*timestamppb.Timestamp {
if x != nil {
return x.Timestamps
}
@@ -475,15 +475,15 @@ func file_proto_seen_proto_rawDescGZIP() []byte {
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
(*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*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

View File

@@ -6,7 +6,7 @@ package seen
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "google.golang.org/protobuf/types/known/timestamppb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package seen;
option go_package = "proto;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
@@ -49,4 +49,4 @@ message ReadRequest {
message ReadResponse {
map<string, google.protobuf.Timestamp> timestamps = 1;
}
}

View File

@@ -7,8 +7,13 @@ init:
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/sentiment.proto
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/sentiment.proto
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/sentiment.proto
@redoc-cli bundle api-sentiment.json
.PHONY: build
build:
go build -o sentiment *.go

View File

@@ -1,129 +1,225 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.15.5
// source: proto/sentiment.proto
package sentiment
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
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 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
// 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 Request struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
Lang string `protobuf:"bytes,2,opt,name=lang,proto3" json:"lang,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
Lang string `protobuf:"bytes,2,opt,name=lang,proto3" json:"lang,omitempty"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_sentiment_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Request) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
mi := &file_proto_sentiment_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 Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
return fileDescriptor_ab79e813d74ef963, []int{0}
return file_proto_sentiment_proto_rawDescGZIP(), []int{0}
}
func (m *Request) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Request.Unmarshal(m, b)
}
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
}
func (m *Request) XXX_Merge(src proto.Message) {
xxx_messageInfo_Request.Merge(m, src)
}
func (m *Request) XXX_Size() int {
return xxx_messageInfo_Request.Size(m)
}
func (m *Request) XXX_DiscardUnknown() {
xxx_messageInfo_Request.DiscardUnknown(m)
}
var xxx_messageInfo_Request proto.InternalMessageInfo
func (m *Request) GetText() string {
if m != nil {
return m.Text
func (x *Request) GetText() string {
if x != nil {
return x.Text
}
return ""
}
func (m *Request) GetLang() string {
if m != nil {
return m.Lang
func (x *Request) GetLang() string {
if x != nil {
return x.Lang
}
return ""
}
type Response struct {
Score float64 `protobuf:"fixed64,1,opt,name=score,proto3" json:"score,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Score float64 `protobuf:"fixed64,1,opt,name=score,proto3" json:"score,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (x *Response) Reset() {
*x = Response{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_sentiment_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Response) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Response) ProtoMessage() {}
func (x *Response) ProtoReflect() protoreflect.Message {
mi := &file_proto_sentiment_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 Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
return fileDescriptor_ab79e813d74ef963, []int{1}
return file_proto_sentiment_proto_rawDescGZIP(), []int{1}
}
func (m *Response) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Response.Unmarshal(m, b)
}
func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Response.Marshal(b, m, deterministic)
}
func (m *Response) XXX_Merge(src proto.Message) {
xxx_messageInfo_Response.Merge(m, src)
}
func (m *Response) XXX_Size() int {
return xxx_messageInfo_Response.Size(m)
}
func (m *Response) XXX_DiscardUnknown() {
xxx_messageInfo_Response.DiscardUnknown(m)
}
var xxx_messageInfo_Response proto.InternalMessageInfo
func (m *Response) GetScore() float64 {
if m != nil {
return m.Score
func (x *Response) GetScore() float64 {
if x != nil {
return x.Score
}
return 0
}
func init() {
proto.RegisterType((*Request)(nil), "sentiment.Request")
proto.RegisterType((*Response)(nil), "sentiment.Response")
var File_proto_sentiment_proto protoreflect.FileDescriptor
var file_proto_sentiment_proto_rawDesc = []byte{
0x0a, 0x15, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e,
0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65,
0x6e, 0x74, 0x22, 0x31, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78,
0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01,
0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x32, 0x41, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x12,
0x12, 0x2e, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x11, 0x5a, 0x0f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
func init() { proto.RegisterFile("proto/sentiment.proto", fileDescriptor_ab79e813d74ef963) }
var (
file_proto_sentiment_proto_rawDescOnce sync.Once
file_proto_sentiment_proto_rawDescData = file_proto_sentiment_proto_rawDesc
)
var fileDescriptor_ab79e813d74ef963 = []byte{
// 161 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2d, 0x28, 0xca, 0x2f,
0xc9, 0xd7, 0x2f, 0x4e, 0xcd, 0x2b, 0xc9, 0xcc, 0x4d, 0xcd, 0x2b, 0xd1, 0x03, 0xf3, 0x85, 0x38,
0xe1, 0x02, 0x4a, 0x86, 0x5c, 0xec, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, 0x5c,
0x2c, 0x25, 0xa9, 0x15, 0x25, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0x36, 0x48, 0x2c,
0x27, 0x31, 0x2f, 0x5d, 0x82, 0x09, 0x22, 0x06, 0x62, 0x2b, 0x29, 0x70, 0x71, 0x04, 0xa5, 0x16,
0x17, 0xe4, 0xe7, 0x15, 0xa7, 0x0a, 0x89, 0x70, 0xb1, 0x16, 0x27, 0xe7, 0x17, 0xa5, 0x82, 0x35,
0x31, 0x06, 0x41, 0x38, 0x46, 0x8e, 0x5c, 0x9c, 0xc1, 0x30, 0x1b, 0x84, 0x4c, 0xb8, 0xd8, 0x1d,
0xf3, 0x12, 0x73, 0x2a, 0xab, 0x52, 0x85, 0x84, 0xf4, 0x10, 0x2e, 0x81, 0xda, 0x2a, 0x25, 0x8c,
0x22, 0x06, 0x31, 0x56, 0x89, 0xc1, 0x49, 0x30, 0x8a, 0x1f, 0xec, 0x56, 0x6b, 0xb8, 0x6c, 0x12,
0x1b, 0x58, 0xc0, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x55, 0xd3, 0x83, 0xd5, 0x00, 0x00,
0x00,
func file_proto_sentiment_proto_rawDescGZIP() []byte {
file_proto_sentiment_proto_rawDescOnce.Do(func() {
file_proto_sentiment_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_sentiment_proto_rawDescData)
})
return file_proto_sentiment_proto_rawDescData
}
var file_proto_sentiment_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_sentiment_proto_goTypes = []interface{}{
(*Request)(nil), // 0: sentiment.Request
(*Response)(nil), // 1: sentiment.Response
}
var file_proto_sentiment_proto_depIdxs = []int32{
0, // 0: sentiment.Sentiment.Analyze:input_type -> sentiment.Request
1, // 1: sentiment.Sentiment.Analyze:output_type -> sentiment.Response
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_proto_sentiment_proto_init() }
func file_proto_sentiment_proto_init() {
if File_proto_sentiment_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_sentiment_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_sentiment_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Response); 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_sentiment_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_sentiment_proto_goTypes,
DependencyIndexes: file_proto_sentiment_proto_depIdxs,
MessageInfos: file_proto_sentiment_proto_msgTypes,
}.Build()
File_proto_sentiment_proto = out.File
file_proto_sentiment_proto_rawDesc = nil
file_proto_sentiment_proto_goTypes = nil
file_proto_sentiment_proto_depIdxs = nil
}

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package sentiment;
option go_package = "proto;sentiment";
option go_package = "./proto;sentiment";
service Sentiment {
rpc Analyze(Request) returns (Response) {};

View File

@@ -15,8 +15,8 @@ build:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/streams.proto
@redoc-cli bundle api-streams.json
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/streams.proto
@redoc-cli bundle api-protobuf.json
.PHONY: test
test:

View File

@@ -1,6 +1,9 @@
package handler
import (
"fmt"
"regexp"
"strings"
"time"
"github.com/micro/micro/v3/service/errors"
@@ -11,6 +14,7 @@ import (
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")
@@ -22,6 +26,7 @@ type Token struct {
Token string `gorm:"primaryKey"`
Topic string
ExpiresAt time.Time
Namespace string
}
type Streams struct {
@@ -29,3 +34,18 @@ type Streams struct {
Events events.Stream
Time func() time.Time
}
// fmtTopic returns a topic string with namespace prefix and hyphens replaced with dots
func fmtTopic(ns, topic string) string {
// events topic names can only be alphanumeric and "."
return fmt.Sprintf("%s.%s", strings.ReplaceAll(ns, "-", "."), topic)
}
// validateTopicInput validates that topic is alphanumeric
func validateTopicInput(topic string) error {
reg := regexp.MustCompile("^[a-zA-Z0-9]+$")
if len(reg.FindString(topic)) == 0 {
return ErrInvalidTopic
}
return nil
}

View File

@@ -1,6 +1,7 @@
package handler_test
import (
"os"
"testing"
"time"
@@ -12,7 +13,11 @@ import (
func testHandler(t *testing.T) *handler.Streams {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/postgres?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
@@ -22,11 +27,6 @@ func testHandler(t *testing.T) *handler.Streams {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE tokens CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Streams{
DB: db,
Events: new(eventsMock),

View File

@@ -3,6 +3,8 @@ 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/streams/proto"
)
@@ -12,11 +14,18 @@ func (s *Streams) Publish(ctx context.Context, req *pb.Message, rsp *pb.PublishR
if len(req.Topic) == 0 {
return ErrMissingTopic
}
if err := validateTopicInput(req.Topic); err != nil {
return err
}
if len(req.Message) == 0 {
return ErrMissingMessage
}
acc, ok := auth.AccountFromContext(ctx)
if !ok {
return errors.Unauthorized("UNAUTHORIZED", "Unauthorized")
}
// publish the message
logger.Infof("Publishing message to topic: %v", req.Topic)
return s.Events.Publish(req.Topic, req.Message)
return s.Events.Publish(fmtTopic(acc.Issuer, req.Topic), req.Message)
}

View File

@@ -2,9 +2,11 @@ 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"
@@ -12,30 +14,34 @@ import (
func TestPublish(t *testing.T) {
msg := "{\"foo\":\"bar\"}"
topic := uuid.New().String()
topic := strings.ReplaceAll(uuid.New().String(), "-", "")
t.Run("MissingTopic", func(t *testing.T) {
h := testHandler(t)
err := h.Publish(context.TODO(), &pb.Message{Message: msg}, &pb.PublishResponse{})
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)
err := h.Publish(context.TODO(), &pb.Message{Topic: topic}, &pb.PublishResponse{})
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)
err := h.Publish(context.TODO(), &pb.Message{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
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)
assert.Equal(t, topic, h.Events.(*eventsMock).PublishTopic)
// topic is prefixed with acc issuer to implement multitenancy
assert.Equal(t, "foo."+topic, h.Events.(*eventsMock).PublishTopic)
})
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"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"
@@ -13,7 +14,7 @@ import (
)
func (s *Streams) Subscribe(ctx context.Context, req *pb.SubscribeRequest, stream pb.Streams_SubscribeStream) error {
logger.Infof("Recieved subscribe request. Topic: '%v', Token: '%v'", req.Topic, req.Token)
logger.Infof("Received subscribe request. Topic: '%v', Token: '%v'", req.Topic, req.Token)
// validate the request
if len(req.Token) == 0 {
@@ -22,10 +23,18 @@ func (s *Streams) Subscribe(ctx context.Context, req *pb.SubscribeRequest, strea
if len(req.Topic) == 0 {
return ErrMissingTopic
}
if err := validateTopicInput(req.Topic); err != nil {
return err
}
acc, ok := auth.AccountFromContext(ctx)
if !ok {
return errors.Unauthorized("UNAUTHORIZED", "Unauthorized")
}
// find the token and check to see if it has expired
var token Token
if err := s.DB.Where(&Token{Token: req.Token}).First(&token).Error; err == gorm.ErrRecordNotFound {
if err := s.DB.Where(&Token{Token: req.Token, Namespace: acc.Issuer}).First(&token).Error; err == gorm.ErrRecordNotFound {
return ErrInvalidToken
} else if err != nil {
logger.Errorf("Error reading token from store: %v", err)
@@ -42,12 +51,11 @@ func (s *Streams) Subscribe(ctx context.Context, req *pb.SubscribeRequest, strea
// start the subscription
logger.Infof("Subscribing to %v via queue %v", req.Topic, token.Token)
evChan, err := s.Events.Consume(req.Topic, events.WithGroup(token.Token))
evChan, err := s.Events.Consume(fmtTopic(acc.Issuer, req.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")
}
defer stream.Close()
for {
msg, ok := <-evChan
@@ -57,7 +65,7 @@ func (s *Streams) Subscribe(ctx context.Context, req *pb.SubscribeRequest, strea
logger.Infof("Sending message to subscriber %v", token.Topic)
pbMsg := &pb.Message{
Topic: msg.Topic,
Topic: req.Topic, // use req.Topic not msg.Topic because topic is munged for multitenancy
Message: string(msg.Payload),
SentAt: timestamppb.New(msg.Timestamp),
}

View File

@@ -2,10 +2,12 @@ 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"
@@ -17,7 +19,8 @@ func TestSubscribe(t *testing.T) {
h := testHandler(t)
s := new(streamMock)
err := h.Subscribe(context.TODO(), &pb.SubscribeRequest{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
err := h.Subscribe(ctx, &pb.SubscribeRequest{
Topic: "helloworld",
}, s)
@@ -29,7 +32,8 @@ func TestSubscribe(t *testing.T) {
h := testHandler(t)
s := new(streamMock)
err := h.Subscribe(context.TODO(), &pb.SubscribeRequest{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
err := h.Subscribe(ctx, &pb.SubscribeRequest{
Token: uuid.New().String(),
}, s)
@@ -41,7 +45,8 @@ func TestSubscribe(t *testing.T) {
h := testHandler(t)
s := new(streamMock)
err := h.Subscribe(context.TODO(), &pb.SubscribeRequest{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
err := h.Subscribe(ctx, &pb.SubscribeRequest{
Topic: "helloworld",
Token: uuid.New().String(),
}, s)
@@ -54,7 +59,8 @@ func TestSubscribe(t *testing.T) {
h := testHandler(t)
var tRsp pb.TokenResponse
err := h.Token(context.TODO(), &pb.TokenRequest{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
err := h.Token(ctx, &pb.TokenRequest{
Topic: "helloworld",
}, &tRsp)
assert.NoError(t, err)
@@ -62,7 +68,7 @@ func TestSubscribe(t *testing.T) {
ct := h.Time()
h.Time = func() time.Time { return ct.Add(handler.TokenTTL * 2) }
s := new(streamMock)
err = h.Subscribe(context.TODO(), &pb.SubscribeRequest{
err = h.Subscribe(ctx, &pb.SubscribeRequest{
Topic: "helloworld",
Token: tRsp.Token,
}, s)
@@ -75,13 +81,14 @@ func TestSubscribe(t *testing.T) {
h := testHandler(t)
var tRsp pb.TokenResponse
err := h.Token(context.TODO(), &pb.TokenRequest{
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(context.TODO(), &pb.SubscribeRequest{
err = h.Subscribe(ctx, &pb.SubscribeRequest{
Topic: "helloworld",
Token: tRsp.Token,
}, s)
@@ -91,23 +98,33 @@ func TestSubscribe(t *testing.T) {
})
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
err := h.Token(context.TODO(), &pb.TokenRequest{
ctx := auth.ContextWithAccount(context.TODO(), &auth.Account{Issuer: "foo"})
err := h.Token(ctx, &pb.TokenRequest{
Topic: "helloworld",
}, &tRsp)
assert.NoError(t, err)
s := &streamMock{Messages: []*pb.Message{}}
err = h.Subscribe(context.TODO(), &pb.SubscribeRequest{
Topic: "helloworld",
Token: tRsp.Token,
}, s)
assert.NoError(t, err)
assert.Equal(t, "helloworld", h.Events.(*eventsMock).ConsumeTopic)
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(),
@@ -138,6 +155,13 @@ func TestSubscribe(t *testing.T) {
t.Log("Event2 consumed")
}
close(c)
wg.Wait()
assert.NoError(t, subsErr)
assert.Equal(t, "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
@@ -151,6 +175,45 @@ func TestSubscribe(t *testing.T) {
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 {

View File

@@ -4,17 +4,29 @@ 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 {
acc, ok := auth.AccountFromContext(ctx)
if !ok {
return errors.Unauthorized("UNAUTHORIZED", "Unauthorized")
}
if len(req.Topic) > 0 {
if err := validateTopicInput(req.Topic); err != nil {
return err
}
}
// construct the token and write it to the database
t := Token{
Token: uuid.New().String(),
ExpiresAt: s.Time().Add(TokenTTL),
Topic: req.Topic,
Namespace: acc.Issuer,
}
if err := s.DB.Create(&t).Error; err != nil {
logger.Errorf("Error creating token in store: %v", err)

View File

@@ -4,6 +4,8 @@ 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"
)
@@ -13,15 +15,24 @@ func TestToken(t *testing.T) {
t.Run("WithoutTopic", func(t *testing.T) {
var rsp pb.TokenResponse
err := h.Token(context.TODO(), &pb.TokenRequest{}, &rsp)
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
err := h.Token(context.TODO(), &pb.TokenRequest{Topic: "helloworld"}, &rsp)
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)
})
}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// protoc v3.15.5
// source: proto/tags.proto
package tags

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package tags;
option go_package = "proto;tags";
option go_package = "./proto;tags";
service Tags {
// Add a tag to a resource

View File

@@ -139,7 +139,7 @@ func testPosts(t *test.T) {
if err := test.Try("Save post", t, func() ([]byte, error) {
// Attention! The content must be unquoted, don't add quotes.
outp, err := cmd.Exec("posts", "--id=1", "--title=Hi", "--content=Hi there", "--tags=a,b", "save")
outp, err := cmd.Exec("posts", "save", "--id=1", "--title=Hi", "--content=Hi there", "--tags=a,b")
if err != nil {
outp1, _ := cmd.Exec("logs", "posts")
return append(outp, outp1...), err
@@ -206,7 +206,7 @@ func testPosts(t *test.T) {
time.Sleep(5 * time.Second)
// Inserting an other post so tag counts increase
outp, err = cmd.Exec("posts", "--id=2", "--title=Hi1", "--content=Hi there1", "--tags=a,b", "save")
outp, err = cmd.Exec("posts", "save", "--id=2", "--title=Hi1", "--content=Hi there1", "--tags=a,b")
if err != nil {
t.Fatal(string(outp))
return
@@ -238,7 +238,7 @@ func testPosts(t *test.T) {
}
// test updating fields fields and removing tags
outp, err = cmd.Exec("posts", "--id=2", "--title=Hi2", "--tags=a", "save")
outp, err = cmd.Exec("posts", "save", "--id=2", "--title=Hi2", "--tags=a")
if err != nil {
t.Fatal(string(outp))
return

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/threads.proto
@redoc-cli bundle api-threads.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,9 +1,11 @@
package handler_test
import (
"os"
"testing"
"time"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/micro/services/threads/handler"
pb "github.com/micro/services/threads/proto"
"github.com/stretchr/testify/assert"
@@ -14,11 +16,20 @@ import (
func testHandler(t *testing.T) *handler.Threads {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/threads?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS conversations, messages CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&handler.Conversation{}, &handler.Message{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
@@ -54,7 +65,7 @@ func assertConversationsMatch(t *testing.T, exp, act *pb.Conversation) {
return
}
assert.True(t, exp.CreatedAt.AsTime().Equal(act.CreatedAt.AsTime()))
assert.True(t, microSecondTime(exp.CreatedAt).Equal(microSecondTime(act.CreatedAt)))
}
func assertMessagesMatch(t *testing.T, exp, act *pb.Message) {
@@ -80,5 +91,11 @@ func assertMessagesMatch(t *testing.T, exp, act *pb.Message) {
return
}
assert.True(t, exp.SentAt.AsTime().Equal(act.SentAt.AsTime()))
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 *timestamp.Timestamp) time.Time {
tt := t.AsTime()
return time.Unix(tt.Unix(), int64(tt.Nanosecond()-tt.Nanosecond()%1000))
}

View File

@@ -1,17 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.23.0
// protoc v3.13.0
// protoc-gen-go v1.25.0
// protoc v3.15.5
// source: proto/threads.proto
package threads
import (
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
reflect "reflect"
sync "sync"
)
@@ -32,10 +32,10 @@ type Conversation struct {
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 *timestamp.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
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 *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
}
func (x *Conversation) Reset() {
@@ -91,7 +91,7 @@ func (x *Conversation) GetTopic() string {
return ""
}
func (x *Conversation) GetCreatedAt() *timestamp.Timestamp {
func (x *Conversation) GetCreatedAt() *timestamppb.Timestamp {
if x != nil {
return x.CreatedAt
}
@@ -103,11 +103,11 @@ type Message struct {
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"`
ConversationId string `protobuf:"bytes,3,opt,name=conversation_id,json=conversationId,proto3" json:"conversation_id,omitempty"`
Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"`
SentAt *timestamp.Timestamp `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`
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"`
ConversationId string `protobuf:"bytes,3,opt,name=conversation_id,json=conversationId,proto3" json:"conversation_id,omitempty"`
Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"`
SentAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`
}
func (x *Message) Reset() {
@@ -170,7 +170,7 @@ func (x *Message) GetText() string {
return ""
}
func (x *Message) GetSentAt() *timestamp.Timestamp {
func (x *Message) GetSentAt() *timestamppb.Timestamp {
if x != nil {
return x.SentAt
}
@@ -284,8 +284,8 @@ type ReadConversationRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
GroupId *wrappers.StringValue `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
GroupId *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
}
func (x *ReadConversationRequest) Reset() {
@@ -327,7 +327,7 @@ func (x *ReadConversationRequest) GetId() string {
return ""
}
func (x *ReadConversationRequest) GetGroupId() *wrappers.StringValue {
func (x *ReadConversationRequest) GetGroupId() *wrapperspb.StringValue {
if x != nil {
return x.GroupId
}
@@ -785,9 +785,9 @@ type ListMessagesRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConversationId string `protobuf:"bytes,1,opt,name=conversation_id,json=conversationId,proto3" json:"conversation_id,omitempty"`
SentBefore *timestamp.Timestamp `protobuf:"bytes,2,opt,name=sent_before,json=sentBefore,proto3" json:"sent_before,omitempty"`
Limit *wrappers.Int32Value `protobuf:"bytes,3,opt,name=limit,proto3" json:"limit,omitempty"`
ConversationId string `protobuf:"bytes,1,opt,name=conversation_id,json=conversationId,proto3" json:"conversation_id,omitempty"`
SentBefore *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=sent_before,json=sentBefore,proto3" json:"sent_before,omitempty"`
Limit *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=limit,proto3" json:"limit,omitempty"`
}
func (x *ListMessagesRequest) Reset() {
@@ -829,14 +829,14 @@ func (x *ListMessagesRequest) GetConversationId() string {
return ""
}
func (x *ListMessagesRequest) GetSentBefore() *timestamp.Timestamp {
func (x *ListMessagesRequest) GetSentBefore() *timestamppb.Timestamp {
if x != nil {
return x.SentBefore
}
return nil
}
func (x *ListMessagesRequest) GetLimit() *wrappers.Int32Value {
func (x *ListMessagesRequest) GetLimit() *wrapperspb.Int32Value {
if x != nil {
return x.Limit
}
@@ -895,8 +895,8 @@ type RecentMessagesRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConversationIds []string `protobuf:"bytes,1,rep,name=conversation_ids,json=conversationIds,proto3" json:"conversation_ids,omitempty"`
LimitPerConversation *wrappers.Int32Value `protobuf:"bytes,2,opt,name=limit_per_conversation,json=limitPerConversation,proto3" json:"limit_per_conversation,omitempty"`
ConversationIds []string `protobuf:"bytes,1,rep,name=conversation_ids,json=conversationIds,proto3" json:"conversation_ids,omitempty"`
LimitPerConversation *wrapperspb.Int32Value `protobuf:"bytes,2,opt,name=limit_per_conversation,json=limitPerConversation,proto3" json:"limit_per_conversation,omitempty"`
}
func (x *RecentMessagesRequest) Reset() {
@@ -938,7 +938,7 @@ func (x *RecentMessagesRequest) GetConversationIds() []string {
return nil
}
func (x *RecentMessagesRequest) GetLimitPerConversation() *wrappers.Int32Value {
func (x *RecentMessagesRequest) GetLimitPerConversation() *wrapperspb.Int32Value {
if x != nil {
return x.LimitPerConversation
}
@@ -1189,9 +1189,9 @@ var file_proto_threads_proto_goTypes = []interface{}{
(*ListMessagesResponse)(nil), // 15: threads.ListMessagesResponse
(*RecentMessagesRequest)(nil), // 16: threads.RecentMessagesRequest
(*RecentMessagesResponse)(nil), // 17: threads.RecentMessagesResponse
(*timestamp.Timestamp)(nil), // 18: google.protobuf.Timestamp
(*wrappers.StringValue)(nil), // 19: google.protobuf.StringValue
(*wrappers.Int32Value)(nil), // 20: google.protobuf.Int32Value
(*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp
(*wrapperspb.StringValue)(nil), // 19: google.protobuf.StringValue
(*wrapperspb.Int32Value)(nil), // 20: google.protobuf.Int32Value
}
var file_proto_threads_proto_depIdxs = []int32{
18, // 0: threads.Conversation.created_at:type_name -> google.protobuf.Timestamp

View File

@@ -6,8 +6,8 @@ package threads
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/timestamp"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/timestamppb"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package threads;
option go_package = "proto;threads";
option go_package = "./proto;threads";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

View File

@@ -12,7 +12,7 @@ proto:
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/users.proto
@redoc-cli bundle api-users.json
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:

View File

@@ -1,6 +1,7 @@
package handler_test
import (
"os"
"testing"
"time"
@@ -14,21 +15,25 @@ import (
func testHandler(t *testing.T) *handler.Users {
// connect to the database
db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/users?sslmode=disable"), &gorm.Config{})
addr := os.Getenv("POSTGRES_URL")
if len(addr) == 0 {
addr = "postgresql://postgres@localhost:5432/postgres?sslmode=disable"
}
db, err := gorm.Open(postgres.Open(addr), &gorm.Config{})
if err != nil {
t.Fatalf("Error connecting to database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("DROP TABLE IF EXISTS users, tokens CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
// migrate the database
if err := db.AutoMigrate(&handler.User{}, &handler.Token{}); err != nil {
t.Fatalf("Error migrating database: %v", err)
}
// clean any data from a previous run
if err := db.Exec("TRUNCATE TABLE users, tokens CASCADE").Error; err != nil {
t.Fatalf("Error cleaning database: %v", err)
}
return &handler.Users{DB: db, Time: time.Now}
}

View File

@@ -1,16 +1,15 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.23.0
// protoc v3.13.0
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/users.proto
package users
import (
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
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"
)
@@ -22,10 +21,6 @@ const (
_ = 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 User struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -416,11 +411,11 @@ type UpdateRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
FirstName *wrappers.StringValue `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"`
LastName *wrappers.StringValue `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"`
Email *wrappers.StringValue `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"`
Password *wrappers.StringValue `protobuf:"bytes,5,opt,name=password,proto3" json:"password,omitempty"`
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() {
@@ -462,28 +457,28 @@ func (x *UpdateRequest) GetId() string {
return ""
}
func (x *UpdateRequest) GetFirstName() *wrappers.StringValue {
func (x *UpdateRequest) GetFirstName() *wrapperspb.StringValue {
if x != nil {
return x.FirstName
}
return nil
}
func (x *UpdateRequest) GetLastName() *wrappers.StringValue {
func (x *UpdateRequest) GetLastName() *wrapperspb.StringValue {
if x != nil {
return x.LastName
}
return nil
}
func (x *UpdateRequest) GetEmail() *wrappers.StringValue {
func (x *UpdateRequest) GetEmail() *wrapperspb.StringValue {
if x != nil {
return x.Email
}
return nil
}
func (x *UpdateRequest) GetPassword() *wrappers.StringValue {
func (x *UpdateRequest) GetPassword() *wrapperspb.StringValue {
if x != nil {
return x.Password
}
@@ -1123,7 +1118,8 @@ var file_proto_users_proto_rawDesc = []byte{
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, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
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 (
@@ -1140,28 +1136,28 @@ func file_proto_users_proto_rawDescGZIP() []byte {
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
(*wrappers.StringValue)(nil), // 21: google.protobuf.StringValue
(*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

View File

@@ -6,7 +6,7 @@ package users
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/wrappers"
_ "google.golang.org/protobuf/types/known/wrapperspb"
math "math"
)

View File

@@ -1,7 +1,7 @@
syntax = "proto3";
package users;
option go_package = "proto;users";
option go_package = "./proto;users";
import "google/protobuf/wrappers.proto";
service Users {
@@ -101,4 +101,4 @@ message ValidateRequest {
message ValidateResponse {
User user = 1;
}
}