From b41b90d3a4dd4068a60621ef7a389f7fdb5ed788 Mon Sep 17 00:00:00 2001 From: Dragomir Todorov Date: Thu, 13 Dec 2018 18:41:47 +0200 Subject: [PATCH 1/4] NY-6110: Updates the way accounts are retrieved to allow total count population --- .../account/grid/ag/AdminServiceImpl.java | 8 +- .../nynja/account/grid/ag/AgGridService.java | 167 ++++++++++++------ .../AccountByAccessStatusRepository.java | 12 ++ .../AccountByFirstNameRepository.java | 12 ++ .../AccountByLastNameRepository.java | 12 ++ ...CreationTimestampRepositoryAdditional.java | 14 +- ...stUpdateTimestampRepositoryAdditional.java | 14 +- ...tionTimestampRepositoryAdditionalImpl.java | 37 ++-- ...dateTimestampRepositoryAdditionalImpl.java | 36 ++-- .../account/grid/ag/AgGridServiceTests.java | 21 +-- 10 files changed, 198 insertions(+), 135 deletions(-) diff --git a/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java b/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java index 89a6d6f..5f0ecfe 100644 --- a/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java +++ b/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java @@ -3,14 +3,11 @@ */ package biz.nynja.account.grid.ag; -import java.util.List; - import org.lognet.springboot.grpc.GRpcService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import biz.nynja.account.admin.grpc.AccountAdminResponse; -import biz.nynja.account.admin.grpc.AccountDetails; import biz.nynja.account.admin.grpc.AccountsAdminResponse; import biz.nynja.account.admin.grpc.AccountsCount; import biz.nynja.account.admin.grpc.AdminAccountServiceGrpc; @@ -63,11 +60,10 @@ public class AdminServiceImpl extends AdminAccountServiceGrpc.AdminAccountServic return; } - List accounts = agGridService.getData(request.getEndRow(), request.getStartRow(), + AccountAdminResponse response = agGridService.getData(request.getEndRow(), request.getStartRow(), request.getFilterModelList()); - responseObserver.onNext(AccountsAdminResponse.newBuilder() - .setAccountsResponse(AccountAdminResponse.newBuilder().addAllAccountDetails(accounts).build()).build()); + responseObserver.onNext(AccountsAdminResponse.newBuilder().setAccountsResponse(response).build()); responseObserver.onCompleted(); } diff --git a/src/main/java/biz/nynja/account/grid/ag/AgGridService.java b/src/main/java/biz/nynja/account/grid/ag/AgGridService.java index ca0a6b9..a6cbafc 100644 --- a/src/main/java/biz/nynja/account/grid/ag/AgGridService.java +++ b/src/main/java/biz/nynja/account/grid/ag/AgGridService.java @@ -17,8 +17,10 @@ import org.springframework.data.cassandra.core.query.CassandraPageRequest; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; import org.springframework.stereotype.Service; +import biz.nynja.account.admin.grpc.AccountAdminResponse; import biz.nynja.account.admin.grpc.AccountDetails; import biz.nynja.account.admin.grpc.AccountDetails.Builder; import biz.nynja.account.admin.grpc.FilterModel; @@ -96,18 +98,45 @@ public class AgGridService { this.accountRepositoryAdditional = accountRepositoryAdditional; } - public List getData(int endRow, int startRow, List filterModelList) { + private class AccountsHelper { + private Slice accounts; + private int count; + + public int getCount() { + return count; + } + + public Slice getAccounts() { + return accounts; + } + + public AccountsHelper(Slice accounts, int count) { + this.accounts = accounts; + this.count = count; + } + + public AccountsHelper(List emptyList, Long countByFirstName) { + this(new SliceImpl<>(emptyList), countByFirstName.intValue()); + } + + } + + public AccountAdminResponse getData(int endRow, int startRow, List filterModelList) { Slice accounts = null; List rows = new ArrayList<>(); + long count; Pageable pageable = CassandraPageRequest.of(0, endRow); if (filterModelList.isEmpty()) { logger.debug("No filter parametrs. Retrieving all accounts."); accounts = accountRepository.findAll(pageable); + count = accountRepository.count(); } else { logger.debug("Filter(s) are present. Applying them one by one."); - accounts = retrieveFilterResults(pageable, filterModelList); + AccountsHelper helper = retrieveFilterResults(pageable, filterModelList); + accounts = helper.getAccounts(); + count = helper.getCount(); } accounts.getContent().subList(startRow - 1, accounts.getNumberOfElements()).forEach(account -> { @@ -121,24 +150,33 @@ public class AgGridService { } }); - return rows; + return AccountAdminResponse.newBuilder().addAllAccountDetails(rows).setAllUsersCount(count).build(); } - private Slice retrieveFilterResults(Pageable pageable, List filterModelList) { + private AccountsHelper retrieveFilterResults(Pageable pageable, List filterModelList) { List accounts = new ArrayList<>(); + int count = 0; + + AccountsHelper helper; for (FilterModel filterModel : filterModelList) { logger.debug("Applying filter: {}", filterModel); if (accounts.isEmpty()) { - accounts.addAll(getFilteredResults(pageable, filterModel)); + helper = getFilteredResults(pageable, filterModel); + accounts.addAll(helper.getAccounts().getContent()); + count = helper.getCount(); } else { - accounts.retainAll(getFilteredResults(pageable, filterModel)); + helper = getFilteredResults(pageable, filterModel); + accounts.retainAll(helper.getAccounts().getContent()); + if (count < helper.getCount()) { + count = helper.getCount(); + } } } - return new PageImpl<>(accounts); + return new AccountsHelper(new PageImpl<>(accounts), count); } - private List getFilteredResults(Pageable pageable, FilterModel filterModel) { + private AccountsHelper getFilteredResults(Pageable pageable, FilterModel filterModel) { switch (filterModel.getColId()) { case FILTER_USERNAME: return retrieveUsernameFilteredResults(pageable, filterModel); @@ -157,15 +195,16 @@ public class AgGridService { case FILTER_EMAIL: return retrieveLoginOptionFilteredResults(filterModel, AuthenticationType.EMAIL.toString()); case FILTER_SOCIAL: - List socialAccounts = retrieveLoginOptionFilteredResults(filterModel, + AccountsHelper result = retrieveLoginOptionFilteredResults(filterModel, AuthenticationType.GOOGLEPLUS.toString()); - socialAccounts - .addAll(retrieveLoginOptionFilteredResults(filterModel, AuthenticationType.FACEBOOK.toString())); - return socialAccounts; + if (result.getCount() != 0) { + return result; + } + return retrieveLoginOptionFilteredResults(filterModel, AuthenticationType.FACEBOOK.toString()); default: break; } - return Collections.emptyList(); + return emptyAccountHelper(); } @@ -176,14 +215,15 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveUsernameFilteredResults(Pageable pageable, FilterModel filterModel) { + private AccountsHelper retrieveUsernameFilteredResults(Pageable pageable, FilterModel filterModel) { if (!FilterType.EQUALS.equals(filterModel.getFilterType())) { // ONLY EQUALS is supported at the moment logger.debug(ERROR_ONLY_EQUALS_SUPPORTED, filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } Slice listAccountsByUsername = accountByUsernameRepository .findByUsername(filterModel.getFilterValue(), pageable); - return listAccountsByUsername.stream().map(t -> t.getAccount()).collect(Collectors.toList()); + return new AccountsHelper(listAccountsByUsername.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + (long) listAccountsByUsername.getNumberOfElements()); } /** @@ -193,14 +233,17 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveFirstnameFilteredResults(Pageable pageable, FilterModel filterModel) { + private AccountsHelper retrieveFirstnameFilteredResults(Pageable pageable, FilterModel filterModel) { if (!FilterType.EQUALS.equals(filterModel.getFilterType())) { // Only EQUALS is supported at the moment logger.debug(ERROR_ONLY_EQUALS_SUPPORTED, filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } Slice listAccountsByFirstname = accountByFirstNameRepository .findByFirstName(filterModel.getFilterValue(), pageable); - return listAccountsByFirstname.stream().map(t -> t.getAccount()).collect(Collectors.toList()); + + return new AccountsHelper( + listAccountsByFirstname.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + accountByFirstNameRepository.countByFirstName(filterModel.getFilterValue())); } /** @@ -210,14 +253,15 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveLastnameFilteredResults(Pageable pageable, FilterModel filterModel) { + private AccountsHelper retrieveLastnameFilteredResults(Pageable pageable, FilterModel filterModel) { if (!FilterType.EQUALS.equals(filterModel.getFilterType())) { // Only EQUALS is supported at the moment logger.debug(ERROR_ONLY_EQUALS_SUPPORTED, filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } Slice listAccountsByLastname = accountByLastNameRepository .findByLastName(filterModel.getFilterValue(), pageable); - return listAccountsByLastname.stream().map(t -> t.getAccount()).collect(Collectors.toList()); + return new AccountsHelper(listAccountsByLastname.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + accountByLastNameRepository.countByLastName(filterModel.getFilterValue())); } /** @@ -227,15 +271,17 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveAccessStatusFilteredResults(Pageable pageable, FilterModel filterModel) { + private AccountsHelper retrieveAccessStatusFilteredResults(Pageable pageable, FilterModel filterModel) { if (!FilterType.EQUALS.equals(filterModel.getFilterType())) { // Only EQUALS is supported at the moment logger.debug(ERROR_ONLY_EQUALS_SUPPORTED, filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } Slice listAccountsByAccessStatus = accountByAccessStatusRepository .findByAccessStatus(filterModel.getFilterValue(), pageable); - return listAccountsByAccessStatus.stream().map(t -> t.getAccount()).collect(Collectors.toList()); + return new AccountsHelper( + listAccountsByAccessStatus.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + accountByAccessStatusRepository.countByAccessStatus(filterModel.getFilterValue())); } /** @@ -245,29 +291,33 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveCreationTimestampFilteredResults(Pageable pageable, FilterModel filterModel) { - Slice listAccountsByCreationTimestamp; + private AccountsHelper retrieveCreationTimestampFilteredResults(Pageable pageable, FilterModel filterModel) { + List retrievedAccounts; if (FilterType.EQUALS.equals(filterModel.getFilterType()) || FilterType.WITHIN_A_DATE_RANGE.equals(filterModel.getFilterType()) || FilterType.WITHIN_A_TIME_RANGE.equals(filterModel.getFilterType())) { - listAccountsByCreationTimestamp = accountByCreationTimestampRepositoryAdditional - .findWithinRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue(), pageable); + retrievedAccounts = accountByCreationTimestampRepositoryAdditional + .findWithinRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue()); } else if (FilterType.NOTEQUAL.equals(filterModel.getFilterType()) || FilterType.OUTSIDE_A_DATE_RANGE.equals(filterModel.getFilterType()) || FilterType.OUTSIDE_A_TIME_RANGE.equals(filterModel.getFilterType())) { - listAccountsByCreationTimestamp = accountByCreationTimestampRepositoryAdditional - .findOutsideRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue(), pageable); + retrievedAccounts = accountByCreationTimestampRepositoryAdditional + .findOutsideRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue()); } else if (FilterType.BEFORE_OR_EQUAL.equals(filterModel.getFilterType())) { - listAccountsByCreationTimestamp = accountByCreationTimestampRepositoryAdditional - .beforeOrEquals(filterModel.getFilterValue(), pageable); + retrievedAccounts = accountByCreationTimestampRepositoryAdditional + .beforeOrEquals(filterModel.getFilterValue()); } else if (FilterType.AFTER_OR_EQUAL.equals(filterModel.getFilterType())) { - listAccountsByCreationTimestamp = accountByCreationTimestampRepositoryAdditional - .afterOrEquals(filterModel.getFilterValue(), pageable); + retrievedAccounts = accountByCreationTimestampRepositoryAdditional + .afterOrEquals(filterModel.getFilterValue()); } else { logger.debug("Error when applying filter {}, FilterType is not supported.", filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } - return listAccountsByCreationTimestamp.stream().map(t -> t.getAccount()).collect(Collectors.toList()); + + Slice pagedAccounts = new PageImpl<>(retrievedAccounts, pageable, + retrievedAccounts.size()); + return new AccountsHelper(pagedAccounts.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + Long.valueOf(retrievedAccounts.size())); } /** @@ -277,30 +327,33 @@ public class AgGridService { * @param filterModel * @return */ - private List retrieveLastUpdatedTimestampFilteredResults(Pageable pageable, FilterModel filterModel) { - Slice listAccountsByLastUpdatedTimestamp; + private AccountsHelper retrieveLastUpdatedTimestampFilteredResults(Pageable pageable, FilterModel filterModel) { + + List retrievedAccounts; if (FilterType.EQUALS.equals(filterModel.getFilterType()) || FilterType.WITHIN_A_DATE_RANGE.equals(filterModel.getFilterType()) || FilterType.WITHIN_A_TIME_RANGE.equals(filterModel.getFilterType())) { - listAccountsByLastUpdatedTimestamp = accountByLastUpdateTimestampRepositoryAdditional - .findWithinRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue(), pageable); + retrievedAccounts = accountByLastUpdateTimestampRepositoryAdditional + .findWithinRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue()); } else if (FilterType.NOTEQUAL.equals(filterModel.getFilterType()) || FilterType.OUTSIDE_A_DATE_RANGE.equals(filterModel.getFilterType()) || FilterType.OUTSIDE_A_TIME_RANGE.equals(filterModel.getFilterType())) { - listAccountsByLastUpdatedTimestamp = accountByLastUpdateTimestampRepositoryAdditional - .findOutsideRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue(), pageable); + retrievedAccounts = accountByLastUpdateTimestampRepositoryAdditional + .findOutsideRange(filterModel.getFilterValue(), filterModel.getAdditionalFilterValue()); } else if (FilterType.BEFORE_OR_EQUAL.equals(filterModel.getFilterType())) { - listAccountsByLastUpdatedTimestamp = accountByLastUpdateTimestampRepositoryAdditional - .beforeOrEquals(filterModel.getFilterValue(), pageable); + retrievedAccounts = accountByLastUpdateTimestampRepositoryAdditional + .beforeOrEquals(filterModel.getFilterValue()); } else if (FilterType.AFTER_OR_EQUAL.equals(filterModel.getFilterType())) { - listAccountsByLastUpdatedTimestamp = accountByLastUpdateTimestampRepositoryAdditional - .afterOrEquals(filterModel.getFilterValue(), pageable); + retrievedAccounts = accountByLastUpdateTimestampRepositoryAdditional + .afterOrEquals(filterModel.getFilterValue()); } else { logger.debug("Error when applying filter {}, FilterType is not supported.", filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } - return listAccountsByLastUpdatedTimestamp.stream().map(t -> t.getAccount()).collect(Collectors.toList()); - + Slice pagedAccounts = new PageImpl<>(retrievedAccounts, pageable, + retrievedAccounts.size()); + return new AccountsHelper(pagedAccounts.stream().map(t -> t.getAccount()).collect(Collectors.toList()), + Long.valueOf(retrievedAccounts.size())); } /** @@ -309,13 +362,13 @@ public class AgGridService { * @param authType * @return */ - private List retrieveLoginOptionFilteredResults(FilterModel filterModel, String authType) { + private AccountsHelper retrieveLoginOptionFilteredResults(FilterModel filterModel, String authType) { AuthenticationProvider authenticationProvider = AuthenticationProvider .createAuthenticationProviderFromStrings(authType, filterModel.getFilterValue()); if (!FilterType.EQUALS.equals(filterModel.getFilterType())) { // ONLY EQUALS is supported at the moment logger.error(ERROR_ONLY_EQUALS_SUPPORTED, filterModel); - return Collections.emptyList(); + return emptyAccountHelper(); } Optional accountByProfileId = null; @@ -324,14 +377,18 @@ public class AgGridService { } catch (IncorrectAccountCountException e) { logger.error("Error when applying filter, more than one account found with type {} and value {}.", authType, filterModel.getFilterValue()); - return Collections.emptyList(); + return emptyAccountHelper(); } if (!accountByProfileId.isPresent()) { - return Collections.emptyList(); + return emptyAccountHelper(); } - return new ArrayList<>(Arrays.asList(accountByProfileId.get().toAccount())); + return new AccountsHelper(new ArrayList<>(Arrays.asList(accountByProfileId.get().toAccount())), 1l); + } + + private AccountsHelper emptyAccountHelper() { + return new AccountsHelper(Collections.emptyList(), 0l); } private AccountDetails adminAccountToProto(Account account, Profile profile) { diff --git a/src/main/java/biz/nynja/account/repositories/AccountByAccessStatusRepository.java b/src/main/java/biz/nynja/account/repositories/AccountByAccessStatusRepository.java index a6f8c94..68032d0 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountByAccessStatusRepository.java +++ b/src/main/java/biz/nynja/account/repositories/AccountByAccessStatusRepository.java @@ -4,8 +4,10 @@ package biz.nynja.account.repositories; import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import biz.nynja.account.models.AccountByAccessStatus; @@ -15,4 +17,14 @@ public interface AccountByAccessStatusRepository extends CassandraRepository findByAccessStatus(String accessStatus, Pageable pageable); + /** + * Here this is done with a query instead of countByColumnName as there is a bug with current version of + * CassandraRepository that is fixed in a later version (currently ours is 2.0.8, fix is in 2.1) + * + * refer: https://jira.spring.io/si/jira.issueviews:issue-html/DATACASS-512/DATACASS-512.html + * + */ + @Query("select count(*) from accountbyaccessstatus where accessstatus=:accessstatus") + Long countByAccessStatus(@Param("accessstatus") String accessstatus); + } diff --git a/src/main/java/biz/nynja/account/repositories/AccountByFirstNameRepository.java b/src/main/java/biz/nynja/account/repositories/AccountByFirstNameRepository.java index b61fff9..8c593ea 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountByFirstNameRepository.java +++ b/src/main/java/biz/nynja/account/repositories/AccountByFirstNameRepository.java @@ -4,8 +4,10 @@ package biz.nynja.account.repositories; import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import biz.nynja.account.models.AccountByFirstName; @@ -15,4 +17,14 @@ public interface AccountByFirstNameRepository extends CassandraRepository findByFirstName(String firstname, Pageable pageable); + /** + * Here this is done with a query instead of countByColumnName as there is a bug with current version of + * CassandraRepository that is fixed in a later version (currently ours is 2.0.8, fix is in 2.1) + * + * refer: https://jira.spring.io/si/jira.issueviews:issue-html/DATACASS-512/DATACASS-512.html + * + */ + @Query("select count(*) from accountbyfirstname where firstname=:firstname") + Long countByFirstName(@Param("firstname") String firstname); + } diff --git a/src/main/java/biz/nynja/account/repositories/AccountByLastNameRepository.java b/src/main/java/biz/nynja/account/repositories/AccountByLastNameRepository.java index 50625ae..93de98a 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountByLastNameRepository.java +++ b/src/main/java/biz/nynja/account/repositories/AccountByLastNameRepository.java @@ -4,8 +4,10 @@ package biz.nynja.account.repositories; import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import biz.nynja.account.models.AccountByLastName; @@ -15,4 +17,14 @@ public interface AccountByLastNameRepository extends CassandraRepository findByLastName(String lastname, Pageable pageable); + /** + * Here this is done with a query instead of countByColumnName as there is a bug with current version of + * CassandraRepository that is fixed in a later version (currently ours is 2.0.8, fix is in 2.1) + * + * refer: https://jira.spring.io/si/jira.issueviews:issue-html/DATACASS-512/DATACASS-512.html + * + */ + @Query("select count(*) from accountbylastname where lastname=:lastname") + Long countByLastName(@Param("lastname") String lastname); + } diff --git a/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java index 70636f9..2d75dc2 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java @@ -3,8 +3,8 @@ */ package biz.nynja.account.repositories.customized; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; +import java.util.List; + import org.springframework.stereotype.Repository; import biz.nynja.account.models.AccountByCreationTimestamp; @@ -18,13 +18,11 @@ import biz.nynja.account.models.AccountByCreationTimestamp; @Repository public interface AccountByCreationTimestampRepositoryAdditional { - Slice findWithinRange(String filterValue, String additionalFilterValue, - Pageable pageble); + List findWithinRange(String filterValue, String additionalFilterValue); - Slice findOutsideRange(String filterValue, String additionalFilterValue, - Pageable pageble); + List findOutsideRange(String filterValue, String additionalFilterValue); - Slice beforeOrEquals(String filterValue, Pageable pageble); + List beforeOrEquals(String filterValue); - Slice afterOrEquals(String filterValue, Pageable pageble); + List afterOrEquals(String filterValue); } \ No newline at end of file diff --git a/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java index 6e80f9d..7958904 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java @@ -3,8 +3,8 @@ */ package biz.nynja.account.repositories.customized; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; +import java.util.List; + import org.springframework.stereotype.Repository; import biz.nynja.account.models.AccountByLastUpdateTimestamp; @@ -18,14 +18,12 @@ import biz.nynja.account.models.AccountByLastUpdateTimestamp; @Repository public interface AccountByLastUpdateTimestampRepositoryAdditional { - Slice findWithinRange(String filterValue, String additionalFilterValue, - Pageable pageble); + List findWithinRange(String filterValue, String additionalFilterValue); - Slice findOutsideRange(String filterValue, String additionalFilterValue, - Pageable pageble); + List findOutsideRange(String filterValue, String additionalFilterValue); - Slice beforeOrEquals(String filterValue, Pageable pageble); + List beforeOrEquals(String filterValue); - Slice afterOrEquals(String filterValue, Pageable pageble); + List afterOrEquals(String filterValue); } \ No newline at end of file diff --git a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java index b63092b..5ef546a 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java @@ -7,9 +7,6 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.cassandra.core.CassandraTemplate; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; import biz.nynja.account.models.AccountByCreationTimestamp; @@ -27,55 +24,47 @@ public class AccountByCreationTimestampRepositoryAdditionalImpl } @Override - public Slice findWithinRange(String filterValue, String additionalFilterValue, - Pageable pageble) { + public List findWithinRange(String filterValue, String additionalFilterValue) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate.select( + + return cassandraTemplate.select( "SELECT * FROM " + "accountbycreationtimestamp " + "WHERE token(creationtimestamp)>=token(" + filterValue + ") AND token(creationtimestamp)<=token(" + additionalFilterValue + ");", AccountByCreationTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); } @Override - public Slice findOutsideRange(String filterValue, String additionalFilterValue, - Pageable pageble) { + public List findOutsideRange(String filterValue, String additionalFilterValue) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate.select( + return cassandraTemplate.select( "SELECT * FROM " + "accountbycreationtimestamp " + "WHERE token(creationtimestamp)token(" + additionalFilterValue + ");", AccountByCreationTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); } @Override - public Slice beforeOrEquals(String filterValue, Pageable pageble) { - return executeSingleDirectionQuery(filterValue, pageble, "<="); + public List beforeOrEquals(String filterValue) { + return executeSingleDirectionQuery(filterValue, "<="); } @Override - public Slice afterOrEquals(String filterValue, Pageable pageble) { - return executeSingleDirectionQuery(filterValue, pageble, ">="); + public List afterOrEquals(String filterValue) { + return executeSingleDirectionQuery(filterValue, ">="); } - private Slice executeSingleDirectionQuery(String filterValue, Pageable pageble, - String sign) { + private List executeSingleDirectionQuery(String filterValue, String sign) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate - .select("SELECT * FROM " + "accountbycreationtimestamp " + "WHERE token(creationtimestamp)" + sign - + "token(" + filterValue + ");", AccountByCreationTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); + return cassandraTemplate.select("SELECT * FROM " + "accountbycreationtimestamp " + + "WHERE token(creationtimestamp)" + sign + "token(" + filterValue + ");", + AccountByCreationTimestamp.class); } } diff --git a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java index d33eabb..94dc7ba 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java @@ -7,9 +7,6 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.cassandra.core.CassandraTemplate; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; import biz.nynja.account.models.AccountByLastUpdateTimestamp; @@ -27,55 +24,46 @@ public class AccountByLastUpdateTimestampRepositoryAdditionalImpl } @Override - public Slice findWithinRange(String filterValue, String additionalFilterValue, - Pageable pageble) { + public List findWithinRange(String filterValue, String additionalFilterValue) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate.select( + return cassandraTemplate.select( "SELECT * FROM " + "accountbylastupdatetimestamp " + "WHERE token(lastUpdateTimestamp)>=token(" + filterValue + ") AND token(lastUpdateTimestamp)<=token(" + additionalFilterValue + ");", AccountByLastUpdateTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); } @Override - public Slice findOutsideRange(String filterValue, String additionalFilterValue, - Pageable pageble) { + public List findOutsideRange(String filterValue, String additionalFilterValue) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate.select( + return cassandraTemplate.select( "SELECT * FROM " + "accountbylastupdatetimestamp " + "WHERE token(lastUpdateTimestamp)token(" + additionalFilterValue + ");", AccountByLastUpdateTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); } @Override - public Slice beforeOrEquals(String filterValue, Pageable pageble) { - return singleDirectionQuery(filterValue, pageble, "<="); + public List beforeOrEquals(String filterValue) { + return singleDirectionQuery(filterValue, "<="); } @Override - public Slice afterOrEquals(String filterValue, Pageable pageble) { - return singleDirectionQuery(filterValue, pageble, ">="); + public List afterOrEquals(String filterValue) { + return singleDirectionQuery(filterValue, ">="); } - private Slice singleDirectionQuery(String filterValue, Pageable pageble, - String sign) { + private List singleDirectionQuery(String filterValue, String sign) { // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime // error. - List retrievedAccounts = cassandraTemplate - .select("SELECT * FROM " + "accountbylastupdatetimestamp " + "WHERE token(lastUpdateTimestamp)" + sign - + "token(" + filterValue + ");", AccountByLastUpdateTimestamp.class); - - return new PageImpl<>(retrievedAccounts, pageble, retrievedAccounts.size()); + return cassandraTemplate.select("SELECT * FROM " + "accountbylastupdatetimestamp " + + "WHERE token(lastUpdateTimestamp)" + sign + "token(" + filterValue + ");", + AccountByLastUpdateTimestamp.class); } } diff --git a/src/test/java/biz/nynja/account/grid/ag/AgGridServiceTests.java b/src/test/java/biz/nynja/account/grid/ag/AgGridServiceTests.java index 60b806a..9399c08 100644 --- a/src/test/java/biz/nynja/account/grid/ag/AgGridServiceTests.java +++ b/src/test/java/biz/nynja/account/grid/ag/AgGridServiceTests.java @@ -20,7 +20,7 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.test.context.junit4.SpringRunner; -import biz.nynja.account.admin.grpc.AccountDetails; +import biz.nynja.account.admin.grpc.AccountAdminResponse; import biz.nynja.account.admin.grpc.FilterModel; import biz.nynja.account.admin.grpc.FilterModel.FilterType; import biz.nynja.account.models.Account; @@ -115,16 +115,16 @@ public class AgGridServiceTests { @Test public void testEmptyFilter() { - List result = agGridService.getData(50, 1, Lists.emptyList()); - assertEquals("Result count should be all 3", 3, result.size()); + AccountAdminResponse result = agGridService.getData(50, 1, Lists.emptyList()); + assertEquals("Result count should be all 3", 3, result.getAccountDetailsList().size()); } @Test public void testFilterByFirstName() { FilterModel filter = FilterModel.newBuilder().setFilterValue("Georgi").setColId("firstname") .setFilterType(FilterType.EQUALS).build(); - List result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter))); - assertEquals("Result count should be 2", 2, result.size()); + AccountAdminResponse result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter))); + assertEquals("Result count should be 2", 2, result.getAccountDetailsList().size()); } @Test @@ -134,16 +134,17 @@ public class AgGridServiceTests { FilterModel filter2 = FilterModel.newBuilder().setFilterValue("georgi.petrov").setColId("username") .setFilterType(FilterType.EQUALS).build(); - List result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter, filter2))); - assertEquals("Result count should be all only 1", 1, result.size()); - assertEquals("Username should be georgi.petrov", "georgi.petrov", result.get(0).getUsername()); + AccountAdminResponse result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter, filter2))); + assertEquals("Result count should be all only 1", 1, result.getAccountDetailsList().size()); + assertEquals("Username should be georgi.petrov", "georgi.petrov", + result.getAccountDetailsList().get(0).getUsername()); } @Test public void testFilterByLastNameNoResult() { FilterModel filter = FilterModel.newBuilder().setFilterValue("Georgiev").setColId("lastname") .setFilterType(FilterType.EQUALS).build(); - List result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter))); - assertEquals("Result count should be all only 0", 0, result.size()); + AccountAdminResponse result = agGridService.getData(50, 1, new ArrayList<>(Arrays.asList(filter))); + assertEquals("Result count should be all only 0", 0, result.getAccountDetailsList().size()); } } -- GitLab From a27e4b522a954950860f566fc9e66c10b4aca90c Mon Sep 17 00:00:00 2001 From: Dragomir Todorov Date: Thu, 13 Dec 2018 19:10:05 +0200 Subject: [PATCH 2/4] NY-6110: Updated count variable name, bugfix for search by time --- .../java/biz/nynja/account/grid/ag/AgGridService.java | 2 +- ...ntByCreationTimestampRepositoryAdditionalImpl.java | 11 +++-------- ...ByLastUpdateTimestampRepositoryAdditionalImpl.java | 11 +++-------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/java/biz/nynja/account/grid/ag/AgGridService.java b/src/main/java/biz/nynja/account/grid/ag/AgGridService.java index a6cbafc..3ffa009 100644 --- a/src/main/java/biz/nynja/account/grid/ag/AgGridService.java +++ b/src/main/java/biz/nynja/account/grid/ag/AgGridService.java @@ -150,7 +150,7 @@ public class AgGridService { } }); - return AccountAdminResponse.newBuilder().addAllAccountDetails(rows).setAllUsersCount(count).build(); + return AccountAdminResponse.newBuilder().addAllAccountDetails(rows).setAccountsCount(count).build(); } private AccountsHelper retrieveFilterResults(Pageable pageable, List filterModelList) { diff --git a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java index 5ef546a..8de80fe 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByCreationTimestampRepositoryAdditionalImpl.java @@ -38,14 +38,9 @@ public class AccountByCreationTimestampRepositoryAdditionalImpl @Override public List findOutsideRange(String filterValue, String additionalFilterValue) { - - // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token - // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime - // error. - return cassandraTemplate.select( - "SELECT * FROM " + "accountbycreationtimestamp " + "WHERE token(creationtimestamp)token(" + additionalFilterValue + ");", - AccountByCreationTimestamp.class); + List accounts = executeSingleDirectionQuery(filterValue, "<"); + accounts.addAll(executeSingleDirectionQuery(additionalFilterValue, ">")); + return accounts; } @Override diff --git a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java index 94dc7ba..bb07b8d 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/customized/impl/AccountByLastUpdateTimestampRepositoryAdditionalImpl.java @@ -37,14 +37,9 @@ public class AccountByLastUpdateTimestampRepositoryAdditionalImpl @Override public List findOutsideRange(String filterValue, String additionalFilterValue) { - - // In this case we don't use prepared statements due to a bug in the QueryBuilder library with cassandra token - // function. In the build CQL it's comparing token(lastUpdateTimestamp) >= 'token(value)' which causes runtime - // error. - return cassandraTemplate.select( - "SELECT * FROM " + "accountbylastupdatetimestamp " + "WHERE token(lastUpdateTimestamp)token(" + additionalFilterValue + ");", - AccountByLastUpdateTimestamp.class); + List accounts = singleDirectionQuery(filterValue, "<"); + accounts.addAll(singleDirectionQuery(additionalFilterValue, ">")); + return accounts; } @Override -- GitLab From 452574ca785e5e6e4f6720fec3a383661a290ef9 Mon Sep 17 00:00:00 2001 From: Dragomir Todorov Date: Fri, 14 Dec 2018 12:28:41 +0200 Subject: [PATCH 3/4] NY-6110: Small fix for validation --- .../java/biz/nynja/account/grid/ag/AdminServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java b/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java index 5f0ecfe..1c9272e 100644 --- a/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java +++ b/src/main/java/biz/nynja/account/grid/ag/AdminServiceImpl.java @@ -74,9 +74,10 @@ public class AdminServiceImpl extends AdminAccountServiceGrpc.AdminAccountServic "startRow parameter (" + startRow + ") should be more than 1 and less or equal to endRow parameter (" + endRow + ").", Cause.ADMIN_INVALID_START_ROW)); - } else if (endRow < startRow || endRow > 100) { + } else if (endRow < startRow || (endRow > accountRepository.count() + 100)) { validation.addError(new ValidationError("endRow parameter (" + endRow + ") should be more than start row (" - + startRow + ") and less than current max of 100.", Cause.ADMIN_INVALID_END_ROW)); + + startRow + ") and less than all users plus maximum pagination of 100." + + (accountRepository.count() + 100), Cause.ADMIN_INVALID_END_ROW)); } return validation; } -- GitLab From 4af78e90157c9a2647cc873e936d545e072ffe81 Mon Sep 17 00:00:00 2001 From: Dragomir Todorov Date: Fri, 14 Dec 2018 17:01:42 +0200 Subject: [PATCH 4/4] NY-6110: Added new lines --- .../AccountByCreationTimestampRepositoryAdditional.java | 2 +- .../AccountByLastUpdateTimestampRepositoryAdditional.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java index 2d75dc2..476b640 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/customized/AccountByCreationTimestampRepositoryAdditional.java @@ -25,4 +25,4 @@ public interface AccountByCreationTimestampRepositoryAdditional { List beforeOrEquals(String filterValue); List afterOrEquals(String filterValue); -} \ No newline at end of file +} diff --git a/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java index 7958904..9029044 100644 --- a/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/customized/AccountByLastUpdateTimestampRepositoryAdditional.java @@ -26,4 +26,4 @@ public interface AccountByLastUpdateTimestampRepositoryAdditional { List afterOrEquals(String filterValue); -} \ No newline at end of file +} -- GitLab