diff --git a/src/main/java/biz/nynja/account/components/Validator.java b/src/main/java/biz/nynja/account/components/Validator.java index d35f8195b985f810350f640dae3bb1c359b671df..a27e8a676f87c42379cac91bae15df03a2abb1b0 100644 --- a/src/main/java/biz/nynja/account/components/Validator.java +++ b/src/main/java/biz/nynja/account/components/Validator.java @@ -7,6 +7,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.time.DateTimeException; +import java.time.LocalDate; import java.util.HashMap; import java.util.Optional; import java.util.regex.Matcher; @@ -31,6 +33,7 @@ import biz.nynja.account.grpc.CompletePendingAccountCreationRequest; import biz.nynja.account.grpc.ContactDetails; import biz.nynja.account.grpc.ContactType; import biz.nynja.account.grpc.CreatePendingAccountRequest; +import biz.nynja.account.grpc.Date; import biz.nynja.account.grpc.DeleteAuthenticationProviderRequest; import biz.nynja.account.grpc.DeleteContactInfoRequest; import biz.nynja.account.grpc.ErrorResponse.Cause; @@ -304,6 +307,10 @@ public class Validator { return null; } + public boolean validateBirthdayIsSet(Date birthday) { + return (birthday != null && birthday.getYear() != 0 && birthday.getMonth() != 0 && birthday.getDay() != 0); + } + public Cause validateUpdateAccountRequest(UpdateAccountRequest request) { if (request.getUsername() != null && !request.getUsername().trim().isEmpty() @@ -327,6 +334,15 @@ public class Validator { return Cause.ACCOUNT_NAME_INVALID; } + if (validateBirthdayIsSet(request.getBirthday())) { + try { + LocalDate.of(request.getBirthday().getYear(), request.getBirthday().getMonth(), + request.getBirthday().getDay()); + } catch (DateTimeException e) { + return Cause.INVALID_BIRTHDAY_DATE; + } + } + return null; } diff --git a/src/main/java/biz/nynja/account/models/Account.java b/src/main/java/biz/nynja/account/models/Account.java index 1446b913e54a6293dbd951f69642e7c8f1908f79..6920d9d8f2bb71810aedf95da5031a13ec409d71 100644 --- a/src/main/java/biz/nynja/account/models/Account.java +++ b/src/main/java/biz/nynja/account/models/Account.java @@ -4,6 +4,7 @@ package biz.nynja.account.models; import java.nio.ByteBuffer; +import java.time.LocalDate; import java.util.Set; import java.util.UUID; @@ -14,6 +15,7 @@ import biz.nynja.account.grpc.AccessStatus; import biz.nynja.account.grpc.AccountDetails; import biz.nynja.account.grpc.AccountDetails.Builder; import biz.nynja.account.grpc.CreatePendingAccountRequest; +import biz.nynja.account.grpc.Date; import biz.nynja.account.grpc.Role; @Table @@ -36,6 +38,7 @@ public class Account { private Set contactsInfo; private Set roles; private String accessStatus; + private LocalDate birthday; public UUID getAccountId() { return accountId; @@ -165,6 +168,14 @@ public class Account { this.accessStatus = accessStatus; } + public LocalDate getBirthday() { + return birthday; + } + + public void setBirthday(LocalDate birthday) { + this.birthday = birthday; + } + @Override public int hashCode() { final int prime = 31; @@ -176,6 +187,7 @@ public class Account { result = prime * result + ((authenticationProvider == null) ? 0 : authenticationProvider.hashCode()); result = prime * result + ((authenticationProviderType == null) ? 0 : authenticationProviderType.hashCode()); result = prime * result + ((avatar == null) ? 0 : avatar.hashCode()); + result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); result = prime * result + ((contactsInfo == null) ? 0 : contactsInfo.hashCode()); result = prime * result + ((creationTimestamp == null) ? 0 : creationTimestamp.hashCode()); result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); @@ -232,6 +244,11 @@ public class Account { return false; } else if (!avatar.equals(other.avatar)) return false; + if (birthday == null) { + if (other.birthday != null) + return false; + } else if (!birthday.equals(other.birthday)) + return false; if (contactsInfo == null) { if (other.contactsInfo != null) return false; @@ -291,7 +308,7 @@ public class Account { .append(", username=").append(username).append(", qrCode=").append(qrCode) .append(", creationTimestamp=").append(creationTimestamp).append(", lastUpdateTimestamp=") .append(lastUpdateTimestamp).append(", contactsInfo=").append(contactsInfo).append(", roles=") - .append(roles).append(", accessStatus=").append(accessStatus).append("]"); + .append(roles).append(", accessStatus=").append(accessStatus).append(", birthday=").append(birthday).append("]"); return builder.toString(); } @@ -352,8 +369,13 @@ public class Account { builder.addContactsInfo(c.toProto()); } } + if (getBirthday() != null) { + builder.setBirthday(Date.newBuilder().setYear(getBirthday().getYear()) + .setMonth(getBirthday().getMonthValue()).setDay(getBirthday().getDayOfMonth()).build()); + } return builder.build(); } + } diff --git a/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java b/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java index f6a58fc4d3cdd384fec9184a2082c0275d394422..bdfa04f39265090c0f3d7ae95c00aa643285bd2b 100644 --- a/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java +++ b/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java @@ -4,11 +4,13 @@ package biz.nynja.account.models; import java.nio.ByteBuffer; +import java.time.LocalDate; import java.util.Set; import java.util.UUID; import biz.nynja.account.grpc.AccessStatus; import biz.nynja.account.grpc.AccountDetails.Builder; +import biz.nynja.account.grpc.Date; import biz.nynja.account.grpc.Role; public class AccountByAuthenticationProvider { @@ -29,6 +31,7 @@ public class AccountByAuthenticationProvider { private String qrCode; private Set roles; private String accessStatus; + private LocalDate birthday; public UUID getAccountId() { return accountId; @@ -158,6 +161,14 @@ public class AccountByAuthenticationProvider { this.accessStatus = accessStatus; } + public LocalDate getBirthday() { + return birthday; + } + + public void setBirthday(LocalDate birthday) { + this.birthday = birthday; + } + @Override public int hashCode() { final int prime = 31; @@ -169,6 +180,7 @@ public class AccountByAuthenticationProvider { result = prime * result + ((authenticationProvider == null) ? 0 : authenticationProvider.hashCode()); result = prime * result + ((authenticationProviderType == null) ? 0 : authenticationProviderType.hashCode()); result = prime * result + ((avatar == null) ? 0 : avatar.hashCode()); + result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); result = prime * result + ((contactsInfo == null) ? 0 : contactsInfo.hashCode()); result = prime * result + ((creationTimestamp == null) ? 0 : creationTimestamp.hashCode()); result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); @@ -225,6 +237,11 @@ public class AccountByAuthenticationProvider { return false; } else if (!avatar.equals(other.avatar)) return false; + if (birthday == null) { + if (other.birthday != null) + return false; + } else if (!birthday.equals(other.birthday)) + return false; if (contactsInfo == null) { if (other.contactsInfo != null) return false; @@ -284,7 +301,7 @@ public class AccountByAuthenticationProvider { .append(", username=").append(username).append(", creationTimestamp=").append(creationTimestamp) .append(", lastUpdateTimestamp=").append(lastUpdateTimestamp).append(", contactsInfo=") .append(contactsInfo).append(", qrCode=").append(qrCode).append(", roles=").append(roles) - .append(", accessStatus=").append(accessStatus).append("]"); + .append(", accessStatus=").append(accessStatus).append(", birthday=").append(birthday).append("]"); return builder.toString(); } @@ -337,6 +354,10 @@ public class AccountByAuthenticationProvider { if (getAccessStatus() != null) { builder.setAccessStatus(AccessStatus.valueOf(getAccessStatus())); } + if (getBirthday() != null) { + builder.setBirthday(Date.newBuilder().setYear(getBirthday().getYear()) + .setMonth(getBirthday().getMonthValue()).setDay(getBirthday().getDayOfMonth()).build()); + } return builder.build(); @@ -360,6 +381,8 @@ public class AccountByAuthenticationProvider { account.setQrCode(this.qrCode); account.setRoles(this.roles); account.setAccessStatus(this.accessStatus); + account.setBirthday(this.birthday); return account; } + } diff --git a/src/main/java/biz/nynja/account/models/AccountByProfileId.java b/src/main/java/biz/nynja/account/models/AccountByProfileId.java index d0da5206603f675b8f6b8462f46ab764f3f6776e..fe37f192bae897b104380175bfcc66cecc0d36c0 100644 --- a/src/main/java/biz/nynja/account/models/AccountByProfileId.java +++ b/src/main/java/biz/nynja/account/models/AccountByProfileId.java @@ -4,11 +4,13 @@ package biz.nynja.account.models; import java.nio.ByteBuffer; +import java.time.LocalDate; import java.util.Set; import java.util.UUID; import biz.nynja.account.grpc.AccessStatus; import biz.nynja.account.grpc.AccountDetails; +import biz.nynja.account.grpc.Date; import biz.nynja.account.grpc.AccountDetails.Builder; import biz.nynja.account.grpc.Role; @@ -30,6 +32,7 @@ public class AccountByProfileId { private String qrCode; private Set roles; private String accessStatus; + private LocalDate birthday; public UUID getAccountId() { return accountId; @@ -159,6 +162,14 @@ public class AccountByProfileId { this.accessStatus = accessStatus; } + public LocalDate getBirthday() { + return birthday; + } + + public void setBirthday(LocalDate birthday) { + this.birthday = birthday; + } + @Override public int hashCode() { final int prime = 31; @@ -170,6 +181,7 @@ public class AccountByProfileId { result = prime * result + ((authenticationProvider == null) ? 0 : authenticationProvider.hashCode()); result = prime * result + ((authenticationProviderType == null) ? 0 : authenticationProviderType.hashCode()); result = prime * result + ((avatar == null) ? 0 : avatar.hashCode()); + result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); result = prime * result + ((contactsInfo == null) ? 0 : contactsInfo.hashCode()); result = prime * result + ((creationTimestamp == null) ? 0 : creationTimestamp.hashCode()); result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); @@ -226,6 +238,11 @@ public class AccountByProfileId { return false; } else if (!avatar.equals(other.avatar)) return false; + if (birthday == null) { + if (other.birthday != null) + return false; + } else if (!birthday.equals(other.birthday)) + return false; if (contactsInfo == null) { if (other.contactsInfo != null) return false; @@ -285,7 +302,7 @@ public class AccountByProfileId { .append(", username=").append(username).append(", creationTimestamp=").append(creationTimestamp) .append(", lastUpdateTimestamp=").append(lastUpdateTimestamp).append(", contactsInfo=") .append(contactsInfo).append(", qrCode=").append(qrCode).append(", roles=").append(roles) - .append(", accessStatus=").append(accessStatus).append("]"); + .append(", accessStatus=").append(accessStatus).append(", birthday=").append(birthday).append("]"); return builder.toString(); } @@ -339,9 +356,13 @@ public class AccountByProfileId { if (getAccessStatus() != null) { builder.setAccessStatus(AccessStatus.valueOf(getAccessStatus())); } + if (getBirthday() != null) { + builder.setBirthday(Date.newBuilder().setYear(getBirthday().getYear()) + .setMonth(getBirthday().getMonthValue()).setDay(getBirthday().getDayOfMonth()).build()); + } return builder.build(); } - + } diff --git a/src/main/java/biz/nynja/account/models/AccountByUsername.java b/src/main/java/biz/nynja/account/models/AccountByUsername.java index ccc616bc1edccac0207b103b8e866de80c462f46..ebe01dcc9e7b90a38a8d7cc969612a712a9b4e13 100644 --- a/src/main/java/biz/nynja/account/models/AccountByUsername.java +++ b/src/main/java/biz/nynja/account/models/AccountByUsername.java @@ -4,6 +4,7 @@ package biz.nynja.account.models; import java.nio.ByteBuffer; +import java.time.LocalDate; import java.util.Set; import java.util.UUID; @@ -25,6 +26,7 @@ public class AccountByUsername { private String qrCode; private Set roles; private String accessStatus; + private LocalDate birthday; public UUID getProfileId() { return profileId; @@ -154,6 +156,14 @@ public class AccountByUsername { this.accessStatus = accessStatus; } + public LocalDate getBirthday() { + return birthday; + } + + public void setBirthday(LocalDate birthday) { + this.birthday = birthday; + } + @Override public int hashCode() { final int prime = 31; @@ -165,6 +175,7 @@ public class AccountByUsername { result = prime * result + ((authenticationProvider == null) ? 0 : authenticationProvider.hashCode()); result = prime * result + ((authenticationProviderType == null) ? 0 : authenticationProviderType.hashCode()); result = prime * result + ((avatar == null) ? 0 : avatar.hashCode()); + result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); result = prime * result + ((contactsInfo == null) ? 0 : contactsInfo.hashCode()); result = prime * result + ((creationTimestamp == null) ? 0 : creationTimestamp.hashCode()); result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); @@ -221,6 +232,11 @@ public class AccountByUsername { return false; } else if (!avatar.equals(other.avatar)) return false; + if (birthday == null) { + if (other.birthday != null) + return false; + } else if (!birthday.equals(other.birthday)) + return false; if (contactsInfo == null) { if (other.contactsInfo != null) return false; @@ -280,8 +296,8 @@ public class AccountByUsername { .append(", username=").append(username).append(", creationTimestamp=").append(creationTimestamp) .append(", lastUpdateTimestamp=").append(lastUpdateTimestamp).append(", contactsInfo=") .append(contactsInfo).append(", qrCode=").append(qrCode).append(", roles=").append(roles) - .append(", accessStatus=").append(accessStatus).append("]"); + .append(", accessStatus=").append(accessStatus).append(", birthday=").append(birthday).append("]"); return builder.toString(); } - + } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java index d9765ca00bdb3933f17031c06ccbd2857a20ed1c..643a88d462cbbaa5fa77a2e209ac9027d4ba72a5 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java @@ -3,7 +3,9 @@ */ package biz.nynja.account.repositories; +import java.time.DateTimeException; import java.time.Instant; +import java.time.LocalDate; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -27,6 +29,7 @@ import com.datastax.driver.core.Session; import biz.nynja.account.components.AccountServiceHelper; import biz.nynja.account.components.StatementsPool; +import biz.nynja.account.components.Validator; import biz.nynja.account.grpc.CompletePendingAccountCreationRequest; import biz.nynja.account.grpc.UpdateAccountRequest; import biz.nynja.account.grpc.UpdateProfileRequest; @@ -82,6 +85,9 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio @Autowired private AccountServiceHelper accountServiceHelper; + @Autowired + private Validator validator; + @Autowired private Session session; @@ -198,18 +204,23 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio CassandraBatchOperations batchOperations = cassandraTemplate.batchOps(); Account existingAccount = accountRepository.findByAccountId(UUID.fromString(request.getAccountId())); if (existingAccount == null) { - logger.info("Existing account with the provided id was not found."); + logger.error("Existing account with the provided id {} was not found.", request.getAccountId()); logger.debug("Existing account with the provided id {} was not found.", request.getAccountId()); return null; } Long timeUpdated = Instant.now().toEpochMilli(); WriteResult wr = null; try { - updateAccountData(batchOperations, request, existingAccount, timeUpdated); + try { + updateAccountData(batchOperations, request, existingAccount, timeUpdated); + } catch (DateTimeException e) { + logger.error("Exception with birthday date while updating account with id {}", request.getAccountId()); + return null; + } wr = batchOperations.execute(); } catch (IllegalArgumentException | IllegalStateException e) { - logger.info("Exception while updating account."); - logger.debug("Exception while updating account: {} ...", e.getMessage()); + logger.error("Exception while updating account with id {}.", request.getAccountId()); + logger.debug("Exception while updating account: {}.", e.getMessage()); return null; } @@ -318,6 +329,12 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio updatedAccount.setUsername(request.getUsername()); updatedAccount.setLastUpdateTimestamp(lastUpdateTimestamp); updatedAccount.setAccessStatus(request.getAccessStatus().toString()); + if (validator.validateBirthdayIsSet(request.getBirthday())) { + updatedAccount.setBirthday(LocalDate.of(request.getBirthday().getYear(), request.getBirthday().getMonth(), + request.getBirthday().getDay())); + } else { + updatedAccount.setBirthday(null); + } batchOps.update(updatedAccount); } diff --git a/src/test/java/biz/nynja/account/services/AccountServiceTests.java b/src/test/java/biz/nynja/account/services/AccountServiceTests.java index 3f46386466fed484681ae14f8346421cf10f80e6..1a3991b77ca7c1c4a037871b3617bdaf042d4ad2 100644 --- a/src/test/java/biz/nynja/account/services/AccountServiceTests.java +++ b/src/test/java/biz/nynja/account/services/AccountServiceTests.java @@ -45,6 +45,7 @@ import biz.nynja.account.grpc.ContactDetails; import biz.nynja.account.grpc.ContactType; import biz.nynja.account.grpc.CreatePendingAccountRequest; import biz.nynja.account.grpc.CreatePendingAccountResponse; +import biz.nynja.account.grpc.Date; import biz.nynja.account.grpc.DeleteAccountRequest; import biz.nynja.account.grpc.DeleteAuthenticationProviderRequest; import biz.nynja.account.grpc.DeleteContactInfoRequest; @@ -1389,4 +1390,39 @@ public class AccountServiceTests extends GrpcServerTestBase { assertTrue(String.format("Reply should contain cause '%s'", Cause.ERROR_EDITING_CONTACT_INFO), reply.getError().getCause().equals(Cause.ERROR_EDITING_CONTACT_INFO)); } + + @Test + public void testUpdateAccountValidBirthdayDate() { + final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setAccountId(Util.ACCOUNT_ID.toString()) + .setFirstName(Util.FIRST_NAME).setBirthday(Date.newBuilder().setYear(Util.BIRTHDAY.getYear()) + .setMonth(Util.BIRTHDAY.getMonthValue()).setDay(Util.BIRTHDAY.getDayOfMonth()).build()) + .build(); + given(accountRepositoryAdditional.updateAccount(request)).willReturn(updatedAccount); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + + final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); + + assertNotNull("Reply should not be null", reply); + assertTrue(String.format("Reply should contain birthday '%s'", Util.BIRTHDAY), + reply.getAccountDetails().getBirthday().getYear() == Util.BIRTHDAY.getYear()); + assertTrue(reply.getAccountDetails().getBirthday().getMonth() == Util.BIRTHDAY.getMonthValue()); + assertTrue(reply.getAccountDetails().getBirthday().getDay() == Util.BIRTHDAY.getDayOfMonth()); + } + + @Test + public void testUpdateAccountInvalidBirthdayDate() { + final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setAccountId(Util.ACCOUNT_ID.toString()) + .setFirstName(Util.FIRST_NAME) + .setBirthday(Date.newBuilder().setYear(1990).setMonth(9).setDay(32).build()).build(); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); + + assertNotNull("Reply should not be null", reply); + assertTrue(String.format("Reply should contain cause '%s'", Cause.INVALID_BIRTHDAY_DATE), + reply.getError().getCause().equals(Cause.INVALID_BIRTHDAY_DATE)); + } } diff --git a/src/test/java/biz/nynja/account/utils/Util.java b/src/test/java/biz/nynja/account/utils/Util.java index e540b019d55fcd2d51986ec28da261f6d58aa3ed..08f4aa2ec4a1f191cce4db505d000b281295b826 100644 --- a/src/test/java/biz/nynja/account/utils/Util.java +++ b/src/test/java/biz/nynja/account/utils/Util.java @@ -5,6 +5,7 @@ package biz.nynja.account.utils; import java.nio.ByteBuffer; +import java.time.LocalDate; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -55,6 +56,7 @@ public class Util { public static final String PASSWORD = "abc123"; public static final String FIRST_NAME = "John"; public static final String LAST_NAME = "Doe"; + public static final LocalDate BIRTHDAY = LocalDate.of(1990, 9, 16); public static final String MIDDLE_NAME = "Kass"; public static final String PHONE_NUMBER = "+359887123456"; public static final String PHONE_PROVIDER = "BG:+359887123456"; @@ -174,6 +176,7 @@ public class Util { account.setUsername(USERNAME); account.setFirstName(FIRST_NAME); account.setLastName(LAST_NAME); + account.setBirthday(BIRTHDAY); account.setAccountMark(UPDATED_ACCOUNT_MARK); return account; }