From 6d7d194b32cf3b06203de2e111cc6a9cac0d448b Mon Sep 17 00:00:00 2001 From: Daniel Oluojomu Date: Wed, 18 May 2022 10:44:10 +0100 Subject: [PATCH 1/5] feat: add ReplayAppEvent endpoint --- docs/docs.go | 122 +++++++++++++++++++++++++++++++++- docs/swagger.json | 120 ++++++++++++++++++++++++++++++++++ docs/swagger.yaml | 64 ++++++++++++++++++ docs/v3/openapi3.json | 134 ++++++++++++++++++++++++++++++++++++++ docs/v3/openapi3.yaml | 70 ++++++++++++++++++++ server/event.go | 25 +++++++ server/middleware.go | 1 + server/route.go | 3 + services/event_service.go | 16 +++++ 9 files changed, 554 insertions(+), 1 deletion(-) diff --git a/docs/docs.go b/docs/docs.go index 606efe7d41..f865a57655 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,6 @@ // Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag at -// 2022-05-15 21:23:12.449897 +0100 WAT m=+68.719807710 +// 2022-05-18 10:45:32.778166 +0100 WAT m=+82.107380043 package docs import ( @@ -2444,6 +2444,126 @@ var doc = `{ } } } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "This endpoint replays an app event", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Events" + ], + "summary": "Replay app event", + "parameters": [ + { + "type": "string", + "description": "group id", + "name": "groupId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "event id", + "name": "eventID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/datastore.Event" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + } + } } }, "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { diff --git a/docs/swagger.json b/docs/swagger.json index 87627ba5ef..b2b0156b90 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2432,6 +2432,126 @@ } } } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "This endpoint replays an app event", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Events" + ], + "summary": "Replay app event", + "parameters": [ + { + "type": "string", + "description": "group id", + "name": "groupId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "event id", + "name": "eventID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/datastore.Event" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.serverResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] + } + } + } } }, "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index f8fd04aeb9..668221630a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1788,6 +1788,70 @@ paths: summary: Get app event tags: - Events + put: + consumes: + - application/json + description: This endpoint replays an app event + parameters: + - description: group id + in: query + name: groupId + required: true + type: string + - description: event id + in: path + name: eventID + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/server.serverResponse' + - properties: + data: + allOf: + - $ref: '#/definitions/datastore.Event' + - properties: + data: + $ref: '#/definitions/server.Stub' + type: object + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.serverResponse' + - properties: + data: + $ref: '#/definitions/server.Stub' + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.serverResponse' + - properties: + data: + $ref: '#/definitions/server.Stub' + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.serverResponse' + - properties: + data: + $ref: '#/definitions/server.Stub' + type: object + security: + - ApiKeyAuth: [] + summary: Replay app event + tags: + - Events /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: get: consumes: diff --git a/docs/v3/openapi3.json b/docs/v3/openapi3.json index 80191bc884..b1e38cdb0a 100644 --- a/docs/v3/openapi3.json +++ b/docs/v3/openapi3.json @@ -3432,6 +3432,140 @@ "tags": [ "Events" ] + }, + "put": { + "description": "This endpoint replays an app event", + "parameters": [ + { + "description": "group id", + "in": "query", + "name": "groupId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "event id", + "in": "path", + "name": "eventID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/server.serverResponse" + }, + { + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/components/schemas/datastore.Event" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/server.Stub" + } + }, + "type": "object" + } + ] + } + }, + "type": "object" + } + ] + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/server.serverResponse" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/server.Stub" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/server.serverResponse" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/server.Stub" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/server.serverResponse" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/server.Stub" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Internal Server Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Replay app event", + "tags": [ + "Events" + ] } }, "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { diff --git a/docs/v3/openapi3.yaml b/docs/v3/openapi3.yaml index b5208ef36c..3a6bf7efe3 100644 --- a/docs/v3/openapi3.yaml +++ b/docs/v3/openapi3.yaml @@ -1939,6 +1939,76 @@ paths: summary: Get app event tags: - Events + put: + description: This endpoint replays an app event + parameters: + - description: group id + in: query + name: groupId + required: true + schema: + type: string + - description: event id + in: path + name: eventID + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/server.serverResponse' + - properties: + data: + allOf: + - $ref: '#/components/schemas/datastore.Event' + - properties: + data: + $ref: '#/components/schemas/server.Stub' + type: object + type: object + description: OK + "400": + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/server.serverResponse' + - properties: + data: + $ref: '#/components/schemas/server.Stub' + type: object + description: Bad Request + "401": + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/server.serverResponse' + - properties: + data: + $ref: '#/components/schemas/server.Stub' + type: object + description: Unauthorized + "500": + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/server.serverResponse' + - properties: + data: + $ref: '#/components/schemas/server.Stub' + type: object + description: Internal Server Error + security: + - ApiKeyAuth: [] + summary: Replay app event + tags: + - Events /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: get: description: This endpoint fetches an app message's delivery attempts diff --git a/server/event.go b/server/event.go index cfb5347860..9a1e9cc176 100644 --- a/server/event.go +++ b/server/event.go @@ -46,6 +46,31 @@ func (a *applicationHandler) CreateAppEvent(w http.ResponseWriter, r *http.Reque _ = render.Render(w, r, newServerResponse("App event created successfully", event, http.StatusCreated)) } +// ReplayAppEvent +// @Summary Replay app event +// @Description This endpoint replays an app event +// @Tags Events +// @Accept json +// @Produce json +// @Param groupId query string true "group id" +// @Param eventID path string true "event id" +// @Success 200 {object} serverResponse{data=datastore.Event{data=Stub}} +// @Failure 400,401,500 {object} serverResponse{data=Stub} +// @Security ApiKeyAuth +// @Router /events/{eventID} [put] +func (a *applicationHandler) ReplayAppEvent(w http.ResponseWriter, r *http.Request) { + g := getGroupFromContext(r.Context()) + event := getEventFromContext(r.Context()) + + err := a.eventService.ReplayAppEvent(r.Context(), event, g) + if err != nil { + _ = render.Render(w, r, newServiceErrResponse(err)) + return + } + + _ = render.Render(w, r, newServerResponse("App event replayed successfully", event, http.StatusOK)) +} + // GetAppEvent // @Summary Get app event // @Description This endpoint fetches an app event diff --git a/server/middleware.go b/server/middleware.go index 10227edbfa..90424f88f8 100644 --- a/server/middleware.go +++ b/server/middleware.go @@ -456,6 +456,7 @@ func requireGroup(groupRepo datastore.GroupRepository, cache cache.Cache) func(n } } } else { + // TODO(all): maybe we should only use default-group if require_auth is false? groupCacheKey := convoy.GroupsCacheKey.Get("default-group").String() err = cache.Get(r.Context(), groupCacheKey, &group) if err != nil { diff --git a/server/route.go b/server/route.go index 31e4afeaa5..06bf204ace 100644 --- a/server/route.go +++ b/server/route.go @@ -125,6 +125,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) + eventSubRouter.Put("/", app.ReplayAppEvent) }) }) @@ -255,6 +256,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) + eventSubRouter.Put("/", app.ReplayAppEvent) }) }) @@ -320,6 +322,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) + eventSubRouter.Put("/", app.ReplayAppEvent) }) }) diff --git a/services/event_service.go b/services/event_service.go index 78e940f441..3f05b65930 100644 --- a/services/event_service.go +++ b/services/event_service.go @@ -109,6 +109,22 @@ func (e *EventService) CreateAppEvent(ctx context.Context, newMessage *models.Ev return event, nil } +func (e *EventService) ReplayAppEvent(ctx context.Context, event *datastore.Event, g *datastore.Group) error { + taskName := convoy.CreateEventProcessor.SetPrefix(g.Name) + job := &queue.Job{ + ID: event.UID, + Event: event, + } + + err := e.createEventQueue.Publish(context.Background(), taskName, job, 0) + if err != nil { + log.WithError(err).Error("replay_event: failed to write event to the queue") + return NewServiceError(http.StatusBadRequest, errors.New("failed to write event to queue")) + } + + return nil +} + func (e *EventService) GetAppEvent(ctx context.Context, id string) (*datastore.Event, error) { event, err := e.eventRepo.FindEventByID(ctx, id) if err != nil { From 34a92e457b3ca4fd536f0979ad1e15635fae3c0b Mon Sep 17 00:00:00 2001 From: Daniel Oluojomu Date: Wed, 18 May 2022 14:14:31 +0100 Subject: [PATCH 2/5] tests: add tests --- docs/docs.go | 2 +- server/event_integration_test.go | 19 +++++++++ services/event_service_test.go | 68 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/docs/docs.go b/docs/docs.go index f865a57655..e0d3b9473e 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,6 @@ // Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag at -// 2022-05-18 10:45:32.778166 +0100 WAT m=+82.107380043 +// 2022-05-18 14:15:37.023759 +0100 WAT m=+65.462890168 package docs import ( diff --git a/server/event_integration_test.go b/server/event_integration_test.go index 661e379819..7b0c307e39 100644 --- a/server/event_integration_test.go +++ b/server/event_integration_test.go @@ -138,6 +138,25 @@ func (s *EventIntegrationTestSuite) Test_GetAppEvent_Valid_Event() { require.Equal(s.T(), event.UID, respEvent.UID) } +func (s *EventIntegrationTestSuite) Test_ReplayAppEvent_Valid_Event() { + eventID := uuid.NewString() + expectedStatusCode := http.StatusOK + + // Just Before. + app, _ := testdb.SeedApplication(s.DB, s.DefaultGroup, uuid.NewString(), "", false) + _, _ = testdb.SeedEvent(s.DB, app, eventID, "*", []byte(`{}`)) + + url := fmt.Sprintf("/api/v1/events/%s", eventID) + req := createRequest(http.MethodPut, url, nil) + w := httptest.NewRecorder() + + // Act. + s.Router.ServeHTTP(w, req) + + // Assert. + require.Equal(s.T(), expectedStatusCode, w.Code) +} + func (s *EventIntegrationTestSuite) Test_GetAppEvent_Event_not_found() { eventID := uuid.NewString() expectedStatusCode := http.StatusNotFound diff --git a/services/event_service_test.go b/services/event_service_test.go index 3097ce5218..7424168680 100644 --- a/services/event_service_test.go +++ b/services/event_service_test.go @@ -486,6 +486,74 @@ func TestEventService_GetAppEvent(t *testing.T) { } } +func TestEventService_ReplayAppEvent(t *testing.T) { + ctx := context.Background() + type args struct { + ctx context.Context + event *datastore.Event + g *datastore.Group + } + tests := []struct { + name string + args args + dbFn func(es *EventService) + wantErr bool + wantErrCode int + wantErrMsg string + }{ + { + name: "should_replay_app_event", + args: args{ + ctx: ctx, + event: &datastore.Event{UID: "123"}, + g: &datastore.Group{UID: "123", Name: "test_group"}, + }, + dbFn: func(es *EventService) { + eq, _ := es.createEventQueue.(*mocks.MockQueuer) + eq.EXPECT().Publish(gomock.Any(), convoy.TaskName("test_group-CreateEventProcessor"), gomock.Any(), gomock.Any()). + Times(1).Return(nil) + }, + }, + { + name: "should_fail_to_replay_app_event", + args: args{ + ctx: ctx, + event: &datastore.Event{UID: "123"}, + g: &datastore.Group{UID: "123", Name: "test_group"}, + }, + dbFn: func(es *EventService) { + eq, _ := es.createEventQueue.(*mocks.MockQueuer) + eq.EXPECT().Publish(gomock.Any(), convoy.TaskName("test_group-CreateEventProcessor"), gomock.Any(), gomock.Any()). + Times(1).Return(errors.New("failed")) + }, + wantErr: true, + wantErrCode: http.StatusBadRequest, + wantErrMsg: "failed to write event to queue", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + es := provideEventService(ctrl) + + if tc.dbFn != nil { + tc.dbFn(es) + } + + err := es.ReplayAppEvent(tc.args.ctx, tc.args.event, tc.args.g) + if tc.wantErr { + require.NotNil(t, err) + require.Equal(t, tc.wantErrCode, err.(*ServiceError).ErrCode()) + require.Equal(t, tc.wantErrMsg, err.(*ServiceError).Error()) + return + } + + require.Nil(t, err) + }) + } +} + func TestEventService_GetEventDelivery(t *testing.T) { ctx := context.Background() From cd3d5fb99e3a4636bf715004824c2bcdc004055d Mon Sep 17 00:00:00 2001 From: Daniel Oluojomu Date: Wed, 18 May 2022 21:24:25 +0100 Subject: [PATCH 3/5] fix: specify wantErr --- docs/docs.go | 100 ++++++++++++++++---------------- docs/swagger.json | 98 +++++++++++++++---------------- docs/swagger.yaml | 75 ++++++++++++------------ docs/v3/openapi3.json | 102 +++++++++++++++++---------------- docs/v3/openapi3.yaml | 77 +++++++++++++------------ services/event_service_test.go | 1 + 6 files changed, 231 insertions(+), 222 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index e0d3b9473e..2d901aa42e 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,6 @@ // Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag at -// 2022-05-18 14:15:37.023759 +0100 WAT m=+65.462890168 +// 2022-05-18 21:25:34.66965 +0100 WAT m=+68.766185293 package docs import ( @@ -2444,14 +2444,16 @@ var doc = `{ } } } - }, - "put": { + } + }, + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint replays an app event", + "description": "This endpoint fetches an app message's delivery attempts", "consumes": [ "application/json" ], @@ -2459,21 +2461,21 @@ var doc = `{ "application/json" ], "tags": [ - "Events" + "DeliveryAttempts" ], - "summary": "Replay app event", + "summary": "Get delivery attempts", "parameters": [ { "type": "string", - "description": "group id", - "name": "groupId", - "in": "query", + "description": "event id", + "name": "eventID", + "in": "path", "required": true }, { "type": "string", - "description": "event id", - "name": "eventID", + "description": "event delivery id", + "name": "eventDeliveryID", "in": "path", "required": true } @@ -2490,19 +2492,10 @@ var doc = `{ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/datastore.Event" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/server.Stub" - } - } - } - ] + "type": "array", + "items": { + "$ref": "#/definitions/datastore.DeliveryAttempt" + } } } } @@ -2566,14 +2559,14 @@ var doc = `{ } } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint fetches an app message's delivery attempts", + "description": "This endpoint fetches an app event delivery attempt", "consumes": [ "application/json" ], @@ -2583,7 +2576,7 @@ var doc = `{ "tags": [ "DeliveryAttempts" ], - "summary": "Get delivery attempts", + "summary": "Get delivery attempt", "parameters": [ { "type": "string", @@ -2598,6 +2591,13 @@ var doc = `{ "name": "eventDeliveryID", "in": "path", "required": true + }, + { + "type": "string", + "description": "delivery attempt id", + "name": "deliveryAttemptID", + "in": "path", + "required": true } ], "responses": { @@ -2612,10 +2612,7 @@ var doc = `{ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/datastore.DeliveryAttempt" - } + "$ref": "#/definitions/datastore.DeliveryAttempt" } } } @@ -2679,14 +2676,14 @@ var doc = `{ } } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { - "get": { + "/events/{eventID}/replay": { + "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint fetches an app event delivery attempt", + "description": "This endpoint replays an app event", "consumes": [ "application/json" ], @@ -2694,28 +2691,21 @@ var doc = `{ "application/json" ], "tags": [ - "DeliveryAttempts" + "Events" ], - "summary": "Get delivery attempt", + "summary": "Replay app event", "parameters": [ { "type": "string", - "description": "event id", - "name": "eventID", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "event delivery id", - "name": "eventDeliveryID", - "in": "path", + "description": "group id", + "name": "groupId", + "in": "query", "required": true }, { "type": "string", - "description": "delivery attempt id", - "name": "deliveryAttemptID", + "description": "event id", + "name": "eventID", "in": "path", "required": true } @@ -2732,7 +2722,19 @@ var doc = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/datastore.DeliveryAttempt" + "allOf": [ + { + "$ref": "#/definitions/datastore.Event" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] } } } diff --git a/docs/swagger.json b/docs/swagger.json index b2b0156b90..9462229497 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2432,14 +2432,16 @@ } } } - }, - "put": { + } + }, + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint replays an app event", + "description": "This endpoint fetches an app message's delivery attempts", "consumes": [ "application/json" ], @@ -2447,21 +2449,21 @@ "application/json" ], "tags": [ - "Events" + "DeliveryAttempts" ], - "summary": "Replay app event", + "summary": "Get delivery attempts", "parameters": [ { "type": "string", - "description": "group id", - "name": "groupId", - "in": "query", + "description": "event id", + "name": "eventID", + "in": "path", "required": true }, { "type": "string", - "description": "event id", - "name": "eventID", + "description": "event delivery id", + "name": "eventDeliveryID", "in": "path", "required": true } @@ -2478,19 +2480,10 @@ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/datastore.Event" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/server.Stub" - } - } - } - ] + "type": "array", + "items": { + "$ref": "#/definitions/datastore.DeliveryAttempt" + } } } } @@ -2554,14 +2547,14 @@ } } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint fetches an app message's delivery attempts", + "description": "This endpoint fetches an app event delivery attempt", "consumes": [ "application/json" ], @@ -2571,7 +2564,7 @@ "tags": [ "DeliveryAttempts" ], - "summary": "Get delivery attempts", + "summary": "Get delivery attempt", "parameters": [ { "type": "string", @@ -2586,6 +2579,13 @@ "name": "eventDeliveryID", "in": "path", "required": true + }, + { + "type": "string", + "description": "delivery attempt id", + "name": "deliveryAttemptID", + "in": "path", + "required": true } ], "responses": { @@ -2600,10 +2600,7 @@ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/datastore.DeliveryAttempt" - } + "$ref": "#/definitions/datastore.DeliveryAttempt" } } } @@ -2667,14 +2664,14 @@ } } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { - "get": { + "/events/{eventID}/replay": { + "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "This endpoint fetches an app event delivery attempt", + "description": "This endpoint replays an app event", "consumes": [ "application/json" ], @@ -2682,28 +2679,21 @@ "application/json" ], "tags": [ - "DeliveryAttempts" + "Events" ], - "summary": "Get delivery attempt", + "summary": "Replay app event", "parameters": [ { "type": "string", - "description": "event id", - "name": "eventID", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "event delivery id", - "name": "eventDeliveryID", - "in": "path", + "description": "group id", + "name": "groupId", + "in": "query", "required": true }, { "type": "string", - "description": "delivery attempt id", - "name": "deliveryAttemptID", + "description": "event id", + "name": "eventID", "in": "path", "required": true } @@ -2720,7 +2710,19 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/datastore.DeliveryAttempt" + "allOf": [ + { + "$ref": "#/definitions/datastore.Event" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/server.Stub" + } + } + } + ] } } } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 668221630a..f3645a6351 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1788,21 +1788,22 @@ paths: summary: Get app event tags: - Events - put: + /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: + get: consumes: - application/json - description: This endpoint replays an app event + description: This endpoint fetches an app message's delivery attempts parameters: - - description: group id - in: query - name: groupId - required: true - type: string - description: event id in: path name: eventID required: true type: string + - description: event delivery id + in: path + name: eventDeliveryID + required: true + type: string produces: - application/json responses: @@ -1813,12 +1814,9 @@ paths: - $ref: '#/definitions/server.serverResponse' - properties: data: - allOf: - - $ref: '#/definitions/datastore.Event' - - properties: - data: - $ref: '#/definitions/server.Stub' - type: object + items: + $ref: '#/definitions/datastore.DeliveryAttempt' + type: array type: object "400": description: Bad Request @@ -1849,14 +1847,14 @@ paths: type: object security: - ApiKeyAuth: [] - summary: Replay app event + summary: Get delivery attempts tags: - - Events - /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: + - DeliveryAttempts + /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}: get: consumes: - application/json - description: This endpoint fetches an app message's delivery attempts + description: This endpoint fetches an app event delivery attempt parameters: - description: event id in: path @@ -1868,6 +1866,11 @@ paths: name: eventDeliveryID required: true type: string + - description: delivery attempt id + in: path + name: deliveryAttemptID + required: true + type: string produces: - application/json responses: @@ -1878,9 +1881,7 @@ paths: - $ref: '#/definitions/server.serverResponse' - properties: data: - items: - $ref: '#/definitions/datastore.DeliveryAttempt' - type: array + $ref: '#/definitions/datastore.DeliveryAttempt' type: object "400": description: Bad Request @@ -1911,28 +1912,23 @@ paths: type: object security: - ApiKeyAuth: [] - summary: Get delivery attempts + summary: Get delivery attempt tags: - DeliveryAttempts - /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}: - get: + /events/{eventID}/replay: + put: consumes: - application/json - description: This endpoint fetches an app event delivery attempt + description: This endpoint replays an app event parameters: - - description: event id - in: path - name: eventID - required: true - type: string - - description: event delivery id - in: path - name: eventDeliveryID + - description: group id + in: query + name: groupId required: true type: string - - description: delivery attempt id + - description: event id in: path - name: deliveryAttemptID + name: eventID required: true type: string produces: @@ -1945,7 +1941,12 @@ paths: - $ref: '#/definitions/server.serverResponse' - properties: data: - $ref: '#/definitions/datastore.DeliveryAttempt' + allOf: + - $ref: '#/definitions/datastore.Event' + - properties: + data: + $ref: '#/definitions/server.Stub' + type: object type: object "400": description: Bad Request @@ -1976,9 +1977,9 @@ paths: type: object security: - ApiKeyAuth: [] - summary: Get delivery attempt + summary: Replay app event tags: - - DeliveryAttempts + - Events /groups: get: consumes: diff --git a/docs/v3/openapi3.json b/docs/v3/openapi3.json index b1e38cdb0a..49dd6e817f 100644 --- a/docs/v3/openapi3.json +++ b/docs/v3/openapi3.json @@ -3432,23 +3432,25 @@ "tags": [ "Events" ] - }, - "put": { - "description": "This endpoint replays an app event", + } + }, + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "get": { + "description": "This endpoint fetches an app message's delivery attempts", "parameters": [ { - "description": "group id", - "in": "query", - "name": "groupId", + "description": "event id", + "in": "path", + "name": "eventID", "required": true, "schema": { "type": "string" } }, { - "description": "event id", + "description": "event delivery id", "in": "path", - "name": "eventID", + "name": "eventDeliveryID", "required": true, "schema": { "type": "string" @@ -3467,19 +3469,10 @@ { "properties": { "data": { - "allOf": [ - { - "$ref": "#/components/schemas/datastore.Event" - }, - { - "properties": { - "data": { - "$ref": "#/components/schemas/server.Stub" - } - }, - "type": "object" - } - ] + "items": { + "$ref": "#/components/schemas/datastore.DeliveryAttempt" + }, + "type": "array" } }, "type": "object" @@ -3562,15 +3555,15 @@ "ApiKeyAuth": [] } ], - "summary": "Replay app event", + "summary": "Get delivery attempts", "tags": [ - "Events" + "DeliveryAttempts" ] } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts": { + "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { "get": { - "description": "This endpoint fetches an app message's delivery attempts", + "description": "This endpoint fetches an app event delivery attempt", "parameters": [ { "description": "event id", @@ -3589,6 +3582,15 @@ "schema": { "type": "string" } + }, + { + "description": "delivery attempt id", + "in": "path", + "name": "deliveryAttemptID", + "required": true, + "schema": { + "type": "string" + } } ], "responses": { @@ -3603,10 +3605,7 @@ { "properties": { "data": { - "items": { - "$ref": "#/components/schemas/datastore.DeliveryAttempt" - }, - "type": "array" + "$ref": "#/components/schemas/datastore.DeliveryAttempt" } }, "type": "object" @@ -3689,38 +3688,29 @@ "ApiKeyAuth": [] } ], - "summary": "Get delivery attempts", + "summary": "Get delivery attempt", "tags": [ "DeliveryAttempts" ] } }, - "/events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}": { - "get": { - "description": "This endpoint fetches an app event delivery attempt", + "/events/{eventID}/replay": { + "put": { + "description": "This endpoint replays an app event", "parameters": [ { - "description": "event id", - "in": "path", - "name": "eventID", - "required": true, - "schema": { - "type": "string" - } - }, - { - "description": "event delivery id", - "in": "path", - "name": "eventDeliveryID", + "description": "group id", + "in": "query", + "name": "groupId", "required": true, "schema": { "type": "string" } }, { - "description": "delivery attempt id", + "description": "event id", "in": "path", - "name": "deliveryAttemptID", + "name": "eventID", "required": true, "schema": { "type": "string" @@ -3739,7 +3729,19 @@ { "properties": { "data": { - "$ref": "#/components/schemas/datastore.DeliveryAttempt" + "allOf": [ + { + "$ref": "#/components/schemas/datastore.Event" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/server.Stub" + } + }, + "type": "object" + } + ] } }, "type": "object" @@ -3822,9 +3824,9 @@ "ApiKeyAuth": [] } ], - "summary": "Get delivery attempt", + "summary": "Replay app event", "tags": [ - "DeliveryAttempts" + "Events" ] } }, diff --git a/docs/v3/openapi3.yaml b/docs/v3/openapi3.yaml index 3a6bf7efe3..539bf967b7 100644 --- a/docs/v3/openapi3.yaml +++ b/docs/v3/openapi3.yaml @@ -1939,18 +1939,19 @@ paths: summary: Get app event tags: - Events - put: - description: This endpoint replays an app event + /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: + get: + description: This endpoint fetches an app message's delivery attempts parameters: - - description: group id - in: query - name: groupId + - description: event id + in: path + name: eventID required: true schema: type: string - - description: event id + - description: event delivery id in: path - name: eventID + name: eventDeliveryID required: true schema: type: string @@ -1963,12 +1964,9 @@ paths: - $ref: '#/components/schemas/server.serverResponse' - properties: data: - allOf: - - $ref: '#/components/schemas/datastore.Event' - - properties: - data: - $ref: '#/components/schemas/server.Stub' - type: object + items: + $ref: '#/components/schemas/datastore.DeliveryAttempt' + type: array type: object description: OK "400": @@ -2006,12 +2004,12 @@ paths: description: Internal Server Error security: - ApiKeyAuth: [] - summary: Replay app event + summary: Get delivery attempts tags: - - Events - /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts: + - DeliveryAttempts + /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}: get: - description: This endpoint fetches an app message's delivery attempts + description: This endpoint fetches an app event delivery attempt parameters: - description: event id in: path @@ -2025,6 +2023,12 @@ paths: required: true schema: type: string + - description: delivery attempt id + in: path + name: deliveryAttemptID + required: true + schema: + type: string responses: "200": content: @@ -2034,9 +2038,7 @@ paths: - $ref: '#/components/schemas/server.serverResponse' - properties: data: - items: - $ref: '#/components/schemas/datastore.DeliveryAttempt' - type: array + $ref: '#/components/schemas/datastore.DeliveryAttempt' type: object description: OK "400": @@ -2074,28 +2076,22 @@ paths: description: Internal Server Error security: - ApiKeyAuth: [] - summary: Get delivery attempts + summary: Get delivery attempt tags: - DeliveryAttempts - /events/{eventID}/eventdeliveries/{eventDeliveryID}/deliveryattempts/{deliveryAttemptID}: - get: - description: This endpoint fetches an app event delivery attempt + /events/{eventID}/replay: + put: + description: This endpoint replays an app event parameters: - - description: event id - in: path - name: eventID - required: true - schema: - type: string - - description: event delivery id - in: path - name: eventDeliveryID + - description: group id + in: query + name: groupId required: true schema: type: string - - description: delivery attempt id + - description: event id in: path - name: deliveryAttemptID + name: eventID required: true schema: type: string @@ -2108,7 +2104,12 @@ paths: - $ref: '#/components/schemas/server.serverResponse' - properties: data: - $ref: '#/components/schemas/datastore.DeliveryAttempt' + allOf: + - $ref: '#/components/schemas/datastore.Event' + - properties: + data: + $ref: '#/components/schemas/server.Stub' + type: object type: object description: OK "400": @@ -2146,9 +2147,9 @@ paths: description: Internal Server Error security: - ApiKeyAuth: [] - summary: Get delivery attempt + summary: Replay app event tags: - - DeliveryAttempts + - Events /groups: get: description: This endpoint fetches groups diff --git a/services/event_service_test.go b/services/event_service_test.go index 7424168680..9b9503ab00 100644 --- a/services/event_service_test.go +++ b/services/event_service_test.go @@ -513,6 +513,7 @@ func TestEventService_ReplayAppEvent(t *testing.T) { eq.EXPECT().Publish(gomock.Any(), convoy.TaskName("test_group-CreateEventProcessor"), gomock.Any(), gomock.Any()). Times(1).Return(nil) }, + wantErr: false, }, { name: "should_fail_to_replay_app_event", From 33106ff43a2b3ac313ff66fa83cbb6c1955ae61f Mon Sep 17 00:00:00 2001 From: Daniel Oluojomu Date: Wed, 18 May 2022 21:27:17 +0100 Subject: [PATCH 4/5] fix: change url to /events/{eventID/replay --- docs/docs.go | 2 +- server/event.go | 2 +- server/event_integration_test.go | 2 +- server/route.go | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 2d901aa42e..0b8416d613 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,6 @@ // Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag at -// 2022-05-18 21:25:34.66965 +0100 WAT m=+68.766185293 +// 2022-05-18 22:17:00.313618 +0100 WAT m=+66.012353960 package docs import ( diff --git a/server/event.go b/server/event.go index 9a1e9cc176..279aedfc5a 100644 --- a/server/event.go +++ b/server/event.go @@ -57,7 +57,7 @@ func (a *applicationHandler) CreateAppEvent(w http.ResponseWriter, r *http.Reque // @Success 200 {object} serverResponse{data=datastore.Event{data=Stub}} // @Failure 400,401,500 {object} serverResponse{data=Stub} // @Security ApiKeyAuth -// @Router /events/{eventID} [put] +// @Router /events/{eventID}/replay [put] func (a *applicationHandler) ReplayAppEvent(w http.ResponseWriter, r *http.Request) { g := getGroupFromContext(r.Context()) event := getEventFromContext(r.Context()) diff --git a/server/event_integration_test.go b/server/event_integration_test.go index 7b0c307e39..e88e1586e6 100644 --- a/server/event_integration_test.go +++ b/server/event_integration_test.go @@ -146,7 +146,7 @@ func (s *EventIntegrationTestSuite) Test_ReplayAppEvent_Valid_Event() { app, _ := testdb.SeedApplication(s.DB, s.DefaultGroup, uuid.NewString(), "", false) _, _ = testdb.SeedEvent(s.DB, app, eventID, "*", []byte(`{}`)) - url := fmt.Sprintf("/api/v1/events/%s", eventID) + url := fmt.Sprintf("/api/v1/events/%s/replay", eventID) req := createRequest(http.MethodPut, url, nil) w := httptest.NewRecorder() diff --git a/server/route.go b/server/route.go index 06bf204ace..68b991c525 100644 --- a/server/route.go +++ b/server/route.go @@ -125,7 +125,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) - eventSubRouter.Put("/", app.ReplayAppEvent) + eventSubRouter.Put("/replay", app.ReplayAppEvent) }) }) @@ -256,7 +256,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) - eventSubRouter.Put("/", app.ReplayAppEvent) + eventSubRouter.Put("/replay", app.ReplayAppEvent) }) }) @@ -322,7 +322,7 @@ func buildRoutes(app *applicationHandler) http.Handler { eventRouter.Route("/{eventID}", func(eventSubRouter chi.Router) { eventSubRouter.Use(requireEvent(app.eventRepo)) eventSubRouter.Get("/", app.GetAppEvent) - eventSubRouter.Put("/", app.ReplayAppEvent) + eventSubRouter.Put("/replay", app.ReplayAppEvent) }) }) From a86f4e73613246e77748bff2c2a7f6cd7a689345 Mon Sep 17 00:00:00 2001 From: Daniel Oluojomu Date: Mon, 30 May 2022 19:09:18 +0100 Subject: [PATCH 5/5] tests: fix testdb.SeedEvent call --- docs/docs.go | 2 +- server/event_integration_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 490979a625..81c82fbb39 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,6 @@ // Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag at -// 2022-05-25 15:51:00.014377 +0100 WAT m=+67.530462293 +// 2022-05-30 19:10:25.941245 +0100 WAT m=+66.892945167 package docs import ( diff --git a/server/event_integration_test.go b/server/event_integration_test.go index 4b07ddc03d..0dfd172545 100644 --- a/server/event_integration_test.go +++ b/server/event_integration_test.go @@ -144,7 +144,7 @@ func (s *EventIntegrationTestSuite) Test_ReplayAppEvent_Valid_Event() { // Just Before. app, _ := testdb.SeedApplication(s.DB, s.DefaultGroup, uuid.NewString(), "", false) - _, _ = testdb.SeedEvent(s.DB, app, eventID, "*", []byte(`{}`)) + _, _ = testdb.SeedEvent(s.DB, app, s.DefaultGroup.UID, eventID, "*", []byte(`{}`)) url := fmt.Sprintf("/api/v1/events/%s/replay", eventID) req := createRequest(http.MethodPut, url, nil)