From 70445af6e35fb9bb6ea14454b7051c51754dba13 Mon Sep 17 00:00:00 2001 From: Harold Wanyama <81645226+nickmango@users.noreply.github.com> Date: Sat, 25 Feb 2023 02:12:44 +0300 Subject: [PATCH] Feature/ Events Search (#3809) Co-authored-by: David Deal --- cla-backend-go/events/mock.go | 12 +++--- cla-backend-go/events/mockrepo.go | 4 +- cla-backend-go/events/repository.go | 58 ++++++++++++++-------------- cla-backend-go/events/service.go | 12 +++--- cla-backend-go/swagger/cla.v2.yaml | 1 + cla-backend-go/v2/events/handlers.go | 4 +- 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/cla-backend-go/events/mock.go b/cla-backend-go/events/mock.go index 882c8358e..ba77958cb 100644 --- a/cla-backend-go/events/mock.go +++ b/cla-backend-go/events/mock.go @@ -56,18 +56,18 @@ func (mr *MockServiceMockRecorder) GetClaGroupEvents(arg0, arg1, arg2, arg3, arg } // GetCompanyClaGroupEvents mocks base method -func (m *MockService) GetCompanyClaGroupEvents(arg0, arg1, arg2 string, arg3 *string, arg4 *int64, arg5 bool) (*models.EventList, error) { +func (m *MockService) GetCompanyClaGroupEvents(arg0, arg1, arg2 string, arg3 *string, arg4 *int64, arg5 *string, arg6 bool) (*models.EventList, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCompanyClaGroupEvents", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "GetCompanyClaGroupEvents", arg0, arg1, arg2, arg3, arg4, arg5, arg6) ret0, _ := ret[0].(*models.EventList) ret1, _ := ret[1].(error) return ret0, ret1 } // GetCompanyClaGroupEvents indicates an expected call of GetCompanyClaGroupEvents -func (mr *MockServiceMockRecorder) GetCompanyClaGroupEvents(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) GetCompanyClaGroupEvents(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCompanyClaGroupEvents", reflect.TypeOf((*MockService)(nil).GetCompanyClaGroupEvents), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCompanyClaGroupEvents", reflect.TypeOf((*MockService)(nil).GetCompanyClaGroupEvents), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } // GetCompanyEvents mocks base method @@ -86,9 +86,9 @@ func (mr *MockServiceMockRecorder) GetCompanyEvents(arg0, arg1, arg2, arg3, arg4 } // GetCompanyFoundationEvents mocks base method -func (m *MockService) GetCompanyFoundationEvents(arg0, arg1, arg2 string, arg3 *string, arg4 *int64, arg5 bool) (*models.EventList, error) { +func (m *MockService) GetCompanyFoundationEvents(arg0, arg1, arg2 string, arg3 *string, arg4 *int64, arg5 *string, arg6 bool) (*models.EventList, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCompanyFoundationEvents", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "GetCompanyFoundationEvents", arg0, arg1, arg2, arg3, arg4, arg5, arg6) ret0, _ := ret[0].(*models.EventList) ret1, _ := ret[1].(error) return ret0, ret1 diff --git a/cla-backend-go/events/mockrepo.go b/cla-backend-go/events/mockrepo.go index 0ba7ceee1..52e29c8e1 100644 --- a/cla-backend-go/events/mockrepo.go +++ b/cla-backend-go/events/mockrepo.go @@ -24,11 +24,11 @@ func (repo *mockRepository) AddDataToEvent(eventID, foundationSFID, projectSFID, panic("implement me") } -func (repo *mockRepository) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { +func (repo *mockRepository) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, searchterm *string, all bool) (*models.EventList, error) { panic("implement me") } -func (repo *mockRepository) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { +func (repo *mockRepository) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) { panic("implement me") } diff --git a/cla-backend-go/events/repository.go b/cla-backend-go/events/repository.go index 951b5f4a7..245921ecf 100644 --- a/cla-backend-go/events/repository.go +++ b/cla-backend-go/events/repository.go @@ -45,6 +45,7 @@ const ( EventFoundationSFIDEpochIndex = "event-foundation-sfid-event-time-epoch-index" EventProjectIDEpochIndex = "event-project-id-event-time-epoch-index" EventCLAGroupIDEpochIndex = "event-cla-group-id-event-time-epoch-index" + EventCompanySFIDEventDataLowerIndex = "event-company-sfid-event-data-lower-index" ) // constants @@ -60,8 +61,8 @@ type Repository interface { SearchEvents(params *eventOps.SearchEventsParams, pageSize int64) (*models.EventList, error) GetRecentEvents(pageSize int64) (*models.EventList, error) - GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) - GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) + GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) + GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) GetCompanyEvents(companyID, eventType string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) GetFoundationEvents(foundationSFID string, nextKey *string, paramPageSize *int64, all bool, searchTerm *string) (*models.EventList, error) GetClaGroupEvents(claGroupID string, nextKey *string, paramPageSize *int64, all bool, searchTerm *string) (*models.EventList, error) @@ -373,24 +374,6 @@ func (repo *repository) queryEventsTable(indexName string, condition expression. log.WithFields(f).Debug("querying events table...") builder := expression.NewBuilder().WithKeyCondition(condition) - // If we have a search term... - if searchTerm != nil { - log.WithFields(f).Debugf("adding searchTerm: %s", *searchTerm) - eventLowerFilter := expression.Name("event_data_lower").Contains(strings.ToLower(*searchTerm)) - if filter == nil { - // Create a new filter - filter = &eventLowerFilter - } else { - // Add to existing filter - filter.And(eventLowerFilter) - } - } - - // Add the filter to the builder - if filter != nil { - builder = builder.WithFilter(*filter) - } - // Use the nice builder to create the expression expr, err := builder.Build() if err != nil { @@ -456,8 +439,14 @@ func (repo *repository) queryEventsTable(indexName string, condition expression. return nil, modelErr } - // Trim to how many the caller asked for - just in case we go over events = append(events, eventsList...) + // Add search term filtering + if len(events) > 0 && searchTerm != nil { + log.WithFields(f).Debugf("filtering events by search term: %s", *searchTerm) + events = filterEventsBySearchTerm(events, *searchTerm) + } + + // Trim to how many the caller asked for - just in case we go over if int64(len(events)) > maxResults { events = events[:maxResults] } @@ -502,6 +491,17 @@ func (repo *repository) queryEventsTable(indexName string, condition expression. }, nil } +func filterEventsBySearchTerm(events []*models.Event, s string) []*models.Event { + var filteredEvents []*models.Event + for _, event := range events { + log.Debugf("checking event: %s", event.EventData) + if strings.Contains(strings.ToLower(event.EventData), strings.ToLower(s)) { + filteredEvents = append(filteredEvents, event) + } + } + return filteredEvents +} + func buildNextKey(indexName string, event *models.Event) (string, error) { nextKey := make(map[string]*dynamodb.AttributeValue) nextKey["event_id"] = &dynamodb.AttributeValue{S: aws.String(event.EventID)} @@ -534,7 +534,7 @@ func buildNextKey(indexName string, event *models.Event) (string, error) { } // GetCompanyFoundationEvents returns the list of events for foundation and company -func (repo *repository) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { +func (repo *repository) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) { f := logrus.Fields{ "functionName": "v1.events.repository.GetCompanyFoundationEvents", "companySFID": companySFID, @@ -544,16 +544,16 @@ func (repo *repository) GetCompanyFoundationEvents(companySFID, companyID, found "paramPageSize": utils.Int64Value(paramPageSize), "loadAll": all, } - log.WithFields(f).Debugf("adding key condition of 'event_parent_project_sfid = %s'", foundationSFID) - keyCondition := expression.Key("event_parent_project_sfid").Equal(expression.Value(foundationSFID)) + log.WithFields(f).Debugf("adding key condition of 'event_company_sfid_sfid = %s'", companySFID) + keyCondition := expression.Key("event_company_sfid").Equal(expression.Value(companySFID)) var filter expression.ConditionBuilder - log.WithFields(f).Debugf("adding filter condition of 'event_company_sfid = %s'", companySFID) - filter = expression.Name("event_company_sfid").Equal(expression.Value(companySFID)) - return repo.queryEventsTable(EventFoundationSFIDEpochIndex, keyCondition, &filter, nextKey, paramPageSize, all, nil) + log.WithFields(f).Debugf("adding filter condition of 'event_parent_project_sfid = %s'", foundationSFID) + filter = expression.Name("event_parent_project_sfid").Equal(expression.Value(foundationSFID)) + return repo.queryEventsTable(EventCompanySFIDEventDataLowerIndex, keyCondition, &filter, nextKey, paramPageSize, all, searchTerm) } // GetCompanyClaGroupEvents returns the list of events for cla group and the company -func (repo *repository) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { +func (repo *repository) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) { f := logrus.Fields{ "functionName": "v1.events.repository.GetCompanyClaGroupEvents", "companySFID": companySFID, @@ -568,7 +568,7 @@ func (repo *repository) GetCompanyClaGroupEvents(companySFID, companyID, claGrou var filter expression.ConditionBuilder log.WithFields(f).Debugf("adding filter condition of 'event_company_sfid = %s'", companySFID) filter = expression.Name("event_company_sfid").Equal(expression.Value(companySFID)) - return repo.queryEventsTable(EventCLAGroupIDEpochIndex, keyCondition, &filter, nextKey, paramPageSize, all, nil) + return repo.queryEventsTable(EventCLAGroupIDEpochIndex, keyCondition, &filter, nextKey, paramPageSize, all, searchTerm) } // GetCompanyEvents returns the list of events for given company id and event types diff --git a/cla-backend-go/events/service.go b/cla-backend-go/events/service.go index 7182e9558..4acb7d696 100644 --- a/cla-backend-go/events/service.go +++ b/cla-backend-go/events/service.go @@ -39,8 +39,8 @@ type Service interface { GetFoundationEvents(foundationSFID string, nextKey *string, paramPageSize *int64, all bool, searchTerm *string) (*models.EventList, error) GetClaGroupEvents(claGroupID string, nextKey *string, paramPageSize *int64, all bool, searchTerm *string) (*models.EventList, error) - GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) - GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) + GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) + GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) GetCompanyEvents(companyID, eventType string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) } @@ -101,13 +101,13 @@ func (s *service) GetClaGroupEvents(projectSFDC string, nextKey *string, paramPa } // GetCompanyFoundationEvents returns list of events for company and foundation -func (s *service) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { - return s.repo.GetCompanyFoundationEvents(companySFID, companyID, foundationSFID, nextKey, paramPageSize, all) +func (s *service) GetCompanyFoundationEvents(companySFID, companyID, foundationSFID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) { + return s.repo.GetCompanyFoundationEvents(companySFID, companyID, foundationSFID, nextKey, paramPageSize, searchTerm, all) } // GetCompanyClaGroupEvents returns list of events for company and cla group -func (s *service) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { - return s.repo.GetCompanyClaGroupEvents(companySFID, companyID, claGroupID, nextKey, paramPageSize, all) +func (s *service) GetCompanyClaGroupEvents(companySFID, companyID, claGroupID string, nextKey *string, paramPageSize *int64, searchTerm *string, all bool) (*models.EventList, error) { + return s.repo.GetCompanyClaGroupEvents(companySFID, companyID, claGroupID, nextKey, paramPageSize, searchTerm, all) } func (s *service) GetCompanyEvents(companyID, eventType string, nextKey *string, paramPageSize *int64, all bool) (*models.EventList, error) { diff --git a/cla-backend-go/swagger/cla.v2.yaml b/cla-backend-go/swagger/cla.v2.yaml index dbdc861d2..1ea79bdd3 100644 --- a/cla-backend-go/swagger/cla.v2.yaml +++ b/cla-backend-go/swagger/cla.v2.yaml @@ -1078,6 +1078,7 @@ paths: - $ref: '#/parameters/path-projectSFID' - $ref: '#/parameters/path-companyID' - $ref: '#/parameters/nextKey' + - $ref: '#/parameters/searchTerm' - $ref: '#/parameters/returnAllEvents' produces: - application/json diff --git a/cla-backend-go/v2/events/handlers.go b/cla-backend-go/v2/events/handlers.go index da32630e0..bb0fd33b9 100644 --- a/cla-backend-go/v2/events/handlers.go +++ b/cla-backend-go/v2/events/handlers.go @@ -310,7 +310,7 @@ func Configure(api *operations.EasyclaAPI, service v1Events.Service, v1CompanyRe var result *v1Models.EventList if utils.IsProjectHasRootParent(projectDetails) { log.WithFields(f).Debugf("loading foundation level events for projectSFID: %s...", params.ProjectSFID) - result, err = service.GetCompanyFoundationEvents(v1Company.CompanyExternalID, "", params.ProjectSFID, params.NextKey, params.PageSize, aws.BoolValue(params.ReturnAllEvents)) + result, err = service.GetCompanyFoundationEvents(v1Company.CompanyExternalID, "", params.ProjectSFID, params.NextKey, params.PageSize, params.SearchTerm, aws.BoolValue(params.ReturnAllEvents)) } else { log.WithFields(f).Debugf("loading project level events for projectSFID :%s...", params.ProjectSFID) pm, perr := projectsClaGroupsRepo.GetClaGroupIDForProject(ctx, params.ProjectSFID) @@ -325,7 +325,7 @@ func Configure(api *operations.EasyclaAPI, service v1Events.Service, v1CompanyRe log.WithFields(f).WithError(perr).Warnf("problem determining CLA Group for project SFID: %s", params.ProjectSFID) return events.NewGetCompanyProjectEventsInternalServerError().WithPayload(errorResponse(reqID, perr)) } - result, err = service.GetCompanyClaGroupEvents(v1Company.CompanyExternalID, params.CompanyID, pm.ClaGroupID, params.NextKey, params.PageSize, aws.BoolValue(params.ReturnAllEvents)) + result, err = service.GetCompanyClaGroupEvents(v1Company.CompanyExternalID, params.CompanyID, pm.ClaGroupID, params.NextKey, params.PageSize, params.SearchTerm, aws.BoolValue(params.ReturnAllEvents)) } if err != nil { log.WithFields(f).WithError(err).Warn("problem loading events")