diff --git a/Jenkinsfile b/Jenkinsfile index 9c949e5ba6c09b3d365bb17dc894a3c070eeb7e3..cff5afe5e54a4bae575f5debd47931ce662e4a58 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -51,6 +51,7 @@ pipeline { } } } + /* stage('Build commits') { when { not { @@ -73,7 +74,7 @@ pipeline { } } } - + */ stage('Build Dev') { when { branch env.DEV_BRANCH diff --git a/charts/account-service/Chart.yaml b/charts/account-service/Chart.yaml index 15646489e1bf3df41f8d059527e6eae14ea613dd..1e6397e3d12bcf01eb81ac73238901e959840b29 100644 --- a/charts/account-service/Chart.yaml +++ b/charts/account-service/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: Deployment of the nynja account service. name: account-service -version: 0.1.0 +version: 0.1.2 diff --git a/charts/account-service/templates/deployment.yaml b/charts/account-service/templates/deployment.yaml index 05a885c5a826e4bc8f9d34943012d5fc00f7d11b..342b9d6084b630c76972ac82d911cbe57f2490d9 100644 --- a/charts/account-service/templates/deployment.yaml +++ b/charts/account-service/templates/deployment.yaml @@ -58,6 +58,12 @@ spec: value: {{ .Values.ports.containerPort.http | quote }} - name: GRPC_SERVER_PORT value: {{ .Values.ports.containerPort.grpc | quote }} + - name: BRIDGE_ENABLED + value: {{ .Values.bridge.enabled | quote }} + - name: BRIDGE_HOST + value: {{ .Values.bridge.host | quote }} + - name: BRIDGE_PORT + value: {{ .Values.bridge.port | quote }} resources: {{ toYaml .Values.resources | indent 12 }} {{- with .Values.nodeSelector }} diff --git a/releases/dev/account-service.yaml b/releases/dev/account-service.yaml index 7a7aa881207bdddd87226df204d5d174c4ebdae3..677022a35bcb3195065c363c3899a828f6f80ed8 100644 --- a/releases/dev/account-service.yaml +++ b/releases/dev/account-service.yaml @@ -1,10 +1,14 @@ +apiVersion: flux.weave.works/v1beta1 kind: HelmRelease metadata: name: account-service namespace: account spec: + releaseName: account-service chart: + repository: https://nynjagroup.jfrog.io/nynjagroup/helm/ name: account-service + version: 0.1.2 values: replicaCount: 1 @@ -31,6 +35,11 @@ spec: http: 8080 grpc: 6565 + bridge: + enabled: true + host: bridge-service.bridge-service.svc.cluster.local + port: 6570 + # CORS policy corsPolicy: allowOrigin: diff --git a/releases/staging/account-service.yaml b/releases/staging/account-service.yaml index 6adc18ac0870f0b407e1f34c4220f6469a8a39de..17707c24a89591a9934d3d5759ea4d4e7f6850fd 100644 --- a/releases/staging/account-service.yaml +++ b/releases/staging/account-service.yaml @@ -1,10 +1,14 @@ +apiVersion: flux.weave.works/v1beta1 kind: HelmRelease metadata: name: account-service namespace: account spec: + releaseName: account-service chart: + repository: https://nynjagroup.jfrog.io/nynjagroup/helm/ name: account-service + version: 0.1.0 values: replicaCount: 2 diff --git a/src/main/java/biz/nynja/account/Application.java b/src/main/java/biz/nynja/account/Application.java index f19c3d10434c5e8f31d924d56ebdc731fec98c02..cffdaaf1b5f28ec8a9924d0f0389a0cd29676a73 100644 --- a/src/main/java/biz/nynja/account/Application.java +++ b/src/main/java/biz/nynja/account/Application.java @@ -3,17 +3,26 @@ */ package biz.nynja.account; +import biz.nynja.account.configuration.ErlangBridgeConfiguration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Main entry point class. - * */ @SpringBootApplication public class Application { + private static final Logger LOGGER = LogManager.getLogger(Application.class); + + public Application(ErlangBridgeConfiguration configuration) { + LOGGER.info("bridge configuration: " + configuration); + } + public static void main(String[] args) { SpringApplication.run(Application.class, args); } + } diff --git a/src/main/java/biz/nynja/account/StartupScriptsListener.java b/src/main/java/biz/nynja/account/StartupScriptsListener.java index 88f09f532aacec51828be670b3456cabd5e372c0..628bc54483619b4644742e7a6cb9f139af4ffe88 100644 --- a/src/main/java/biz/nynja/account/StartupScriptsListener.java +++ b/src/main/java/biz/nynja/account/StartupScriptsListener.java @@ -6,8 +6,6 @@ package biz.nynja.account; import java.util.Arrays; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.event.ContextRefreshedEvent; @@ -15,9 +13,7 @@ import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import com.datastax.driver.core.Session; -import com.datastax.driver.core.exceptions.InvalidQueryException; -import biz.nynja.account.repositories.AccountRepositoryAdditional; /** * This acts as {@link CassandraAccountConfig} startupScripts executor but activated after the spring has setup the needed * tables though JPA @@ -28,45 +24,18 @@ import biz.nynja.account.repositories.AccountRepositoryAdditional; @Component public class StartupScriptsListener { - private static final Logger logger = LoggerFactory.getLogger(StartupScriptsListener.class); private String keyspace; @Autowired private Session session; - @Autowired - private AccountRepositoryAdditional accountRepositoryAdditional; - @EventListener(ContextRefreshedEvent.class) public void contextRefreshedEvent() { keyspace = session.getLoggedKeyspace(); - boolean searchableColumnAlreadyExists = false, searchableFeildAlreadyExists = false; for (String script : getStartupScripts()) { session.execute(script); } - - try { - // add searchable column - session.execute(getScriptsForSearchableOption().get(0)); - } catch (InvalidQueryException e) { - logger.warn("Exception while executing script for adding searchable column: {}", e.getMessage()); - // In the current case InvalidQueryException is used to confirm that the searchable column already exists. - searchableColumnAlreadyExists = true; - } - - try { - // add searchable field - session.execute(getScriptsForSearchableOption().get(1)); - } catch (InvalidQueryException e) { - logger.warn("Exception while executing script for adding searchable field: {}", e.getMessage()); - // In the current case InvalidQueryException is used to confirm that the searchable column already exists. - searchableFeildAlreadyExists = true; - } - - if (searchableColumnAlreadyExists && searchableFeildAlreadyExists) { - accountRepositoryAdditional.removeNullsForSearchableOption(); - } } private List getStartupScripts() { @@ -120,13 +89,4 @@ public class StartupScriptsListener { scriptAccountViewByFirstName, scriptAccountViewByLastName, scriptAccountViewByAccessStatus, scriptAccountViewByCreationTimestamp, scriptAccountViewByLastUpdateTimestamp); } - - private List getScriptsForSearchableOption() { - String addSearchableColumnScript = "ALTER TABLE " + keyspace - + ".profilebyauthenticationprovider ADD searchable boolean;"; - - String addSearchableToAuthenticationProviderType = "ALTER TYPE authenticationprovider add searchable boolean;"; - - return Arrays.asList(addSearchableColumnScript, addSearchableToAuthenticationProviderType); - } } diff --git a/src/main/java/biz/nynja/account/configuration/ErlangBridgeConfiguration.java b/src/main/java/biz/nynja/account/configuration/ErlangBridgeConfiguration.java index 32f7914fd9b8bd0032aaedfa43cc7a40034a0f62..0e745316aa39d795d0d31a863c7fa7bb515a8c85 100644 --- a/src/main/java/biz/nynja/account/configuration/ErlangBridgeConfiguration.java +++ b/src/main/java/biz/nynja/account/configuration/ErlangBridgeConfiguration.java @@ -6,6 +6,8 @@ package biz.nynja.account.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import java.util.StringJoiner; + @Configuration @ConfigurationProperties(prefix = "erlang-bridge") public class ErlangBridgeConfiguration { @@ -37,4 +39,14 @@ public class ErlangBridgeConfiguration { public void setPort(String port) { this.port = port; } + + @Override + public String toString() { + return new StringJoiner(", ", ErlangBridgeConfiguration.class.getSimpleName() + "[", "]") + .add("enabled=" + enabled) + .add("host='" + host + "'") + .add("port='" + port + "'") + .toString(); + } + } diff --git a/src/main/java/biz/nynja/account/models/AccountBuilder.java b/src/main/java/biz/nynja/account/models/AccountBuilder.java index 02720e110d5f8d1588d4408eb74626e77b92a3f8..1718ac10524ccb808bde0c1c903446188cae0eaf 100644 --- a/src/main/java/biz/nynja/account/models/AccountBuilder.java +++ b/src/main/java/biz/nynja/account/models/AccountBuilder.java @@ -51,7 +51,7 @@ public class AccountBuilder { updatedAccount.setBirthday(null); } - return account; + return updatedAccount; } } diff --git a/src/main/java/biz/nynja/account/permissions/PermissionsInterceptor.java b/src/main/java/biz/nynja/account/permissions/PermissionsInterceptor.java index 9b731b258f1ff891383ab94247b8a153d24dfbb4..63c7b1de41e34d79b0b3cf34e1424473204e5455 100644 --- a/src/main/java/biz/nynja/account/permissions/PermissionsInterceptor.java +++ b/src/main/java/biz/nynja/account/permissions/PermissionsInterceptor.java @@ -74,31 +74,47 @@ public class PermissionsInterceptor implements ServerInterceptor { * Expected metadata is "Authorization" : "Bearer --accessTokenValue--" so we can skip validation as istio won't * allow this request through */ - String accessToken = (headers.get(ACCESS_TOKEN_METADATA).split(" "))[1]; - String rpc = getRpcName(call); boolean permitted = false; Context ctx = null; String[] requestingRoles = null; + String rpc = getRpcName(call); + + String metadataEntry = headers.get(ACCESS_TOKEN_METADATA); + if (metadataEntry == null) { + permissionDenied(call, headers, "Permission denied for rpc {}. Access token not in headers", rpc ); + return NOOP_LISTENER; + } + String[] parts = metadataEntry.split(" "); + if (parts.length < 2) { + permissionDenied(call, headers, "Permission denied for rpc {}. Access token not in headers", rpc ); + return NOOP_LISTENER; + } + String accessToken = parts[1]; + if (accessToken == null && accessToken.isEmpty()) { permissionDenied(call, headers, "Permission denied for rpc {}. Access token not in headers", rpc ); + return NOOP_LISTENER; } ctx = Context.current().withValue(ACCESS_TOKEN_CTX, accessToken); DecodedJWT decodedToken = JWT.decode(accessToken); if (!accessPointAvailable(accessToken, decodedToken, rpc)) { permissionDenied(call, headers, "Permission denied for rpc {}. No access point available for this account and access token.", rpc ); + return NOOP_LISTENER; } requestingRoles = getRolesFromAccessToken(decodedToken); if (requestingRoles == null) { permissionDenied(call, headers, "Permission denied for rpc {}. No roles found for requesting account in access token.", rpc ); + return NOOP_LISTENER; } Method method = getMethod(rpc); if (method == null) { permissionDenied(call, headers, "Permission denied for rpc {}. Could not identify the method implementing this rpc.", rpc ); + return NOOP_LISTENER; } Permitted[] permittedRoles = method.getAnnotationsByType(Permitted.class); @@ -176,11 +192,10 @@ public class PermissionsInterceptor implements ServerInterceptor { return false; } - private ServerCall.Listener permissionDenied(ServerCall call, Metadata headers, String message, String rpc ) { + private void permissionDenied(ServerCall call, Metadata headers, String message, String rpc ) { logger.error(message, rpc); call.close(Status.PERMISSION_DENIED.withDescription("An unauthorized call was made to " + rpc + "."), headers); - return NOOP_LISTENER; } } diff --git a/src/main/java/biz/nynja/account/permissions/PermissionsValidator.java b/src/main/java/biz/nynja/account/permissions/PermissionsValidator.java index 44edf68cc891dffb4baf1a2ce9ca11d8fd5af8f6..4c6c40cf44053e9bd250d4eb04ffb17f7676385b 100644 --- a/src/main/java/biz/nynja/account/permissions/PermissionsValidator.java +++ b/src/main/java/biz/nynja/account/permissions/PermissionsValidator.java @@ -20,10 +20,6 @@ public class PermissionsValidator { public boolean isRpcAllowed(String accountId) { - // WARNING: THe line bellow is to be removed and code following uncommented - // when Istio starts sending an access token with each and every request - // return true; - DecodedJWT decodedToken = retrieveDecodedToken(); String requestingAccountId = new String(Base64.getDecoder().decode(decodedToken.getSubject())); @@ -33,6 +29,13 @@ public class PermissionsValidator { return isAuthorizedRequestingRole(decodedToken); } + public boolean isRpcAllowedForCurrentRole() { + + DecodedJWT decodedToken = retrieveDecodedToken(); + + return isAuthorizedRequestingRole(decodedToken); + } + private DecodedJWT retrieveDecodedToken() { String accessToken = (String) PermissionsInterceptor.ACCESS_TOKEN_CTX.get(); // This check is for isAdminToken method @@ -45,10 +48,6 @@ public class PermissionsValidator { public boolean isRpcAllowed(List existingAccountsForProfile) { - // WARNING: The line bellow is to be removed and code following uncommented - // when Istio starts sending an access token with each and every request - // return true; - String accessToken = (String) PermissionsInterceptor.ACCESS_TOKEN_CTX.get(); DecodedJWT decodedToken = JWT.decode(accessToken); String requestingAccountId = new String(Base64.getDecoder().decode(decodedToken.getSubject())); @@ -74,6 +73,19 @@ public class PermissionsValidator { return false; } + private static boolean isAdminRole(DecodedJWT decodedToken) { + String[] requestingRoles = null; + Claim claim = decodedToken.getClaim("roles"); + + if (claim != null) { + requestingRoles = claim.asArray(String.class); + if (requestingRoles != null) { + return isAdmin(requestingRoles); + } + } + return false; + } + private static boolean isAuthorized(String[] requestingRoles) { for (String role : requestingRoles) { switch (role) { @@ -84,11 +96,20 @@ public class PermissionsValidator { } return false; } + + private static boolean isAdmin(String[] requestingRoles) { + for (String role : requestingRoles) { + if (role.equals(RoleConstants.ACCOUNT_ADMIN)) { + return true; + } + } + return false; + } public boolean isAdminToken() { DecodedJWT decodedToken = retrieveDecodedToken(); if(decodedToken != null) { - return isAuthorizedRequestingRole(decodedToken); + return isAdminRole(decodedToken); } else return false; } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java index 800a1cde24c7dd695aa9f8077dbcc9d9c0a7239d..4149a68ed8b17049cc62cd4129977eb57b66f6d1 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java @@ -62,7 +62,5 @@ public interface AccountRepositoryAdditional { Optional searchAccountByLoginOption(AuthenticationProvider loginOption) throws IncorrectAccountCountException; - void removeNullsForSearchableOption(); - boolean updateSearchableOption(UUID profileId, String authProviderType, String authProvider, SearchableOption searchableOption); } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java index b541a36dd5a4b04af9ac1bd19b24b1c4801dd79f..277f72f0c55c7d9062380783398ec6463efade82 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java @@ -3,18 +3,13 @@ */ package biz.nynja.account.repositories; -import static biz.nynja.account.validation.Validators.util; - import java.time.DateTimeException; import java.time.Instant; -import java.time.LocalDate; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import javax.annotation.PostConstruct; @@ -26,7 +21,6 @@ import org.springframework.data.cassandra.core.CassandraBatchOperations; import org.springframework.data.cassandra.core.CassandraTemplate; import org.springframework.data.cassandra.core.UpdateOptions; import org.springframework.data.cassandra.core.WriteResult; -import org.springframework.data.cassandra.core.cql.CqlOperations; import org.springframework.stereotype.Service; import com.auth0.jwt.JWT; @@ -131,8 +125,10 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio public Account completePendingAccountCreation(CompletePendingAccountCreationRequest request) { Transaction sagaTransaction = new SagaTransaction(cassandraTemplate); - PendingAccount pendingAccount = pendingAccountRepository - .findByAccountId(UUID.fromString(request.getAccountId())); + + UUID accountId = UUID.fromString(request.getAccountId()); + + PendingAccount pendingAccount = pendingAccountRepository.findByAccountId(accountId); if (pendingAccount == null) { logger.info("Existing pending account with the provided id was not found or creation timeout expired."); logger.debug("Existing pending account with the provided id {} was not found or creation timeout expired.", @@ -180,21 +176,29 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return null; } if (wr.wasApplied()) { - pendingAccountRepository.deleteById(UUID.fromString(request.getAccountId())); - return accountRepository.findByAccountId(UUID.fromString(request.getAccountId())); + pendingAccountRepository.deleteById(accountId); + return accountRepository.findByAccountId(accountId); } return null; } - private Account newAccountInsert(Transaction batchOps, CompletePendingAccountCreationRequest request, - PendingAccount pendingAccount, Long creationTimestamp) { + private Account newAccountInsert( + Transaction batchOps, + CompletePendingAccountCreationRequest request, + PendingAccount pendingAccount, + Long creationTimestamp) { + Account newAccount = AccountBuilder.buildNewAccount(request, pendingAccount, creationTimestamp); batchOps.insert(newAccount); return newAccount; } - private Profile newProfileInsert(Transaction batchOps, CompletePendingAccountCreationRequest request, - PendingAccount pendingAccount, Long creationTimestamp) { + private Profile newProfileInsert( + Transaction batchOps, + CompletePendingAccountCreationRequest request, + PendingAccount pendingAccount, + Long creationTimestamp) { + Profile newProfile = new Profile(); newProfile.setProfileId(pendingAccount.getProfileId()); Set authenticationProvidersSet = new HashSet(); @@ -208,7 +212,9 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return newProfile; } - private void newProfileByAuthenticationProviderInsert(Transaction batchOps, PendingAccount pendingAccount) { + private void newProfileByAuthenticationProviderInsert( + Transaction batchOps, PendingAccount pendingAccount) { + ProfileByAuthenticationProvider newProfileByAuthenticationProvider = new ProfileByAuthenticationProvider(); newProfileByAuthenticationProvider.setAuthenticationProvider(pendingAccount.getAuthenticationProvider()); newProfileByAuthenticationProvider @@ -222,29 +228,43 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio public Account updateAccount(UpdateAccountRequest request) { Transaction sagaTransaction = new SagaTransaction(cassandraTemplate); - Account existingAccount = accountRepository.findByAccountId(UUID.fromString(request.getAccountId())); + UUID accountId = UUID.fromString(request.getAccountId()); + + Account existingAccount = accountRepository.findByAccountId(accountId); if (existingAccount == null) { 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; } - Set existingRoles = existingAccount.getRoles().stream().map(Role::valueOf).collect(Collectors.toSet()); + Profile existingProfile = profileRepository.findByProfileId(existingAccount.getProfileId()); + + Set existingRoles = existingAccount.getRoles().stream() + .map(Role::valueOf) + .collect(Collectors.toSet()); if (!permissionsValidator.isAdminToken()) { // No permission to update roles, load old ones - request = UpdateAccountRequest.newBuilder(request).clearRoles().addAllRoles(existingRoles).build(); + // No permission to update access status, load the old one + request = UpdateAccountRequest.newBuilder(request) + .clearRoles() + .addAllRoles(existingRoles) + .clearAccessStatus() + .setAccessStatus(AccessStatus.valueOf(existingAccount.getAccessStatus())) + .build(); } + Long timeUpdated = Instant.now().toEpochMilli(); WriteResult wr = null; try { + Account updatedAccount = updateAccountData(request, existingAccount, timeUpdated); try { - updateAccountData(sagaTransaction, request, existingAccount, timeUpdated); + sagaTransaction.update(updatedAccount, existingAccount); } catch (DateTimeException e) { logger.error("Exception with birthday date while updating account with id {}", request.getAccountId()); return null; } wr = sagaTransaction.execute(); - if (!erlangAccountBridge.updateAccount(existingAccount)) { + if (!erlangAccountBridge.updateAccount(existingProfile, updatedAccount)) { logger.error("Internal error with erlang"); sagaTransaction.rollBack(); return null; @@ -264,7 +284,7 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio if (applied) { if (request.getAccessStatus().equals(AccessStatus.DISABLED) || request.getAccessStatus().equals(AccessStatus.SUSPENDED)) { - if (!accessPointService.deleteAccessPointsForAccount(UUID.fromString(request.getAccountId()))) { + if (!accessPointService.deleteAccessPointsForAccount(accountId)) { logger.error("Error deleting accesspoints from the DB for account {}.", request.getAccountId()); return null; } @@ -275,7 +295,7 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return null; } } - Account updatedAccount = accountRepository.findByAccountId(UUID.fromString(request.getAccountId())); + Account updatedAccount = accountRepository.findByAccountId(accountId); return updatedAccount; } } @@ -290,7 +310,8 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio String accessToken = accessPoint.getAccessToken(); DecodedJWT decodedToken = JWT.decode(accessToken); List accesspointRoles = getRolesFromAccessToken(decodedToken); - if (accesspointRoles.contains(Role.ACCOUNT_ADMIN.name()) || accesspointRoles.contains(Role.AUTHENTICATION_ADMIN.name())) { + if (accesspointRoles.contains(Role.ACCOUNT_ADMIN.name()) + || accesspointRoles.contains(Role.AUTHENTICATION_ADMIN.name())) { if (!accessPointService.deleteAccessPoint(UUID.fromString(accountId), accessToken)) { logger.error("Error deleting accesspoint record from DB for account with id {} and role {}.", accountId, Role.ACCOUNT_ADMIN.name()); @@ -428,29 +449,16 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return false; } - private void updateAccountData(Transaction transaction, UpdateAccountRequest request, Account currentAccountState, - Long lastUpdateTimestamp) { - Account newAccountState = (Account) SerializationUtils.clone(currentAccountState); - newAccountState.setAvatar(request.getAvatar()); - newAccountState.setAccountMark(request.getAccountMark()); - newAccountState.setAccountName(request.getAccountName()); - newAccountState.setFirstName(request.getFirstName()); - newAccountState.setLastName(request.getLastName()); - newAccountState.setUsername(request.getUsername()); - newAccountState.setLastUpdateTimestamp(lastUpdateTimestamp); - newAccountState.setAccessStatus(request.getAccessStatus().toString()); + private Account updateAccountData( + UpdateAccountRequest request, Account currentAccountState, Long lastUpdateTimestamp) { + + Account newAccountState = AccountBuilder.updateAccount(request, currentAccountState, lastUpdateTimestamp); if (request.getRolesList() == null || request.getRolesList().isEmpty()) { newAccountState.setRoles(Set.of(Role.USER.toString())); } else { newAccountState.setRoles(request.getRolesList().stream().map(Enum::toString).collect(Collectors.toSet())); } - if (util.validateBirthdayIsSet(request.getBirthday())) { - newAccountState.setBirthday(LocalDate.of(request.getBirthday().getYear(), request.getBirthday().getMonth(), - request.getBirthday().getDay())); - } else { - newAccountState.setBirthday(null); - } - transaction.update(newAccountState, currentAccountState); + return newAccountState; } private void updateAuthProvidersInProfileWhenDeletingAccount(Transaction transaction, Profile currentProfileState, @@ -583,7 +591,8 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio Account existingAccount = accountRepository.findByAccountId(accountByProfileId.getAccountId()); deleteAccountData(batchOperations, existingAccount); if (!accessPointService.deleteAccessPointsForAccount(accountByProfileId.getAccountId())) { - logger.error("Error deleting accesspoints from the DB for account {}.", accountByProfileId.getAccountId()); + logger.error("Error deleting accesspoints from the DB for account {}.", + accountByProfileId.getAccountId()); } } @@ -1088,61 +1097,6 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return pendingAccount; } - public void removeNullsForSearchableOption() { - List profilesByAuthenticationProvider = profileByAuthenticationProviderRepository - .findAll(); - for (int i = 0; i < profilesByAuthenticationProvider.size(); i++) { - if (profilesByAuthenticationProvider.get(i).getSearchable() == null) { - logger.error("Found null for searchable option for {}:{} in profile: {}", - profilesByAuthenticationProvider.get(i).getAuthenticationProviderType(), - profilesByAuthenticationProvider.get(i).getAuthenticationProvider(), - profilesByAuthenticationProvider.get(i).getProfileId()); - Profile profileToUpdate = profileRepository - .findByProfileId(profilesByAuthenticationProvider.get(i).getProfileId()); - if (profileToUpdate == null) { - logger.error( - "Error replacing null with default searchable option for auth provider {}:{} in profile {}. Profile not found.", - profilesByAuthenticationProvider.get(i).getAuthenticationProviderType(), - profilesByAuthenticationProvider.get(i).getAuthenticationProvider(), - profilesByAuthenticationProvider.get(i).getProfileId()); - continue; - } - - logger.info("Replacing null with default searchable option for profile {}", - profilesByAuthenticationProvider.get(i).getProfileId()); - - CassandraBatchOperations batchOperations = cassandraTemplate.batchOps(); - WriteResult wr; - try { - updateSearchableInProfileByAuthenticationProvider(batchOperations, - profilesByAuthenticationProvider.get(i), SearchableOption.SEARCH_ENABLED); - if (!updateSearchableInProfile(batchOperations, profileToUpdate, - profilesByAuthenticationProvider.get(i).getAuthenticationProviderType(), - profilesByAuthenticationProvider.get(i).getAuthenticationProvider(), - SearchableOption.SEARCH_ENABLED)) { - logger.error( - "Error replacing null with default searchable option for profile {}: auth provider {}:{}.", - profilesByAuthenticationProvider.get(i).getProfileId(), - profilesByAuthenticationProvider.get(i).getAuthenticationProviderType(), - profilesByAuthenticationProvider.get(i).getAuthenticationProvider()); - } - wr = batchOperations.execute(); - } catch (IllegalArgumentException | IllegalStateException e) { - logger.debug( - "Exception while replacing null with default searchable option for auth provider {}:{} in profile{}: {}.", - profilesByAuthenticationProvider.get(i).getAuthenticationProviderType(), - profilesByAuthenticationProvider.get(i).getAuthenticationProvider(), - profilesByAuthenticationProvider.get(i).getProfileId(), e.getMessage()); - continue; - } - if (wr != null && wr.wasApplied()) { - logger.info("Successfully replaced null with default searchable option in profile {}.", - profilesByAuthenticationProvider.get(i).getProfileId()); - } - } - } - } - private void updateSearchableInProfileByAuthenticationProvider(CassandraBatchOperations batchOps, ProfileByAuthenticationProvider profileByAuthenticationProvider, SearchableOption searchableOption) { profileByAuthenticationProvider.setSearchable(AuthenticationProvider.isSearchDisabled(searchableOption)); diff --git a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java index c78dd22e539af6411658d6d59113c06fb6674584..457c7841b693d981ebf92951980815dc5ca4e339 100644 --- a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java +++ b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import biz.nynja.account.accesspoints.AccessPointService; import biz.nynja.account.configuration.ProfileDataConfiguration; +import biz.nynja.account.grpc.AccessStatus; import biz.nynja.account.grpc.AccountByAccountIdRequest; import biz.nynja.account.grpc.AccountResponse; import biz.nynja.account.grpc.AccountServiceGrpc; @@ -467,7 +468,6 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas @Override @Permitted(role = RoleConstants.ACCOUNT_ADMIN) @Permitted(role = RoleConstants.AUTH_SERVICE) - @Permitted(role = RoleConstants.USER) public void createPendingAccount(CreatePendingAccountRequest request, StreamObserver responseObserver) { CreatePendingAccountResponse response; @@ -523,6 +523,11 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas request.getAccountId(), Cause.INVALID_ACCOUNT_ID, "Invalid Account ID"); return; } + if (request.getAccessStatus().equals(AccessStatus.UNKNOWN_ACCESS_STATUS)) { + logAndBuildGrpcAccountResponse(responseObserver, AccountResponse.newBuilder(), "Invalid access status for account id: {}", + request.getAccountId(), Cause.INVALID_ACCESS_STATUS, "Invalid access status"); + return; + } if (!permissionsValidator.isRpcAllowed(request.getAccountId())) { logAndBuildGrpcAccountResponse(responseObserver, AccountResponse.newBuilder(), "Can not update account {}.", @@ -1069,6 +1074,7 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas return searchResultDetails.build(); } + // Currently not supported @Override @PerformPermissionCheck @Permitted(role = RoleConstants.ACCOUNT_ADMIN) @@ -1076,6 +1082,15 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas @Permitted(role = RoleConstants.USER) public void updateAuthenticationProviderForProfile(UpdateAuthenticationProviderRequest request, StreamObserver responseObserver) { + + // This logic is used because the operation of updating authentication provider is currently not supported + if (true) { + logAndBuildGrpcStatusResponse(responseObserver, StatusResponse.newBuilder(), + "Not supported operation of updating authentication provider for profile: {}", + request.getProfileId(), Cause.ERROR_UPDATING_AUTH_PROVIDER, "Operation not supported"); + return; + } + logger.info("Updating auth provider for profile {} requested.", request.getProfileId()); logger.debug("Updating auth provider for profile requested: {}", request); @@ -1167,11 +1182,26 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas Optional account = accountProvider.getAccountResponseByLoginOption( request.getAuthenticationType(), request.getAuthenticationIdentifier()); if (!account.isPresent()) { + // If account is not found the method isRpcAllowedForCurrentRole() is used to check the current role and + // if it is "USER" to return "ERROR_PERMISSION_DENIED" + if (!permissionsValidator.isRpcAllowedForCurrentRole()) { + logAndBuildGrpcAccountResponse(responseObserver, AccountResponse.newBuilder(), + "Account info can not be obtained for this account.", "", Cause.ERROR_PERMISSION_DENIED, + "Permission denied"); + return; + } logAndBuildGrpcAccountResponse(responseObserver, AccountResponse.newBuilder(), "Account not found for login option: " + request.getAuthenticationIdentifier() + ":" + request.getAuthenticationIdentifier(), "", Cause.ACCOUNT_NOT_FOUND, "Account not found"); } else { + + if (!permissionsValidator.isRpcAllowed(account.get().getAccountDetails().getAccountId())) { + logAndBuildGrpcAccountResponse(responseObserver, AccountResponse.newBuilder(), + "Account info can not be obtained for this account.", "", Cause.ERROR_PERMISSION_DENIED, + "Permission denied"); + return; + } AccountResponse response = account.get(); logger.info("SUCCESS: Found account by login option {}. Account Id={}.", request.getAuthenticationIdentifier(), response.getAccountDetails().getAccountId()); diff --git a/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java b/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java index 8d31c915774a0fda99df738a727cbe3db0bde1d3..59a3347677cb6e4866e57fad34ccde53a87f0ccf 100644 --- a/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java +++ b/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java @@ -153,7 +153,7 @@ public class AccountCreator { if (createdAccount == null) { return logAndBuildGrpcAccountResponse(AccountResponse.newBuilder(), - "Error creating account with useraname: {}", request.getUsername(), Cause.ERROR_CREATING_ACCOUNT, + "Error creating account with username: {}", request.getUsername(), Cause.ERROR_CREATING_ACCOUNT, "Failed to create account"); } else { logger.debug("Account \"{}\" saved into the DB", createdAccount); diff --git a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountBridge.java b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountBridge.java index f30b96de8e78a525154c2a33ca21fdac1631e159..6a88a903e62b5a20bb905ed2ba059101d3e54637 100644 --- a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountBridge.java +++ b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountBridge.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018 Nynja Inc. All rights reserved. + * Copyright (C) 2018 Nynja Inc. All rights reserved. */ package biz.nynja.account.services.erlang; @@ -10,13 +10,14 @@ import java.util.List; import java.util.UUID; public interface ErlangAccountBridge { + boolean createProfile(Profile profile, Account defaultAccount); boolean deleteProfile(UUID profileId, List accountsIds); - boolean createAccount(Account account); + boolean createAccount(Profile profile, Account account); - boolean updateAccount(Account account); + boolean updateAccount(Profile profile, Account account); boolean deleteAccount(UUID profileId, UUID accountId); diff --git a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountHttpBridge.java b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountHttpBridge.java index 24574f35ea38ecc756361d9b13a652bfef73f863..17206e6ace35c26dda6d380f27d805aeb862fdc5 100644 --- a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountHttpBridge.java +++ b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountHttpBridge.java @@ -81,12 +81,12 @@ public class ErlangAccountHttpBridge implements ErlangAccountBridge { } @Override - public boolean createAccount(Account account) { - return updateAccount(account); + public boolean createAccount(Profile profile, Account account) { + return updateAccount(profile, account); } @Override - public boolean updateAccount(Account account) { + public boolean updateAccount(Profile profile, Account account) { if (!erlangBridgeConfiguration.isEnabled()) return true; JsonObject accountObject = prepareAccountJsonObject(account); diff --git a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountMqttBridge.java b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountMqttBridge.java index da3fdf52957e8ff68b67a1a673a99136f0ca9a4a..310c27dcfe33aa6e659607c489cd8630ff7acda0 100644 --- a/src/main/java/biz/nynja/account/services/erlang/ErlangAccountMqttBridge.java +++ b/src/main/java/biz/nynja/account/services/erlang/ErlangAccountMqttBridge.java @@ -1,108 +1,157 @@ -/** - * Copyright (C) 2018 Nynja Inc. All rights reserved. +/* + * Copyright (C) 2018 Nynja Inc. All rights reserved. */ package biz.nynja.account.services.erlang; -import java.net.MalformedURLException; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - import biz.nynja.account.configuration.ErlangBridgeConfiguration; import biz.nynja.account.models.Account; +import biz.nynja.account.models.AuthenticationProvider; import biz.nynja.account.models.Profile; import biz.nynja.account.services.erlang.interceptor.TokenInterceptorConstants; import biz.nynja.bridge.grpc.AccountBridgeGrpc; import biz.nynja.bridge.grpc.AccountData; -import biz.nynja.bridge.grpc.BridgeSuccessResponse; import biz.nynja.bridge.grpc.ProfileData; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; import io.grpc.stub.MetadataUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; @Component @Primary public class ErlangAccountMqttBridge implements ErlangAccountBridge { - private final ErlangBridgeConfiguration erlangBridgeConfiguration; + private static final String EMAIL_PROVIDER = "EMAIL"; + private static final String PHONE_PROVIDER = "PHONE"; + + private final ErlangBridgeConfiguration configuration; - public ErlangAccountMqttBridge(ErlangBridgeConfiguration erlangBridgeConfiguration) { - this.erlangBridgeConfiguration = erlangBridgeConfiguration; + public ErlangAccountMqttBridge(ErlangBridgeConfiguration configuration) { + this.configuration = configuration; } @Override public boolean createProfile(Profile profile, Account account) { - - if (!erlangBridgeConfiguration.isEnabled()) + if (!configuration.isEnabled()) return true; + ProfileData profileData = buildProfileData(profile, account); - return buildGrpcConnection().createProfile(profileData).getSuccess(); + return buildGrpcConnection() + .createProfile(profileData) + .getSuccess(); } @Override public boolean deleteProfile(UUID profileId, List accountsIds) { - if (!erlangBridgeConfiguration.isEnabled()) + if (!configuration.isEnabled()) return true; - return buildGrpcConnection().deleteProfile(buildDeleteProfileData(profileId, (UUID[]) accountsIds.toArray())).getSuccess(); + + return buildGrpcConnection() + .deleteProfile(buildDeleteProfileData(profileId, (UUID[]) accountsIds.toArray())) + .getSuccess(); } @Override - public boolean createAccount(Account account) { - if (!erlangBridgeConfiguration.isEnabled()) + public boolean createAccount(Profile profile, Account account) { + if (!configuration.isEnabled()) return true; - return buildGrpcConnection().createAccount(buildAccountData(account)).getSuccess(); + + Map providers = getAuthenticationProviders(profile); + + return buildGrpcConnection() + .createAccount(buildAccountData(account, providers.get(EMAIL_PROVIDER))) + .getSuccess(); } @Override - public boolean updateAccount(Account account) { - if (!erlangBridgeConfiguration.isEnabled()) + public boolean updateAccount(Profile profile, Account account) { + if (!configuration.isEnabled()) return true; - return buildGrpcConnection().updateAccount(buildAccountData(account)).getSuccess(); + + Map providers = getAuthenticationProviders(profile); + + return buildGrpcConnection() + .updateAccount(buildAccountData(account, providers.get(EMAIL_PROVIDER))) + .getSuccess(); } @Override public boolean deleteAccount(UUID profileId, UUID accountId) { - if (!erlangBridgeConfiguration.isEnabled()) + if (!configuration.isEnabled()) return true; - return buildGrpcConnection().deleteAccount(buildDeleteProfileData(profileId, accountId)).getSuccess(); + + return buildGrpcConnection() + .deleteAccount(buildDeleteProfileData(profileId, accountId)) + .getSuccess(); } private ProfileData buildProfileData(Profile profile, Account account) { - return ProfileData.newBuilder().setProfileId(profile.getProfileId().toString()) - .setDefaultAccount(buildAccountData(account)) - .setLastUpdateTimestamp(profile.getCreationTimestamp().toString()).build(); + Map providers = getAuthenticationProviders(profile); + + ProfileData.Builder builder = ProfileData.newBuilder() + .setProfileId(profile.getProfileId().toString()) + .setDefaultAccount(buildAccountData(account, providers.get(EMAIL_PROVIDER))) + .setLastUpdateTimestamp(profile.getCreationTimestamp().toString()); + + if (providers.get(PHONE_PROVIDER) != null) { + builder.setPhoneNumber(providers.get(PHONE_PROVIDER)); + } + + return builder.build(); + } + + private Map getAuthenticationProviders(Profile profile) { + return profile.getAuthenticationProviders().stream() + .filter(AuthenticationProvider::getSearchable) + .filter(auth -> auth.getType().equals(PHONE_PROVIDER) + || auth.getType().equals(EMAIL_PROVIDER)) + .collect(Collectors.toUnmodifiableMap(AuthenticationProvider::getType, AuthenticationProvider::getValue)); } - private AccountData buildAccountData(Account account) { - return AccountData.newBuilder().setAccountId(account.getAccountId().toString()) - .setFirstName(account.getFirstName()).setLastName(account.getLastName()) - .setProfileId(account.getProfileId().toString()).setUsername(account.getUsername()) + private AccountData buildAccountData(Account account, String email) { + AccountData.Builder builder = AccountData.newBuilder() + .setAccountId(account.getAccountId().toString()) + .setFirstName(account.getFirstName()) + .setLastName(account.getLastName()) + .setProfileId(account.getProfileId().toString()) + .setUsername(account.getUsername()) .setAvatar(account.getAvatar()) .setLastUpdateTimestamp( - Objects.isNull(account.getLastUpdateTimestamp()) ? Long.toString(System.currentTimeMillis()) - : account.getLastUpdateTimestamp().toString()) - .build(); + Objects.isNull(account.getLastUpdateTimestamp()) + ? Long.toString(System.currentTimeMillis()) + : account.getLastUpdateTimestamp().toString()); + + if (email != null) { + builder.setEmail(email); + } + + return builder.build(); } // Erlang protocol private ProfileData buildDeleteProfileData(UUID profileId, UUID... accountsId) { - return ProfileData.newBuilder().setProfileId(profileId.toString()) - .addAllAccountsIds(Arrays.stream(accountsId).map(UUID::toString).collect(Collectors.toList())).build(); + return ProfileData.newBuilder() + .setProfileId(profileId.toString()) + .addAllAccountsIds( + Arrays.stream(accountsId) + .map(UUID::toString) + .collect(Collectors.toList()) + ) + .build(); } private AccountBridgeGrpc.AccountBridgeBlockingStub buildGrpcConnection() { ManagedChannel managedChannel = ManagedChannelBuilder - .forAddress(erlangBridgeConfiguration.getHost(), Integer.parseInt(erlangBridgeConfiguration.getPort())) - .usePlaintext().build(); - AccountBridgeGrpc.AccountBridgeBlockingStub bridgeServiceBlockingStub = AccountBridgeGrpc - .newBlockingStub(managedChannel); - return MetadataUtils.attachHeaders(bridgeServiceBlockingStub, getHeaders()); + .forAddress(configuration.getHost(), Integer.parseInt(configuration.getPort())) + .usePlaintext() + .build(); + AccountBridgeGrpc.AccountBridgeBlockingStub bridgeService = + AccountBridgeGrpc.newBlockingStub(managedChannel); + return MetadataUtils.attachHeaders(bridgeService, getHeaders()); } /** @@ -117,4 +166,5 @@ public class ErlangAccountMqttBridge implements ErlangAccountBridge { headers.put(key, "Bearer " + TokenInterceptorConstants.ACCESS_TOKEN_CTX.get()); return headers; } + } diff --git a/src/main/performance/READ.ME b/src/main/performance/READ.ME new file mode 100644 index 0000000000000000000000000000000000000000..27fc4520170d265ba68b1e5b782b9e43df76bda4 --- /dev/null +++ b/src/main/performance/READ.ME @@ -0,0 +1,55 @@ +This file describes one approach of doing performance testing +of gRPC services. It uses a simple command line utility called ghz. + +ghz facilitates load testing and benchmarking of gRPC services. +It is intended to be used for testing and debugging services locally, +and in automated continous intergration environments for performance +regression testing. + +Instructions to install, configure and use ghz can be found using this link: +https://ghz.sh/docs/intro. + +For the purpose of testing the the NYNJA account services a number of +JSON config files are provided. Each file has the of the gRPC/endpoint +to be tested with extension .json. + +For example, updateSearchableOption gRPC/endpoint could be tested using +the config file updateSearchableOption.json. The file ocntains: + +{ + "proto": "/account.proto", + "call": "account.AccountService.updateSearchableOption", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06", + "authenticationType": "PHONE", + "authenticationIdentifier": "448873598834", + "searchOption": 1 + }, + "host": "" +} + +Configuration options can be found following the above link under +"Options Reference". The ones worth mentioning here are: +- call - the endpoint name - 'package/service/method' +- d - the call data as stringified JSON, i.e the parameters to be send +with the request. + is the actual path to the account.proto file + is the address of the account service as IP address:port. +For example to test on your local machine use "127.0.0.1:6565". + +The way to test an endpoint is to call ghz from the command line like: + + >ghz -config ./updateSearchableOption.json + + +ghz produces some output showing a Summary, Response time histogram and +Latency distribution. + + +To achieve more realistic results it would be beneficial to: +1) runeach test multiple times and get the average results +2) configure each test with data existing in the DB and run it multiple times +3) configure each test with data non-existing in the DB and run it multiple times diff --git a/src/main/performance/addAuthenticationProviderToProfile.json b/src/main/performance/addAuthenticationProviderToProfile.json new file mode 100644 index 0000000000000000000000000000000000000000..6b0e20cf5b0de9282f098750f303b4608a923511 --- /dev/null +++ b/src/main/performance/addAuthenticationProviderToProfile.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.addAuthenticationProviderToProfile", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "123e4567-e89b-12d3-a456-426655440011", + "authenticationProvider":{"authenticationType": "PHONE", "authenticationProvider": "448873598834"} + }, + "host": "" +} diff --git a/src/main/performance/addContactInfoToAccount.json b/src/main/performance/addContactInfoToAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..80543d2126d0b66a78d44bff9a8d9b73051bd7a2 --- /dev/null +++ b/src/main/performance/addContactInfoToAccount.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.addContactInfoToAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35", + "contactInfo":{"type": "PHONE_CONTACT", "value": "448873598834", "label": "The_Label"} + }, + "host": "" +} diff --git a/src/main/performance/completePendingAccountCreation.json b/src/main/performance/completePendingAccountCreation.json new file mode 100644 index 0000000000000000000000000000000000000000..1302b4af6fa3fbd3c5217115398615cf18d49d2e --- /dev/null +++ b/src/main/performance/completePendingAccountCreation.json @@ -0,0 +1,13 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.completePendingAccountCreation", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06", + "accountName": "Name of account", + "firstName": "Atanas" + }, + "host": "" +} diff --git a/src/main/performance/createPendingAccount.json b/src/main/performance/createPendingAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..b0b1a337452e4ff6b3b6fac0b48af55109eae610 --- /dev/null +++ b/src/main/performance/createPendingAccount.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.createPendingAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "authenticationType": "EMAIL", + "authenticationProvider": "pepi.toshev@msn.com" + }, + "host": "" +} diff --git a/src/main/performance/deleteAccount.json b/src/main/performance/deleteAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..1904039f840f839139ace30a15b0c2a18cb5bb96 --- /dev/null +++ b/src/main/performance/deleteAccount.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.deleteAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06" + }, + "host": "" +} diff --git a/src/main/performance/deleteAuthenticationProviderFromProfile.json b/src/main/performance/deleteAuthenticationProviderFromProfile.json new file mode 100644 index 0000000000000000000000000000000000000000..130b2df4e60b581279d59b692141b8bf3d5e1077 --- /dev/null +++ b/src/main/performance/deleteAuthenticationProviderFromProfile.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.deleteAuthenticationProviderFromProfile", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35", + "authenticationProvider":{"authenticationType": "EMAIL", "authenticationProvider": "bill.gates@msn.com", "searchOption": "SEARCH_ENABLED"} + }, + "host": "" +} diff --git a/src/main/performance/deleteContactInfoFromAccount.json b/src/main/performance/deleteContactInfoFromAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..90a444a9994aa2948709c4df647b623a1836d8b0 --- /dev/null +++ b/src/main/performance/deleteContactInfoFromAccount.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.deleteContactInfoFromAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35", + "contactInfo":{"type": "PHONE_CONTACT", "value": "448873598834", "label": "The_Label"} + }, + "host": "" +} diff --git a/src/main/performance/deleteProfile.json b/src/main/performance/deleteProfile.json new file mode 100644 index 0000000000000000000000000000000000000000..f1bf0d0b0ba41c622acc6f3c85b12efd8c923be4 --- /dev/null +++ b/src/main/performance/deleteProfile.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.deleteProfile", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06" + }, + "host": "" +} diff --git a/src/main/performance/editContactInfoForAccount.json b/src/main/performance/editContactInfoForAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..bed30955434c0ab15ab73857b45b0cc5dedc4db5 --- /dev/null +++ b/src/main/performance/editContactInfoForAccount.json @@ -0,0 +1,13 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.editContactInfoForAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35", + "oldContactInfo":{"type": "PHONE_CONTACT", "value": "448873598834", "label": "The_Label"}, + "editedContactInfo":{"type": "PHONE_CONTACT", "value": "448873598877", "label": "New_Label"} + }, + "host": "" +} diff --git a/src/main/performance/getAccountByAccountId.json b/src/main/performance/getAccountByAccountId.json new file mode 100644 index 0000000000000000000000000000000000000000..04f08097f55fda56cedaa3cef7db4f02a71ca78b --- /dev/null +++ b/src/main/performance/getAccountByAccountId.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAccountByAccountId", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35" + }, + "host": "127.0.0.1:6565" +} diff --git a/src/main/performance/getAccountByCreationProvider.json b/src/main/performance/getAccountByCreationProvider.json new file mode 100644 index 0000000000000000000000000000000000000000..1609cf67f386ac04b2f8ac7cd6f90b1354c8b4c3 --- /dev/null +++ b/src/main/performance/getAccountByCreationProvider.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAccountByCreationProvider", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "authenticationType": "EMAIL", + "authenticationIdentifier": "pepi.toshev@msn.com" + }, + "host": "" +} diff --git a/src/main/performance/getAccountByLoginOption.json b/src/main/performance/getAccountByLoginOption.json new file mode 100644 index 0000000000000000000000000000000000000000..77c6ad1e38f0a70b1af043aecc07d7f06cdb2691 --- /dev/null +++ b/src/main/performance/getAccountByLoginOption.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAccountByLoginOption", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "authenticationType": "PHONE", + "authenticationIdentifier": "448873598834" + }, + "host": "" +} diff --git a/src/main/performance/getAccountByQrCode.json b/src/main/performance/getAccountByQrCode.json new file mode 100644 index 0000000000000000000000000000000000000000..d516f44ba3bd0b162120aa26c11c82e781605219 --- /dev/null +++ b/src/main/performance/getAccountByQrCode.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAccountByQrCode", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "qrCode": "qrCoded" + }, + "host": "" +} diff --git a/src/main/performance/getAllAccountsByProfileId.json b/src/main/performance/getAllAccountsByProfileId.json new file mode 100644 index 0000000000000000000000000000000000000000..b2992ec2f73abe1d057a23e23d4d74c6ef4d5fe8 --- /dev/null +++ b/src/main/performance/getAllAccountsByProfileId.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAllAccountsByProfileId", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06" + }, + "host": "" +} diff --git a/src/main/performance/getProfileByProfileId.json b/src/main/performance/getProfileByProfileId.json new file mode 100644 index 0000000000000000000000000000000000000000..c45a75284153cba5cb630aea2058f5723c6c1172 --- /dev/null +++ b/src/main/performance/getProfileByProfileId.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getProfileByProfileId", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35" + }, + "host": "" +} diff --git a/src/main/performance/searchByEmail.json b/src/main/performance/searchByEmail.json new file mode 100644 index 0000000000000000000000000000000000000000..c1ce6cf8410ce77d7390121d72157b99adb76e65 --- /dev/null +++ b/src/main/performance/searchByEmail.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.searchByEmail", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "email": "gogo@yahoo.com" + }, + "host": "" +} diff --git a/src/main/performance/searchByPhoneNumber.json b/src/main/performance/searchByPhoneNumber.json new file mode 100644 index 0000000000000000000000000000000000000000..4ca967a79b154356a777b3cfb2484762a7f8912f --- /dev/null +++ b/src/main/performance/searchByPhoneNumber.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.searchByPhoneNumber", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "phoneNumber": "359888777995" + }, + "host": "" +} diff --git a/src/main/performance/searchByQrCode.json b/src/main/performance/searchByQrCode.json new file mode 100644 index 0000000000000000000000000000000000000000..4103974bf51ca4bf404406cb30354fb43b8d1a23 --- /dev/null +++ b/src/main/performance/searchByQrCode.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.searchByQrCode", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "qrCode": "qrCoded" + }, + "host": "" +} diff --git a/src/main/performance/searchBySocialProvider.json b/src/main/performance/searchBySocialProvider.json new file mode 100644 index 0000000000000000000000000000000000000000..9e1e782791c93c6136e59bad4fe162abeeaef992 --- /dev/null +++ b/src/main/performance/searchBySocialProvider.json @@ -0,0 +1,12 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.searchBySocialProvider", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "authenticationType": "PHONE", + "authenticationIdentifier": "448873598834" + }, + "host": "" +} diff --git a/src/main/performance/searchByUsername.json b/src/main/performance/searchByUsername.json new file mode 100644 index 0000000000000000000000000000000000000000..5ef8f7a610b3f980c890f687b4c5c89faf9d3866 --- /dev/null +++ b/src/main/performance/searchByUsername.json @@ -0,0 +1,11 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.getAccountByUsername", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "username": "PetarPetrov" + }, + "host": "" +} diff --git a/src/main/performance/updateAccount.json b/src/main/performance/updateAccount.json new file mode 100644 index 0000000000000000000000000000000000000000..d4bbe399fe1ba76cb7b2568e33a4488b8a07de9d --- /dev/null +++ b/src/main/performance/updateAccount.json @@ -0,0 +1,13 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.updateAccount", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "accountId": "0994566e-ac7b-45b2-b6ef-36440e44a15a", + "username": "acctIvanv", + "firstName": "Neda" + }, + "host": "" +} diff --git a/src/main/performance/updateAuthenticationProviderForProfile.json b/src/main/performance/updateAuthenticationProviderForProfile.json new file mode 100644 index 0000000000000000000000000000000000000000..e8c132f0a77e1ea1d74374fb681b308b73205572 --- /dev/null +++ b/src/main/performance/updateAuthenticationProviderForProfile.json @@ -0,0 +1,13 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.updateAuthenticationProviderForProfile", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "ac6d30c3-1e87-4932-ae0f-ebc9c9873b35", + "oldAuthProvider":{"authenticationType": "PHONE", "authenticationProvider": "448873598834", "searchOption": 1}, + "updatedAuthProvider":{"authenticationType": "PHONE", "authenticationProvider": "448873598877", "searchOption": 1} + }, + "host": "" +} diff --git a/src/main/performance/updateSearchableOption.json b/src/main/performance/updateSearchableOption.json new file mode 100644 index 0000000000000000000000000000000000000000..1ee14d73d218315d3b21dbcee261220190914642 --- /dev/null +++ b/src/main/performance/updateSearchableOption.json @@ -0,0 +1,14 @@ +{ + "proto": "/account.proto", + "call": "account.AccountService.updateSearchableOption", + "insecure": true, + "n": 2000, + "c": 50, + "d": { + "profileId": "47b50a3e-97d3-4b68-b63d-fb83bb9d2e06", + "authenticationType": "PHONE", + "authenticationIdentifier": "448873598834", + "searchOption": 1 + }, + "host": "" +} diff --git a/src/main/resources/application-production.yml b/src/main/resources/application-production.yml index d87560032f5939aabc5fa344dc62b9c8aa09ca14..c76cc62a22c1964068e5402212ad11f24b644236 100644 --- a/src/main/resources/application-production.yml +++ b/src/main/resources/application-production.yml @@ -32,9 +32,9 @@ profile-data: max-authenticationproviders-per-profile: 3 erlang-bridge: - enabled: ${ERLANG_ENABLED:false} - ip: ${ERLANG_IP} - port: ${ERLANG_PORT} + enabled: ${BRIDGE_ENABLED:false} + host: ${BRIDGE_HOST} + port: ${BRIDGE_PORT} #Metrics related configurations management: diff --git a/src/test/java/biz/nynja/account/services/AccountServiceTests.java b/src/test/java/biz/nynja/account/services/AccountServiceTests.java index 6bd124fdac63a4908c3533e64a8f5bafce325950..95148ec480408fb89d39cf168f5b6f7687b5b4de 100644 --- a/src/test/java/biz/nynja/account/services/AccountServiceTests.java +++ b/src/test/java/biz/nynja/account/services/AccountServiceTests.java @@ -19,6 +19,7 @@ import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -36,6 +37,7 @@ import biz.nynja.account.accesspoints.AccessPointService; import biz.nynja.account.components.AccountServiceHelper; import biz.nynja.account.components.PreparedStatementsCache; import biz.nynja.account.configurations.CassandraTestsConfig; +import biz.nynja.account.grpc.AccessStatus; import biz.nynja.account.grpc.AccountByAccountIdRequest; import biz.nynja.account.grpc.AccountDetails; import biz.nynja.account.grpc.AccountResponse; @@ -415,7 +417,8 @@ public class AccountServiceTests extends GrpcServerTestBase { @Test public void testUpdateAccount() throws ExecutionException, InterruptedException { final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setAccountId(Util.ACCOUNT_ID.toString()) - .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setFirstName(Util.FIRST_NAME).build(); + .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setFirstName(Util.FIRST_NAME) + .setAccessStatus(AccessStatus.ENABLED).build(); given(accountRepositoryAdditional.updateAccount(request)).willReturn(updatedAccount); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); @@ -427,7 +430,7 @@ public class AccountServiceTests extends GrpcServerTestBase { @Test public void testUpdateAccountMissingFirstName() { final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setAccountId(Util.ACCOUNT_ID.toString()) - .setAccountMark(Util.UPDATED_ACCOUNT_MARK).build(); + .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setAccessStatus(AccessStatus.ENABLED).build(); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); assertNotNull("Reply should not be null", reply); @@ -438,7 +441,7 @@ public class AccountServiceTests extends GrpcServerTestBase { @Test public void testUpdateAccountMissingAccountId() { final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setFirstName(Util.FIRST_NAME) - .setAccountMark(Util.UPDATED_ACCOUNT_MARK).build(); + .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setAccessStatus(AccessStatus.ENABLED).build(); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); assertNotNull("Reply should not be null", reply); @@ -450,7 +453,7 @@ public class AccountServiceTests extends GrpcServerTestBase { public void testUpdateAccountAccountIdNotFound() { final UpdateAccountRequest request = UpdateAccountRequest.newBuilder() .setAccountId(Util.ACCOUNT_ID_NOT_FOUND.toString()).setFirstName(Util.FIRST_NAME) - .setAccountMark(Util.UPDATED_ACCOUNT_MARK).build(); + .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setAccessStatus(AccessStatus.ENABLED).build(); given(accountRepositoryAdditional.updateAccount(request)).willReturn(null); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); @@ -463,7 +466,7 @@ public class AccountServiceTests extends GrpcServerTestBase { public void testUpdateAccountUsernameAlreadyUsed() { final UpdateAccountRequest request = UpdateAccountRequest.newBuilder().setAccountId(Util.ACCOUNT_ID.toString()) .setAccountMark(Util.UPDATED_ACCOUNT_MARK).setFirstName(Util.FIRST_NAME).setUsername(Util.USERNAME) - .build(); + .setAccessStatus(AccessStatus.ENABLED).build(); given(accountRepositoryAdditional.foundExistingNotOwnUsername(UUID.fromString(request.getAccountId()), request.getUsername())).willReturn(true); @@ -1446,7 +1449,7 @@ public class AccountServiceTests extends GrpcServerTestBase { 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(); + .setAccessStatus(AccessStatus.ENABLED).build(); given(accountRepositoryAdditional.updateAccount(request)).willReturn(updatedAccount); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); @@ -1462,7 +1465,8 @@ public class AccountServiceTests extends GrpcServerTestBase { 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(); + .setBirthday(Date.newBuilder().setYear(1990).setMonth(9).setDay(32).build()) + .setAccessStatus(AccessStatus.ENABLED).build(); final AccountResponse reply = accountServiceBlockingStub.updateAccount(request); @@ -1721,6 +1725,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.MISSING_PROFILE_ID)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderPhoneForProfileOK() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1738,6 +1744,8 @@ public class AccountServiceTests extends GrpcServerTestBase { assertEquals("SUCCESS", reply.getStatus()); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderEmailForProfileOK() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1755,6 +1763,8 @@ public class AccountServiceTests extends GrpcServerTestBase { assertEquals("SUCCESS", reply.getStatus()); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileErrorUpdatingAuthProvider() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1774,6 +1784,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.ERROR_UPDATING_AUTH_PROVIDER)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderEmailForProfileAuthProviderUsed() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1798,6 +1810,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.ERROR_UPDATING_AUTH_PROVIDER)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileInvalidProfileId() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1813,6 +1827,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.INVALID_PROFILE_ID)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileMissingProfileId() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1827,6 +1843,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.MISSING_PROFILE_ID)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileMissingAuthProviderType() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1842,6 +1860,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.MISSING_AUTH_PROVIDER_TYPE)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileMissingAuthProviderIdentifier() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1857,6 +1877,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.MISSING_AUTH_PROVIDER_ID)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileInvalidPhone() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1873,6 +1895,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.INVALID_PHONENUMBER)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileInvalidEmail() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1889,6 +1913,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.INVALID_EMAIL)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileInvalidTypeFacebook() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() @@ -1906,6 +1932,8 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.INVALID_ADDITIONAL_LOGIN_OPTION_TYPE)); } + // The test is disabled because update of auth provider is currently not supported + @Ignore @Test public void testUpdateAuthProviderForProfileInvalidTypeGoogleplus() { final UpdateAuthenticationProviderRequest request = UpdateAuthenticationProviderRequest.newBuilder() diff --git a/src/test/java/biz/nynja/account/utils/Util.java b/src/test/java/biz/nynja/account/utils/Util.java index 7e0bf5becd5d6720bec7cd3ce111de1420f1361e..e71388983683d21a93f44dc9415a7280f7bfd4cb 100644 --- a/src/test/java/biz/nynja/account/utils/Util.java +++ b/src/test/java/biz/nynja/account/utils/Util.java @@ -230,6 +230,7 @@ public class Util { account.setLastName(LAST_NAME); account.setBirthday(BIRTHDAY); account.setAccountMark(UPDATED_ACCOUNT_MARK); + account.setAccessStatus(AccessStatus.ENABLED.toString()); return account; }