Skip to content

Commit

Permalink
🛠️ Refactor: Removed InsertExecution endpoint. Enqueue function now c…
Browse files Browse the repository at this point in the history
…alls EnqueueCriteria with the proper search criteria execution id
  • Loading branch information
lhbelfanti committed Sep 28, 2024
1 parent 43e59d8 commit 0fa9da8
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 162 deletions.
6 changes: 2 additions & 4 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,14 @@ func main() {
selectCriteriaByID := criteria.MakeSelectByID(db)
collectExecutionDAORows := database.MakeCollectRows[criteria.ExecutionDAO]()
selectExecutionsByStatuses := criteria.MakeSelectExecutionsByStatuses(db, collectExecutionDAORows)
insertCriteriaExecution := criteria.MakeInsertExecution(db)
scrapperEnqueueCriteria := scrapper.MakeEnqueueCriteria(httpClient, os.Getenv("ENQUEUE_CRITERIA_API_URL"))
enqueueCriteria := criteria.MakeEnqueue(selectCriteriaByID, selectExecutionsByStatuses, scrapperEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(selectCriteriaByID, selectExecutionsByStatuses, insertCriteriaExecution, scrapperEnqueueCriteria)

selectLastDayExecutedByCriteriaID := criteria.MakeSelectLastDayExecutedByCriteriaID(db)
resumeCriteria := criteria.MakeResume(selectCriteriaByID, selectLastDayExecutedByCriteriaID, selectExecutionsByStatuses, scrapperEnqueueCriteria)
initCriteria := criteria.MakeInit(selectExecutionsByStatuses, resumeCriteria)

insertCriteriaExecution := criteria.MakeInsertExecution(db)

updateCriteriaExecution := criteria.MakeUpdateExecution(db)

insertCriteriaExecutionDay := criteria.MakeInsertExecutionDay(db)
Expand All @@ -80,7 +79,6 @@ func main() {
router.HandleFunc("POST /tweets/v1", tweets.InsertHandlerV1(insertTweets))
router.HandleFunc("POST /criteria/{criteria_id}/enqueue/v1", criteria.EnqueueHandlerV1(enqueueCriteria))
router.HandleFunc("POST /criteria/init/v1", criteria.InitHandlerV1(initCriteria))
router.HandleFunc("POST /criteria/{criteria_id}/executions/v1", criteria.InsertExecutionHandlerV1(insertCriteriaExecution))
router.HandleFunc("PUT /criteria/executions/{execution_id}/v1", criteria.UpdateExecutionHandlerV1(updateCriteriaExecution))
router.HandleFunc("POST /criteria/executions/{execution_id}/day/v1", criteria.InsertExecutionDayHandlerV1(insertCriteriaExecutionDay))
log.Info(ctx, "Router initialized!")
Expand Down
6 changes: 0 additions & 6 deletions cmd/api/search/criteria/dtos.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,4 @@ type (
ErrorReason *string `json:"error_reason"`
SearchCriteriaExecutionID int `json:"search_criteria_execution_id"`
}

// InsertExecutionHandlerV1Response represents the response of the InsertExecutionHandlerV1 function
InsertExecutionHandlerV1Response struct {
Message string `json:"message"`
ExecutionID int `json:"execution_id"`
}
)
10 changes: 8 additions & 2 deletions cmd/api/search/criteria/enqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type (
)

// MakeEnqueue creates a new Enqueue
func MakeEnqueue(selectCriteriaByID SelectByID, selectExecutionsByStatuses SelectExecutionsByStatuses, enqueueCriteria scrapper.EnqueueCriteria) Enqueue {
func MakeEnqueue(selectCriteriaByID SelectByID, selectExecutionsByStatuses SelectExecutionsByStatuses, insertExecution InsertExecution, enqueueCriteria scrapper.EnqueueCriteria) Enqueue {
return func(ctx context.Context, criteriaID int, forced bool) error {
criteriaDAO, err := selectCriteriaByID(ctx, criteriaID)
if err != nil {
Expand All @@ -41,7 +41,13 @@ func MakeEnqueue(selectCriteriaByID SelectByID, selectExecutionsByStatuses Selec
}
}

err = enqueueCriteria(ctx, criteriaDAO.toCriteriaDTO(), 0)
executionID, err := insertExecution(ctx, criteriaID, forced)
if err != nil {
log.Error(ctx, err.Error())
return FailedToInsertSearchCriteriaExecution
}

err = enqueueCriteria(ctx, criteriaDAO.toCriteriaDTO(), executionID)
if err != nil {
log.Error(ctx, err.Error())
return FailedToExecuteEnqueueCriteria
Expand Down
33 changes: 26 additions & 7 deletions cmd/api/search/criteria/enqueue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ func TestEnqueue_success(t *testing.T) {

for _, tt := range tests {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), nil)
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

got := enqueueCriteria(context.Background(), 1, tt.forced)

Expand All @@ -36,9 +37,10 @@ func TestEnqueue_success(t *testing.T) {
func TestEnqueue_failsWhenSelectCriteriaByIDThrowsError(t *testing.T) {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), errors.New("failed to execute select criteria by id"))
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), nil)
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

want := criteria.FailedToExecuteSelectCriteriaByID
got := enqueueCriteria(context.Background(), 1, false)
Expand All @@ -49,9 +51,10 @@ func TestEnqueue_failsWhenSelectCriteriaByIDThrowsError(t *testing.T) {
func TestEnqueue_failsWhenSelectExecutionsByStatusesThrowsError(t *testing.T) {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), nil)
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), errors.New("failed to execute select executions by statuses"))
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

want := criteria.FailedToExecuteSelectExecutionsByStatuses
got := enqueueCriteria(context.Background(), 1, false)
Expand All @@ -62,22 +65,38 @@ func TestEnqueue_failsWhenSelectExecutionsByStatusesThrowsError(t *testing.T) {
func TestEnqueue_failsWhenThereIsAlreadyAnExecutionWithTheSameCriteriaIDEnqueued(t *testing.T) {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), nil)
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), nil)
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

want := criteria.AnExecutionOfThisCriteriaIDIsAlreadyEnqueued
got := enqueueCriteria(context.Background(), 4, false)
got := enqueueCriteria(context.Background(), 2, false)

assert.Equal(t, want, got)
}

func TestEnqueue_failsWhenInsertExecutionThrowsError(t *testing.T) {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), nil)
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), nil)
mockInsertExecution := criteria.MockInsertExecution(-1, errors.New("failed to insert execution"))
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(nil)

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

want := criteria.FailedToInsertSearchCriteriaExecution
got := enqueueCriteria(context.Background(), 1, false)

assert.Equal(t, want, got)
}

func TestEnqueue_failsWhenEnqueueCriteriaThrowsError(t *testing.T) {
mockSelectCriteriaByID := criteria.MockSelectByID(criteria.MockCriteriaDAO(), nil)
mockSelectExecutionsByStatuses := criteria.MockSelectExecutionsByStatuses(criteria.MockExecutionsDAO(), nil)
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockEnqueueCriteria := scrapper.MockEnqueueCriteria(errors.New("failed to execute enqueue criteria"))

enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockEnqueueCriteria)
enqueueCriteria := criteria.MakeEnqueue(mockSelectCriteriaByID, mockSelectExecutionsByStatuses, mockInsertExecution, mockEnqueueCriteria)

want := criteria.FailedToExecuteEnqueueCriteria
got := enqueueCriteria(context.Background(), 1, false)
Expand Down
31 changes: 13 additions & 18 deletions cmd/api/search/criteria/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@ const (
)

var (
NoCriteriaDataFoundForTheGivenCriteriaID = errors.New("no criteria data found for given criteria id")
FailedExecuteQueryToRetrieveCriteriaData = errors.New("failed to execute query to retrieve criteria data")

FailedToRetrieveAllCriteriaData = errors.New("failed to retrieve all criteria data")
FailedToExecuteSelectCollectRowsInSelectAll = errors.New("failed to execute select collect rows in select all")

FailedToExecuteSelectCriteriaByID = errors.New("failed to execute select criteria by id")
FailedToExecuteSelectLastDayExecutedByCriteriaID = errors.New("failed to execute select last day executed by criteria id")
FailedToExecuteSelectExecutionsByStatuses = errors.New("failed to execute select executions by statuses")
AnExecutionOfThisCriteriaIDIsAlreadyEnqueued = errors.New("an execution of this criteria is already enqueued")
FailedToExecuteEnqueueCriteria = errors.New("failed to execute enqueue criteria")
FailedToRetrieveSearchCriteriaExecutionID = errors.New("failed to retrieve search criteria execution id")

NoCriteriaDataFoundForTheGivenCriteriaID = errors.New("no criteria data found for given criteria id")
FailedExecuteQueryToRetrieveCriteriaData = errors.New("failed to execute query to retrieve criteria data")
FailedToRetrieveAllCriteriaData = errors.New("failed to retrieve all criteria data")
FailedToExecuteSelectCollectRowsInSelectAll = errors.New("failed to execute select collect rows in select all")
FailedToExecuteSelectCriteriaByID = errors.New("failed to execute select criteria by id")
FailedToExecuteSelectLastDayExecutedByCriteriaID = errors.New("failed to execute select last day executed by criteria id")
FailedToExecuteSelectExecutionsByStatuses = errors.New("failed to execute select executions by statuses")
AnExecutionOfThisCriteriaIDIsAlreadyEnqueued = errors.New("an execution of this criteria is already enqueued")
FailedToExecuteEnqueueCriteria = errors.New("failed to execute enqueue criteria")
FailedToRetrieveSearchCriteriaExecutionID = errors.New("failed to retrieve search criteria execution id")
FailedToInsertSearchCriteriaExecution = errors.New("failed to insert search criteria execution")
FailedToUpdateSearchCriteriaExecution = errors.New("failed to update search criteria execution")
FailedToExecuteSelectSearchCriteriaExecutionByState = errors.New("failed to execute select search criteria execution by state")
FailedToExecuteSelectCollectRowsInSelectExecutionByState = errors.New("failed to execute select collect rows in select criteria execution by state")

FailedToInsertSearchCriteriaExecutionDay = errors.New("failed to insert search criteria execution day")

FailedToRetrieveLastDayExecutedDate = errors.New("failed to retrieve last day executed date")
NoExecutionDaysFoundForTheGivenCriteriaID = errors.New("no execution days found for the given criteria id")
FailedToInsertSearchCriteriaExecutionDay = errors.New("failed to insert search criteria execution day")
FailedToRetrieveLastDayExecutedDate = errors.New("failed to retrieve last day executed date")
NoExecutionDaysFoundForTheGivenCriteriaID = errors.New("no execution days found for the given criteria id")
)
39 changes: 0 additions & 39 deletions cmd/api/search/criteria/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,45 +69,6 @@ func InitHandlerV1(init Init) http.HandlerFunc {
}
}

// InsertExecutionHandlerV1 HTTP Handler of the endpoint /criteria/{criteria_id}/executions/{execution_id}/v1
func InsertExecutionHandlerV1(insertExecution InsertExecution) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

criteriaIDParam := r.PathValue("criteria_id")
criteriaID, err := strconv.Atoi(criteriaIDParam)
if err != nil {
log.Error(ctx, err.Error())
http.Error(w, InvalidURLParameter, http.StatusBadRequest)
return
}
ctx = log.With(ctx, log.Param("criteria_id", criteriaIDParam))

executionID, err := insertExecution(ctx, criteriaID, true)
if err != nil {
log.Error(ctx, err.Error())
http.Error(w, FailedToExecuteInsertCriteriaExecution, http.StatusInternalServerError)
return
}

response := InsertExecutionHandlerV1Response{
Message: "Criteria execution successfully inserted",
ExecutionID: executionID,
}

log.Info(ctx, "Criteria execution successfully inserted")
w.Header().Set("Content-Type", "application/json")

err = json.NewEncoder(w).Encode(response) // w.WriteHeader(http.StatusOK) is implicitly set inside the encoder
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(ctx, err.Error())
http.Error(w, FailedToEncodeInsertCriteriaExecutionResponse, http.StatusInternalServerError)
return
}
}
}

// UpdateExecutionHandlerV1 HTTP Handler of the endpoint /criteria/executions/{execution_id}/v1
func UpdateExecutionHandlerV1(updateExecution UpdateExecution) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
Expand Down
63 changes: 0 additions & 63 deletions cmd/api/search/criteria/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,69 +133,6 @@ func TestInitHandlerV1_failsWhenInitThrowsError(t *testing.T) {
assert.Equal(t, want, got)
}

func TestInsertExecutionHandlerV1_success(t *testing.T) {
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/executions/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "1")

handlerV1 := criteria.InsertExecutionHandlerV1(mockInsertExecution)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusOK
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestInsertExecutionHandlerV1_failsWhenTheURLParamIsEmpty(t *testing.T) {
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/executions/v1", http.NoBody)

handlerV1 := criteria.InsertExecutionHandlerV1(mockInsertExecution)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusBadRequest
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestInsertExecutionHandlerV1_failsWhenInsertExecutionThrowsError(t *testing.T) {
mockInsertExecution := criteria.MockInsertExecution(-1, errors.New("failed while executing insert criteria"))
mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/executions/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "1")

handlerV1 := criteria.InsertExecutionHandlerV1(mockInsertExecution)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusInternalServerError
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestInsertExecutionHandlerV1_failsWhenJSONEncoderThrowsError(t *testing.T) {
mockInsertExecution := criteria.MockInsertExecution(1, nil)
mockResponseWriter := &criteria.MockErrorResponseWriter{ResponseRecorder: httptest.NewRecorder()}
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/executions/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "1")

handlerV1 := criteria.InsertExecutionHandlerV1(mockInsertExecution)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusInternalServerError
got := mockResponseWriter.ResponseRecorder.Result().StatusCode

assert.Equal(t, want, got)
}

func TestUpdateExecutionHandlerV1_success(t *testing.T) {
mockUpdateExecution := criteria.MockUpdateExecution(nil)
mockResponseWriter := httptest.NewRecorder()
Expand Down
1 change: 1 addition & 0 deletions cmd/api/search/criteria/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func MakeInsertExecution(db database.Connection) InsertExecution {
forcedInsertQuery string = `
INSERT INTO search_criteria_executions(status, search_criteria_id)
VALUES ('PENDING', %d)
RETURNING id;
`
)

Expand Down
23 changes: 0 additions & 23 deletions cmd/api/search/criteria/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package criteria

import (
"context"
"errors"
"net/http"
"net/http/httptest"
"time"
)

Expand Down Expand Up @@ -166,23 +163,3 @@ func MockExecutionDTO() ExecutionDTO {
SearchCriteriaID: 0,
}
}

// MockErrorResponseWriter mocks a ResponseRecorder
type MockErrorResponseWriter struct {
ResponseRecorder *httptest.ResponseRecorder
}

// Write is the method of MockErrorResponseWriter that mocks the Write behaviour of a ResponseRecorder
func (w *MockErrorResponseWriter) Write(b []byte) (int, error) {
return 0, errors.New("error while executing ResponseRecorder.Write")
}

// WriteHeader is the method of MockErrorResponseWriter that mocks the WriteHeader behaviour of a ResponseRecorder
func (w *MockErrorResponseWriter) WriteHeader(statusCode int) {
w.ResponseRecorder.WriteHeader(statusCode)
}

// Header is the method of MockErrorResponseWriter that mocks the Header behaviour of a ResponseRecorder
func (w *MockErrorResponseWriter) Header() http.Header {
return w.ResponseRecorder.Header()
}

0 comments on commit 0fa9da8

Please sign in to comment.