From a61911ee411b0c6ea1d9ee7ca7bb97c5fbdf84c3 Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Sun, 5 Jul 2020 17:56:59 +0200 Subject: [PATCH 001/267] store contact us in a new collection --- cmd/api/main.go | 6 ++++- deployments/nats.yaml | 24 +++++++++++++++++ deployments/secrets.yaml | 21 +++++++++++++++ go.mod | 3 ++- go.sum | 2 ++ internal/infra/docstore.go | 4 +++ pkg/content/repository.go | 33 +++++++++++++++++++++++ pkg/content/repository_mock.go | 47 +++++++++++++++++++++++++++++++++ pkg/content/repository_test.go | 18 +++++++++++++ pkg/content/service.go | 48 +++------------------------------- pkg/content/types.go | 14 ++++++++++ 11 files changed, 174 insertions(+), 46 deletions(-) create mode 100644 deployments/nats.yaml create mode 100644 deployments/secrets.yaml create mode 100644 pkg/content/repository.go create mode 100644 pkg/content/repository_mock.go create mode 100644 pkg/content/repository_test.go create mode 100644 pkg/content/types.go diff --git a/cmd/api/main.go b/cmd/api/main.go index 6520a90..3cbd623 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -43,6 +43,10 @@ func main() { ensureNoError(err, "user:docstore collection") defer userColl.Close() + contactUsColl, err := infra.NewContactUsCollection() + ensureNoError(err, "content:ContactUs collection") + defer contactUsColl.Close() + topic, err := infra.NewTopic(os.Getenv("TOPIC_CAPTURE")) ensureNoError(err, "pubsub topic capture") defer topic.Shutdown(context.Background()) @@ -62,7 +66,7 @@ func main() { tweetService := tweet.NewService(tweet.NewRepository(tweetColl), searchService, userService, twitterApi, logger, topic) ensureNotNil(tweetService, "tweet:NewService") - contentService := content.NewService(os.Getenv("SENDGRID_APIKEY")) + contentService := content.NewService(content.NewRepository(contactUsColl)) ensureNotNil(contentService, "content service") rootResolver := graph.NewResolver() diff --git a/deployments/nats.yaml b/deployments/nats.yaml new file mode 100644 index 0000000..0d6aece --- /dev/null +++ b/deployments/nats.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nats + labels: + app: nats + version: v1 +spec: + containers: + - name: nats-standalone + image: nats + ports: + - containerPort: 4222 +--- +apiVersion: v1 +kind: Service +metadata: + name: nats +spec: + ports: + - port: 4222 + selector: + app: nats + version: v1 diff --git a/deployments/secrets.yaml b/deployments/secrets.yaml new file mode 100644 index 0000000..80cacd2 --- /dev/null +++ b/deployments/secrets.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Secret +metadata: + name: connection-secrets +type: Opague +stringData: + MONGO_SERVER_URL: "mongodb://***REMOVED***:***REMOVED***@mongodb:27017" + TWITTER_ACCESS_SECRET: "***REMOVED***" + TWITTER_ACCESS_TOKEN: "***REMOVED***" + TWITTER_CONSUMER_KEY: "***REMOVED***" + TWITTER_CONSUMER_SECRET: "***REMOVED***" + GRAPHQL_ENABLE_PLAYGROUND: "false" + ALGOLIA_SECRET: "***REMOVED***" + ALGOLIA_CLIENT_ID: "***REMOVED***" + ALGOLIA_INDEX: "tweets-K8S" + DOCSTORE_TWEETS: "mongo://capturetweet/tweets?id_field=id" + DOCSTORE_USERS: "mongo://capturetweet/authors?id_field=id" + TOPIC_CAPTURE: "nats://capture.request" + NATS_SERVER_URL: "nats://nats:4222" + SENDGRID_TEMPLATE_ID: "***REMOVED***" + SENDGRID_APIKEY: "***REMOVED***" diff --git a/go.mod b/go.mod index fa04052..43aa96c 100644 --- a/go.mod +++ b/go.mod @@ -17,12 +17,13 @@ require ( github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.0.3 // indirect github.com/golang/mock v1.4.3 + github.com/google/uuid v1.1.1 github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/joho/godotenv v1.3.0 github.com/mitchellh/mapstructure v1.3.2 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 - github.com/rs/cors v1.6.0 + github.com/rs/cors v1.7.0 github.com/stretchr/testify v1.6.1 github.com/vektah/gqlparser/v2 v2.0.1 go.uber.org/zap v1.15.0 diff --git a/go.sum b/go.sum index 1b973f4..a1729ed 100644 --- a/go.sum +++ b/go.sum @@ -347,6 +347,8 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= diff --git a/internal/infra/docstore.go b/internal/infra/docstore.go index 2ddf373..0a9396c 100644 --- a/internal/infra/docstore.go +++ b/internal/infra/docstore.go @@ -29,3 +29,7 @@ func NewTweetCollection() (*docstore.Collection, error) { func NewUserCollection() (*docstore.Collection, error) { return NewDocstore(os.Getenv("DOCSTORE_USERS")) } + +func NewContactUsCollection() (*docstore.Collection, error) { + return NewDocstore(os.Getenv("DOCSTORE_CONTACT_US")) +} diff --git a/pkg/content/repository.go b/pkg/content/repository.go new file mode 100644 index 0000000..eafd6d0 --- /dev/null +++ b/pkg/content/repository.go @@ -0,0 +1,33 @@ +//go:generate mockgen -package=content -self_package=com.capturetweet/pkg/content -destination=repository_mock.go . Repository +package content + +import ( + "context" + "github.com/google/uuid" + "gocloud.dev/docstore" + "time" +) + +type Repository interface { + ContactUs(email, fullName, message string) error +} + +type repositoryImpl struct { + contactUs *docstore.Collection +} + +func NewRepository(contactUs *docstore.Collection) Repository { + return &repositoryImpl{contactUs} +} + +func (r repositoryImpl) ContactUs(email, fullName, message string) error { + + id := uuid.New().String() + return r.contactUs.Create(context.Background(), &ContactUs{ + ID: id, + CreatedAt: time.Now(), + Email: email, + FullName: fullName, + Message: message, + }) +} diff --git a/pkg/content/repository_mock.go b/pkg/content/repository_mock.go new file mode 100644 index 0000000..ca90ca5 --- /dev/null +++ b/pkg/content/repository_mock.go @@ -0,0 +1,47 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: com.capturetweet/pkg/content (interfaces: Repository) + +// Package content is a generated GoMock package. +package content + +import ( + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockRepository is a mock of Repository interface. +type MockRepository struct { + ctrl *gomock.Controller + recorder *MockRepositoryMockRecorder +} + +// MockRepositoryMockRecorder is the mock recorder for MockRepository. +type MockRepositoryMockRecorder struct { + mock *MockRepository +} + +// NewMockRepository creates a new mock instance. +func NewMockRepository(ctrl *gomock.Controller) *MockRepository { + mock := &MockRepository{ctrl: ctrl} + mock.recorder = &MockRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { + return m.recorder +} + +// ContactUs mocks base method. +func (m *MockRepository) ContactUs(arg0, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContactUs", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContactUs indicates an expected call of ContactUs. +func (mr *MockRepositoryMockRecorder) ContactUs(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContactUs", reflect.TypeOf((*MockRepository)(nil).ContactUs), arg0, arg1, arg2) +} diff --git a/pkg/content/repository_test.go b/pkg/content/repository_test.go new file mode 100644 index 0000000..d5fef09 --- /dev/null +++ b/pkg/content/repository_test.go @@ -0,0 +1,18 @@ +package content + +import ( + "com.capturetweet/internal/infra" + "github.com/stretchr/testify/require" + "testing" +) + +func TestRepository_ContactUS(t *testing.T) { + coll, err := infra.NewDocstore("mem://collection/id") + require.NoError(t, err) + defer coll.Close() + + repo := NewRepository(coll) + + err = repo.ContactUs("test", "ramazan", "hello") + require.NoError(t, err) +} diff --git a/pkg/content/service.go b/pkg/content/service.go index 749ad61..f358e24 100644 --- a/pkg/content/service.go +++ b/pkg/content/service.go @@ -1,57 +1,17 @@ package content import ( - "bytes" "com.capturetweet/pkg/service" - "fmt" - "log" - "net/http" - "os" ) type serviceImpl struct { - apiKey string + repo Repository } -func NewService(apiKey string) service.ContentService { - return &serviceImpl{apiKey} +func NewService(repo Repository) service.ContentService { + return &serviceImpl{repo} } func (s serviceImpl) SendMail(senderMail, senderName, message string) error { - body := bytes.NewBufferString(fmt.Sprintf(`{ - "personalizations": [ - { - "to": [ - { - "email": "rayyildiz@ymail.com", - "name": "Ramazan AYYILDIZ" - } - ], - "dynamic_template_data": { - "name": "%s", - "mail": "%s", - "message": "%s" - }, - "subject": "[CaptureTweet] Contact us" - } - ], - "from": { - "email": "%s", - "name": "%s" - }, - "template_id": "%s" -}`, senderName, senderMail, message, senderMail, senderName, os.Getenv("SENDGRID_TEMPLATE_ID"))) - - request, err := http.NewRequest("POST", "https://api.sendgrid.com/v3/mail/send", body) - if err != nil { - return err - } - request.Header.Set("authorization", "Bearer "+s.apiKey) - request.Header.Set("content-type", "application/json") - response, err := http.DefaultClient.Do(request) - if err != nil { - return err - } - log.Printf("http send response %v", response.Status) - return nil + return s.repo.ContactUs(senderMail, senderMail, message) } diff --git a/pkg/content/types.go b/pkg/content/types.go new file mode 100644 index 0000000..2aff391 --- /dev/null +++ b/pkg/content/types.go @@ -0,0 +1,14 @@ +package content + +import ( + "time" +) + +type ContactUs struct { + ID string `docstore:"id"` + CreatedAt time.Time `docstore:"created_at"` + Email string `docstore:"email"` + FullName string `docstore:"full_name"` + Message string `docstore:"message"` + DocstoreRevision interface{} +} From 33ea5272dcec268c2a94f7e0c33adfcee64cf81d Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Sun, 5 Jul 2020 18:22:58 +0200 Subject: [PATCH 002/267] added sentry --- cmd/api/main.go | 5 ++ cmd/capture/handler.go | 14 +++-- cmd/capture/main.go | 5 ++ cmd/sitemap/handler.go | 9 +-- cmd/sitemap/main.go | 5 ++ cmd/thumb/handler.go | 25 ++++++--- cmd/thumb/main.go | 5 ++ go.mod | 1 + go.sum | 118 +++++++++++++++++++++++++++++++++++++++ internal/infra/sentry.go | 16 ++++++ pkg/graph/mutation.go | 6 +- pkg/graph/query.go | 3 + 12 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 internal/infra/sentry.go diff --git a/cmd/api/main.go b/cmd/api/main.go index 3cbd623..7d79f5d 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -3,6 +3,7 @@ package main import ( "com.capturetweet/pkg/content" "context" + "github.com/getsentry/sentry-go" "log" "net/http" "os" @@ -25,6 +26,10 @@ func init() { } func main() { + err := infra.InitSentry() + ensureNoError(err, "sentry init") + + defer sentry.Flush(time.Second * 2) start := time.Now() port := os.Getenv("PORT") diff --git a/cmd/capture/handler.go b/cmd/capture/handler.go index 18210cb..f765282 100644 --- a/cmd/capture/handler.go +++ b/cmd/capture/handler.go @@ -3,6 +3,7 @@ package main import ( "com.capturetweet/pkg/service" "encoding/json" + "github.com/getsentry/sentry-go" "go.uber.org/zap" "net/http" ) @@ -25,17 +26,17 @@ func (h handlerImpl) handleCapture(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if r.Method != http.MethodPost { - w.WriteHeader(http.StatusMethodNotAllowed) - http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) h.log.Warn("method not allowed", zap.String("method", r.Method)) + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) return } var payload PubSubMessage err := json.NewDecoder(r.Body).Decode(&payload) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("bad request", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } defer r.Body.Close() @@ -43,16 +44,17 @@ func (h handlerImpl) handleCapture(w http.ResponseWriter, r *http.Request) { request := service.CaptureRequestModel{} err = json.Unmarshal(payload.Message.Data, &request) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("bad request, decode payload.data", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } respModel, err := h.service.CaptureSaveUpdateDatabase(&request) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + sentry.CaptureException(err) h.log.Error("could not capture", zap.String("tweet_id", request.ID), zap.String("url", request.Url), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } diff --git a/cmd/capture/main.go b/cmd/capture/main.go index 56620e2..a2c57c4 100644 --- a/cmd/capture/main.go +++ b/cmd/capture/main.go @@ -4,6 +4,7 @@ import ( "com.capturetweet/internal/infra" "com.capturetweet/pkg/browser" "com.capturetweet/pkg/tweet" + "github.com/getsentry/sentry-go" "github.com/joho/godotenv" "go.uber.org/zap" "log" @@ -17,6 +18,10 @@ func init() { } func main() { + err := infra.InitSentry() + ensureNoError(err, "sentry init") + defer sentry.Flush(time.Second * 2) + start := time.Now() logger := infra.NewLogger() ensureNotNil(logger, "zap:logger") diff --git a/cmd/sitemap/handler.go b/cmd/sitemap/handler.go index 8fe2ec7..36157ff 100644 --- a/cmd/sitemap/handler.go +++ b/cmd/sitemap/handler.go @@ -5,6 +5,7 @@ import ( "com.capturetweet/pkg/tweet" "context" "fmt" + "github.com/getsentry/sentry-go" "go.uber.org/zap" "gocloud.dev/blob" "net/http" @@ -38,17 +39,17 @@ func (h handlerImpl) handleRequest(w http.ResponseWriter, r *http.Request) { tweets, err := h.repo.FindAllOrderByUpdated(size) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + sentry.CaptureException(err) h.log.Warn("could not get repositories", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } err = createSitemap(r.Context(), h.log, h.bucket, tweets) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + sentry.CaptureException(err) h.log.Warn("could not get create sitemap", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } diff --git a/cmd/sitemap/main.go b/cmd/sitemap/main.go index d6e2491..238829c 100644 --- a/cmd/sitemap/main.go +++ b/cmd/sitemap/main.go @@ -3,6 +3,7 @@ package main import ( "com.capturetweet/internal/infra" "com.capturetweet/pkg/tweet" + "github.com/getsentry/sentry-go" "github.com/joho/godotenv" . "go.uber.org/zap" "log" @@ -16,6 +17,10 @@ func init() { } func main() { + err := infra.InitSentry() + ensureNoError(err, "sentry init") + defer sentry.Flush(time.Second * 2) + start := time.Now() port := os.Getenv("PORT") diff --git a/cmd/thumb/handler.go b/cmd/thumb/handler.go index 8fe5043..5546ac1 100644 --- a/cmd/thumb/handler.go +++ b/cmd/thumb/handler.go @@ -6,6 +6,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/getsentry/sentry-go" "github.com/nfnt/resize" "go.uber.org/zap" "gocloud.dev/blob" @@ -51,8 +52,9 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { var payload PubSubMessage err := json.NewDecoder(r.Body).Decode(&payload) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("bad request", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } defer r.Body.Close() @@ -60,8 +62,9 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { request := StorageMessage{} err = json.Unmarshal(payload.Message.Data, &request) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("bad request, decode payload.data", zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -77,15 +80,17 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { img, err := h.bucket.ReadAll(ctx, request.Name) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("open bucket", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } attrs, err := h.bucket.Attributes(ctx, request.Name) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("read image attributes", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -95,8 +100,9 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { decoder, _, err := image.Decode(bytes.NewBuffer(img)) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("image decode", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -109,8 +115,9 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { buf := new(bytes.Buffer) err = jpeg.Encode(buf, newImage, nil) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("jpeg encode image", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -125,16 +132,18 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { }, }) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("open bucket for thumbnail", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } h.log.Info("image stored successfully", zap.String("image_key", thumbNailKey), zap.String("image_key", request.Name), zap.String("tweet_id", tweetId), zap.String("tweet_user", tweetUser)) err = h.service.UpdateThumbImage(tweetId, thumbNailKey) if err != nil { - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + sentry.CaptureException(err) h.log.Error("save in database", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } diff --git a/cmd/thumb/main.go b/cmd/thumb/main.go index 4227745..f92973b 100644 --- a/cmd/thumb/main.go +++ b/cmd/thumb/main.go @@ -3,6 +3,7 @@ package main import ( "com.capturetweet/internal/infra" "com.capturetweet/pkg/tweet" + "github.com/getsentry/sentry-go" "github.com/joho/godotenv" "go.uber.org/zap" "log" @@ -16,6 +17,10 @@ func init() { } func main() { + err := infra.InitSentry() + ensureNoError(err, "sentry init") + defer sentry.Flush(time.Second * 2) + start := time.Now() logger := infra.NewLogger() ensureNotNil(logger, "zap:logger") diff --git a/go.mod b/go.mod index 43aa96c..5d8792d 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc // indirect github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 // indirect + github.com/getsentry/sentry-go v0.6.1 github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.0.3 // indirect github.com/golang/mock v1.4.3 diff --git a/go.sum b/go.sum index a1729ed..3e04958 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,7 @@ contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcig dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4= github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= @@ -87,22 +88,30 @@ github.com/ChimeraCoder/anaconda v2.0.0+incompatible h1:F0eD7CHXieZ+VLboCD5UAqCe github.com/ChimeraCoder/anaconda v2.0.0+incompatible/go.mod h1:TCt3MijIq3Qqo9SBtuW/rrM4x7rDfWqYWHj8T7hLcLg= github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 h1:r+EmXjfPosKO4wfiMLe1XQictsIlhErTufbWUsjOTZs= github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7/go.mod h1:b2EuEMLSG9q3bZ95ql1+8oVqzzrTNSiOQqSXWFBzxeI= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/algolia/algoliasearch-client-go/v3 v3.8.0 h1:B1W2ZtnOvy7LsZu//otvll27FVGZfE8huUAYTMvmvcM= github.com/algolia/algoliasearch-client-go/v3 v3.8.0/go.mod h1:i7tLoP7TYDmHX3Q7vkIOL4syVse/k5VJ+k0i8WqFiJk= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.31.13 h1:UeWMTRTL0XAKLR7vxDL4/u7KOtz/LtfJr+lXtxN4YEQ= github.com/aws/aws-sdk-go v1.31.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 h1:ekDALXAVvY/Ub1UtNta3inKQwZ/jMB/zpOtD8rAYh78= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330/go.mod h1:nH+k0SvAt3HeiYyOlJpLLv1HG1p7KWP7qU9QPp2/pCo= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -118,36 +127,58 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc h1:tP7tkU+vIsEOKiK+l/NSLN4uUtkyuxc6hgYpQeCWAeI= github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc/go.mod h1:ORH5Qp2bskd9NzSfKqAF7tKfONsEkCarTE5ESr/RVBw= github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad h1:Qk76DOWdOp+GlyDKBAG3Klr9cn7N+LcYc82AZ2S7+cA= github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad/go.mod h1:mPKfmRa823oBIgl2r20LeMSpTAteW5j7FLkc0vjmzyQ= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 h1:GOfMz6cRgTJ9jWV0qAezv642OhPnKEG7gtUjJSdStHE= github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN6fkKKaPSAeNq/er3xObxTW4VLeY6UUK895gLQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.6.1 h1:K84dY1/57OtWhdyr5lbU78Q/+qgzkEyGc/ud+Sipi5k= +github.com/getsentry/sentry-go v0.6.1/go.mod h1:0yZBuzSvbZwBnvaF9VwZIMen3kXscY8/uasKtAX1qG8= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -215,6 +246,7 @@ github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 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= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -223,6 +255,7 @@ 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 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.0 h1:AX7FUb4BjrrzNvblr/OlgwrmFiep6soj5K2QSDW7BGk= @@ -248,36 +281,59 @@ github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.8 h1:eLeJ3dr/Y9+XRfJT4l+8ZjmtB5RPJhucH2HeCV5+IZY= github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08 h1:V0an7KRw92wmJysvFvtqtKMAPmvS5O0jtB0nYo6t+gs= github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08/go.mod h1:dFWs1zEqDjFtnBXsd1vPOZaLsESovai349994nHx3e0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -287,9 +343,12 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= @@ -298,13 +357,20 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg= github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -312,7 +378,10 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/nats-io/jwt v0.2.6/go.mod h1:mQxQ0uHQ9FhEVPIcTSKwx2lqZEpXWWcCgA7R6NrWvvY= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/jwt v1.0.1 h1:71ivoESdfT2K/qDiw5YwX/3W9/dR7c+m83xiGOj/EZ4= @@ -331,9 +400,15 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -349,8 +424,11 @@ github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 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/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= @@ -360,8 +438,15 @@ github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJV github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= @@ -377,8 +462,17 @@ 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/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o= @@ -388,6 +482,14 @@ github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhe github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +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.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= @@ -463,9 +565,12 @@ golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -474,6 +579,7 @@ golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -508,6 +614,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03i golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -520,7 +628,9 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -555,12 +665,15 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -696,6 +809,11 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/infra/sentry.go b/internal/infra/sentry.go new file mode 100644 index 0000000..3d8ea75 --- /dev/null +++ b/internal/infra/sentry.go @@ -0,0 +1,16 @@ +package infra + +import ( + "github.com/getsentry/sentry-go" + "os" +) + +func InitSentry() error { + dsn := os.Getenv("SENTRY_DSN") + if len(dsn) > 0 { + return sentry.Init(sentry.ClientOptions{ + Dsn: dsn, + }) + } + return nil +} diff --git a/pkg/graph/mutation.go b/pkg/graph/mutation.go index 4865754..84a07ef 100644 --- a/pkg/graph/mutation.go +++ b/pkg/graph/mutation.go @@ -4,6 +4,7 @@ import ( "com.capturetweet/internal/convert" "context" "errors" + "github.com/getsentry/sentry-go" "go.uber.org/zap" ) @@ -17,12 +18,14 @@ func newMutationResolver() MutationResolver { func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, error) { id, err := _twitterService.Store(url) if err != nil { + sentry.CaptureException(err) _log.Error("capture error", zap.String("url", url), zap.Error(err)) return nil, err } model, err := _twitterService.FindById(id) if err != nil { + sentry.CaptureException(err) _log.Error("capture error, findById", zap.String("id", id), zap.Error(err)) return nil, err } @@ -55,8 +58,9 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, func (r mutationResolverImpl) Contact(ctx context.Context, input ContactInput) (string, error) { err := _contentService.SendMail(input.Email, input.FullName, input.Message) if err != nil { + sentry.CaptureException(err) _log.Error("could not send mail", zap.String("contact_email", input.Email), zap.String("contact_fullName", input.FullName), zap.Error(err)) return "", errors.New("error occurred, please try again or contact from info@capturetweet.com mail address") } - return "we had your message and we will contact you as soon as possible, thanks for feedback", nil + return "we saved your message and we will contact you as soon as possible, thanks for feedback", nil } diff --git a/pkg/graph/query.go b/pkg/graph/query.go index 888454c..9cf7bfd 100644 --- a/pkg/graph/query.go +++ b/pkg/graph/query.go @@ -4,6 +4,7 @@ import ( "com.capturetweet/internal/convert" "context" "errors" + "github.com/getsentry/sentry-go" "go.uber.org/zap" "gocloud.dev/gcerrors" ) @@ -24,6 +25,7 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) } if err != nil { + sentry.CaptureException(err) _log.Error("tweet find error", zap.String("id", id), zap.Error(err)) return nil, err } @@ -56,6 +58,7 @@ func (r queryResolverImpl) Search(ctx context.Context, input SearchInput, size i models, err := _twitterService.Search(input.Term, size, start, page) if err != nil { + sentry.CaptureException(err) _log.Error("search error", zap.String("term", input.Term), zap.Error(err)) return nil, errors.New("could not ind any result") } From 05a4929f5ecb51c9e4df6117e84ab99b43ab7ce5 Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Sun, 5 Jul 2020 22:59:16 +0200 Subject: [PATCH 003/267] first telemetry try --- cmd/api/main.go | 3 +++ go.mod | 5 +++++ go.sum | 31 +++++++++++++++++++++++++++++++ internal/infra/trace.go | 41 +++++++++++++++++++++++++++++++++++++++++ pkg/graph/mutation.go | 14 ++++++++++++++ pkg/graph/query.go | 12 ++++++++++++ 6 files changed, 106 insertions(+) create mode 100644 internal/infra/trace.go diff --git a/cmd/api/main.go b/cmd/api/main.go index 7d79f5d..790e680 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -37,6 +37,9 @@ func main() { port = "4000" } + err = infra.InitTrace() + ensureNoError(err, "init tracer") + logger := infra.NewLogger() ensureNotNil(logger, "zap:logger") diff --git a/go.mod b/go.mod index 5d8792d..c4ef2df 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module com.capturetweet go 1.14 require ( + cloud.google.com/go v0.60.0 // indirect github.com/99designs/gqlgen v0.11.3 github.com/ChimeraCoder/anaconda v2.0.0+incompatible github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0 github.com/agnivade/levenshtein v1.1.0 // indirect github.com/algolia/algoliasearch-client-go/v3 v3.8.0 github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 // indirect @@ -27,6 +29,8 @@ require ( github.com/rs/cors v1.7.0 github.com/stretchr/testify v1.6.1 github.com/vektah/gqlparser/v2 v2.0.1 + go.opencensus.io v0.22.4 // indirect + go.opentelemetry.io/otel v0.7.0 go.uber.org/zap v1.15.0 gocloud.dev v0.20.0 gocloud.dev/docstore/mongodocstore v0.20.0 @@ -35,6 +39,7 @@ require ( golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect golang.org/x/text v0.3.3 // indirect golang.org/x/tools v0.0.0-20200702044944-0cc1aa72b347 // indirect + google.golang.org/genproto v0.0.0-20200702021140-07506425bd67 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/go.sum b/go.sum index 3e04958..4d40bec 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.58.0 h1:vtAfVc723K3xKq1BQydk/FyCldnaNFhGhpJxaJzgRMQ= cloud.google.com/go v0.58.0/go.mod h1:W+9FnSUw6nhVwXlFcp1eL+krq5+HQUJeUogSeJZZiWg= +cloud.google.com/go v0.60.0 h1:R+tDlceO7Ss+zyvtsdhTxacDyZ1k99xwskQ4FT7ruoM= +cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -90,7 +92,11 @@ github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 h1:r+EmXj github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7/go.mod h1:b2EuEMLSG9q3bZ95ql1+8oVqzzrTNSiOQqSXWFBzxeI= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go v0.2.1 h1:k2teLLhREL6kjdzr27RHe5fn5JWOZ+xQiuYE3PRjtAE= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0 h1:d/0HrwVskjLkJIz70Gn9ADURRNaNdTGOkQ1TiuCOefU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0/go.mod h1:Ps0PAOihxzMbs4J2PWLffeKwJo3Bka6LHMLP6r/K0l8= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -114,6 +120,8 @@ github.com/aws/aws-sdk-go v1.31.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 h1:ekDALXAVvY/Ub1UtNta3inKQwZ/jMB/zpOtD8rAYh78= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330/go.mod h1:nH+k0SvAt3HeiYyOlJpLLv1HG1p7KWP7qU9QPp2/pCo= +github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= 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/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac h1:T7V5BXqnYd55Hj/g5uhDYumg9Fp3rMTS6bykYtTIFX4= @@ -255,11 +263,14 @@ 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 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.0 h1:AX7FUb4BjrrzNvblr/OlgwrmFiep6soj5K2QSDW7BGk= github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -405,6 +416,7 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -500,6 +512,12 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io v0.1.0 h1:EANZoRCOP+A3faIlw/iN6YEWoYb1vleZRKm1EvH8T48= +go.opentelemetry.io/otel v0.5.0/go.mod h1:jzBIgIzK43Iu1BpDAXwqOd6UPsSAk+ewVZ5ofSXw4Ek= +go.opentelemetry.io/otel v0.7.0 h1:u43jukpwqR8EsyeJOMgrsUgZwVI1e1eVw7yuzRkD1l0= +go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= @@ -720,6 +738,7 @@ golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200608174601-1b747fd94509 h1:MI14dOfl3OG6Zd32w3ugsrvcUO810fDZdWakTq39dH4= golang.org/x/tools v0.0.0-20200608174601-1b747fd94509/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200702044944-0cc1aa72b347 h1:/e4fNMHdLn7SQSxTrRZTma2xjQW6ELdxcnpqMhpo9X4= golang.org/x/tools v0.0.0-20200702044944-0cc1aa72b347/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -742,6 +761,8 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08= google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0 h1:jMF5hhVfMkTZwHW1SDpKq5CkgWLXOb31Foaca9Zr3oM= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -760,6 +781,7 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -770,6 +792,7 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200303153909-beee998c1893/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200317114155-1f3552e48f24/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -782,6 +805,9 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200603110839-e855014d5736/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8= google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200702021140-07506425bd67 h1:4BC1C1i30F3MZeiIO6y6IIo4DxrtOwITK87bQl3lhFA= +google.golang.org/genproto v0.0.0-20200702021140-07506425bd67/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -794,6 +820,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -804,6 +832,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= 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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -817,6 +847,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= diff --git a/internal/infra/trace.go b/internal/infra/trace.go new file mode 100644 index 0000000..c790b12 --- /dev/null +++ b/internal/infra/trace.go @@ -0,0 +1,41 @@ +package infra + +import ( + "fmt" + export "go.opentelemetry.io/otel/sdk/export/trace" + "os" + + texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" + "go.opentelemetry.io/otel/api/global" + "go.opentelemetry.io/otel/exporters/trace/stdout" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +func InitTrace() error { + projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") + + var exporter export.SpanSyncer + if len(projectID) > 0 { + exo, err := texporter.NewExporter(texporter.WithProjectID(projectID)) + if err != nil { + return fmt.Errorf("texporter.NewExporter: %v", err) + } + exporter = exo + + } else { + exo, err := stdout.NewExporter(stdout.Options{PrettyPrint: true}) + if err != nil { + return err + } + + exporter = exo + } + + tp, err := sdktrace.NewProvider(sdktrace.WithSyncer(exporter)) + if err != nil { + return err + } + global.SetTraceProvider(tp) + + return nil +} diff --git a/pkg/graph/mutation.go b/pkg/graph/mutation.go index 84a07ef..ea152ec 100644 --- a/pkg/graph/mutation.go +++ b/pkg/graph/mutation.go @@ -5,6 +5,8 @@ import ( "context" "errors" "github.com/getsentry/sentry-go" + "go.opentelemetry.io/otel/api/global" + "go.opentelemetry.io/otel/api/kv" "go.uber.org/zap" ) @@ -16,12 +18,17 @@ func newMutationResolver() MutationResolver { } func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, error) { + tr := global.Tracer("capturetweet/api") + spanCtx, span := tr.Start(ctx, "capture") + defer span.End() + id, err := _twitterService.Store(url) if err != nil { sentry.CaptureException(err) _log.Error("capture error", zap.String("url", url), zap.Error(err)) return nil, err } + span.AddEvent(spanCtx, "tweet captured", kv.String("id", id)) model, err := _twitterService.FindById(id) if err != nil { @@ -29,6 +36,7 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, _log.Error("capture error, findById", zap.String("id", id), zap.Error(err)) return nil, err } + span.AddEvent(spanCtx, "tweet captured, get details", kv.String("id", id)) var resources []*Resource for _, res := range model.Resources { @@ -56,11 +64,17 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, } func (r mutationResolverImpl) Contact(ctx context.Context, input ContactInput) (string, error) { + tr := global.Tracer("capturetweet/api") + spanCtx, span := tr.Start(ctx, "capture") + defer span.End() + err := _contentService.SendMail(input.Email, input.FullName, input.Message) if err != nil { sentry.CaptureException(err) _log.Error("could not send mail", zap.String("contact_email", input.Email), zap.String("contact_fullName", input.FullName), zap.Error(err)) + span.AddEvent(spanCtx, "could not insert", kv.String("email", input.Email)) return "", errors.New("error occurred, please try again or contact from info@capturetweet.com mail address") } + span.AddEvent(spanCtx, "successfully stored the contact", kv.String("email", input.Email)) return "we saved your message and we will contact you as soon as possible, thanks for feedback", nil } diff --git a/pkg/graph/query.go b/pkg/graph/query.go index 9cf7bfd..68f55ee 100644 --- a/pkg/graph/query.go +++ b/pkg/graph/query.go @@ -5,6 +5,8 @@ import ( "context" "errors" "github.com/getsentry/sentry-go" + "go.opentelemetry.io/otel/api/global" + "go.opentelemetry.io/otel/api/kv" "go.uber.org/zap" "gocloud.dev/gcerrors" ) @@ -17,10 +19,15 @@ func newQueryResolver() QueryResolver { } func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) { + tr := global.Tracer("capturetweet/api") + spanCtx, span := tr.Start(ctx, "tweet") + defer span.End() + model, err := _twitterService.FindById(id) code := gcerrors.Code(err) if code == gcerrors.NotFound { _log.Warn("tweet not found", zap.String("id", id)) + span.AddEvent(spanCtx, "tweet not found", kv.String("id", id)) return nil, nil } @@ -29,6 +36,7 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) _log.Error("tweet find error", zap.String("id", id), zap.Error(err)) return nil, err } + span.AddEvent(spanCtx, "found tweet", kv.String("id", id)) var resources []*Resource for _, res := range model.Resources { resources = append(resources, &Resource{ @@ -55,6 +63,9 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) } func (r queryResolverImpl) Search(ctx context.Context, input SearchInput, size int, page int, start int) ([]*Tweet, error) { + tr := global.Tracer("capturetweet/api") + spanCtx, span := tr.Start(ctx, "search") + defer span.End() models, err := _twitterService.Search(input.Term, size, start, page) if err != nil { @@ -62,6 +73,7 @@ func (r queryResolverImpl) Search(ctx context.Context, input SearchInput, size i _log.Error("search error", zap.String("term", input.Term), zap.Error(err)) return nil, errors.New("could not ind any result") } + span.AddEvent(spanCtx, "search result", kv.Int("length", len(models))) var list []*Tweet for _, model := range models { From f9224c905aeebc24326e22c1ee5f3ca3227849b0 Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Sun, 5 Jul 2020 23:18:47 +0200 Subject: [PATCH 004/267] first telemetry try --- cmd/api/main.go | 3 --- go.mod | 3 +-- go.sum | 15 --------------- internal/infra/trace.go | 41 ----------------------------------------- pkg/graph/mutation.go | 15 --------------- pkg/graph/query.go | 13 ------------- 6 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 internal/infra/trace.go diff --git a/cmd/api/main.go b/cmd/api/main.go index 790e680..7d79f5d 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -37,9 +37,6 @@ func main() { port = "4000" } - err = infra.InitTrace() - ensureNoError(err, "init tracer") - logger := infra.NewLogger() ensureNotNil(logger, "zap:logger") diff --git a/go.mod b/go.mod index c4ef2df..ac1446e 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/99designs/gqlgen v0.11.3 github.com/ChimeraCoder/anaconda v2.0.0+incompatible github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0 github.com/agnivade/levenshtein v1.1.0 // indirect github.com/algolia/algoliasearch-client-go/v3 v3.8.0 github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 // indirect @@ -30,7 +29,6 @@ require ( github.com/stretchr/testify v1.6.1 github.com/vektah/gqlparser/v2 v2.0.1 go.opencensus.io v0.22.4 // indirect - go.opentelemetry.io/otel v0.7.0 go.uber.org/zap v1.15.0 gocloud.dev v0.20.0 gocloud.dev/docstore/mongodocstore v0.20.0 @@ -40,6 +38,7 @@ require ( golang.org/x/text v0.3.3 // indirect golang.org/x/tools v0.0.0-20200702044944-0cc1aa72b347 // indirect google.golang.org/genproto v0.0.0-20200702021140-07506425bd67 // indirect + google.golang.org/grpc v1.30.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/go.sum b/go.sum index 4d40bec..49943a7 100644 --- a/go.sum +++ b/go.sum @@ -92,11 +92,7 @@ github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 h1:r+EmXj github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7/go.mod h1:b2EuEMLSG9q3bZ95ql1+8oVqzzrTNSiOQqSXWFBzxeI= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= -github.com/GoogleCloudPlatform/opentelemetry-operations-go v0.2.1 h1:k2teLLhREL6kjdzr27RHe5fn5JWOZ+xQiuYE3PRjtAE= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0 h1:d/0HrwVskjLkJIz70Gn9ADURRNaNdTGOkQ1TiuCOefU= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.2.0/go.mod h1:Ps0PAOihxzMbs4J2PWLffeKwJo3Bka6LHMLP6r/K0l8= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -120,8 +116,6 @@ github.com/aws/aws-sdk-go v1.31.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 h1:ekDALXAVvY/Ub1UtNta3inKQwZ/jMB/zpOtD8rAYh78= github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330/go.mod h1:nH+k0SvAt3HeiYyOlJpLLv1HG1p7KWP7qU9QPp2/pCo= -github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= 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/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac h1:T7V5BXqnYd55Hj/g5uhDYumg9Fp3rMTS6bykYtTIFX4= @@ -270,7 +264,6 @@ github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxG github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.0 h1:AX7FUb4BjrrzNvblr/OlgwrmFiep6soj5K2QSDW7BGk= github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -416,7 +409,6 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -514,10 +506,6 @@ go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io v0.1.0 h1:EANZoRCOP+A3faIlw/iN6YEWoYb1vleZRKm1EvH8T48= -go.opentelemetry.io/otel v0.5.0/go.mod h1:jzBIgIzK43Iu1BpDAXwqOd6UPsSAk+ewVZ5ofSXw4Ek= -go.opentelemetry.io/otel v0.7.0 h1:u43jukpwqR8EsyeJOMgrsUgZwVI1e1eVw7yuzRkD1l0= -go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= @@ -781,7 +769,6 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -792,7 +779,6 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200303153909-beee998c1893/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200317114155-1f3552e48f24/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -847,7 +833,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= diff --git a/internal/infra/trace.go b/internal/infra/trace.go deleted file mode 100644 index c790b12..0000000 --- a/internal/infra/trace.go +++ /dev/null @@ -1,41 +0,0 @@ -package infra - -import ( - "fmt" - export "go.opentelemetry.io/otel/sdk/export/trace" - "os" - - texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/exporters/trace/stdout" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -func InitTrace() error { - projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") - - var exporter export.SpanSyncer - if len(projectID) > 0 { - exo, err := texporter.NewExporter(texporter.WithProjectID(projectID)) - if err != nil { - return fmt.Errorf("texporter.NewExporter: %v", err) - } - exporter = exo - - } else { - exo, err := stdout.NewExporter(stdout.Options{PrettyPrint: true}) - if err != nil { - return err - } - - exporter = exo - } - - tp, err := sdktrace.NewProvider(sdktrace.WithSyncer(exporter)) - if err != nil { - return err - } - global.SetTraceProvider(tp) - - return nil -} diff --git a/pkg/graph/mutation.go b/pkg/graph/mutation.go index ea152ec..ee360a4 100644 --- a/pkg/graph/mutation.go +++ b/pkg/graph/mutation.go @@ -5,8 +5,6 @@ import ( "context" "errors" "github.com/getsentry/sentry-go" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" "go.uber.org/zap" ) @@ -18,17 +16,12 @@ func newMutationResolver() MutationResolver { } func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, error) { - tr := global.Tracer("capturetweet/api") - spanCtx, span := tr.Start(ctx, "capture") - defer span.End() - id, err := _twitterService.Store(url) if err != nil { sentry.CaptureException(err) _log.Error("capture error", zap.String("url", url), zap.Error(err)) return nil, err } - span.AddEvent(spanCtx, "tweet captured", kv.String("id", id)) model, err := _twitterService.FindById(id) if err != nil { @@ -36,8 +29,6 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, _log.Error("capture error, findById", zap.String("id", id), zap.Error(err)) return nil, err } - span.AddEvent(spanCtx, "tweet captured, get details", kv.String("id", id)) - var resources []*Resource for _, res := range model.Resources { resources = append(resources, &Resource{ @@ -64,17 +55,11 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, } func (r mutationResolverImpl) Contact(ctx context.Context, input ContactInput) (string, error) { - tr := global.Tracer("capturetweet/api") - spanCtx, span := tr.Start(ctx, "capture") - defer span.End() - err := _contentService.SendMail(input.Email, input.FullName, input.Message) if err != nil { sentry.CaptureException(err) _log.Error("could not send mail", zap.String("contact_email", input.Email), zap.String("contact_fullName", input.FullName), zap.Error(err)) - span.AddEvent(spanCtx, "could not insert", kv.String("email", input.Email)) return "", errors.New("error occurred, please try again or contact from info@capturetweet.com mail address") } - span.AddEvent(spanCtx, "successfully stored the contact", kv.String("email", input.Email)) return "we saved your message and we will contact you as soon as possible, thanks for feedback", nil } diff --git a/pkg/graph/query.go b/pkg/graph/query.go index 68f55ee..5f4e1dd 100644 --- a/pkg/graph/query.go +++ b/pkg/graph/query.go @@ -5,8 +5,6 @@ import ( "context" "errors" "github.com/getsentry/sentry-go" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" "go.uber.org/zap" "gocloud.dev/gcerrors" ) @@ -19,15 +17,10 @@ func newQueryResolver() QueryResolver { } func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) { - tr := global.Tracer("capturetweet/api") - spanCtx, span := tr.Start(ctx, "tweet") - defer span.End() - model, err := _twitterService.FindById(id) code := gcerrors.Code(err) if code == gcerrors.NotFound { _log.Warn("tweet not found", zap.String("id", id)) - span.AddEvent(spanCtx, "tweet not found", kv.String("id", id)) return nil, nil } @@ -36,7 +29,6 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) _log.Error("tweet find error", zap.String("id", id), zap.Error(err)) return nil, err } - span.AddEvent(spanCtx, "found tweet", kv.String("id", id)) var resources []*Resource for _, res := range model.Resources { resources = append(resources, &Resource{ @@ -63,17 +55,12 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) } func (r queryResolverImpl) Search(ctx context.Context, input SearchInput, size int, page int, start int) ([]*Tweet, error) { - tr := global.Tracer("capturetweet/api") - spanCtx, span := tr.Start(ctx, "search") - defer span.End() - models, err := _twitterService.Search(input.Term, size, start, page) if err != nil { sentry.CaptureException(err) _log.Error("search error", zap.String("term", input.Term), zap.Error(err)) return nil, errors.New("could not ind any result") } - span.AddEvent(spanCtx, "search result", kv.Int("length", len(models))) var list []*Tweet for _, model := range models { From 8889f63047281f042ff6a081a8ad00f33c324f15 Mon Sep 17 00:00:00 2001 From: Ramazan A Date: Mon, 6 Jul 2020 13:17:14 +0200 Subject: [PATCH 005/267] Update ci.yml --- .github/workflows/ci.yml | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 350b18e..f888179 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,25 +11,20 @@ jobs: build: name: Build runs-on: ubuntu-latest - + env: + CGO_ENABLED: "1" + steps: - - name: Set up Go 1.14 - uses: actions/setup-go@v1 + - uses: actions/checkout@v1 + + - uses: actions/setup-go@v1 with: go-version: 1.14 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v1 - - - name: Get dependencies - run: go mod download - env: - CGO_ENABLED: 1 + + - run: go mod download - - name: Test - run: go test -cover -coverprofile=coverage.txt -covermode=atomic ./... + - run: go test -cover -coverprofile=coverage.txt -covermode=atomic ./... - - uses: codecov/codecov-action@v1.0.7 + - uses: codecov/codecov-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} From 8e189af55db44e44e0f13739e1da5fe85a6600a7 Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Tue, 7 Jul 2020 22:07:23 +0200 Subject: [PATCH 006/267] increment the retry timeout --- pkg/browser/service.go | 2 +- web/app/src/pages/TweetPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/browser/service.go b/pkg/browser/service.go index 7880ce4..51bd90d 100644 --- a/pkg/browser/service.go +++ b/pkg/browser/service.go @@ -118,7 +118,7 @@ func (s *serviceImpl) CaptureURL(model *service.CaptureRequestModel) ([]byte, er func fullScreenshot(url string, quality int64, res *[]byte) chromedp.Tasks { return chromedp.Tasks{ chromedp.Navigate(url), - chromedp.Sleep(time.Millisecond * 2000), + chromedp.Sleep(time.Millisecond * 3000), chromedp.ActionFunc(func(ctx context.Context) error { // get layout metrics _, _, contentSize, err := page.GetLayoutMetrics().Do(ctx) diff --git a/web/app/src/pages/TweetPage.tsx b/web/app/src/pages/TweetPage.tsx index ca01a3b..7bc6c64 100644 --- a/web/app/src/pages/TweetPage.tsx +++ b/web/app/src/pages/TweetPage.tsx @@ -86,7 +86,7 @@ const TweetImageCard: FC = ({id}) => { }) useEffect(() => { - startPolling(1500); + startPolling(1900); return () => stopPolling(); }, [id, startPolling, stopPolling]) From 9e9cc5aab348daf444659969515ec6e3e8862298 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2020 13:24:24 +0000 Subject: [PATCH 007/267] Bump github.com/algolia/algoliasearch-client-go/v3 from 3.8.0 to 3.8.2 Bumps [github.com/algolia/algoliasearch-client-go/v3](https://github.com/algolia/algoliasearch-client-go) from 3.8.0 to 3.8.2. - [Release notes](https://github.com/algolia/algoliasearch-client-go/releases) - [Changelog](https://github.com/algolia/algoliasearch-client-go/blob/master/ChangeLog.md) - [Commits](https://github.com/algolia/algoliasearch-client-go/compare/v3.8.0...v3.8.2) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ac1446e..05c6ff5 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/ChimeraCoder/anaconda v2.0.0+incompatible github.com/ChimeraCoder/tokenbucket v0.0.0-20131201223612-c5a927568de7 // indirect github.com/agnivade/levenshtein v1.1.0 // indirect - github.com/algolia/algoliasearch-client-go/v3 v3.8.0 + github.com/algolia/algoliasearch-client-go/v3 v3.8.2 github.com/azr/backoff v0.0.0-20160115115103-53511d3c7330 // indirect github.com/chromedp/cdproto v0.0.0-20200608134039-8a80cdaf865c github.com/chromedp/chromedp v0.5.3 diff --git a/go.sum b/go.sum index 49943a7..6ae6c42 100644 --- a/go.sum +++ b/go.sum @@ -102,8 +102,11 @@ github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6 github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/algolia/algoliasearch-client-go v2.25.0+incompatible h1:FGQr9l++u4uQPDXrW8jM5kNJm3Iw5SxEJJtYXSFmPRY= github.com/algolia/algoliasearch-client-go/v3 v3.8.0 h1:B1W2ZtnOvy7LsZu//otvll27FVGZfE8huUAYTMvmvcM= github.com/algolia/algoliasearch-client-go/v3 v3.8.0/go.mod h1:i7tLoP7TYDmHX3Q7vkIOL4syVse/k5VJ+k0i8WqFiJk= +github.com/algolia/algoliasearch-client-go/v3 v3.8.2 h1:ZTY1PQeN2zGQEbFUOxJIYEsPEz9g+bKG24iUmKWirfY= +github.com/algolia/algoliasearch-client-go/v3 v3.8.2/go.mod h1:i7tLoP7TYDmHX3Q7vkIOL4syVse/k5VJ+k0i8WqFiJk= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= From 3807a9c01711ac00b0071bfd2216efc468cf7809 Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Fri, 10 Jul 2020 20:09:13 +0200 Subject: [PATCH 008/267] move services to /api folder rename cmd/api as cmd/server --- pkg/service/interfaces.go => api/service.go | 4 +-- .../interfaces_mock.go => api/service_mock.go | 6 ++-- {pkg/service => api}/types.go | 2 +- cmd/capture/handler.go | 6 ++-- cmd/{api => server}/Dockerfile | 0 cmd/{api => server}/cloudbuild.yaml | 6 ++-- cmd/{api => server}/main.go | 0 cmd/thumb/handler.go | 4 +-- pkg/browser/service.go | 14 +++++----- pkg/content/service.go | 4 +-- pkg/graph/resolver.go | 12 ++++---- pkg/search/service.go | 10 +++---- pkg/search/service_test.go | 4 +-- pkg/tweet/service.go | 28 +++++++++---------- pkg/user/service.go | 14 +++++----- 15 files changed, 57 insertions(+), 57 deletions(-) rename pkg/service/interfaces.go => api/service.go (83%) rename pkg/service/interfaces_mock.go => api/service_mock.go (98%) rename {pkg/service => api}/types.go (98%) rename cmd/{api => server}/Dockerfile (100%) rename cmd/{api => server}/cloudbuild.yaml (90%) rename cmd/{api => server}/main.go (100%) diff --git a/pkg/service/interfaces.go b/api/service.go similarity index 83% rename from pkg/service/interfaces.go rename to api/service.go index c6dc80d..3b17d14 100644 --- a/pkg/service/interfaces.go +++ b/api/service.go @@ -1,5 +1,5 @@ -//go:generate mockgen -package=service -self_package=com.capturetweet/pkg/service -destination=interfaces_mock.go . UserService,TweetService,SearchService,BrowserService,ContentService -package service +//go:generate mockgen -package=api -self_package=com.capturetweet/api -destination=service_mock.go . UserService,TweetService,SearchService,BrowserService,ContentService +package api import ( "github.com/ChimeraCoder/anaconda" diff --git a/pkg/service/interfaces_mock.go b/api/service_mock.go similarity index 98% rename from pkg/service/interfaces_mock.go rename to api/service_mock.go index 0fef9b9..6995e8e 100644 --- a/pkg/service/interfaces_mock.go +++ b/api/service_mock.go @@ -1,8 +1,8 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: com.capturetweet/pkg/service (interfaces: UserService,TweetService,SearchService,BrowserService,ContentService) +// Source: com.capturetweet/api (interfaces: UserService,TweetService,SearchService,BrowserService,ContentService) -// Package service is a generated GoMock package. -package service +// Package api is a generated GoMock package. +package api import ( anaconda "github.com/ChimeraCoder/anaconda" diff --git a/pkg/service/types.go b/api/types.go similarity index 98% rename from pkg/service/types.go rename to api/types.go index a0bcf2b..5356b14 100644 --- a/pkg/service/types.go +++ b/api/types.go @@ -1,4 +1,4 @@ -package service +package api import ( "time" diff --git a/cmd/capture/handler.go b/cmd/capture/handler.go index f765282..3bc5b45 100644 --- a/cmd/capture/handler.go +++ b/cmd/capture/handler.go @@ -1,7 +1,7 @@ package main import ( - "com.capturetweet/pkg/service" + "com.capturetweet/api" "encoding/json" "github.com/getsentry/sentry-go" "go.uber.org/zap" @@ -10,7 +10,7 @@ import ( type handlerImpl struct { log *zap.Logger - service service.BrowserService + service api.BrowserService } type PubSubMessage struct { @@ -41,7 +41,7 @@ func (h handlerImpl) handleCapture(w http.ResponseWriter, r *http.Request) { } defer r.Body.Close() - request := service.CaptureRequestModel{} + request := api.CaptureRequestModel{} err = json.Unmarshal(payload.Message.Data, &request) if err != nil { sentry.CaptureException(err) diff --git a/cmd/api/Dockerfile b/cmd/server/Dockerfile similarity index 100% rename from cmd/api/Dockerfile rename to cmd/server/Dockerfile diff --git a/cmd/api/cloudbuild.yaml b/cmd/server/cloudbuild.yaml similarity index 90% rename from cmd/api/cloudbuild.yaml rename to cmd/server/cloudbuild.yaml index 46d642b..4dcc42e 100644 --- a/cmd/api/cloudbuild.yaml +++ b/cmd/server/cloudbuild.yaml @@ -2,15 +2,15 @@ steps: - name: 'golang:1.14' args: ['go', 'build', '-a', '-installsuffix','cgo', '-o' ,'tmp/app','.'] env: ['GO111MODULE=on','CGO_ENABLED=0','GOOS=linux'] - dir: 'cmd/api' + dir: 'cmd/server' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' args: ['docker','build', '-f', 'Dockerfile', '--tag=eu.gcr.io/$PROJECT_ID/api:$SHORT_SHA', '.'] - dir: 'cmd/api' + dir: 'cmd/server' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' args: ['docker','push', 'eu.gcr.io/$PROJECT_ID/api:$SHORT_SHA'] - dir: 'cmd/api' + dir: 'cmd/server' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' args: ['gcloud', 'run','deploy','api','--image','eu.gcr.io/$PROJECT_ID/api:$SHORT_SHA', '--platform', 'managed','--region','europe-west1'] diff --git a/cmd/api/main.go b/cmd/server/main.go similarity index 100% rename from cmd/api/main.go rename to cmd/server/main.go diff --git a/cmd/thumb/handler.go b/cmd/thumb/handler.go index 5546ac1..4113f8f 100644 --- a/cmd/thumb/handler.go +++ b/cmd/thumb/handler.go @@ -2,7 +2,7 @@ package main import ( "bytes" - "com.capturetweet/pkg/service" + "com.capturetweet/api" "context" "encoding/json" "fmt" @@ -34,7 +34,7 @@ type StorageMessage struct { type handlerImpl struct { log *zap.Logger - service service.TweetService + service api.TweetService bucket *blob.Bucket } diff --git a/pkg/browser/service.go b/pkg/browser/service.go index 51bd90d..c860a0b 100644 --- a/pkg/browser/service.go +++ b/pkg/browser/service.go @@ -1,7 +1,7 @@ package browser import ( - "com.capturetweet/pkg/service" + "com.capturetweet/api" "context" "fmt" "github.com/chromedp/cdproto/emulation" @@ -15,7 +15,7 @@ import ( type serviceImpl struct { log *zap.Logger - tweetService service.TweetService + tweetService api.TweetService bucket *blob.Bucket browser *browserCtx } @@ -25,11 +25,11 @@ type browserCtx struct { cancelFunc context.CancelFunc } -func NewService(log *zap.Logger, tweetService service.TweetService, bucket *blob.Bucket) service.BrowserService { +func NewService(log *zap.Logger, tweetService api.TweetService, bucket *blob.Bucket) api.BrowserService { return &serviceImpl{log, tweetService, bucket, nil} } -func (s serviceImpl) CaptureSaveUpdateDatabase(model *service.CaptureRequestModel) (*service.CaptureResponseModel, error) { +func (s serviceImpl) CaptureSaveUpdateDatabase(model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { originalImage, err := s.CaptureURL(model) if err != nil { @@ -56,7 +56,7 @@ func (s serviceImpl) CaptureSaveUpdateDatabase(model *service.CaptureRequestMode return response, nil } -func (s serviceImpl) SaveCapture(originalImage []byte, model *service.CaptureRequestModel) (*service.CaptureResponseModel, error) { +func (s serviceImpl) SaveCapture(originalImage []byte, model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { imageKey := fmt.Sprintf("capture/large/%s.jpg", model.ID) err := s.bucket.WriteAll(context.Background(), imageKey, originalImage, &blob.WriterOptions{ @@ -74,7 +74,7 @@ func (s serviceImpl) SaveCapture(originalImage []byte, model *service.CaptureReq return nil, err } - return &service.CaptureResponseModel{ + return &api.CaptureResponseModel{ ID: model.ID, CaptureURL: imageKey, }, nil @@ -86,7 +86,7 @@ func (s serviceImpl) Close() { } } -func (s *serviceImpl) CaptureURL(model *service.CaptureRequestModel) ([]byte, error) { +func (s *serviceImpl) CaptureURL(model *api.CaptureRequestModel) ([]byte, error) { if s.browser == nil { opts := []chromedp.ExecAllocatorOption{ chromedp.DisableGPU, diff --git a/pkg/content/service.go b/pkg/content/service.go index f358e24..87e0d57 100644 --- a/pkg/content/service.go +++ b/pkg/content/service.go @@ -1,14 +1,14 @@ package content import ( - "com.capturetweet/pkg/service" + "com.capturetweet/api" ) type serviceImpl struct { repo Repository } -func NewService(repo Repository) service.ContentService { +func NewService(repo Repository) api.ContentService { return &serviceImpl{repo} } diff --git a/pkg/graph/resolver.go b/pkg/graph/resolver.go index 32653d4..69fa320 100644 --- a/pkg/graph/resolver.go +++ b/pkg/graph/resolver.go @@ -2,7 +2,7 @@ package graph import ( - "com.capturetweet/pkg/service" + "com.capturetweet/api" "go.uber.org/zap" ) @@ -22,13 +22,13 @@ func (r resolver) Query() QueryResolver { } var ( - _twitterService service.TweetService = nil - _userService service.UserService = nil - _log *zap.Logger = nil - _contentService service.ContentService = nil + _twitterService api.TweetService = nil + _userService api.UserService = nil + _log *zap.Logger = nil + _contentService api.ContentService = nil ) -func InitService(log *zap.Logger, twitterService service.TweetService, userService service.UserService, contentService service.ContentService) { +func InitService(log *zap.Logger, twitterService api.TweetService, userService api.UserService, contentService api.ContentService) { _twitterService = twitterService _userService = userService _log = log diff --git a/pkg/search/service.go b/pkg/search/service.go index 1680087..263c509 100644 --- a/pkg/search/service.go +++ b/pkg/search/service.go @@ -1,8 +1,8 @@ package search import ( + "com.capturetweet/api" "com.capturetweet/internal/infra" - "com.capturetweet/pkg/service" "github.com/algolia/algoliasearch-client-go/v3/algolia/opt" ) @@ -10,16 +10,16 @@ type serviceImpl struct { index infra.IndexInterface } -func NewService(index infra.IndexInterface) service.SearchService { +func NewService(index infra.IndexInterface) api.SearchService { return &serviceImpl{index} } -func (s serviceImpl) Search(term string, size int) ([]service.SearchModel, error) { +func (s serviceImpl) Search(term string, size int) ([]api.SearchModel, error) { res, err := s.index.Search(term, opt.HitsPerPage(size)) if err != nil { return nil, err } - var list []service.SearchModel + var list []api.SearchModel err = res.UnmarshalHits(&list) if err != nil { @@ -29,7 +29,7 @@ func (s serviceImpl) Search(term string, size int) ([]service.SearchModel, error } func (s serviceImpl) Put(tweetId, fullText, author string) error { - _, err := s.index.SaveObject(service.SearchModel{ + _, err := s.index.SaveObject(api.SearchModel{ TweetID: tweetId, FullText: fullText, Author: author, diff --git a/pkg/search/service_test.go b/pkg/search/service_test.go index e1634e6..bc80686 100644 --- a/pkg/search/service_test.go +++ b/pkg/search/service_test.go @@ -1,8 +1,8 @@ package search import ( + "com.capturetweet/api" "com.capturetweet/internal/infra" - "com.capturetweet/pkg/service" "github.com/algolia/algoliasearch-client-go/v3/algolia/search" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -54,7 +54,7 @@ func TestService_Put(t *testing.T) { defer ctrl.Finish() algolia := infra.NewMockIndexInterface(ctrl) - algolia.EXPECT().SaveObject(service.SearchModel{ + algolia.EXPECT().SaveObject(api.SearchModel{ TweetID: "1", FullText: "test", Author: "RAYYILDIZ", diff --git a/pkg/tweet/service.go b/pkg/tweet/service.go index d62c97b..fa0650e 100644 --- a/pkg/tweet/service.go +++ b/pkg/tweet/service.go @@ -1,9 +1,9 @@ package tweet import ( + "com.capturetweet/api" "com.capturetweet/internal/convert" "com.capturetweet/internal/infra" - "com.capturetweet/pkg/service" "context" "encoding/json" "fmt" @@ -16,27 +16,27 @@ import ( type serviceImpl struct { repo Repository twitterAPI infra.TweetAPI - search service.SearchService - user service.UserService + search api.SearchService + user api.UserService log *zap.Logger topic *pubsub.Topic } -func NewService(repo Repository, search service.SearchService, userService service.UserService, twitterAPI infra.TweetAPI, log *zap.Logger, topic *pubsub.Topic) service.TweetService { +func NewService(repo Repository, search api.SearchService, userService api.UserService, twitterAPI infra.TweetAPI, log *zap.Logger, topic *pubsub.Topic) api.TweetService { return &serviceImpl{repo, twitterAPI, search, userService, log, topic} } -func (s serviceImpl) FindById(id string) (*service.TweetModel, error) { +func (s serviceImpl) FindById(id string) (*api.TweetModel, error) { tweet, err := s.repo.FindById(id) if err != nil { s.log.Error("tweet:service findById", zap.String("tweet_id", id), zap.Error(err)) return nil, err } - var resources []service.ResourceModel + var resources []api.ResourceModel for _, res := range tweet.Resources { - resources = append(resources, service.ResourceModel{ + resources = append(resources, api.ResourceModel{ ID: res.ID, URL: res.URL, Width: res.Width, @@ -45,7 +45,7 @@ func (s serviceImpl) FindById(id string) (*service.TweetModel, error) { }) } - return &service.TweetModel{ + return &api.TweetModel{ ID: tweet.ID, PostedAt: convert.Time(tweet.PostedAt), FullText: tweet.FullText, @@ -95,7 +95,7 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { go func(id, author, url string) { - data, err := json.Marshal(service.CaptureRequestModel{ + data, err := json.Marshal(api.CaptureRequestModel{ ID: id, Author: author, Url: url, @@ -123,7 +123,7 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { return tweetIdStr, nil } -func (s serviceImpl) Search(term string, size, start, page int) ([]service.TweetModel, error) { +func (s serviceImpl) Search(term string, size, start, page int) ([]api.TweetModel, error) { searchModels, err := s.search.Search(term, size) if err != nil { s.log.Error("tweet:service search, search service call", zap.String("search_term", term), zap.Error(err)) @@ -141,13 +141,13 @@ func (s serviceImpl) Search(term string, size, start, page int) ([]service.Tweet return nil, err } - var res []service.TweetModel + var res []api.TweetModel for _, tweet := range tweets { - var resources []service.ResourceModel + var resources []api.ResourceModel for _, res := range tweet.Resources { - resources = append(resources, service.ResourceModel{ + resources = append(resources, api.ResourceModel{ ID: res.ID, URL: res.URL, Width: res.Width, @@ -156,7 +156,7 @@ func (s serviceImpl) Search(term string, size, start, page int) ([]service.Tweet }) } - res = append(res, service.TweetModel{ + res = append(res, api.TweetModel{ ID: tweet.ID, FullText: tweet.FullText, Lang: tweet.Lang, diff --git a/pkg/user/service.go b/pkg/user/service.go index d7a411f..ce05146 100644 --- a/pkg/user/service.go +++ b/pkg/user/service.go @@ -1,8 +1,8 @@ package user import ( + "com.capturetweet/api" "com.capturetweet/internal/convert" - "com.capturetweet/pkg/service" "github.com/ChimeraCoder/anaconda" "go.uber.org/zap" "time" @@ -13,18 +13,18 @@ type serviceImpl struct { log *zap.Logger } -func NewService(repo Repository, log *zap.Logger) service.UserService { +func NewService(repo Repository, log *zap.Logger) api.UserService { return &serviceImpl{repo, log} } -func (s serviceImpl) FindById(id string) (*service.UserModel, error) { +func (s serviceImpl) FindById(id string) (*api.UserModel, error) { user, err := s.repo.FindById(id) if err != nil { s.log.Error("user:service findById", zap.String("tweet_id", id), zap.Error(err)) return nil, err } - return &service.UserModel{ + return &api.UserModel{ ID: user.ID, UserName: user.Username, ScreenName: user.ScreenName, @@ -33,12 +33,12 @@ func (s serviceImpl) FindById(id string) (*service.UserModel, error) { }, nil } -func (s serviceImpl) FindOrCreate(author *anaconda.User) (*service.UserModel, error) { +func (s serviceImpl) FindOrCreate(author *anaconda.User) (*api.UserModel, error) { id := author.IdStr user, err := s.repo.FindById(id) if user != nil { - return &service.UserModel{ + return &api.UserModel{ ID: user.ID, UserName: user.Username, ScreenName: user.ScreenName, @@ -58,7 +58,7 @@ func (s serviceImpl) FindOrCreate(author *anaconda.User) (*service.UserModel, er return nil, err } - return &service.UserModel{ + return &api.UserModel{ ID: id, UserName: author.ScreenName, ScreenName: author.Name, From bc5b49d4e161ce89853cf30ca09849ec4551b04c Mon Sep 17 00:00:00 2001 From: Ramazan AYYILDIZ Date: Sun, 12 Jul 2020 12:51:45 +0200 Subject: [PATCH 009/267] added context support --- api/service.go | 27 +- api/service_mock.go | 105 +- cmd/capture/handler.go | 2 +- cmd/thumb/handler.go | 2 +- go.sum | 2 + gqlgen.yml | 2 +- internal/convert/primitive.go | 3 + pkg/browser/service.go | 16 +- pkg/content/repository.go | 6 +- pkg/content/repository_mock.go | 9 +- pkg/content/repository_test.go | 3 +- pkg/content/service.go | 5 +- pkg/graph/gen_interfaces.go | 2 +- pkg/graph/mutation.go | 6 +- pkg/graph/query.go | 4 +- pkg/graph/types.go | 3 +- pkg/search/service.go | 5 +- pkg/search/service_test.go | 5 +- pkg/tweet/repository.go | 44 +- pkg/tweet/repository_mock.go | 57 +- pkg/tweet/repository_test.go | 28 +- pkg/tweet/service.go | 30 +- pkg/user/repository.go | 20 +- pkg/user/repository_mock.go | 25 +- pkg/user/repository_test.go | 18 +- pkg/user/service.go | 11 +- pkg/user/service_test.go | 19 +- schema.graphqls => schema.graphql | 0 web/app/Makefile | 2 +- web/app/package.json | 24 +- web/app/src/components/Search.tsx | 4 +- web/app/src/pages/ContactPage.tsx | 11 +- web/app/src/pages/HomePage.css | 11 +- web/app/src/pages/HomePage.tsx | 12 +- web/app/src/pages/SearchPage.tsx | 2 +- web/app/src/pages/TweetPage.tsx | 12 +- web/app/yarn.lock | 1480 +++++++++++++++-------------- 37 files changed, 1042 insertions(+), 975 deletions(-) rename schema.graphqls => schema.graphql (100%) diff --git a/api/service.go b/api/service.go index 3b17d14..16860f7 100644 --- a/api/service.go +++ b/api/service.go @@ -2,39 +2,40 @@ package api import ( + "context" "github.com/ChimeraCoder/anaconda" ) type UserService interface { - FindById(id string) (*UserModel, error) - FindOrCreate(user *anaconda.User) (*UserModel, error) + FindById(ctx context.Context, id string) (*UserModel, error) + FindOrCreate(ctx context.Context, user *anaconda.User) (*UserModel, error) } type TweetService interface { - FindById(id string) (*TweetModel, error) - Store(url string) (string, error) - Search(term string, size, start, page int) ([]TweetModel, error) - UpdateLargeImage(id, captureUrl string) error - UpdateThumbImage(id, captureUrl string) error + FindById(ctx context.Context, id string) (*TweetModel, error) + Store(ctx context.Context, url string) (string, error) + Search(ctx context.Context, term string, size, start, page int) ([]TweetModel, error) + UpdateLargeImage(ctx context.Context, id, captureUrl string) error + UpdateThumbImage(ctx context.Context, id, captureUrl string) error } type SearchService interface { - Search(term string, size int) ([]SearchModel, error) - Put(tweetId, fullText, author string) error + Search(ctx context.Context, term string, size int) ([]SearchModel, error) + Put(ctx context.Context, tweetId, fullText, author string) error } type BrowserService interface { // Capture and return a image (PNG) - CaptureURL(model *CaptureRequestModel) ([]byte, error) + CaptureURL(ctx context.Context, model *CaptureRequestModel) ([]byte, error) // Save in a bucket - SaveCapture(originalImage []byte, model *CaptureRequestModel) (*CaptureResponseModel, error) + SaveCapture(ctx context.Context, originalImage []byte, model *CaptureRequestModel) (*CaptureResponseModel, error) - CaptureSaveUpdateDatabase(model *CaptureRequestModel) (*CaptureResponseModel, error) + CaptureSaveUpdateDatabase(ctx context.Context, model *CaptureRequestModel) (*CaptureResponseModel, error) Close() } type ContentService interface { - SendMail(senderMail, senderName, message string) error + SendMail(ctx context.Context, senderMail, senderName, message string) error } diff --git a/api/service_mock.go b/api/service_mock.go index 6995e8e..440e5f3 100644 --- a/api/service_mock.go +++ b/api/service_mock.go @@ -5,6 +5,7 @@ package api import ( + context "context" anaconda "github.com/ChimeraCoder/anaconda" gomock "github.com/golang/mock/gomock" reflect "reflect" @@ -34,33 +35,33 @@ func (m *MockUserService) EXPECT() *MockUserServiceMockRecorder { } // FindById mocks base method. -func (m *MockUserService) FindById(arg0 string) (*UserModel, error) { +func (m *MockUserService) FindById(arg0 context.Context, arg1 string) (*UserModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindById", arg0) + ret := m.ctrl.Call(m, "FindById", arg0, arg1) ret0, _ := ret[0].(*UserModel) ret1, _ := ret[1].(error) return ret0, ret1 } // FindById indicates an expected call of FindById. -func (mr *MockUserServiceMockRecorder) FindById(arg0 interface{}) *gomock.Call { +func (mr *MockUserServiceMockRecorder) FindById(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockUserService)(nil).FindById), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockUserService)(nil).FindById), arg0, arg1) } // FindOrCreate mocks base method. -func (m *MockUserService) FindOrCreate(arg0 *anaconda.User) (*UserModel, error) { +func (m *MockUserService) FindOrCreate(arg0 context.Context, arg1 *anaconda.User) (*UserModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOrCreate", arg0) + ret := m.ctrl.Call(m, "FindOrCreate", arg0, arg1) ret0, _ := ret[0].(*UserModel) ret1, _ := ret[1].(error) return ret0, ret1 } // FindOrCreate indicates an expected call of FindOrCreate. -func (mr *MockUserServiceMockRecorder) FindOrCreate(arg0 interface{}) *gomock.Call { +func (mr *MockUserServiceMockRecorder) FindOrCreate(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOrCreate", reflect.TypeOf((*MockUserService)(nil).FindOrCreate), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOrCreate", reflect.TypeOf((*MockUserService)(nil).FindOrCreate), arg0, arg1) } // MockTweetService is a mock of TweetService interface. @@ -87,76 +88,76 @@ func (m *MockTweetService) EXPECT() *MockTweetServiceMockRecorder { } // FindById mocks base method. -func (m *MockTweetService) FindById(arg0 string) (*TweetModel, error) { +func (m *MockTweetService) FindById(arg0 context.Context, arg1 string) (*TweetModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindById", arg0) + ret := m.ctrl.Call(m, "FindById", arg0, arg1) ret0, _ := ret[0].(*TweetModel) ret1, _ := ret[1].(error) return ret0, ret1 } // FindById indicates an expected call of FindById. -func (mr *MockTweetServiceMockRecorder) FindById(arg0 interface{}) *gomock.Call { +func (mr *MockTweetServiceMockRecorder) FindById(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockTweetService)(nil).FindById), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockTweetService)(nil).FindById), arg0, arg1) } // Search mocks base method. -func (m *MockTweetService) Search(arg0 string, arg1, arg2, arg3 int) ([]TweetModel, error) { +func (m *MockTweetService) Search(arg0 context.Context, arg1 string, arg2, arg3, arg4 int) ([]TweetModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Search", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "Search", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].([]TweetModel) ret1, _ := ret[1].(error) return ret0, ret1 } // Search indicates an expected call of Search. -func (mr *MockTweetServiceMockRecorder) Search(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockTweetServiceMockRecorder) Search(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockTweetService)(nil).Search), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockTweetService)(nil).Search), arg0, arg1, arg2, arg3, arg4) } // Store mocks base method. -func (m *MockTweetService) Store(arg0 string) (string, error) { +func (m *MockTweetService) Store(arg0 context.Context, arg1 string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Store", arg0) + ret := m.ctrl.Call(m, "Store", arg0, arg1) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // Store indicates an expected call of Store. -func (mr *MockTweetServiceMockRecorder) Store(arg0 interface{}) *gomock.Call { +func (mr *MockTweetServiceMockRecorder) Store(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockTweetService)(nil).Store), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockTweetService)(nil).Store), arg0, arg1) } // UpdateLargeImage mocks base method. -func (m *MockTweetService) UpdateLargeImage(arg0, arg1 string) error { +func (m *MockTweetService) UpdateLargeImage(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateLargeImage", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateLargeImage", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // UpdateLargeImage indicates an expected call of UpdateLargeImage. -func (mr *MockTweetServiceMockRecorder) UpdateLargeImage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockTweetServiceMockRecorder) UpdateLargeImage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLargeImage", reflect.TypeOf((*MockTweetService)(nil).UpdateLargeImage), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLargeImage", reflect.TypeOf((*MockTweetService)(nil).UpdateLargeImage), arg0, arg1, arg2) } // UpdateThumbImage mocks base method. -func (m *MockTweetService) UpdateThumbImage(arg0, arg1 string) error { +func (m *MockTweetService) UpdateThumbImage(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateThumbImage", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateThumbImage", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // UpdateThumbImage indicates an expected call of UpdateThumbImage. -func (mr *MockTweetServiceMockRecorder) UpdateThumbImage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockTweetServiceMockRecorder) UpdateThumbImage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateThumbImage", reflect.TypeOf((*MockTweetService)(nil).UpdateThumbImage), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateThumbImage", reflect.TypeOf((*MockTweetService)(nil).UpdateThumbImage), arg0, arg1, arg2) } // MockSearchService is a mock of SearchService interface. @@ -183,32 +184,32 @@ func (m *MockSearchService) EXPECT() *MockSearchServiceMockRecorder { } // Put mocks base method. -func (m *MockSearchService) Put(arg0, arg1, arg2 string) error { +func (m *MockSearchService) Put(arg0 context.Context, arg1, arg2, arg3 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // Put indicates an expected call of Put. -func (mr *MockSearchServiceMockRecorder) Put(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSearchServiceMockRecorder) Put(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockSearchService)(nil).Put), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockSearchService)(nil).Put), arg0, arg1, arg2, arg3) } // Search mocks base method. -func (m *MockSearchService) Search(arg0 string, arg1 int) ([]SearchModel, error) { +func (m *MockSearchService) Search(arg0 context.Context, arg1 string, arg2 int) ([]SearchModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Search", arg0, arg1) + ret := m.ctrl.Call(m, "Search", arg0, arg1, arg2) ret0, _ := ret[0].([]SearchModel) ret1, _ := ret[1].(error) return ret0, ret1 } // Search indicates an expected call of Search. -func (mr *MockSearchServiceMockRecorder) Search(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSearchServiceMockRecorder) Search(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockSearchService)(nil).Search), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockSearchService)(nil).Search), arg0, arg1, arg2) } // MockBrowserService is a mock of BrowserService interface. @@ -235,33 +236,33 @@ func (m *MockBrowserService) EXPECT() *MockBrowserServiceMockRecorder { } // CaptureSaveUpdateDatabase mocks base method. -func (m *MockBrowserService) CaptureSaveUpdateDatabase(arg0 *CaptureRequestModel) (*CaptureResponseModel, error) { +func (m *MockBrowserService) CaptureSaveUpdateDatabase(arg0 context.Context, arg1 *CaptureRequestModel) (*CaptureResponseModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaptureSaveUpdateDatabase", arg0) + ret := m.ctrl.Call(m, "CaptureSaveUpdateDatabase", arg0, arg1) ret0, _ := ret[0].(*CaptureResponseModel) ret1, _ := ret[1].(error) return ret0, ret1 } // CaptureSaveUpdateDatabase indicates an expected call of CaptureSaveUpdateDatabase. -func (mr *MockBrowserServiceMockRecorder) CaptureSaveUpdateDatabase(arg0 interface{}) *gomock.Call { +func (mr *MockBrowserServiceMockRecorder) CaptureSaveUpdateDatabase(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaptureSaveUpdateDatabase", reflect.TypeOf((*MockBrowserService)(nil).CaptureSaveUpdateDatabase), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaptureSaveUpdateDatabase", reflect.TypeOf((*MockBrowserService)(nil).CaptureSaveUpdateDatabase), arg0, arg1) } // CaptureURL mocks base method. -func (m *MockBrowserService) CaptureURL(arg0 *CaptureRequestModel) ([]byte, error) { +func (m *MockBrowserService) CaptureURL(arg0 context.Context, arg1 *CaptureRequestModel) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaptureURL", arg0) + ret := m.ctrl.Call(m, "CaptureURL", arg0, arg1) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // CaptureURL indicates an expected call of CaptureURL. -func (mr *MockBrowserServiceMockRecorder) CaptureURL(arg0 interface{}) *gomock.Call { +func (mr *MockBrowserServiceMockRecorder) CaptureURL(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaptureURL", reflect.TypeOf((*MockBrowserService)(nil).CaptureURL), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaptureURL", reflect.TypeOf((*MockBrowserService)(nil).CaptureURL), arg0, arg1) } // Close mocks base method. @@ -277,18 +278,18 @@ func (mr *MockBrowserServiceMockRecorder) Close() *gomock.Call { } // SaveCapture mocks base method. -func (m *MockBrowserService) SaveCapture(arg0 []byte, arg1 *CaptureRequestModel) (*CaptureResponseModel, error) { +func (m *MockBrowserService) SaveCapture(arg0 context.Context, arg1 []byte, arg2 *CaptureRequestModel) (*CaptureResponseModel, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveCapture", arg0, arg1) + ret := m.ctrl.Call(m, "SaveCapture", arg0, arg1, arg2) ret0, _ := ret[0].(*CaptureResponseModel) ret1, _ := ret[1].(error) return ret0, ret1 } // SaveCapture indicates an expected call of SaveCapture. -func (mr *MockBrowserServiceMockRecorder) SaveCapture(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBrowserServiceMockRecorder) SaveCapture(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveCapture", reflect.TypeOf((*MockBrowserService)(nil).SaveCapture), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveCapture", reflect.TypeOf((*MockBrowserService)(nil).SaveCapture), arg0, arg1, arg2) } // MockContentService is a mock of ContentService interface. @@ -315,15 +316,15 @@ func (m *MockContentService) EXPECT() *MockContentServiceMockRecorder { } // SendMail mocks base method. -func (m *MockContentService) SendMail(arg0, arg1, arg2 string) error { +func (m *MockContentService) SendMail(arg0 context.Context, arg1, arg2, arg3 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendMail", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "SendMail", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // SendMail indicates an expected call of SendMail. -func (mr *MockContentServiceMockRecorder) SendMail(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockContentServiceMockRecorder) SendMail(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMail", reflect.TypeOf((*MockContentService)(nil).SendMail), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMail", reflect.TypeOf((*MockContentService)(nil).SendMail), arg0, arg1, arg2, arg3) } diff --git a/cmd/capture/handler.go b/cmd/capture/handler.go index 3bc5b45..e63ebda 100644 --- a/cmd/capture/handler.go +++ b/cmd/capture/handler.go @@ -50,7 +50,7 @@ func (h handlerImpl) handleCapture(w http.ResponseWriter, r *http.Request) { return } - respModel, err := h.service.CaptureSaveUpdateDatabase(&request) + respModel, err := h.service.CaptureSaveUpdateDatabase(r.Context(), &request) if err != nil { sentry.CaptureException(err) h.log.Error("could not capture", zap.String("tweet_id", request.ID), zap.String("url", request.Url), zap.Error(err)) diff --git a/cmd/thumb/handler.go b/cmd/thumb/handler.go index 4113f8f..823bb0f 100644 --- a/cmd/thumb/handler.go +++ b/cmd/thumb/handler.go @@ -139,7 +139,7 @@ func (h handlerImpl) handleResize(w http.ResponseWriter, r *http.Request) { } h.log.Info("image stored successfully", zap.String("image_key", thumbNailKey), zap.String("image_key", request.Name), zap.String("tweet_id", tweetId), zap.String("tweet_user", tweetUser)) - err = h.service.UpdateThumbImage(tweetId, thumbNailKey) + err = h.service.UpdateThumbImage(ctx, tweetId, thumbNailKey) if err != nil { sentry.CaptureException(err) h.log.Error("save in database", zap.String("image_key", request.Name), zap.String("image_kind", request.Kind), zap.Error(err)) diff --git a/go.sum b/go.sum index 6ae6c42..158309d 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,7 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcju github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -431,6 +432,7 @@ github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/gqlgen.yml b/gqlgen.yml index 3f49b49..41f8d5e 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -1,5 +1,5 @@ schema: - - schema.graphqls + - schema.graphql exec: filename: pkg/graph/gen_interfaces.go diff --git a/internal/convert/primitive.go b/internal/convert/primitive.go index 385947b..5ef3390 100644 --- a/internal/convert/primitive.go +++ b/internal/convert/primitive.go @@ -5,6 +5,9 @@ import ( ) func String(s string) *string { + if len(s) == 0 { + return nil + } return &s } diff --git a/pkg/browser/service.go b/pkg/browser/service.go index c860a0b..1b0f9c8 100644 --- a/pkg/browser/service.go +++ b/pkg/browser/service.go @@ -29,9 +29,9 @@ func NewService(log *zap.Logger, tweetService api.TweetService, bucket *blob.Buc return &serviceImpl{log, tweetService, bucket, nil} } -func (s serviceImpl) CaptureSaveUpdateDatabase(model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { +func (s serviceImpl) CaptureSaveUpdateDatabase(ctx context.Context, model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { - originalImage, err := s.CaptureURL(model) + originalImage, err := s.CaptureURL(ctx, model) if err != nil { s.log.Error("browser CaptureSaveUpdateDatabase, captureURL", zap.String("tweet_id", model.ID), zap.Error(err)) return nil, err @@ -41,13 +41,13 @@ func (s serviceImpl) CaptureSaveUpdateDatabase(model *api.CaptureRequestModel) ( return nil, fmt.Errorf("image size is less than 25 Kb. try again. size is %d", len(originalImage)) } - response, err := s.SaveCapture(originalImage, model) + response, err := s.SaveCapture(ctx, originalImage, model) if err != nil { s.log.Error("browser CaptureSaveUpdateDatabase, SaveCapture", zap.String("tweet_id", model.ID), zap.Error(err)) return nil, err } - err = s.tweetService.UpdateLargeImage(model.ID, response.CaptureURL) + err = s.tweetService.UpdateLargeImage(ctx, model.ID, response.CaptureURL) if err != nil { s.log.Error("browser CaptureSaveUpdateDatabase, service.UpdateLargeImage", zap.String("tweet_id", model.ID), zap.Error(err)) return nil, err @@ -56,10 +56,10 @@ func (s serviceImpl) CaptureSaveUpdateDatabase(model *api.CaptureRequestModel) ( return response, nil } -func (s serviceImpl) SaveCapture(originalImage []byte, model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { +func (s serviceImpl) SaveCapture(ctx context.Context, originalImage []byte, model *api.CaptureRequestModel) (*api.CaptureResponseModel, error) { imageKey := fmt.Sprintf("capture/large/%s.jpg", model.ID) - err := s.bucket.WriteAll(context.Background(), imageKey, originalImage, &blob.WriterOptions{ + err := s.bucket.WriteAll(ctx, imageKey, originalImage, &blob.WriterOptions{ ContentType: "image/jpg", CacheControl: "private,max-age=86400", Metadata: map[string]string{ @@ -86,7 +86,7 @@ func (s serviceImpl) Close() { } } -func (s *serviceImpl) CaptureURL(model *api.CaptureRequestModel) ([]byte, error) { +func (s *serviceImpl) CaptureURL(ctx context.Context, model *api.CaptureRequestModel) ([]byte, error) { if s.browser == nil { opts := []chromedp.ExecAllocatorOption{ chromedp.DisableGPU, @@ -98,7 +98,7 @@ func (s *serviceImpl) CaptureURL(model *api.CaptureRequestModel) ([]byte, error) chromedp.Flag("user-data-dir", "/tmp/headless"), } - allocCtx, _ := chromedp.NewExecAllocator(context.Background(), opts...) + allocCtx, _ := chromedp.NewExecAllocator(ctx, opts...) ctx, cancel := chromedp.NewContext(allocCtx) s.browser = &browserCtx{ browserContext: ctx, diff --git a/pkg/content/repository.go b/pkg/content/repository.go index eafd6d0..befff17 100644 --- a/pkg/content/repository.go +++ b/pkg/content/repository.go @@ -9,7 +9,7 @@ import ( ) type Repository interface { - ContactUs(email, fullName, message string) error + ContactUs(ctx context.Context, email, fullName, message string) error } type repositoryImpl struct { @@ -20,10 +20,10 @@ func NewRepository(contactUs *docstore.Collection) Repository { return &repositoryImpl{contactUs} } -func (r repositoryImpl) ContactUs(email, fullName, message string) error { +func (r repositoryImpl) ContactUs(ctx context.Context, email, fullName, message string) error { id := uuid.New().String() - return r.contactUs.Create(context.Background(), &ContactUs{ + return r.contactUs.Create(ctx, &ContactUs{ ID: id, CreatedAt: time.Now(), Email: email, diff --git a/pkg/content/repository_mock.go b/pkg/content/repository_mock.go index ca90ca5..c294f16 100644 --- a/pkg/content/repository_mock.go +++ b/pkg/content/repository_mock.go @@ -5,6 +5,7 @@ package content import ( + context "context" gomock "github.com/golang/mock/gomock" reflect "reflect" ) @@ -33,15 +34,15 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // ContactUs mocks base method. -func (m *MockRepository) ContactUs(arg0, arg1, arg2 string) error { +func (m *MockRepository) ContactUs(arg0 context.Context, arg1, arg2, arg3 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ContactUs", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "ContactUs", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // ContactUs indicates an expected call of ContactUs. -func (mr *MockRepositoryMockRecorder) ContactUs(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) ContactUs(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContactUs", reflect.TypeOf((*MockRepository)(nil).ContactUs), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContactUs", reflect.TypeOf((*MockRepository)(nil).ContactUs), arg0, arg1, arg2, arg3) } diff --git a/pkg/content/repository_test.go b/pkg/content/repository_test.go index d5fef09..c3b8a71 100644 --- a/pkg/content/repository_test.go +++ b/pkg/content/repository_test.go @@ -2,6 +2,7 @@ package content import ( "com.capturetweet/internal/infra" + "context" "github.com/stretchr/testify/require" "testing" ) @@ -13,6 +14,6 @@ func TestRepository_ContactUS(t *testing.T) { repo := NewRepository(coll) - err = repo.ContactUs("test", "ramazan", "hello") + err = repo.ContactUs(context.Background(), "test", "ramazan", "hello") require.NoError(t, err) } diff --git a/pkg/content/service.go b/pkg/content/service.go index 87e0d57..3f1a7cd 100644 --- a/pkg/content/service.go +++ b/pkg/content/service.go @@ -2,6 +2,7 @@ package content import ( "com.capturetweet/api" + "context" ) type serviceImpl struct { @@ -12,6 +13,6 @@ func NewService(repo Repository) api.ContentService { return &serviceImpl{repo} } -func (s serviceImpl) SendMail(senderMail, senderName, message string) error { - return s.repo.ContactUs(senderMail, senderMail, message) +func (s serviceImpl) SendMail(ctx context.Context, senderMail, senderName, message string) error { + return s.repo.ContactUs(ctx, senderMail, senderMail, message) } diff --git a/pkg/graph/gen_interfaces.go b/pkg/graph/gen_interfaces.go index 8a15f51..f2abac6 100644 --- a/pkg/graph/gen_interfaces.go +++ b/pkg/graph/gen_interfaces.go @@ -366,7 +366,7 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er } var sources = []*ast.Source{ - &ast.Source{Name: "schema.graphqls", Input: `scalar Time + &ast.Source{Name: "schema.graphql", Input: `scalar Time type Tweet { id:ID! diff --git a/pkg/graph/mutation.go b/pkg/graph/mutation.go index ee360a4..c32ecab 100644 --- a/pkg/graph/mutation.go +++ b/pkg/graph/mutation.go @@ -16,14 +16,14 @@ func newMutationResolver() MutationResolver { } func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, error) { - id, err := _twitterService.Store(url) + id, err := _twitterService.Store(ctx, url) if err != nil { sentry.CaptureException(err) _log.Error("capture error", zap.String("url", url), zap.Error(err)) return nil, err } - model, err := _twitterService.FindById(id) + model, err := _twitterService.FindById(ctx, id) if err != nil { sentry.CaptureException(err) _log.Error("capture error, findById", zap.String("id", id), zap.Error(err)) @@ -55,7 +55,7 @@ func (r mutationResolverImpl) Capture(ctx context.Context, url string) (*Tweet, } func (r mutationResolverImpl) Contact(ctx context.Context, input ContactInput) (string, error) { - err := _contentService.SendMail(input.Email, input.FullName, input.Message) + err := _contentService.SendMail(ctx, input.Email, input.FullName, input.Message) if err != nil { sentry.CaptureException(err) _log.Error("could not send mail", zap.String("contact_email", input.Email), zap.String("contact_fullName", input.FullName), zap.Error(err)) diff --git a/pkg/graph/query.go b/pkg/graph/query.go index 5f4e1dd..0962ece 100644 --- a/pkg/graph/query.go +++ b/pkg/graph/query.go @@ -17,7 +17,7 @@ func newQueryResolver() QueryResolver { } func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) { - model, err := _twitterService.FindById(id) + model, err := _twitterService.FindById(ctx, id) code := gcerrors.Code(err) if code == gcerrors.NotFound { _log.Warn("tweet not found", zap.String("id", id)) @@ -55,7 +55,7 @@ func (r queryResolverImpl) Tweet(ctx context.Context, id string) (*Tweet, error) } func (r queryResolverImpl) Search(ctx context.Context, input SearchInput, size int, page int, start int) ([]*Tweet, error) { - models, err := _twitterService.Search(input.Term, size, start, page) + models, err := _twitterService.Search(ctx, input.Term, size, start, page) if err != nil { sentry.CaptureException(err) _log.Error("search error", zap.String("term", input.Term), zap.Error(err)) diff --git a/pkg/graph/types.go b/pkg/graph/types.go index c800220..3a2999c 100644 --- a/pkg/graph/types.go +++ b/pkg/graph/types.go @@ -2,6 +2,7 @@ package graph import ( "com.capturetweet/internal/convert" + "context" "time" ) @@ -38,7 +39,7 @@ func (c *Tweet) Author() *Author { if c.AuthorID == nil { return nil } - author, err := _userService.FindById(*c.AuthorID) + author, err := _userService.FindById(context.Background(), *c.AuthorID) if err != nil { return nil } diff --git a/pkg/search/service.go b/pkg/search/service.go index 263c509..70421b3 100644 --- a/pkg/search/service.go +++ b/pkg/search/service.go @@ -3,6 +3,7 @@ package search import ( "com.capturetweet/api" "com.capturetweet/internal/infra" + "context" "github.com/algolia/algoliasearch-client-go/v3/algolia/opt" ) @@ -14,7 +15,7 @@ func NewService(index infra.IndexInterface) api.SearchService { return &serviceImpl{index} } -func (s serviceImpl) Search(term string, size int) ([]api.SearchModel, error) { +func (s serviceImpl) Search(ctx context.Context, term string, size int) ([]api.SearchModel, error) { res, err := s.index.Search(term, opt.HitsPerPage(size)) if err != nil { return nil, err @@ -28,7 +29,7 @@ func (s serviceImpl) Search(term string, size int) ([]api.SearchModel, error) { return list, nil } -func (s serviceImpl) Put(tweetId, fullText, author string) error { +func (s serviceImpl) Put(ctx context.Context, tweetId, fullText, author string) error { _, err := s.index.SaveObject(api.SearchModel{ TweetID: tweetId, FullText: fullText, diff --git a/pkg/search/service_test.go b/pkg/search/service_test.go index bc80686..77d6bf9 100644 --- a/pkg/search/service_test.go +++ b/pkg/search/service_test.go @@ -3,6 +3,7 @@ package search import ( "com.capturetweet/api" "com.capturetweet/internal/infra" + "context" "github.com/algolia/algoliasearch-client-go/v3/algolia/search" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -32,7 +33,7 @@ func TestService_Search(t *testing.T) { svc := NewService(algolia) - searchModels, err := svc.Search("test", 20) + searchModels, err := svc.Search(context.Background(), "test", 20) require.NoError(t, err) require.NotNil(t, searchModels) if assert.Equal(t, 2, len(searchModels)) { @@ -62,6 +63,6 @@ func TestService_Put(t *testing.T) { svc := NewService(algolia) - err := svc.Put("1", "test", "RAYYILDIZ") + err := svc.Put(context.Background(), "1", "test", "RAYYILDIZ") require.NoError(t, err) } diff --git a/pkg/tweet/repository.go b/pkg/tweet/repository.go index d911a77..367dac0 100644 --- a/pkg/tweet/repository.go +++ b/pkg/tweet/repository.go @@ -11,14 +11,14 @@ import ( ) type Repository interface { - FindById(id string) (*Tweet, error) - FindByIds(ids []string) ([]Tweet, error) - Store(tweet *anaconda.Tweet) error - Exist(id string) bool - UpdateLargeImage(id, captureUrl string) error - UpdateThumbImage(id, captureUrl string) error - - FindAllOrderByUpdated(size int) ([]Tweet, error) + FindById(ctx context.Context, id string) (*Tweet, error) + FindByIds(ctx context.Context, ids []string) ([]Tweet, error) + Store(ctx context.Context, tweet *anaconda.Tweet) error + Exist(ctx context.Context, id string) bool + UpdateLargeImage(ctx context.Context, id, captureUrl string) error + UpdateThumbImage(ctx context.Context, id, captureUrl string) error + + FindAllOrderByUpdated(ctx context.Context, size int) ([]Tweet, error) } type repositoryImpl struct { @@ -29,9 +29,9 @@ func NewRepository(coll *docstore.Collection) Repository { return &repositoryImpl{coll} } -func (r repositoryImpl) FindById(id string) (*Tweet, error) { +func (r repositoryImpl) FindById(ctx context.Context, id string) (*Tweet, error) { tweet := &Tweet{ID: id} - err := r.coll.Get(context.Background(), tweet) + err := r.coll.Get(ctx, tweet) if err != nil { return nil, err } @@ -39,10 +39,10 @@ func (r repositoryImpl) FindById(id string) (*Tweet, error) { return tweet, nil } -func (r repositoryImpl) Exist(id string) bool { +func (r repositoryImpl) Exist(ctx context.Context, id string) bool { tweet := &Tweet{ID: id} - err := r.coll.Get(context.Background(), tweet, "id") + err := r.coll.Get(ctx, tweet, "id") code := gcerrors.Code(err) if code == gcerrors.NotFound { return false @@ -50,7 +50,7 @@ func (r repositoryImpl) Exist(id string) bool { return true } -func (r repositoryImpl) Store(tweet *anaconda.Tweet) error { +func (r repositoryImpl) Store(ctx context.Context, tweet *anaconda.Tweet) error { postedAt, err := tweet.CreatedAtTime() if err != nil { postedAt = time.Now() @@ -66,7 +66,7 @@ func (r repositoryImpl) Store(tweet *anaconda.Tweet) error { }) } - return r.coll.Create(context.Background(), &Tweet{ + return r.coll.Create(ctx, &Tweet{ ID: tweet.IdStr, CreatedAt: time.Now(), UpdatedAt: time.Now(), @@ -82,30 +82,30 @@ func (r repositoryImpl) Store(tweet *anaconda.Tweet) error { }) } -func (r repositoryImpl) FindByIds(ids []string) ([]Tweet, error) { +func (r repositoryImpl) FindByIds(ctx context.Context, ids []string) ([]Tweet, error) { var list []Tweet for _, id := range ids { - if tweet, err := r.FindById(id); err == nil { + if tweet, err := r.FindById(ctx, id); err == nil { list = append(list, *tweet) } } return list, nil } -func (r repositoryImpl) UpdateLargeImage(id, captureUrl string) error { +func (r repositoryImpl) UpdateLargeImage(ctx context.Context, id, captureUrl string) error { tweet := &Tweet{ID: id} - return r.coll.Actions().Update(tweet, docstore.Mods{"capture_url": captureUrl, "updated_at": time.Now()}).Do(context.Background()) + return r.coll.Actions().Update(tweet, docstore.Mods{"capture_url": captureUrl, "updated_at": time.Now()}).Do(ctx) } -func (r repositoryImpl) UpdateThumbImage(id, captureUrl string) error { +func (r repositoryImpl) UpdateThumbImage(ctx context.Context, id, captureUrl string) error { tweet := &Tweet{ID: id} - return r.coll.Actions().Update(tweet, docstore.Mods{"capture_thumb_url": captureUrl, "updated_at": time.Now()}).Do(context.Background()) + return r.coll.Actions().Update(tweet, docstore.Mods{"capture_thumb_url": captureUrl, "updated_at": time.Now()}).Do(ctx) } -func (r repositoryImpl) FindAllOrderByUpdated(size int) ([]Tweet, error) { +func (r repositoryImpl) FindAllOrderByUpdated(ctx context.Context, size int) ([]Tweet, error) { var tweets []Tweet - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + ctx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() it := r.coll.Query().Limit(size).OrderBy("updated_at", "desc").Get(ctx) diff --git a/pkg/tweet/repository_mock.go b/pkg/tweet/repository_mock.go index 5f8cd57..5710d8e 100644 --- a/pkg/tweet/repository_mock.go +++ b/pkg/tweet/repository_mock.go @@ -5,6 +5,7 @@ package tweet import ( + context "context" anaconda "github.com/ChimeraCoder/anaconda" gomock "github.com/golang/mock/gomock" reflect "reflect" @@ -34,102 +35,102 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Exist mocks base method. -func (m *MockRepository) Exist(arg0 string) bool { +func (m *MockRepository) Exist(arg0 context.Context, arg1 string) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Exist", arg0) + ret := m.ctrl.Call(m, "Exist", arg0, arg1) ret0, _ := ret[0].(bool) return ret0 } // Exist indicates an expected call of Exist. -func (mr *MockRepositoryMockRecorder) Exist(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) Exist(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exist", reflect.TypeOf((*MockRepository)(nil).Exist), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exist", reflect.TypeOf((*MockRepository)(nil).Exist), arg0, arg1) } // FindAllOrderByUpdated mocks base method. -func (m *MockRepository) FindAllOrderByUpdated(arg0 int) ([]Tweet, error) { +func (m *MockRepository) FindAllOrderByUpdated(arg0 context.Context, arg1 int) ([]Tweet, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindAllOrderByUpdated", arg0) + ret := m.ctrl.Call(m, "FindAllOrderByUpdated", arg0, arg1) ret0, _ := ret[0].([]Tweet) ret1, _ := ret[1].(error) return ret0, ret1 } // FindAllOrderByUpdated indicates an expected call of FindAllOrderByUpdated. -func (mr *MockRepositoryMockRecorder) FindAllOrderByUpdated(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) FindAllOrderByUpdated(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAllOrderByUpdated", reflect.TypeOf((*MockRepository)(nil).FindAllOrderByUpdated), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAllOrderByUpdated", reflect.TypeOf((*MockRepository)(nil).FindAllOrderByUpdated), arg0, arg1) } // FindById mocks base method. -func (m *MockRepository) FindById(arg0 string) (*Tweet, error) { +func (m *MockRepository) FindById(arg0 context.Context, arg1 string) (*Tweet, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindById", arg0) + ret := m.ctrl.Call(m, "FindById", arg0, arg1) ret0, _ := ret[0].(*Tweet) ret1, _ := ret[1].(error) return ret0, ret1 } // FindById indicates an expected call of FindById. -func (mr *MockRepositoryMockRecorder) FindById(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) FindById(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockRepository)(nil).FindById), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockRepository)(nil).FindById), arg0, arg1) } // FindByIds mocks base method. -func (m *MockRepository) FindByIds(arg0 []string) ([]Tweet, error) { +func (m *MockRepository) FindByIds(arg0 context.Context, arg1 []string) ([]Tweet, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindByIds", arg0) + ret := m.ctrl.Call(m, "FindByIds", arg0, arg1) ret0, _ := ret[0].([]Tweet) ret1, _ := ret[1].(error) return ret0, ret1 } // FindByIds indicates an expected call of FindByIds. -func (mr *MockRepositoryMockRecorder) FindByIds(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) FindByIds(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByIds", reflect.TypeOf((*MockRepository)(nil).FindByIds), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByIds", reflect.TypeOf((*MockRepository)(nil).FindByIds), arg0, arg1) } // Store mocks base method. -func (m *MockRepository) Store(arg0 *anaconda.Tweet) error { +func (m *MockRepository) Store(arg0 context.Context, arg1 *anaconda.Tweet) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Store", arg0) + ret := m.ctrl.Call(m, "Store", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Store indicates an expected call of Store. -func (mr *MockRepositoryMockRecorder) Store(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) Store(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockRepository)(nil).Store), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockRepository)(nil).Store), arg0, arg1) } // UpdateLargeImage mocks base method. -func (m *MockRepository) UpdateLargeImage(arg0, arg1 string) error { +func (m *MockRepository) UpdateLargeImage(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateLargeImage", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateLargeImage", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // UpdateLargeImage indicates an expected call of UpdateLargeImage. -func (mr *MockRepositoryMockRecorder) UpdateLargeImage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) UpdateLargeImage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLargeImage", reflect.TypeOf((*MockRepository)(nil).UpdateLargeImage), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLargeImage", reflect.TypeOf((*MockRepository)(nil).UpdateLargeImage), arg0, arg1, arg2) } // UpdateThumbImage mocks base method. -func (m *MockRepository) UpdateThumbImage(arg0, arg1 string) error { +func (m *MockRepository) UpdateThumbImage(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateThumbImage", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateThumbImage", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // UpdateThumbImage indicates an expected call of UpdateThumbImage. -func (mr *MockRepositoryMockRecorder) UpdateThumbImage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) UpdateThumbImage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateThumbImage", reflect.TypeOf((*MockRepository)(nil).UpdateThumbImage), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateThumbImage", reflect.TypeOf((*MockRepository)(nil).UpdateThumbImage), arg0, arg1, arg2) } diff --git a/pkg/tweet/repository_test.go b/pkg/tweet/repository_test.go index 205bb42..b2272ba 100644 --- a/pkg/tweet/repository_test.go +++ b/pkg/tweet/repository_test.go @@ -2,6 +2,7 @@ package tweet import ( "com.capturetweet/internal/infra" + "context" "github.com/ChimeraCoder/anaconda" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -14,8 +15,10 @@ func TestRepository_Store(t *testing.T) { require.NoError(t, err) defer coll.Close() + ctx := context.Background() + repo := NewRepository(coll) - err = repo.Store(&anaconda.Tweet{ + err = repo.Store(ctx, &anaconda.Tweet{ IdStr: "1", RetweetCount: 4, FavoriteCount: 9, @@ -29,12 +32,13 @@ func TestRepository_Exist(t *testing.T) { coll, err := infra.NewDocstore("mem://collection/id") require.NoError(t, err) defer coll.Close() + ctx := context.Background() repo := NewRepository(coll) - err = repo.Store(&anaconda.Tweet{IdStr: "testId1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) + err = repo.Store(ctx, &anaconda.Tweet{IdStr: "testId1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) require.NoError(t, err) - b := repo.Exist("testId1") + b := repo.Exist(ctx, "testId1") require.True(t, b) } @@ -43,17 +47,19 @@ func TestRepository_FindByIds(t *testing.T) { require.NoError(t, err) defer coll.Close() + ctx := context.Background() + repo := NewRepository(coll) - err = repo.Store(&anaconda.Tweet{IdStr: "1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) + err = repo.Store(ctx, &anaconda.Tweet{IdStr: "1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) require.NoError(t, err) - err = repo.Store(&anaconda.Tweet{IdStr: "2", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) + err = repo.Store(ctx, &anaconda.Tweet{IdStr: "2", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) require.NoError(t, err) - err = repo.Store(&anaconda.Tweet{IdStr: "3", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) + err = repo.Store(ctx, &anaconda.Tweet{IdStr: "3", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) require.NoError(t, err) - tweets, err := repo.FindByIds([]string{"1", "3", "4"}) + tweets, err := repo.FindByIds(ctx, []string{"1", "3", "4"}) require.NoError(t, err) if assert.Equal(t, 2, len(tweets)) { assert.Equal(t, "1", tweets[0].ID) @@ -66,14 +72,16 @@ func TestRepository_UpdateThumbImage(t *testing.T) { require.NoError(t, err) defer coll.Close() + ctx := context.Background() + repo := NewRepository(coll) - err = repo.Store(&anaconda.Tweet{IdStr: "1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) + err = repo.Store(ctx, &anaconda.Tweet{IdStr: "1", Lang: "en", CreatedAt: time.Now().Format(time.RubyDate)}) require.NoError(t, err) - err = repo.UpdateThumbImage("1", "image1.png") + err = repo.UpdateThumbImage(ctx, "1", "image1.png") require.NoError(t, err) - tweet, err := repo.FindById("1") + tweet, err := repo.FindById(ctx, "1") require.NoError(t, err) if assert.NotNil(t, tweet) { assert.Equal(t, "1", tweet.ID) diff --git a/pkg/tweet/service.go b/pkg/tweet/service.go index fa0650e..847d851 100644 --- a/pkg/tweet/service.go +++ b/pkg/tweet/service.go @@ -26,8 +26,8 @@ func NewService(repo Repository, search api.SearchService, userService api.UserS return &serviceImpl{repo, twitterAPI, search, userService, log, topic} } -func (s serviceImpl) FindById(id string) (*api.TweetModel, error) { - tweet, err := s.repo.FindById(id) +func (s serviceImpl) FindById(ctx context.Context, id string) (*api.TweetModel, error) { + tweet, err := s.repo.FindById(ctx, id) if err != nil { s.log.Error("tweet:service findById", zap.String("tweet_id", id), zap.Error(err)) return nil, err @@ -59,7 +59,7 @@ func (s serviceImpl) FindById(id string) (*api.TweetModel, error) { }, nil } -func (s serviceImpl) Store(tweetURL string) (string, error) { +func (s serviceImpl) Store(ctx context.Context, tweetURL string) (string, error) { tweetID, tweetAuthor, err := parseTweetURL(tweetURL) if err != nil { s.log.Error("tweet:service store, parseTweetUrl", zap.String("url", tweetURL), zap.Error(err)) @@ -67,7 +67,7 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { } tweetIdStr := fmt.Sprintf("%d", tweetID) - if s.repo.Exist(tweetIdStr) { + if s.repo.Exist(ctx, tweetIdStr) { return tweetIdStr, nil } @@ -77,18 +77,18 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { return "", err } - err = s.repo.Store(&tweet) + err = s.repo.Store(ctx, &tweet) if err != nil { s.log.Error("tweet:service store, repo.store", zap.Int64("tweet_id", tweetID), zap.Error(err)) return "", err } - if _, err := s.user.FindOrCreate(&tweet.User); err != nil { + if _, err := s.user.FindOrCreate(ctx, &tweet.User); err != nil { s.log.Warn("tweet:service store, user.findOrCreate", zap.String("tweet_user", tweet.User.ScreenName), zap.Error(err)) } go func(t anaconda.Tweet) { - if err := s.search.Put(t.IdStr, t.FullText, t.User.ScreenName); err != nil { + if err := s.search.Put(ctx, t.IdStr, t.FullText, t.User.ScreenName); err != nil { s.log.Warn("tweet:service store, search.put", zap.String("tweet_id", t.IdStr), zap.String("tweet_user", t.User.ScreenName), zap.Error(err)) } }(tweet) @@ -105,7 +105,7 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { return } - err = s.topic.Send(context.Background(), &pubsub.Message{ + err = s.topic.Send(ctx, &pubsub.Message{ Metadata: map[string]string{ "tweet_id": id, "tweet_user": author, @@ -123,8 +123,8 @@ func (s serviceImpl) Store(tweetURL string) (string, error) { return tweetIdStr, nil } -func (s serviceImpl) Search(term string, size, start, page int) ([]api.TweetModel, error) { - searchModels, err := s.search.Search(term, size) +func (s serviceImpl) Search(ctx context.Context, term string, size, start, page int) ([]api.TweetModel, error) { + searchModels, err := s.search.Search(ctx, term, size) if err != nil { s.log.Error("tweet:service search, search service call", zap.String("search_term", term), zap.Error(err)) return nil, err @@ -135,7 +135,7 @@ func (s serviceImpl) Search(term string, size, start, page int) ([]api.TweetMode ids = append(ids, model.TweetID) } - tweets, err := s.repo.FindByIds(ids) + tweets, err := s.repo.FindByIds(ctx, ids) if err != nil { s.log.Error("tweet:service search, findByIds", zap.Strings("tweet_ids", ids), zap.Error(err)) return nil, err @@ -173,8 +173,8 @@ func (s serviceImpl) Search(term string, size, start, page int) ([]api.TweetMode return res, nil } -func (s serviceImpl) UpdateLargeImage(id, captureUrl string) error { - err := s.repo.UpdateLargeImage(id, captureUrl) +func (s serviceImpl) UpdateLargeImage(ctx context.Context, id, captureUrl string) error { + err := s.repo.UpdateLargeImage(ctx, id, captureUrl) if err != nil { s.log.Error("tweet:service updateLargeImage, findById", zap.String("tweet_id", id), zap.Error(err)) return err @@ -183,8 +183,8 @@ func (s serviceImpl) UpdateLargeImage(id, captureUrl string) error { return nil } -func (s serviceImpl) UpdateThumbImage(id, captureUrl string) error { - err := s.repo.UpdateThumbImage(id, captureUrl) +func (s serviceImpl) UpdateThumbImage(ctx context.Context, id, captureUrl string) error { + err := s.repo.UpdateThumbImage(ctx, id, captureUrl) if err != nil { s.log.Error("tweet:service updateThumbImage, findById", zap.String("tweet_id", id), zap.Error(err)) return err diff --git a/pkg/user/repository.go b/pkg/user/repository.go index 1754c24..8b56ad5 100644 --- a/pkg/user/repository.go +++ b/pkg/user/repository.go @@ -8,10 +8,10 @@ import ( ) type Repository interface { - FindByUserName(userName string) (*User, error) - FindById(id string) (*User, error) + FindByUserName(ctx context.Context, userName string) (*User, error) + FindById(ctx context.Context, id string) (*User, error) - Store(userIdStr, userName, screenName, bio, profileImage string, registeredAt time.Time) error + Store(ctx context.Context, userIdStr, userName, screenName, bio, profileImage string, registeredAt time.Time) error } type repositoryImpl struct { @@ -22,29 +22,29 @@ func NewRepository(coll *docstore.Collection) Repository { return &repositoryImpl{coll} } -func (r repositoryImpl) FindByUserName(userName string) (*User, error) { +func (r repositoryImpl) FindByUserName(ctx context.Context, userName string) (*User, error) { user := &User{} - it := r.coll.Query().Where("username", "=", userName).Limit(1).Get(context.Background()) + it := r.coll.Query().Where("username", "=", userName).Limit(1).Get(ctx) - err := it.Next(context.Background(), user) + err := it.Next(ctx, user) if err != nil { return nil, err } return user, err } -func (r repositoryImpl) FindById(id string) (*User, error) { +func (r repositoryImpl) FindById(ctx context.Context, id string) (*User, error) { user := &User{ID: id} - err := r.coll.Get(context.Background(), user) + err := r.coll.Get(ctx, user) if err != nil { return nil, err } return user, nil } -func (r repositoryImpl) Store(userIdStr, userName, screenName, bio, profileImage string, registeredAt time.Time) error { - return r.coll.Put(context.Background(), &User{ +func (r repositoryImpl) Store(ctx context.Context, userIdStr, userName, screenName, bio, profileImage string, registeredAt time.Time) error { + return r.coll.Put(ctx, &User{ ID: userIdStr, CreatedAt: time.Now(), UpdateAt: time.Now(), diff --git a/pkg/user/repository_mock.go b/pkg/user/repository_mock.go index e687f76..0ae2282 100644 --- a/pkg/user/repository_mock.go +++ b/pkg/user/repository_mock.go @@ -5,6 +5,7 @@ package user import ( + context "context" gomock "github.com/golang/mock/gomock" reflect "reflect" time "time" @@ -34,45 +35,45 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // FindById mocks base method. -func (m *MockRepository) FindById(arg0 string) (*User, error) { +func (m *MockRepository) FindById(arg0 context.Context, arg1 string) (*User, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindById", arg0) + ret := m.ctrl.Call(m, "FindById", arg0, arg1) ret0, _ := ret[0].(*User) ret1, _ := ret[1].(error) return ret0, ret1 } // FindById indicates an expected call of FindById. -func (mr *MockRepositoryMockRecorder) FindById(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) FindById(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockRepository)(nil).FindById), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindById", reflect.TypeOf((*MockRepository)(nil).FindById), arg0, arg1) } // FindByUserName mocks base method. -func (m *MockRepository) FindByUserName(arg0 string) (*User, error) { +func (m *MockRepository) FindByUserName(arg0 context.Context, arg1 string) (*User, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindByUserName", arg0) + ret := m.ctrl.Call(m, "FindByUserName", arg0, arg1) ret0, _ := ret[0].(*User) ret1, _ := ret[1].(error) return ret0, ret1 } // FindByUserName indicates an expected call of FindByUserName. -func (mr *MockRepositoryMockRecorder) FindByUserName(arg0 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) FindByUserName(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserName", reflect.TypeOf((*MockRepository)(nil).FindByUserName), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserName", reflect.TypeOf((*MockRepository)(nil).FindByUserName), arg0, arg1) } // Store mocks base method. -func (m *MockRepository) Store(arg0, arg1, arg2, arg3, arg4 string, arg5 time.Time) error { +func (m *MockRepository) Store(arg0 context.Context, arg1, arg2, arg3, arg4, arg5 string, arg6 time.Time) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Store", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "Store", arg0, arg1, arg2, arg3, arg4, arg5, arg6) ret0, _ := ret[0].(error) return ret0 } // Store indicates an expected call of Store. -func (mr *MockRepositoryMockRecorder) Store(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockRepositoryMockRecorder) Store(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockRepository)(nil).Store), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Store", reflect.TypeOf((*MockRepository)(nil).Store), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } diff --git a/pkg/user/repository_test.go b/pkg/user/repository_test.go index eb23eaf..a34b0f5 100644 --- a/pkg/user/repository_test.go +++ b/pkg/user/repository_test.go @@ -2,6 +2,7 @@ package user import ( "com.capturetweet/internal/infra" + "context" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gocloud.dev/gcerrors" @@ -16,7 +17,7 @@ func TestRepository_Store(t *testing.T) { repo := NewRepository(coll) - err = repo.Store("testId", "username", "display name", "Bio", "profile.png", time.Now()) + err = repo.Store(context.Background(), "testId", "username", "display name", "Bio", "profile.png", time.Now()) require.NoError(t, err) } @@ -29,10 +30,10 @@ func TestRepository_FindById(t *testing.T) { id := "1270800178421706753" - err = repo.Store(id, "test", "screenName", "Bio", "profile.png", time.Now()) + err = repo.Store(context.Background(), id, "test", "screenName", "Bio", "profile.png", time.Now()) require.NoError(t, err) - user, err := repo.FindById(id) + user, err := repo.FindById(context.Background(), id) if assert.NoError(t, err) && assert.NotNil(t, user) { assert.Equal(t, "test", user.Username) assert.Equal(t, "screenName", user.ScreenName) @@ -46,12 +47,13 @@ func TestRepository_FindByUserName(t *testing.T) { defer coll.Close() repo := NewRepository(coll) + ctx := context.Background() - require.NoError(t, repo.Store("1", "test1", "screenName 1", "Bio", "profile1.png", time.Now())) - require.NoError(t, repo.Store("2", "test2", "screenName 2", "Bio", "profile2.png", time.Now())) - require.NoError(t, repo.Store("3", "test3", "screenName 3", "Bio", "profile3.png", time.Now())) + require.NoError(t, repo.Store(ctx, "1", "test1", "screenName 1", "Bio", "profile1.png", time.Now())) + require.NoError(t, repo.Store(ctx, "2", "test2", "screenName 2", "Bio", "profile2.png", time.Now())) + require.NoError(t, repo.Store(ctx, "3", "test3", "screenName 3", "Bio", "profile3.png", time.Now())) - user, err := repo.FindByUserName("test3") + user, err := repo.FindByUserName(ctx, "test3") if assert.NoError(t, err) && assert.NotNil(t, user) { assert.Equal(t, "test3", user.Username) assert.Equal(t, "screenName 3", user.ScreenName) @@ -66,7 +68,7 @@ func TestRepository_FindById_NotFound(t *testing.T) { repo := NewRepository(coll) - user, err := repo.FindById("1") + user, err := repo.FindById(context.Background(), "1") if assert.Nil(t, user) { assert.Error(t, err, "record not found") diff --git a/pkg/user/service.go b/pkg/user/service.go index ce05146..256311f 100644 --- a/pkg/user/service.go +++ b/pkg/user/service.go @@ -3,6 +3,7 @@ package user import ( "com.capturetweet/api" "com.capturetweet/internal/convert" + "context" "github.com/ChimeraCoder/anaconda" "go.uber.org/zap" "time" @@ -17,8 +18,8 @@ func NewService(repo Repository, log *zap.Logger) api.UserService { return &serviceImpl{repo, log} } -func (s serviceImpl) FindById(id string) (*api.UserModel, error) { - user, err := s.repo.FindById(id) +func (s serviceImpl) FindById(ctx context.Context, id string) (*api.UserModel, error) { + user, err := s.repo.FindById(ctx, id) if err != nil { s.log.Error("user:service findById", zap.String("tweet_id", id), zap.Error(err)) return nil, err @@ -33,10 +34,10 @@ func (s serviceImpl) FindById(id string) (*api.UserModel, error) { }, nil } -func (s serviceImpl) FindOrCreate(author *anaconda.User) (*api.UserModel, error) { +func (s serviceImpl) FindOrCreate(ctx context.Context, author *anaconda.User) (*api.UserModel, error) { id := author.IdStr - user, err := s.repo.FindById(id) + user, err := s.repo.FindById(ctx, id) if user != nil { return &api.UserModel{ ID: user.ID, @@ -52,7 +53,7 @@ func (s serviceImpl) FindOrCreate(author *anaconda.User) (*api.UserModel, error) registeredAt = time.Now() } - err = s.repo.Store(id, author.ScreenName, author.Name, author.Description, author.ProfileImageUrlHttps, registeredAt) + err = s.repo.Store(ctx, id, author.ScreenName, author.Name, author.Description, author.ProfileImageUrlHttps, registeredAt) if err != nil { s.log.Error("user:service findOrCreate", zap.String("tweet_id", id), zap.String("tweet_user", author.ScreenName), zap.Error(err)) return nil, err diff --git a/pkg/user/service_test.go b/pkg/user/service_test.go index eec5859..460ab46 100644 --- a/pkg/user/service_test.go +++ b/pkg/user/service_test.go @@ -2,6 +2,7 @@ package user import ( "com.capturetweet/internal/infra" + "context" "github.com/ChimeraCoder/anaconda" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -17,8 +18,10 @@ func TestUserService_FindById(t *testing.T) { log := infra.NewLogger() require.NotNil(t, log) + ctx := context.Background() + repo := NewMockRepository(ctrl) - repo.EXPECT().FindById("testUserIdStr").Return(&User{ + repo.EXPECT().FindById(ctx, "testUserIdStr").Return(&User{ ID: "testUserIdStr", CreatedAt: time.Now(), RegisterAt: time.Now(), @@ -28,7 +31,7 @@ func TestUserService_FindById(t *testing.T) { svc := NewService(repo, log) - userModel, err := svc.FindById("testUserIdStr") + userModel, err := svc.FindById(ctx, "testUserIdStr") require.NoError(t, err) if assert.NotNil(t, userModel) { assert.Equal(t, "testUserIdStr", userModel.ID) @@ -42,9 +45,10 @@ func TestUserService_FindOrCreate_Exist(t *testing.T) { defer ctrl.Finish() log := infra.NewLogger() require.NotNil(t, log) + ctx := context.Background() repo := NewMockRepository(ctrl) - repo.EXPECT().FindById("testId").Return(&User{ + repo.EXPECT().FindById(ctx, "testId").Return(&User{ ID: "testId", CreatedAt: time.Now(), RegisterAt: time.Now(), @@ -54,7 +58,7 @@ func TestUserService_FindOrCreate_Exist(t *testing.T) { svc := NewService(repo, log) - userModel, err := svc.FindOrCreate(&anaconda.User{ + userModel, err := svc.FindOrCreate(ctx, &anaconda.User{ IdStr: "testId", ScreenName: "rayyildiz", Name: "Ramazan A.", @@ -73,6 +77,7 @@ func TestUserService_FindOrCreate_NotExist(t *testing.T) { log := infra.NewLogger() require.NotNil(t, log) + ctx := context.Background() repo := NewMockRepository(ctrl) @@ -80,12 +85,12 @@ func TestUserService_FindOrCreate_NotExist(t *testing.T) { dt, err := time.Parse(time.RubyDate, strDate) require.NoError(t, err) - repo.EXPECT().FindById("testId").Return(nil, nil) - repo.EXPECT().Store("testId", "rayyildiz", "Ramazan A.", "bio", "profile.png", dt).Return(nil) + repo.EXPECT().FindById(ctx, "testId").Return(nil, nil) + repo.EXPECT().Store(ctx, "testId", "rayyildiz", "Ramazan A.", "bio", "profile.png", dt).Return(nil) svc := NewService(repo, log) - userModel, err := svc.FindOrCreate(&anaconda.User{ + userModel, err := svc.FindOrCreate(ctx, &anaconda.User{ IdStr: "testId", ScreenName: "rayyildiz", Name: "Ramazan A.", diff --git a/schema.graphqls b/schema.graphql similarity index 100% rename from schema.graphqls rename to schema.graphql diff --git a/web/app/Makefile b/web/app/Makefile index 3c167e9..6b931e4 100644 --- a/web/app/Makefile +++ b/web/app/Makefile @@ -1,2 +1,2 @@ generate: - apollo client:codegen --localSchemaFile=../../schema.graphqls --tagName=gql --outputFlat --target=typescript src/graph + apollo client:codegen --localSchemaFile=../../schema.graphql --tagName=gql --outputFlat --target=typescript src/graph diff --git a/web/app/package.json b/web/app/package.json index 1f15b6c..2dcd0ad 100644 --- a/web/app/package.json +++ b/web/app/package.json @@ -4,17 +4,17 @@ "private": true, "proxy": "http://localhost:4000", "dependencies": { - "@apollo/client": "^3.0.0-rc.10", + "@apollo/client": "^3.0.0-rc.12", "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", - "@testing-library/user-event": "^7.1.2", - "@types/jest": "^24.0.0", - "@types/node": "^12.0.0", - "@types/react": "^16.9.0", - "@types/react-dom": "^16.9.0", + "@testing-library/react": "^9.5.0", + "@testing-library/user-event": "^7.2.1", + "@types/jest": "^24.9.1", + "@types/node": "^12.12.50", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "bootstrap": "^5.0.0-alpha1", "bootstrap-icons": "^1.0.0-alpha5", - "graphql": "^15.2.0", + "graphql": "^15.3.0", "moment": "^2.27.0", "query-string": "^6.13.1", "react": "^16.13.1", @@ -22,14 +22,15 @@ "react-helmet": "^6.1.0", "react-router-dom": "^5.2.0", "react-scripts": "3.4.1", - "typescript": "~3.7.2" + "typescript": "~3.7.5" }, "scripts": { "start": "BROWSER=none react-scripts start", "build": "react-scripts build", "build:prod": "GENERATE_SOURCEMAP=false react-scripts build", "test": "react-scripts test --watchAll=false", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "packages:upgrade": "yarn upgrade && syncyarnlock -s -k" }, "eslintConfig": { "extends": "react-app" @@ -48,6 +49,7 @@ }, "devDependencies": { "@types/react-helmet": "^6.0.0", - "@types/react-router-dom": "^5.1.5" + "@types/react-router-dom": "^5.1.5", + "syncyarnlock": "^1.0.19" } } diff --git a/web/app/src/components/Search.tsx b/web/app/src/components/Search.tsx index 7e7835f..6334e02 100644 --- a/web/app/src/components/Search.tsx +++ b/web/app/src/components/Search.tsx @@ -17,8 +17,8 @@ export const Search: FC = () => {
diff --git a/web/app/src/pages/ContactPage.tsx b/web/app/src/pages/ContactPage.tsx index 391b4dc..e4cd2c1 100644 --- a/web/app/src/pages/ContactPage.tsx +++ b/web/app/src/pages/ContactPage.tsx @@ -28,10 +28,9 @@ const ContactPage: FC = () => { fullName: name } } - }) - - } catch (e) { - console.error(e); + }); + } catch (ex) { + console.error(ex); } } @@ -40,7 +39,7 @@ const ContactPage: FC = () => {
-
+

Contact Us

{data &&
{data.contact} @@ -72,7 +71,7 @@ const ContactPage: FC = () => {
- +