Domain model change
[portal.git] / portal-BE / src / main / java / org / onap / portal / service / AdminRolesService.java
index c948ece..8049cd6 100644 (file)
 
 package org.onap.portal.service;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
 import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.Tuple;
+import org.apache.commons.lang.StringUtils;
+import org.apache.cxf.transport.http.HTTPException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.portal.domain.db.ep.EpAppFunction;
+import org.onap.portal.domain.db.ep.EpUserRolesRequest;
+import org.onap.portal.domain.db.ep.EpUserRolesRequestDet;
+import org.onap.portal.domain.db.fn.FnApp;
+import org.onap.portal.domain.db.fn.FnFunction;
+import org.onap.portal.domain.db.fn.FnMenuFunctional;
+import org.onap.portal.domain.db.fn.FnMenuFunctionalRoles;
 import org.onap.portal.domain.db.fn.FnRole;
+import org.onap.portal.domain.db.fn.FnRoleFunction;
 import org.onap.portal.domain.db.fn.FnUser;
 import org.onap.portal.domain.db.fn.FnUserRole;
-import org.onap.portal.domain.dto.ecomp.UserRole;
+import org.onap.portal.domain.dto.transport.AppNameIdIsAdmin;
+import org.onap.portal.domain.dto.transport.AppWithRolesForUser;
+import org.onap.portal.domain.dto.transport.AppsListWithAdminRole;
+import org.onap.portal.domain.dto.transport.CentralV2Role;
+import org.onap.portal.domain.dto.transport.EPUserAppCurrentRoles;
+import org.onap.portal.domain.dto.transport.EcompUserAppRoles;
+import org.onap.portal.domain.dto.transport.ExternalAccessUser;
+import org.onap.portal.domain.dto.transport.ExternalAccessUserRoleDetail;
+import org.onap.portal.domain.dto.transport.ExternalRequestFieldsValidator;
+import org.onap.portal.domain.dto.transport.ExternalRoleDescription;
+import org.onap.portal.domain.dto.transport.RemoteRoleV1;
+import org.onap.portal.domain.dto.transport.Role;
+import org.onap.portal.domain.dto.transport.RoleInAppForUser;
+import org.onap.portal.domain.dto.transport.RolesInAppForUser;
+import org.onap.portal.exception.DeleteDomainObjectFailedException;
+import org.onap.portal.exception.SyncUserRolesException;
 import org.onap.portal.logging.format.EPAppMessagesEnum;
 import org.onap.portal.logging.logic.EPLogUtil;
+import org.onap.portal.service.ep.EpAppFunctionService;
+import org.onap.portal.service.ep.EpUserRolesRequestDetService;
+import org.onap.portal.service.ep.EpUserRolesRequestService;
+import org.onap.portal.service.fn.FnAppService;
+import org.onap.portal.service.fn.FnMenuFunctionalRolesService;
+import org.onap.portal.service.fn.FnMenuFunctionalService;
+import org.onap.portal.service.fn.FnRoleService;
+import org.onap.portal.service.fn.FnUserRoleService;
 import org.onap.portal.service.fn.FnUserService;
+import org.onap.portal.utils.EPCommonSystemProperties;
+import org.onap.portal.utils.EPUserUtils;
+import org.onap.portal.utils.EcompPortalUtils;
+import org.onap.portal.utils.PortalConstants;
+import org.onap.portalsdk.core.domain.RoleFunction;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.portalsdk.core.restful.domain.EcompRole;
+import org.onap.portalsdk.core.util.SystemProperties;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
 
 @Service
+@Transactional
 public class AdminRolesService {
 
-       private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AdminRolesService.class);
-
-       private final Long SYS_ADMIN_ROLE_ID = 1L;
-       private final Long ACCOUNT_ADMIN_ROLE_ID = 999L;
-       private final Long ECOMP_APP_ID = 1L;
-       private final String ADMIN_ACCOUNT= "Is account admin for user {}";
-
-       private final EntityManager entityManager;
-       private final FnUserService fnUserService;
-
-       @Autowired
-       public AdminRolesService(final EntityManager entityManager,
-               FnUserService fnUserService) {
-              this.entityManager = entityManager;
-              this.fnUserService = fnUserService;
-       }
-
-       public boolean isSuperAdmin(FnUser user) {
-              if ((user != null) && (user.getOrgUserId() != null)) {
-                     String sql = "SELECT user.USER_ID, user.org_user_id, userrole.ROLE_ID, userrole.APP_ID FROM fn_user_role userrole "
-                             + "INNER JOIN fn_user user ON user.USER_ID = userrole.USER_ID " + "WHERE user.org_user_id = '"
-                             + user.getOrgUserId() + "' " + "AND userrole.ROLE_ID = '" + SYS_ADMIN_ROLE_ID + "' "
-                             + "AND userrole.APP_ID = '" + ECOMP_APP_ID + "';";
-                     try {
-                            List userRoleList = entityManager.createNativeQuery(sql, UserRole.class).getResultList();
-                            if (userRoleList != null && userRoleList.size() > 0) {
-                                   return true;
-                            }
-                     } catch (Exception e) {
-                            EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
-                            logger.error(EELFLoggerDelegate.errorLogger,
-                                    "Exception occurred while executing isSuperAdmin operation", e);
-                     }
+  private final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AdminRolesService.class);
+  private static final Object syncRests = new Object();
+  private final RestTemplate template = new RestTemplate();
+
+  private Long SYS_ADMIN_ROLE_ID = 38L;
+  private final Long ACCOUNT_ADMIN_ROLE_ID = 999L;
+  private final Long ECOMP_APP_ID = 1L;
+  private final String ADMIN_ACCOUNT = "Is account admin for user {}";
+
+  private final AppsCacheService appsCacheService;
+  private final EntityManager entityManager;
+  private final FnUserService fnUserService;
+  private final FnRoleService fnRoleService;
+  private final FnAppService fnAppService;
+  private final FnMenuFunctionalService fnMenuFunctionalService;
+  private final FnUserRoleService fnUserRoleService;
+  private final EpAppFunctionService epAppFunctionService;
+  private final EcompUserAppRolesService ecompUserAppRolesService;
+  private final FnMenuFunctionalRolesService fnMenuFunctionalRolesService;
+  private final ApplicationsRestClientService applicationsRestClientService;
+  private final EpUserRolesRequestDetService epUserRolesRequestDetService;
+  private final ExternalAccessRolesService externalAccessRolesService;
+  private final EpUserRolesRequestService epUserRolesRequestService;
+
+  @Autowired
+  public AdminRolesService(AppsCacheService appsCacheService,
+      final EntityManager entityManager,
+      final FnUserService fnUserService, FnRoleService fnRoleService,
+      FnAppService fnAppService,
+      FnMenuFunctionalService fnMenuFunctionalService,
+      final FnUserRoleService fnUserRoleService,
+      EpAppFunctionService epAppFunctionService,
+      EcompUserAppRolesService ecompUserAppRolesService,
+      FnMenuFunctionalRolesService fnMenuFunctionalRolesService,
+      ApplicationsRestClientService applicationsRestClientService,
+      EpUserRolesRequestDetService epUserRolesRequestDetService,
+      ExternalAccessRolesService externalAccessRolesService,
+      EpUserRolesRequestService epUserRolesRequestService) {
+    this.appsCacheService = appsCacheService;
+    this.entityManager = entityManager;
+    this.fnUserService = fnUserService;
+    this.fnRoleService = fnRoleService;
+    this.fnAppService = fnAppService;
+    this.fnMenuFunctionalService = fnMenuFunctionalService;
+    this.fnUserRoleService = fnUserRoleService;
+    this.epAppFunctionService = epAppFunctionService;
+    this.ecompUserAppRolesService = ecompUserAppRolesService;
+    this.fnMenuFunctionalRolesService = fnMenuFunctionalRolesService;
+    this.applicationsRestClientService = applicationsRestClientService;
+    this.epUserRolesRequestDetService = epUserRolesRequestDetService;
+    this.externalAccessRolesService = externalAccessRolesService;
+    this.epUserRolesRequestService = epUserRolesRequestService;
+  }
+
+  public boolean isSuperAdmin(final String loginId) {
+    boolean isSuperAdmin;
+    try {
+      isSuperAdmin = fnUserRoleService
+          .isSuperAdmin(loginId, SYS_ADMIN_ROLE_ID, ECOMP_APP_ID);
+    } catch (Exception e) {
+      logger.error("isSuperAdmin exception: " + e.toString());
+      throw e;
+    }
+    logger.info("isSuperAdmin " + isSuperAdmin);
+    return isSuperAdmin;
+  }
+
+  public boolean isAccountAdmin(FnUser user) {
+    try {
+      logger.debug(EELFLoggerDelegate.debugLogger, ADMIN_ACCOUNT, user.getId());
+      List<Integer> userAdminApps = getAdminAppsForTheUser(user.getId());
+      logger.debug(EELFLoggerDelegate.debugLogger,
+          "Is account admin for userAdminApps() - for user {}, found userAdminAppsSize {}",
+          user.getOrgUserId(), userAdminApps.size());
+
+      if (user.getId() != null) {
+        for (FnUserRole userApp : user.getUserApps()) {
+          if (userApp.getRoleId().getId().equals(ACCOUNT_ADMIN_ROLE_ID) || (
+              userAdminApps.size() > 1)) {
+            logger.debug(EELFLoggerDelegate.debugLogger,
+                "Is account admin for userAdminApps() - for user {}, found Id {}",
+                user.getOrgUserId(), userApp.getRoleId().getId());
+            return true;
+          }
+        }
+      }
+    } catch (Exception e) {
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      logger.error(EELFLoggerDelegate.errorLogger,
+          "Exception occurred while executing isAccountAdmin operation",
+          e);
+    }
+    return false;
+  }
+
+  boolean isUser(FnUser user) {
+    try {
+      FnUser currentUser = fnUserService.getUser(user.getId()).orElseThrow(Exception::new);
+      if (currentUser != null && currentUser.getId() != null) {
+        for (FnUserRole userApp : currentUser.getUserApps()) {
+          if (!userApp.getFnAppId().getId().equals(ECOMP_APP_ID)) {
+            FnRole role = userApp.getRoleId();
+            if (!role.getId().equals(SYS_ADMIN_ROLE_ID) && !role.getId()
+                .equals(ACCOUNT_ADMIN_ROLE_ID)) {
+              if (role.getActiveYn()) {
+                return true;
               }
-              return false;
-       }
-
-       public boolean isAccountAdmin(FnUser user) {
-              try {
-                     final Map<String, Long> userParams = new HashMap<>();
-                     userParams.put("userId", user.getId());
-                     logger.debug(EELFLoggerDelegate.debugLogger, ADMIN_ACCOUNT, user.getId());
-                     List<Integer> userAdminApps;
-                     String query = "select fa.app_id  from fn_user_role ur,fn_app fa where ur.user_id =:userId and ur.app_id=fa.app_id and ur.role_id= 999 and (fa.enabled = 'Y' || fa.app_id=1)";
-                     userAdminApps = entityManager.createQuery(query, Integer.class).setParameter("userId", user.getId()).getResultList();
-                     logger.debug(EELFLoggerDelegate.debugLogger, "Is account admin for userAdminApps() - for user {}, found userAdminAppsSize {}", user.getOrgUserId(), userAdminApps.size());
-
-
-                     if (user.getId() != null) {
-                            for (FnUserRole userApp : user.getFnUserRoles()) {
-                                   if (userApp.getRoleId().getId().equals(ACCOUNT_ADMIN_ROLE_ID)||(userAdminApps.size()>1)) {
-                                          logger.debug(EELFLoggerDelegate.debugLogger, "Is account admin for userAdminApps() - for user {}, found Id {}", user.getOrgUserId(), userApp.getRoleId().getId());
-                                          return true;
-                                   }
-                            }
-                     }
-              } catch (Exception e) {
-                     EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
-                     logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while executing isAccountAdmin operation",
-                             e);
+            }
+          }
+        }
+      }
+    } catch (Exception e) {
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while executing isUser operation",
+          e);
+    }
+    return false;
+  }
+
+  public boolean isRoleAdmin(Long userId) {
+    try {
+      logger.debug(EELFLoggerDelegate.debugLogger, "Checking if user has isRoleAdmin access");
+      List getRoleFuncListOfUser = fnUserRoleService.getRoleFunctionsOfUserforAlltheApplications(userId);
+      logger.debug(EELFLoggerDelegate.debugLogger,
+          "Checking if user has isRoleAdmin access :: getRoleFuncListOfUser", getRoleFuncListOfUser);
+      Set<String> getRoleFuncListOfPortalSet = new HashSet<>(getRoleFuncListOfUser);
+      Set<String> getRoleFuncListOfPortalSet1 = new HashSet<>();
+      Set<String> roleFunSet;
+      roleFunSet = getRoleFuncListOfPortalSet.stream().filter(x -> x.contains("|"))
+          .collect(Collectors.toSet());
+      if (!roleFunSet.isEmpty()) {
+        for (String roleFunction : roleFunSet) {
+          String type = externalAccessRolesService.getFunctionCodeType(roleFunction);
+          getRoleFuncListOfPortalSet1.add(type);
+        }
+      }
+
+      boolean checkIfFunctionsExits = getRoleFuncListOfPortalSet1.stream()
+          .anyMatch(roleFunction -> roleFunction.equalsIgnoreCase("Approver"));
+      logger.debug(EELFLoggerDelegate.debugLogger, "Checking if user has approver rolefunction",
+          checkIfFunctionsExits);
+
+      return checkIfFunctionsExits;
+
+    } catch (Exception e) {
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      logger.error(EELFLoggerDelegate.errorLogger,
+          "Exception occurred while executing isRoleAdmin operation",
+          e);
+    }
+    return false;
+  }
+
+  private boolean isAccountAdminOfApplication(Long userId, FnApp app) {
+    boolean isApplicationAccountAdmin = false;
+    try {
+      logger.debug(EELFLoggerDelegate.debugLogger, ADMIN_ACCOUNT, userId);
+      List<Integer> userAdminApps = getAdminAppsForTheUser(userId);
+      if (!userAdminApps.isEmpty()) {
+        isApplicationAccountAdmin = userAdminApps.contains(app.getId());
+        logger.debug(EELFLoggerDelegate.debugLogger, "Is account admin for user is true{} ,appId {}", userId,
+            app.getId());
+      }
+    } catch (Exception e) {
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      logger.error(EELFLoggerDelegate.errorLogger,
+          "Exception occurred while executing isAccountAdminOfApplication operation", e);
+    }
+    logger.debug(EELFLoggerDelegate.debugLogger,
+        "In AdminRolesServiceImpl() - isAccountAdminOfApplication = {} and userId ={} ", isApplicationAccountAdmin,
+        userId);
+    return isApplicationAccountAdmin;
+
+  }
+
+  private List<Integer> getAdminAppsForTheUser(final Long userId) {
+    String query = "select fa.app_id from fn_user_role ur,fn_app fa where ur.user_id =:userId and ur.app_id=fa.app_id and ur.role_id= 999 and (fa.enabled = 'Y' || fa.app_id=1)";
+    return entityManager.createQuery(query, Integer.class)
+        .setParameter("userId", userId).getResultList();
+  }
+
+  public ExternalRequestFieldsValidator setAppWithUserRoleStateForUser(FnUser user,
+      AppWithRolesForUser newAppRolesForUser) {
+    boolean result = false;
+    boolean epRequestValue = false;
+    String userId = "";
+    String reqMessage = "";
+    if (newAppRolesForUser != null && newAppRolesForUser.getOrgUserId() != null) {
+      userId = newAppRolesForUser.getOrgUserId().trim();
+    }
+    Long appId = newAppRolesForUser.getAppId();
+    List<RoleInAppForUser> roleInAppForUserList = newAppRolesForUser.getAppRoles();
+
+    if (userId.length() > 0) {
+      ObjectMapper mapper = new ObjectMapper();
+      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+      try {
+        FnApp app = fnAppService.getById(appId);
+
+        boolean checkIfUserisApplicationAccAdmin = isAccountAdminOfApplication(user.getId(),
+            app);
+        Set<EcompRole> rolesGotDeletedFromApprover = new TreeSet<>();
+
+        boolean checkIfUserIsOnlyRoleAdmin =
+            isRoleAdmin(user.getId()) && !checkIfUserisApplicationAccAdmin;
+        if (checkIfUserIsOnlyRoleAdmin) {
+          for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
+            if (!roleInAppForUser.getIsApplied()) {
+              EcompRole ecompRole = new EcompRole();
+              ecompRole.setId(roleInAppForUser.getRoleId());
+              ecompRole.setName(roleInAppForUser.getRoleName());
+              rolesGotDeletedFromApprover.add(ecompRole);
+            }
+          }
+        }
+
+        applyChangesToUserAppRolesForMyLoginsRequest(user, appId);
+
+        boolean systemUser = newAppRolesForUser.isSystemUser();
+
+        if ((app.getAuthCentral() || app.getId().equals(PortalConstants.PORTAL_APP_ID))
+            && systemUser) {
+
+          Set<EcompRole> userRolesInLocalApp = postUsersRolesToLocalApp(roleInAppForUserList);
+          RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(userId, appId,
+              userRolesInLocalApp);
+          List<RoleInAppForUser> roleAppUserList = rolesInAppForUser.getRoles();
+          Set<EcompRole> rolesGotDeletedByApprover = new TreeSet<>();
+          if (EcompPortalUtils.checkIfRemoteCentralAccessAllowed()) {
+            // Apply changes in external Access system
+
+            updateUserRolesInExternalSystem(app, rolesInAppForUser.getOrgUserId(),
+                roleAppUserList,
+                epRequestValue, systemUser, rolesGotDeletedByApprover, false);
+          }
+          result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser, epRequestValue,
+              "Portal",
+              systemUser, rolesGotDeletedByApprover, false);
+
+        } else if (!app.getAuthCentral() && systemUser) {
+          throw new Exception("For non-centralized application we cannot add systemUser");
+        } else {    // if centralized app
+          if (app.getAuthCentral()) {
+            if (!app.getId().equals(PortalConstants.PORTAL_APP_ID)) {
+              pushRemoteUser(roleInAppForUserList, userId, app, mapper,
+                  applicationsRestClientService, false);
+            }
+
+            Set<EcompRole> userRolesInLocalApp = postUsersRolesToLocalApp(
+                roleInAppForUserList);
+            RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(userId,
+                appId,
+                userRolesInLocalApp);
+            List<RoleInAppForUser> roleAppUserList = rolesInAppForUser.getRoles();
+            if (EcompPortalUtils.checkIfRemoteCentralAccessAllowed()) {
+
+              // Apply changes in external Access system
+              updateUserRolesInExternalSystem(app, rolesInAppForUser.getOrgUserId(),
+                  roleAppUserList,
+                  epRequestValue, false, rolesGotDeletedFromApprover,
+                  checkIfUserIsOnlyRoleAdmin);
+            }
+            result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser,
+                epRequestValue, "Portal", systemUser, rolesGotDeletedFromApprover,
+                checkIfUserIsOnlyRoleAdmin);
+          }
+          // In case if portal is not centralized then follow existing approach
+          else if (!app.getAuthCentral() && app.getId()
+              .equals(PortalConstants.PORTAL_APP_ID)) {
+            Set<EcompRole> userRolesInLocalApp = postUsersRolesToLocalApp(
+                roleInAppForUserList);
+            RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(userId,
+                appId,
+                userRolesInLocalApp);
+            Set<EcompRole> rolesGotDeletedByApprover = new TreeSet<>();
+            result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser,
+                epRequestValue, "Portal", false, rolesGotDeletedByApprover, false);
+          } else {// remote app
+            FnUser remoteAppUser;
+            if (!app.getAuthCentral() && !app.getId()
+                .equals(PortalConstants.PORTAL_APP_ID)) {
+
+              remoteAppUser = checkIfRemoteUserExits(userId, app,
+                  applicationsRestClientService);
+
+              if (remoteAppUser == null) {
+                addRemoteUser(roleInAppForUserList, userId, app,
+                    mapper, applicationsRestClientService);
+              }
+              Set<EcompRole> userRolesInRemoteApp = postUsersRolesToRemoteApp(
+                  roleInAppForUserList, mapper,
+                  applicationsRestClientService, appId, userId);
+              RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(
+                  userId, appId,
+                  userRolesInRemoteApp);
+              Set<EcompRole> rolesGotDeletedByApprover = new TreeSet<>();
+              result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser,
+                  epRequestValue, null, false, rolesGotDeletedByApprover, false);
+
+              // If no roles remain, request app to set user inactive.
+              if (userRolesInRemoteApp.size() == 0) {
+                logger.debug(EELFLoggerDelegate.debugLogger,
+                    "setAppWithUserRoleStateForUser: no roles in app {}, set user {} to inactive",
+                    app,
+                    userId);
+                postUserToRemoteApp(userId, app,
+                    applicationsRestClientService);
               }
-              return false;
-       }
-
-       public boolean isUser(FnUser user) {
-              try {
-                     FnUser currentUser = fnUserService.getUser(user.getId()).orElseThrow(Exception::new);
-                     if (currentUser != null && currentUser.getId() != null) {
-                            for (FnUserRole userApp : currentUser.getFnUserRoles()) {
-                                   if (!userApp.getAppId().getId().equals(ECOMP_APP_ID)) {
-                                          FnRole role = userApp.getRoleId();
-                                          if (!role.getId().equals(SYS_ADMIN_ROLE_ID) && !role.getId().equals(ACCOUNT_ADMIN_ROLE_ID)) {
-                                                 if (role.getActiveYn()) {
-                                                        return true;
-                                                 }
-                                          }
-                                   }
-                            }
-                     }
-              } catch (Exception e) {
-                     EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
-                     logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while executing isUser operation", e);
+            }
+          }
+        }
+      } catch (Exception e) {
+        String message = String.format(
+            "Failed to create user or update user roles for User %s, AppId %s",
+            userId, Long.toString(appId));
+        logger.error(EELFLoggerDelegate.errorLogger, message, e);
+        result = false;
+        reqMessage = e.getMessage();
+      }
+    }
+    //return result;
+    return new ExternalRequestFieldsValidator(result, reqMessage);
+
+  }
+
+  private void pushRemoteUser(List<RoleInAppForUser> roleInAppForUserList, String userId, FnApp app,
+      ObjectMapper mapper, ApplicationsRestClientService applicationsRestClientService, boolean appRoleIdUsed)
+      throws Exception {
+    pushUserOnRemoteApp(userId, app, applicationsRestClientService, mapper,
+        roleInAppForUserList, appRoleIdUsed);
+  }
+
+
+  private void postUserToRemoteApp(String userId, FnApp app,
+      ApplicationsRestClientService applicationsRestClientService) throws HTTPException {
+
+    getUser(userId, app, applicationsRestClientService);
+
+  }
+
+  private FnUser getUser(String userId, FnApp app, ApplicationsRestClientService applicationsRestClientService)
+      throws HTTPException {
+    return applicationsRestClientService.get(FnUser.class, app.getId(), String.format("/user/%s", userId), true);
+
+  }
+
+  private void pushUserOnRemoteApp(String userId, FnApp app,
+      ApplicationsRestClientService applicationsRestClientService,
+      ObjectMapper mapper, List<RoleInAppForUser> roleInAppForUserList, boolean appRoleIdUsed)
+      throws Exception {
+
+    FnUser client;
+    client = fnUserService.loadUserByUsername(userId);
+
+    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+    if (client == null) {
+      String msg = "cannot create user " + userId + ", because he/she cannot be found in directory.";
+      logger.error(EELFLoggerDelegate.errorLogger, msg);
+      List<FnUser> userList = fnUserService.getUserWithOrgUserId(userId);
+      if (!userList.isEmpty()) {
+        logger.debug(EELFLoggerDelegate.debugLogger,
+            userList.get(0).getOrgUserId() + " User was found in Portal");
+        client = userList.get(0);
+        client.setUserApps(Collections.EMPTY_SET);
+        client.setIsSystemUser(false);
+      } else {
+        logger.error(EELFLoggerDelegate.errorLogger, "user cannot be found be in directory or in portal");
+        throw new Exception(msg);
+      }
+
+    }
+
+    client.setLoginId(userId);
+    client.setActiveYn(true);
+    client.setOrgUserId(userId);
+
+    roleInAppForUserList.removeIf(role -> role.getIsApplied().equals(false));
+    SortedSet<Role> roles = new TreeSet<>();
+
+    List<FnRole> getAppRoles = fnRoleService.getAppRoles(app.getId());
+    List<FnApp> appList = new ArrayList<>();
+    appList.add(app);
+    List<CentralV2Role> roleList = new ArrayList<>();
+
+    List<FnRole> userRoles = new ArrayList<>();
+
+    for (RoleInAppForUser roleInappForUser : roleInAppForUserList) {
+      FnRole role = new FnRole();
+      role.setId(roleInappForUser.getRoleId());
+      role.setRoleName(roleInappForUser.getRoleName());
+      userRoles.add(role);
+    }
+
+    if (appRoleIdUsed) {
+      List<FnRole> userAppRoles = new ArrayList<>();
+      for (FnRole role : userRoles) {
+        FnRole appRole = getAppRoles.stream()
+            .filter(applicationRole -> role.getId().equals(applicationRole.getAppRoleId())).findAny()
+            .orElse(null);
+        FnRole epRole = new FnRole();
+        if (appRole != null) {
+          epRole.setId(appRole.getId());
+          epRole.setRoleName(appRole.getRoleName());
+        }
+        userAppRoles.add(epRole);
+      }
+      userRoles = new ArrayList<>(userAppRoles);
+    }
+    roleList = externalAccessRolesService.createCentralRoleObject(appList, userRoles, roleList);
+
+    for (CentralV2Role epRole : roleList) {
+      Role role = new Role();
+      FnRole appRole = getAppRoles.stream()
+          .filter(applicationRole -> epRole.getId().equals(applicationRole.getId())).findAny().orElse(null);
+      if (appRole != null) {
+        role.setId(appRole.getAppRoleId());
+        role.setRoleName(epRole.getName());
+        role.setFnRoleFunctions(epRole.getRoleFunctions());
+      }
+      roles.add(role);
+    }
+    client.setRoles(roles.stream().map(this::roleToFnRole).collect(Collectors.toSet()));
+    String userInString;
+    userInString = mapper.writerFor(FnUser.class).writeValueAsString(client);
+    logger.debug(EELFLoggerDelegate.debugLogger,
+        "about to post a client to remote application, users json = " + userInString);
+    applicationsRestClientService.post(FnUser.class, app.getId(), userInString, String.format("/user/%s", userId));
+  }
+
+  private FnRole roleToFnRole(Role role) {
+    return FnRole.builder()
+        .id(role.getId())
+        .roleName(role.getRoleName())
+        .activeYn(role.getActiveYn())
+        .priority(role.getPriority())
+        .fnRoleFunctions(role.getFnRoleFunctions())
+        .childRoles(role.getChildRoles())
+        .parentRoles(role.getParentRoles())
+        .build();
+  }
+
+  private Set<EcompRole> postUsersRolesToRemoteApp(List<RoleInAppForUser> roleInAppForUserList, ObjectMapper mapper,
+      ApplicationsRestClientService applicationsRestClientService, Long appId, String userId)
+      throws JsonProcessingException, HTTPException {
+    Set<EcompRole> updatedUserRolesinRemote = constructUsersRemoteAppRoles(roleInAppForUserList);
+    Set<EcompRole> updateUserRolesInEcomp = constructUsersEcompRoles(roleInAppForUserList);
+    String userRolesAsString = mapper.writeValueAsString(updatedUserRolesinRemote);
+    FnApp externalApp;
+    externalApp = appsCacheService.getApp(appId);
+    String appBaseUri = null;
+    Set<RemoteRoleV1> updatedUserRolesinRemoteV1 = new TreeSet<>();
+    if (externalApp != null) {
+      appBaseUri = externalApp.getAppRestEndpoint();
+    }
+    if (appBaseUri != null && appBaseUri.endsWith("/api")) {
+      for (EcompRole eprole : updatedUserRolesinRemote) {
+        RemoteRoleV1 role = new RemoteRoleV1();
+        role.setId(eprole.getId());
+        role.setName(eprole.getName());
+        updatedUserRolesinRemoteV1.add(role);
+      }
+      userRolesAsString = mapper.writeValueAsString(updatedUserRolesinRemoteV1);
+    }
+    applicationsRestClientService.post(EcompRole.class, appId, userRolesAsString,
+        String.format("/user/%s/roles", userId));
+    return updateUserRolesInEcomp;
+  }
+
+  private void addRemoteUser(List<RoleInAppForUser> roleInAppForUserList, String userId, FnApp app,
+      ObjectMapper mapper, ApplicationsRestClientService applicationsRestClientService) throws Exception {
+    if (remoteUserShouldBeCreated(roleInAppForUserList)) {
+      createNewUserOnRemoteApp(userId, app, applicationsRestClientService, mapper);
+    }
+  }
+
+  private void createNewUserOnRemoteApp(String userId, FnApp app,
+      ApplicationsRestClientService applicationsRestClientService, ObjectMapper mapper)
+      throws Exception {
+
+    FnUser client = fnUserService.loadUserByUsername(userId);
+
+    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+    if (client == null) {
+      String msg = "cannot create user " + userId + ", because he/she cannot be found in phonebook.";
+      logger.error(EELFLoggerDelegate.errorLogger, msg);
+      throw new Exception(msg);
+    }
+
+    client.setLoginId(userId);
+    client.setActiveYn(true);
+
+    String userInString;
+    userInString = mapper.writerFor(FnUser.class).writeValueAsString(client);
+    logger.debug(EELFLoggerDelegate.debugLogger,
+        "about to post new client to remote application, users json = " + userInString);
+    applicationsRestClientService.post(FnUser.class, app.getId(), userInString, String.format("/user", userId));
+
+  }
+
+  private boolean remoteUserShouldBeCreated(List<RoleInAppForUser> roleInAppForUserList) {
+    for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
+      if (roleInAppForUser.getIsApplied()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Set<EcompRole> constructUsersRemoteAppRoles(List<RoleInAppForUser> roleInAppForUserList) {
+    Set<EcompRole> existingUserRoles = new TreeSet<>();
+    for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
+      if (roleInAppForUser.getIsApplied() && !roleInAppForUser.getRoleId()
+          .equals(PortalConstants.ACCOUNT_ADMIN_ROLE_ID)) {
+        EcompRole ecompRole = new EcompRole();
+        ecompRole.setId(roleInAppForUser.getRoleId());
+        ecompRole.setName(roleInAppForUser.getRoleName());
+        existingUserRoles.add(ecompRole);
+      }
+    }
+    return existingUserRoles;
+  }
+
+  private void applyChangesToUserAppRolesForMyLoginsRequest(FnUser user, Long appId) {
+    List<EpUserRolesRequest> epRequestIdVal;
+    try {
+      epRequestIdVal = epUserRolesRequestService.userAppRolesRequestList(user.getId(), appId);
+      if (epRequestIdVal.size() > 0) {
+        EpUserRolesRequest epAppRolesRequestData = epRequestIdVal.get(0);
+        epAppRolesRequestData.setUpdatedDate(LocalDateTime.now());
+        epAppRolesRequestData.setRequestStatus("O");
+        epAppRolesRequestData.setUserId(user);
+        epUserRolesRequestService.saveOne(epAppRolesRequestData);
+        List<EpUserRolesRequestDet> epUserAppRolesDetailList = epUserRolesRequestDetService
+            .appRolesRequestDetailList(epAppRolesRequestData.getReqId());
+        if (epUserAppRolesDetailList.size() > 0) {
+          for (EpUserRolesRequestDet epRequestUpdateList : epUserAppRolesDetailList) {
+            epRequestUpdateList.setRequestType("O");
+            epRequestUpdateList.setReqId(epAppRolesRequestData);
+            epRequestUpdateList.setReqId(epAppRolesRequestData);
+            epUserRolesRequestDetService.saveOne(epRequestUpdateList);
+          }
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "User App roles request from User Page is overridden");
+        }
+      }
+
+    } catch (Exception e) {
+      logger.error(EELFLoggerDelegate.errorLogger, "applyChangesToUserAppRolesRequest failed", e);
+    }
+  }
+
+  private Set<EcompRole> postUsersRolesToLocalApp(List<RoleInAppForUser> roleInAppForUserList) {
+    return constructUsersEcompRoles(roleInAppForUserList);
+  }
+
+  private Set<EcompRole> constructUsersEcompRoles(List<RoleInAppForUser> roleInAppForUserList) {
+    Set<EcompRole> existingUserRoles = new TreeSet<>();
+    for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
+      if (roleInAppForUser.getIsApplied()) {
+        EcompRole ecompRole = new EcompRole();
+        ecompRole.setId(roleInAppForUser.getRoleId());
+        ecompRole.setName(roleInAppForUser.getRoleName());
+        existingUserRoles.add(ecompRole);
+      }
+    }
+    return existingUserRoles;
+  }
+
+  public RolesInAppForUser constructRolesInAppForUserUpdate(String userId, Long appId,
+      Set<EcompRole> userRolesInRemoteApp) {
+    RolesInAppForUser result;
+    result = new RolesInAppForUser();
+    result.setAppId(appId);
+    result.setOrgUserId(userId);
+
+    for (EcompRole role : userRolesInRemoteApp) {
+      RoleInAppForUser roleInAppForUser = new RoleInAppForUser();
+      roleInAppForUser.setRoleId(role.getId());
+      roleInAppForUser.setRoleName(role.getName());
+      roleInAppForUser.setIsApplied(true);
+      result.getRoles().add(roleInAppForUser);
+    }
+    return result;
+  }
+
+  private void updateUserRolesInExternalSystem(FnApp app, String orgUserId, List<RoleInAppForUser> roleInAppUser,
+      boolean isPortalRequest, boolean isSystemUser, Set<EcompRole> deletedRolesByApprover,
+      boolean isLoggedInUserRoleAdminofApp) throws Exception {
+    try {
+      List<FnUser> userInfo = checkIfUserExists(orgUserId);
+      if (userInfo.isEmpty()) {
+        createLocalUserIfNecessary(orgUserId, isSystemUser);
+      }
+      String name;
+      if (EPCommonSystemProperties
+          .containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN)
+          && !isSystemUser) {
+        name = orgUserId
+            + SystemProperties
+            .getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN);
+      } else {
+        name = orgUserId;
+      }
+      ObjectMapper mapper = new ObjectMapper();
+      HttpHeaders headers = EcompPortalUtils.base64encodeKeyForAAFBasicAuth();
+      HttpEntity<String> getUserRolesEntity = new HttpEntity<>(headers);
+      ResponseEntity<String> getResponse = externalAccessRolesService
+          .getUserRolesFromExtAuthSystem(name, getUserRolesEntity);
+
+      List<ExternalAccessUserRoleDetail> userRoleDetailList = new ArrayList<>();
+      String res = getResponse.getBody();
+      JSONObject jsonObj;
+      JSONArray extRoles = null;
+      if (!res.equals("{}")) {
+        jsonObj = new JSONObject(res);
+        extRoles = jsonObj.getJSONArray("role");
+      }
+      ExternalAccessUserRoleDetail userRoleDetail;
+      if (extRoles != null) {
+        for (int i = 0; i < extRoles.length(); i++) {
+          if (extRoles.getJSONObject(i).getString("name").startsWith(app.getAuthNamespace() + ".")
+              && !extRoles.getJSONObject(i).getString("name")
+              .equals(app.getAuthNamespace() + ".admin")
+              && !extRoles.getJSONObject(i).getString("name")
+              .equals(app.getAuthNamespace() + ".owner")) {
+            if (extRoles.getJSONObject(i).has("description")) {
+              ExternalRoleDescription desc = new ExternalRoleDescription(
+                  extRoles.getJSONObject(i).getString("description"));
+              userRoleDetail = new ExternalAccessUserRoleDetail(
+                  extRoles.getJSONObject(i).getString("name"), desc);
+              userRoleDetailList.add(userRoleDetail);
+            } else {
+              userRoleDetail = new ExternalAccessUserRoleDetail(
+                  extRoles.getJSONObject(i).getString("name"), null);
+              userRoleDetailList.add(userRoleDetail);
+            }
+
+          }
+        }
+      }
+
+      List<ExternalAccessUserRoleDetail> userRoleListMatchingInExtAuthAndLocal = checkIfRoleAreMatchingInUserRoleDetailList(
+          userRoleDetailList, app);
+
+      List<EcompUserAppRoles> userAppList;
+      // If request coming from portal not from external role approval system then we have to check if user already
+      // have account admin or system admin as GUI will not send these roles
+      if (!isPortalRequest) {
+        FnUser user = fnUserService.getUserWithOrgUserId(orgUserId).get(0);
+        userAppList = ecompUserAppRolesService.getUserAppExistingRoles(app.getId(), user.getId());
+        if (!roleInAppUser.isEmpty()) {
+          for (EcompUserAppRoles userApp : userAppList) {
+            if (userApp.getRoleId().equals(PortalConstants.SYS_ADMIN_ROLE_ID)
+                || userApp.getRoleId()
+                .equals(PortalConstants.ACCOUNT_ADMIN_ROLE_ID)) {
+              RoleInAppForUser addSpecialRole = new RoleInAppForUser();
+              addSpecialRole.setIsApplied(true);
+              addSpecialRole.setRoleId(userApp.getRoleId());
+              addSpecialRole.setRoleName(userApp.getRoleName());
+              roleInAppUser.add(addSpecialRole);
+            }
+          }
+        }
+      }
+      List<RoleInAppForUser> roleInAppUserNonDupls = roleInAppUser.stream().distinct()
+          .collect(Collectors.toList());
+      Map<String, RoleInAppForUser> currentUserRolesToUpdate = new HashMap<>();
+      for (RoleInAppForUser roleInAppUserNew : roleInAppUserNonDupls) {
+        currentUserRolesToUpdate.put(roleInAppUserNew.getRoleName()
+            .replaceAll(EcompPortalUtils.EXTERNAL_CENTRAL_AUTH_ROLE_HANDLE_SPECIAL_CHARACTERS,
+                "_"), roleInAppUserNew);
+      }
+      final Map<String, ExternalAccessUserRoleDetail> currentUserRolesInExternalSystem = new HashMap<>();
+      for (ExternalAccessUserRoleDetail extAccessUserRole : userRoleListMatchingInExtAuthAndLocal) {
+        currentUserRolesInExternalSystem.put(extAccessUserRole.getName(), extAccessUserRole);
+      }
+
+      if (isLoggedInUserRoleAdminofApp) {
+        if (deletedRolesByApprover.size() > 0) {
+          List<ExternalAccessUserRoleDetail> newUpdatedRoles = new ArrayList<>();
+          for (ExternalAccessUserRoleDetail userRole : userRoleListMatchingInExtAuthAndLocal) {
+            for (EcompRole role : deletedRolesByApprover) {
+              if ((userRole.getName().substring(app.getAuthNamespace().length() + 1))
+                  .equals(role.getName())) {
+                newUpdatedRoles.add(userRole);
+              }
+            }
+          }
+          if (newUpdatedRoles.size() > 0) {
+            userRoleListMatchingInExtAuthAndLocal = new ArrayList<>(newUpdatedRoles);
+          } else {
+            userRoleListMatchingInExtAuthAndLocal = new ArrayList<>();
+            currentUserRolesToUpdate = new HashMap<>();
+
+          }
+
+        } else {
+          userRoleListMatchingInExtAuthAndLocal = new ArrayList<>();
+          currentUserRolesToUpdate = new HashMap<>();
+
+        }
+      }
+
+      // Check if user roles does not exists in local but still there in External Central Auth System delete them all
+      for (ExternalAccessUserRoleDetail userRole : userRoleListMatchingInExtAuthAndLocal) {
+        if (!(currentUserRolesToUpdate
+            .containsKey(userRole.getName().substring(app.getAuthNamespace().length() + 1)))) {
+          HttpEntity<String> entity = new HttpEntity<>(headers);
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "updateUserRolesInExternalSystem: Connecting to external system to DELETE user role {}",
+              userRole.getName());
+          ResponseEntity<String> deleteResponse = template.exchange(
+              SystemProperties
+                  .getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                  + "userRole/" + name + "/" + userRole.getName(),
+              HttpMethod.DELETE, entity, String.class);
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "updateUserRolesInExternalSystem: Finished DELETE operation in external system for user role {} and the response is {}",
+              userRole.getName(), deleteResponse.getBody());
+        }
+      }
+      // Check if user roles does not exists in External Central Auth System add them all
+      for (RoleInAppForUser addUserRole : roleInAppUserNonDupls) {
+        if (!(currentUserRolesInExternalSystem
+            .containsKey(app.getAuthNamespace() + "." + addUserRole.getRoleName().replaceAll(
+                EcompPortalUtils.EXTERNAL_CENTRAL_AUTH_ROLE_HANDLE_SPECIAL_CHARACTERS,
+                "_")))) {
+          ExternalAccessUser extUser = new ExternalAccessUser(name,
+              app.getAuthNamespace() + "." + addUserRole.getRoleName().replaceAll(
+                  EcompPortalUtils.EXTERNAL_CENTRAL_AUTH_ROLE_HANDLE_SPECIAL_CHARACTERS,
+                  "_"));
+          String formattedUserRole = mapper.writeValueAsString(extUser);
+          HttpEntity<String> entity = new HttpEntity<>(formattedUserRole, headers);
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "updateUserRolesInExternalSystem: Connecting to external system for user {} and POST {}",
+              name, addUserRole.getRoleName());
+          ResponseEntity<String> addResponse = template
+              .exchange(SystemProperties
+                  .getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                  + "userRole", HttpMethod.POST, entity, String.class);
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "updateUserRolesInExternalSystem: Finished adding user role in external system {} and added user role {}",
+              addResponse.getBody(), addUserRole.getRoleName());
+          if (addResponse.getStatusCode().value() != 201
+              && addResponse.getStatusCode().value() != 404) {
+            logger.debug(EELFLoggerDelegate.debugLogger,
+                "Finished POST operation in external system but unable to save user role",
+                addResponse.getBody(),
+                addUserRole.getRoleName());
+            throw new Exception(addResponse.getBody());
+          }
+        }
+      }
+    } catch (HttpClientErrorException e) {
+      logger.error(EELFLoggerDelegate.errorLogger,
+          "updateUserRolesInExternalSystem: Failed to add user role for application {} due to {}",
+          app.getId(), e);
+      if (e.getStatusCode() == HttpStatus.FORBIDDEN) {
+        logger.error(EELFLoggerDelegate.errorLogger, "Please enter the valid systemUser",
+            orgUserId);
+        throw new HttpClientErrorException(HttpStatus.FORBIDDEN,
+            "Please enter the valid systemUser");
+      }
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
+        logger.error(EELFLoggerDelegate.errorLogger, "Please enter the valid role");
+        throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Please enter the valid role");
+      }
+      EPLogUtil.logExternalAuthAccessAlarm(logger, HttpStatus.BAD_REQUEST);
+      throw e;
+    } catch (Exception e) {
+      logger.error(EELFLoggerDelegate.errorLogger,
+          "updateUserRolesInExternalSystem: Failed to add user role for application {} due to {}",
+          app.getId(), e);
+      EPLogUtil.logExternalAuthAccessAlarm(logger, HttpStatus.BAD_REQUEST);
+      throw e;
+    }
+  }
+
+  private List<ExternalAccessUserRoleDetail> checkIfRoleAreMatchingInUserRoleDetailList(
+      List<ExternalAccessUserRoleDetail> userRoleDetailList, FnApp app) {
+    Map<String, FnRole> epRoleList = externalAccessRolesService.getAppRoleNamesWithUnderscoreMap(app);
+    //Add Account Admin role for partner app to prevent conflict
+    if (!PortalConstants.PORTAL_APP_ID.equals(app.getId())) {
+      FnRole role = new FnRole();
+      role.setRoleName(PortalConstants.ADMIN_ROLE
+          .replaceAll(EcompPortalUtils.EXTERNAL_CENTRAL_AUTH_ROLE_HANDLE_SPECIAL_CHARACTERS, "_"));
+      epRoleList.put(role.getRoleName(), role);
+    }
+    userRoleDetailList.removeIf(
+        userRoleDetail -> !epRoleList
+            .containsKey(userRoleDetail.getName().substring(app.getAuthNamespace().length() + 1)));
+    return userRoleDetailList;
+  }
+
+  private List<FnUser> checkIfUserExists(String userParams) {
+    return fnUserService.getUserWithOrgUserId(userParams);
+  }
+
+  @Transactional
+  private void createLocalUserIfNecessary(String userId, boolean isSystemUser) {
+    if (StringUtils.isEmpty(userId)) {
+      logger.error(EELFLoggerDelegate.errorLogger, "createLocalUserIfNecessary : empty userId!");
+      return;
+    }
+    try {
+      List<FnUser> userList = fnUserService.getUserWithOrgUserId(userId);
+      if (userList.size() == 0) {
+        FnUser client;
+        if (!isSystemUser) {
+          client = fnUserService.loadUserByUsername(userId);
+        } else {
+          client = new FnUser();
+          client.setOrgUserId(userId);
+          client.setIsSystemUser(true);
+          client.setFirstName(userId.substring(0, userId.indexOf("@")));
+        }
+        if (client == null) {
+          String msg = "createLocalUserIfNecessary: cannot create user " + userId
+              + ", because not found in phonebook";
+          logger.error(EELFLoggerDelegate.errorLogger, msg);
+        } else {
+          client.setLoginId(userId);
+          client.setActiveYn(true);
+        }
+        fnUserService.saveFnUser(client);
+      }
+    } catch (Exception e) {
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+    }
+
+  }
+
+  private FnUser checkIfRemoteUserExits(String userId, FnApp app,
+      ApplicationsRestClientService applicationsRestClientService) throws HTTPException {
+    FnUser checkRemoteUser = null;
+    try {
+      checkRemoteUser = getUserFromApp(userId, app, applicationsRestClientService);
+    } catch (HTTPException e) {
+      // Some apps are returning 400 if user is not found.
+      if (e.getResponseCode() == 400) {
+        logger.debug(EELFLoggerDelegate.debugLogger,
+            "setAppWithUserRoleStateForUser: getuserFromApp threw exception with response code 400; continuing",
+            e);
+      } else if (e.getResponseCode() == 404) {
+        logger.debug(EELFLoggerDelegate.debugLogger,
+            "setAppWithUserRoleStateForUser: getuserFromApp threw exception with response code 404; continuing",
+            e);
+      } else {
+        // Other response code, let it come thru.
+        throw e;
+      }
+    }
+    return checkRemoteUser;
+  }
+
+  private FnUser getUserFromApp(String userId, FnApp app, ApplicationsRestClientService applicationsRestClientService)
+      throws HTTPException {
+    if (PortalConstants.PORTAL_APP_ID.equals(app.getId())) {
+      List<FnUser> userList = fnUserService.getUserWithOrgUserId(userId);
+      if (userList != null && !userList.isEmpty()) {
+        return userList.get(0);
+      } else {
+        return null;
+      }
+    }
+    return getUser(userId, app, applicationsRestClientService);
+  }
+
+  private boolean applyChangesInUserRolesForAppToEcompDB(RolesInAppForUser rolesInAppForUser,
+      boolean externalSystemRequest, String reqType, boolean isSystemUser,
+      Set<EcompRole> rolesDeletedByApprover, boolean isLoggedInUserRoleAdminOfApp) throws Exception {
+    boolean result = false;
+    String userId = rolesInAppForUser.getOrgUserId();
+    Long appId = rolesInAppForUser.getAppId();
+    synchronized (syncRests) {
+      createLocalUserIfNecessary(userId, isSystemUser);
+
+      EcompRole[] userAppRoles = new EcompRole[(int) rolesInAppForUser.getRoles().stream().distinct().count()];
+      for (int i = 0;
+          i < rolesInAppForUser.getRoles().stream().distinct().count(); i++) {
+        RoleInAppForUser roleInAppForUser = rolesInAppForUser.getRoles().get(i);
+        EcompRole role = new EcompRole();
+        role.setId(roleInAppForUser.getRoleId());
+        role.setName(roleInAppForUser.getRoleName());
+        userAppRoles[i] = role;
+      }
+      try {
+        EcompRole[] applicationRoles = null;
+
+        if (isLoggedInUserRoleAdminOfApp) {
+          List<EcompRole> roles = Arrays.stream(userAppRoles)
+              .collect(Collectors.toList());
+          List<EcompRole> roles1 = new ArrayList<>(rolesDeletedByApprover);
+          roles.addAll(roles1);
+          applicationRoles = roles.toArray(new EcompRole[0]);
+        }
+
+        syncUserRoles(userId, appId, userAppRoles, externalSystemRequest,
+            reqType, isLoggedInUserRoleAdminOfApp, applicationRoles);
+        result = true;
+      } catch (Exception e) {
+        logger.error(EELFLoggerDelegate.errorLogger,
+            "applyChangesInUserRolesForAppToEcompDB: failed to syncUserRoles for orgUserId "
+                + userId, e);
+        if ("DELETE".equals(reqType)) {
+          throw new Exception(e.getMessage());
+        }
+      }
+    }
+    return result;
+  }
+
+  private void syncUserRoles(String userId, Long appId,
+      EcompRole[] userAppRoles, Boolean extRequestValue, String reqType, boolean checkIfUserisRoleAdmin,
+      EcompRole[] appRoles) throws Exception {
+
+    Transaction transaction = null;
+    String roleActive;
+    HashMap<Long, EcompRole> newUserAppRolesMap = hashMapFromEcompRoles(userAppRoles);
+    List<FnRole> roleInfo = externalAccessRolesService
+        .getPortalAppRoleInfo(PortalConstants.ACCOUNT_ADMIN_ROLE_ID);
+    FnRole adminRole = new FnRole();
+    if (roleInfo.size() > 0) {
+      adminRole = roleInfo.get(0);
+      logger.debug(EELFLoggerDelegate.debugLogger, "Admin RoleName form DB: " + adminRole.getRoleName());
+    }
+    try {
+      List<FnUser> userList = fnUserService.getUserWithOrgUserId(userId);
+      if (userList.size() > 0) {
+        FnUser client = userList.get(0);
+        roleActive = ("DELETE".equals(reqType)) ? "" : " and role.active = 'Y'";
+        List<FnUserRole> userRoles = fnUserRoleService.retrieveByAppIdAndUserId(appId, userId);
+        entityManager
+            .createQuery("from EPUserApp where app.id=:appId and userId=:userId" + roleActive)
+            .setParameter("appId", appId)
+            .setParameter("userId", client.getId())
+            .getResultList();
+
+        if ("DELETE".equals(reqType)) {
+          for (FnUserRole userAppRoleList : userRoles) {
+            List<FnRole> rolesList =
+                (!userAppRoleList.getRoleId().getRoleName()
+                    .equals(adminRole.getRoleName()))
+                    ? fnRoleService.retrieveAppRolesByRoleNameAndByAppId
+                    (userAppRoleList.getRoleId().getRoleName(), appId)
+                    : fnRoleService.retrieveAppRolesWhereAppIdIsNull();
+            if (!rolesList.isEmpty()) {
+              checkIfRoleInactive(rolesList.get(0));
+            }
+          }
+        }
+
+        if (appRoles != null) {
+          List<EcompRole> appRolesList = Arrays.stream(appRoles).collect(Collectors.toList());
+          List<FnUserRole> finalUserRolesList = new ArrayList<>();
+          if (checkIfUserisRoleAdmin) {
+            for (EcompRole role : appRolesList) {
+              for (FnUserRole userAppRoleList : userRoles) {
+                if (userAppRoleList.getRoleId().getRoleName()
+                    .equals(role.getName())) {
+                  finalUserRolesList.add(userAppRoleList);
+                }
+
+              }
+            }
+            userRoles = new ArrayList<>(finalUserRolesList);
+          }
+        }
+
+        for (FnUserRole userRole : userRoles) {
+          if (!PortalConstants.ACCOUNT_ADMIN_ROLE_ID.equals(userRole.getRoleId().getId())
+              && !PortalConstants.SYS_ADMIN_ROLE_ID
+              .equals(userRole.getRoleId().getId())
+              && !extRequestValue) {
+            syncUserRolesExtension(userRole, appId,
+                newUserAppRolesMap);
+          } else if (extRequestValue && ("PUT".equals(reqType) || "POST".equals(reqType)
+              || "DELETE".equals(reqType))) {
+            syncUserRolesExtension(userRole, appId,
+                newUserAppRolesMap);
+          } else if (extRequestValue && !PortalConstants.ACCOUNT_ADMIN_ROLE_ID
+              .equals(userRole.getRoleId().getId())) {
+            syncUserRolesExtension(userRole, appId,
+                newUserAppRolesMap);
+          }
+        }
+
+        Collection<EcompRole> newRolesToAdd = newUserAppRolesMap.values();
+        if (newRolesToAdd.size() > 0) {
+          FnApp app = fnAppService.getById(appId);
+
+          HashMap<Long, FnRole> rolesMap = new HashMap<>();
+          if (appId.equals(PortalConstants.PORTAL_APP_ID)) { // local app
+            String appIdValue = "";
+            if (!extRequestValue) {
+              appIdValue = "and id != " + PortalConstants.SYS_ADMIN_ROLE_ID;
+            }
+            @SuppressWarnings("unchecked")
+            List<FnRole> roles = entityManager
+                .createQuery(
+                    "from " + FnRole.class.getName() + " where appId is null "
+                        + appIdValue).getResultList();
+            for (FnRole role : roles) {
+              role.setAppId(1L);
+              rolesMap.put(role.getId(), role);
+            }
+          } else { // remote app
+            @SuppressWarnings("unchecked")
+            List<FnRole> roles = entityManager
+                .createQuery("from EPRole where appId=:appId")
+                .setParameter("appId", appId)
+                .getResultList();
+            for (FnRole role : roles) {
+              if (!extRequestValue && app.getAuthCentral()) {
+                rolesMap.put(role.getId(), role);
+              } else {
+                rolesMap.put(role.getAppRoleId(), role);
+              }
+            }
+          }
+
+          FnRole role;
+          for (EcompRole userRole : newRolesToAdd) {
+            FnUserRole userApp = new FnUserRole();
+            if (("PUT".equals(reqType) || "POST".equals(reqType)) && userRole.getName()
+                .equals(adminRole.getRoleName())) {
+              role = fnRoleService.getById(PortalConstants.ACCOUNT_ADMIN_ROLE_ID);
+              userApp.setRoleId(role);
+            } else if ((userRole.getId().equals(PortalConstants.ACCOUNT_ADMIN_ROLE_ID))
+                && !extRequestValue) {
+              continue;
+            } else if ((userRole.getId().equals(PortalConstants.SYS_ADMIN_ROLE_ID)) && app
+                .getId().equals(PortalConstants.PORTAL_APP_ID) && !extRequestValue) {
+              continue;
+            } else {
+              userApp.setRoleId(rolesMap.get(userRole.getId()));
+            }
+
+            userApp.setUserId(client);
+            userApp.setFnAppId(app);
+            fnUserRoleService.saveOne(userApp);
+          }
+
+          if (PortalConstants.PORTAL_APP_ID.equals(appId)) {
+            /*
+             * for local app -- hack - always make sure fn_role
+             * table's app_id is null and not 1 for primary app in
+             * this case being onap portal app; reason: hibernate
+             * is rightly setting this to 1 while persisting to
+             * fn_role as per the mapping but SDK role management
+             * code expects the app_id to be null as there is no
+             * concept of App_id in SDK
+             */
+            Query query = entityManager.createQuery("update fn_role set app_id = null where app_id = 1 ");
+            query.executeUpdate();
+          }
+        }
+      }
+      transaction.commit();
+    } catch (Exception e) {
+      logger.error(EELFLoggerDelegate.errorLogger, "syncUserRoles failed", e);
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      EcompPortalUtils.rollbackTransaction(transaction,
+          "Exception occurred in syncUserRoles, Details: " + e.toString());
+      if ("DELETE".equals(reqType)) {
+        throw new SyncUserRolesException(e.getMessage());
+      }
+    }
+  }
+
+  private static HashMap<Long, EcompRole> hashMapFromEcompRoles(EcompRole[] ecompRoles) {
+    HashMap<Long, EcompRole> result = new HashMap<>();
+    if (ecompRoles != null) {
+      for (EcompRole ecompRole : ecompRoles) {
+        if (ecompRole.getId() != null) {
+          result.put(ecompRole.getId(), ecompRole);
+        }
+      }
+    }
+    return result;
+  }
+
+  private void syncUserRolesExtension(FnUserRole userRole, Long appId,
+      HashMap<Long, EcompRole> newUserAppRolesMap) {
+
+    Long userAppRoleId;
+    if (PortalConstants.PORTAL_APP_ID.equals(appId)) { // local app
+      userAppRoleId = userRole.getRoleId().getId();
+    } else { // remote app
+      userAppRoleId = userRole.getId();
+    }
+
+    if (!newUserAppRolesMap.containsKey(userAppRoleId)) {
+      fnUserRoleService.deleteById(userRole.getId());
+    } else {
+      newUserAppRolesMap.remove(userAppRoleId);
+    }
+  }
+
+  private Role fnRoleToRole(final FnRole role) {
+    return new Role(null, null, null, null, null, null, null, null, null, role.getRoleName(), null, role.getActiveYn(),
+        role.getPriority(), role.getFnRoleFunctions(), role.getChildRoles(), role.getParentRoles());
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<RoleInAppForUser> getAppRolesForUser(Long appId, String orgUserId, Boolean extRequestValue, Long userId) {
+    List<RoleInAppForUser> rolesInAppForUser = null;
+    FnApp app = fnAppService.getById(appId);
+    logger.debug(EELFLoggerDelegate.debugLogger, "In getAppRolesForUser() - app = {}", app);
+    try {
+      // for onap portal app, no need to make a remote call
+      List<Role> roleList = new ArrayList<>();
+      if (!PortalConstants.PORTAL_APP_ID.equals(appId)) {
+        if (app.getAuthCentral()) {
+          List<CentralV2Role> cenRoleList = externalAccessRolesService.getRolesForApp(app.getUebKey());
+          for (CentralV2Role cenRole : cenRoleList) {
+            Role role = new Role();
+            role.setActiveYn(cenRole.isActive());
+            role.setId(cenRole.getId());
+            role.setRoleName(cenRole.getName());
+            role.setPriority(cenRole.getPriority());
+            roleList.add(role);
+          }
+        } else {
+          Optional<FnUser> user = fnUserService.getUser(userId);
+          if (user.isPresent()) {
+            roleList = user.get().getFnRoles().stream().map(this::fnRoleToRole).collect(Collectors.toList());
+          }
+        }
+        List<Role> activeRoleList = new ArrayList<>();
+        for (Role role : roleList) {
+          if (role.getActiveYn()) {
+            if (role.getId() != 1) { // prevent portal admin from being added
+              activeRoleList.add(role);
+            } else if (extRequestValue) {
+              activeRoleList.add(role);
+            }
+          }
+
+        }
+        FnUser localUser = getUserFromApp(Long.toString(userId), app, applicationsRestClientService);
+        // If localUser does not exists return roles
+        Set<FnRole> roleSet = null;
+        FnRole[] roleSetList = null;
+        if (localUser != null) {
+          roleSet = localUser.getAppEPRoles(app);
+          roleSetList = roleSet.toArray(new FnRole[0]);
+        }
+        rolesInAppForUser = fnUserRoleService
+            .constructRolesInAppForUserGet(activeRoleList, roleSetList, extRequestValue);
+        return rolesInAppForUser;
+      }
+
+      EcompRole[] appRoles = null;
+      boolean checkIfUserIsApplicationAccAdmin = false;
+      List<EcompRole> roles = new ArrayList<>();
+      if (app.getAuthCentral()) {
+        List<FnRole> applicationRoles = fnRoleService.retrieveActiveRolesOfApplication(app.getId());
+        FnApp application = fnAppService.getById(appId);
+        checkIfUserIsApplicationAccAdmin = isAccountAdminOfApplication(userId,
+            application);
+
+        List<FnRole> roleSetWithFunctioncds = new ArrayList<>();
+        for (FnRole role : applicationRoles) {
+          List<EpAppFunction> cenRoleFuncList = epAppFunctionService.getAppRoleFunctionList(role.getId(), app.getId());
+          for (EpAppFunction roleFunc : cenRoleFuncList) {
+
+            String functionCode = EcompPortalUtils.getFunctionCode(roleFunc.getFunctionCd());
+            functionCode = EPUserUtils.decodeFunctionCode(functionCode);
+            String type = externalAccessRolesService.getFunctionCodeType(roleFunc.getFunctionCd());
+            String action = externalAccessRolesService.getFunctionCodeAction(roleFunc.getFunctionCd());
+            String name = roleFunc.getFunctionName();
+
+            FnFunction function = new FnFunction();
+            function.setAction(action);
+            function.setType(type);
+            function.setCode(functionCode);
+            function.setName(name);
+            role.getFnRoleFunctions().add(new FnRoleFunction(role, function));
+
+          }
+          roleSetWithFunctioncds.add(role);
+
+
+        }
+
+        for (FnRole role1 : roleSetWithFunctioncds) {
+          EcompRole ecompRole = new EcompRole();
+          ecompRole.setId(role1.getId());
+          ecompRole.setName(role1.getRoleName());
+          ecompRole.setRoleFunctions(role1.getRoleFunctions());
+          roles.add(ecompRole);
+
+        }
+        if (checkIfUserIsApplicationAccAdmin) {
+          appRoles = roles.toArray(new EcompRole[roles.size()]);
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "In getAppRolesForUser() If Logged in user checkIfUserisApplicationAccAdmin- appRoles = {}", appRoles);
+        } else if (isRoleAdmin(userId) && !checkIfUserIsApplicationAccAdmin) {
+          List<EcompRole> roleAdminAppRoles = new ArrayList<>();
+          List<String> roleAdminAppRolesNames = new ArrayList<>();
+          String QUERY =
+              "select distinct fr.role_name as roleName from fn_user_role fu, ep_app_role_function ep, ep_app_function ea, fn_role fr"
+                  + " where fu.role_id = ep.role_id"
+                  + " and fu.app_id = ep.app_id"
+                  + " and fu.user_id = :userId"
+                  + " and fu.role_id = fr.role_id and fr.active_yn='Y'"
+                  + " and ea.function_cd = ep.function_cd and ea.function_cd like 'approver|%'"
+                  + " and exists"
+                  + " ("
+                  + " select fa.app_id from fn_user fu, fn_user_role ur, fn_app fa where fu.user_id =:userId and fu.user_id = ur.user_id"
+                  + " and ur.app_id = fa.app_id and fa.enabled = 'Y')";
+          List<Tuple> tuples = entityManager.createNativeQuery(QUERY, Tuple.class)
+              .setParameter("userId", userId)
+              .getResultList();
+          List<String> getUserApproverRoles = tuples.stream().map(tuple -> (String) tuple.get("roleName"))
+              .collect(Collectors.toList());
+
+          List<EcompRole> userapproverRolesList = new ArrayList<>();
+          for (String str : getUserApproverRoles) {
+            EcompRole epRole = roles.stream().filter(x -> str.equals(x.getName())).findAny().orElse(null);
+            if (epRole != null) {
+              userapproverRolesList.add(epRole);
+            }
+          }
+          for (EcompRole role : userapproverRolesList) {
+
+            List<RoleFunction> roleFunList = new ArrayList<>(role.getRoleFunctions());
+            boolean checkIfFunctionsExits = roleFunList.stream()
+                .anyMatch(roleFunction -> roleFunction.getType().equalsIgnoreCase("Approver"));
+            if (checkIfFunctionsExits) {
+              roleAdminAppRoles.add(role);
+              List<RoleFunction> filteredList = roleFunList.stream()
+                  .filter(x -> "Approver".equalsIgnoreCase(x.getType())).collect(Collectors.toList());
+              roleAdminAppRolesNames.addAll(filteredList.stream().map(RoleFunction::getCode)
+                  .collect(Collectors.toList()));
+            }
+          }
+          for (String name : roleAdminAppRolesNames) {
+            roles.stream().filter(x -> name.equals(x.getName())).findAny().ifPresent(roleAdminAppRoles::add);
+
+          }
+          appRoles = roleAdminAppRoles.toArray(new EcompRole[0]);
+
+        }
+      } else {
+        appRoles = applicationsRestClientService.get(EcompRole[].class, appId, "/roles");
+      }
+      // Test this error case, for generating an internal ONAP Portal
+      // error
+      // EcompRole[] appRoles = null;
+      // If there is an exception in the rest client api, then null will
+      // be returned.
+      if (appRoles != null) {
+        if (!app.getAuthCentral()) {
+          syncAppRoles(appId, appRoles);
+        }
+        EcompRole[] userAppRoles = null;
+        try {
+          try {
+            if (app.getAuthCentral()) {
+              List<FnUser> actualUser = fnUserService.getUserWithOrgUserId(Long.toString(userId));
+              List<EPUserAppCurrentRoles> userAppsRolesList = entityManager
+                  .createNamedQuery("EPUserAppCurrentRoles")
+                  .setParameter("appId", app.getId())
+                  .setParameter("userId", actualUser.get(0).getId())
+                  .getResultList();
+              List<EcompRole> setUserRoles = new ArrayList<>();
+              for (EPUserAppCurrentRoles role : userAppsRolesList) {
+                logger.debug(EELFLoggerDelegate.debugLogger,
+                    "In getAppRolesForUser() - userAppsRolesList get userRolename = {}", role.getRoleName());
+                EcompRole ecompRole = new EcompRole();
+                ecompRole.setId(role.getRoleId());
+                ecompRole.setName(role.getRoleName());
+                setUserRoles.add(ecompRole);
+              }
+
+              boolean checkIfUserisAccAdmin = setUserRoles.stream()
+                  .anyMatch(ecompRole -> ecompRole.getId() == 999L);
+
+              if (!checkIfUserisAccAdmin) {
+                List<EcompRole> appRolesList = Arrays.asList(appRoles);
+                Set<EcompRole> finalUserAppRolesList = new HashSet<>();
+
+                List<String> roleNames = new ArrayList<>();
+                for (EcompRole role : setUserRoles) {
+                  EcompRole epRole = appRolesList.stream()
+                      .filter(x -> role.getName().equals(x.getName())).findAny().orElse(null);
+                  List<RoleFunction> roleFunList = new ArrayList<>();
+
+                  if (epRole != null) {
+                    if (epRole.getRoleFunctions().size() > 0) {
+                      roleFunList.addAll(epRole.getRoleFunctions());
+                    }
+                    boolean checkIfFunctionsExits = roleFunList.stream().anyMatch(
+                        roleFunction -> roleFunction.getType().equalsIgnoreCase("Approver"));
+                    if (checkIfFunctionsExits) {
+                      finalUserAppRolesList.add(role);
+                      List<RoleFunction> filteredList = roleFunList.stream()
+                          .filter(x -> "Approver".equalsIgnoreCase(x.getType()))
+                          .collect(Collectors.toList());
+                      roleNames = filteredList.stream().map(RoleFunction::getCode)
+                          .collect(Collectors.toList());
+                    } else {
+                      roleNames.add(epRole.getName());
+                    }
+                  }
+                  for (String name : roleNames) {
+                    EcompRole ecompRole = appRolesList.stream()
+                        .filter(x -> name.equals(x.getName())).findAny().orElse(null);
+                    if (ecompRole != null) {
+                      finalUserAppRolesList.add(ecompRole);
+                    }
+                  }
+                }
+                for (String name : roleNames) {
+                  boolean checkIfFunctionsExits = userAppsRolesList.stream().anyMatch(
+                      role -> role.getRoleName().equalsIgnoreCase(name));
+                  if (checkIfFunctionsExits) {
+                    appRolesList.stream().filter(x -> name.equals(x.getName()))
+                        .findAny().ifPresent(setUserRoles::add);
+                  }
+                }
+                userAppRoles = setUserRoles.toArray(new EcompRole[0]);
+              }
+            } else {
+              userAppRoles = applicationsRestClientService.get(EcompRole[].class, appId,
+                  String.format("/user/%s/roles", userId));
+            }
+          } catch (HTTPException e) {
+            // Some apps are returning 400 if user is not found.
+            if (e.getResponseCode() == 400) {
+              logger.debug(EELFLoggerDelegate.debugLogger,
+                  "getAppRolesForUser caught exception with response code 400; continuing", e);
+            } else {
+              // Other response code, let it come thru.
+              throw e;
+            }
+          }
+          if (userAppRoles == null) {
+            if (EcompPortalUtils.getExternalAppResponseCode() == 400) {
+              EcompPortalUtils.setExternalAppResponseCode(200);
+              String message = String.format(
+                  "getAppRolesForUser: App %s, User %, endpoint /user/{userid}/roles returned 400, "
+                      + "assuming user doesn't exist, app is framework SDK based, and things are ok. "
+                      + "Overriding to 200 until framework SDK returns a useful response.",
+                  Long.toString(appId), userId);
+              logger.warn(EELFLoggerDelegate.applicationLogger, message);
+            }
+          }
+
+          HashMap<Long, EcompRole> appRolesActiveMap = hashMapFromEcompRoles(appRoles);
+          ArrayList<EcompRole> activeRoles = new ArrayList<>();
+          if (userAppRoles != null) {
+            for (EcompRole userAppRole : userAppRoles) {
+              if (appRolesActiveMap.containsKey(userAppRole.getId())) {
+                EcompRole role = new EcompRole();
+                role.setId(userAppRole.getId());
+                role.setName(userAppRole.getName());
+                activeRoles.add(role);
+              }
+            }
+          }
+          EcompRole[] userAppRolesActive = activeRoles.toArray(new EcompRole[0]);
+
+          boolean checkIfUserisRoleAdmin = isRoleAdmin(userId) && !checkIfUserIsApplicationAccAdmin;
+
+          // If the remote application isn't down we MUST sync user
+          // roles here in case we have this user here!
+          syncUserRoles(Long.toString(userId), appId, userAppRolesActive, extRequestValue, null, checkIfUserisRoleAdmin,
+              appRoles);
+        } catch (Exception e) {
+          // TODO: we may need to check if user exists, maybe remote
+          // app is down.
+          String message = String.format(
+              "getAppRolesForUser: user %s does not exist in remote application %s", userId,
+              Long.toString(appId));
+          logger.error(EELFLoggerDelegate.errorLogger, message, e);
+          userAppRoles = new EcompRole[0];
+        }
+        rolesInAppForUser = fnUserRoleService.constructRolesInAppForUserGet(appRoles, userAppRoles);
+      }
+    } catch (Exception e) {
+      String message = String.format("getAppRolesForUser: failed for User %s, AppId %s", userId,
+          Long.toString(appId));
+      logger.error(EELFLoggerDelegate.errorLogger, message, e);
+    }
+    return rolesInAppForUser;
+  }
+
+  private void syncAppRoles(Long appId, EcompRole[] appRoles) throws Exception {
+    logger.debug(EELFLoggerDelegate.debugLogger, "entering syncAppRoles for appId: " + appId);
+    HashMap<Long, EcompRole> newRolesMap = hashMapFromEcompRoles(appRoles);
+    try {
+      List<FnRole> currentAppRoles = fnRoleService.retrieveAppRolesByAppId(appId);
+
+      List<FnRole> obsoleteRoles = new ArrayList<>();
+      for (FnRole oldAppRole : currentAppRoles) {
+        if (oldAppRole.getAppRoleId() != null) {
+          EcompRole role;
+          role = newRolesMap.get(oldAppRole.getAppRoleId());
+          if (role != null) {
+            if (!(role.getName() == null || oldAppRole.getRoleName().equals(role.getName()))) {
+              oldAppRole.setRoleName(role.getName());
+            }
+            oldAppRole.setActiveYn(true);
+            newRolesMap.remove(oldAppRole.getAppRoleId());
+          } else {
+            obsoleteRoles.add(oldAppRole);
+          }
+        } else {
+          obsoleteRoles.add(oldAppRole);
+        }
+      }
+      Collection<EcompRole> newRolesToAdd = newRolesMap.values();
+      if (obsoleteRoles.size() > 0) {
+        logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: we have obsolete roles to delete");
+        for (FnRole role : obsoleteRoles) {
+          logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: obsolete role: " + role.toString());
+          Long roleId = role.getId();
+          List<FnUserRole> userRoles = fnUserRoleService.getUserRolesForRoleIdAndAppId(roleId, appId);
+
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "syncAppRoles: number of userRoles to delete: " + userRoles.size());
+          for (FnUserRole userRole : userRoles) {
+            logger.debug(EELFLoggerDelegate.debugLogger,
+                "syncAppRoles: about to delete userRole: " + userRole.toString());
+            fnUserRoleService.deleteById(userRole.getId());
+            logger.debug(EELFLoggerDelegate.debugLogger,
+                "syncAppRoles: finished deleting userRole: " + userRole.toString());
+          }
+          List<FnMenuFunctionalRoles> funcMenuRoles = fnMenuFunctionalRolesService.retrieveByroleId(roleId);
+          int numMenuRoles = funcMenuRoles.size();
+          logger.debug(EELFLoggerDelegate.debugLogger,
+              "syncAppRoles: number of funcMenuRoles for roleId: " + roleId + ": " + numMenuRoles);
+          for (FnMenuFunctionalRoles funcMenuRole : funcMenuRoles) {
+            Long menuId = funcMenuRole.getMenuId().getMenuId();
+            // If this is the only role for this menu item, then the
+            // app and roles will be gone,
+            // so must null out the url too, to be consistent
+            List<FnMenuFunctionalRoles> funcMenuRoles2 = fnMenuFunctionalRolesService.retrieveByMenuId(menuId);
+            int numMenuRoles2 = funcMenuRoles2.size();
+            logger.debug(EELFLoggerDelegate.debugLogger,
+                "syncAppRoles: number of funcMenuRoles for menuId: " + menuId + ": " + numMenuRoles2);
+            fnMenuFunctionalRolesService.delete(funcMenuRole);
+
+            if (numMenuRoles2 == 1) {
+              // If this is the only role for this menu item, then
+              // the app and roles will be gone,
+              // so must null out the url too, to be consistent
+              logger.debug(EELFLoggerDelegate.debugLogger,
+                  "syncAppRoles: There is exactly 1 menu item for this role, so emptying the url");
+              List<FnMenuFunctional> funcMenuItems = fnMenuFunctionalService.retrieveByMenuId(menuId);
+              if (funcMenuItems.size() > 0) {
+                logger.debug(EELFLoggerDelegate.debugLogger, "got the menu item");
+                FnMenuFunctional funcMenuItem = funcMenuItems.get(0);
+                funcMenuItem.setUrl("");
+              }
+            }
+          }
+          boolean isPortalRequest = true;
+          deleteRoleDependencyRecords(roleId, appId, isPortalRequest);
+          logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: about to delete the role: " + role.toString());
+          fnRoleService.delete(role);
+          logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: deleted the role");
+        }
+      }
+      for (EcompRole role : newRolesToAdd) {
+        logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: about to add missing role: " + role.toString());
+        FnRole newRole = new FnRole();
+        // Attention! All roles from remote application supposed to be
+        // active!
+        newRole.setActiveYn(true);
+        newRole.setRoleName(role.getName());
+        newRole.setAppId(appId);
+        newRole.setAppRoleId(role.getId());
+        fnRoleService.saveOne(newRole);
+      }
+      logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: about to commit the transaction");
+      logger.debug(EELFLoggerDelegate.debugLogger, "syncAppRoles: committed the transaction");
+    } catch (Exception e) {
+      logger.error(EELFLoggerDelegate.errorLogger, "syncAppRoles failed", e);
+      EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoSystemError, e);
+      throw new Exception(e);
+    }
+  }
+
+  private void deleteRoleDependencyRecords(Long roleId, Long appId, boolean isPortalRequest)
+      throws Exception {
+    Session localSession = entityManager.unwrap(Session.class);
+    try {
+      String sql;
+      Query query;
+      // It should delete only when it portal's roleId
+      if (appId.equals(PortalConstants.PORTAL_APP_ID)) {
+        // Delete from fn_role_function
+        sql = "DELETE FROM fn_role_function WHERE role_id=" + roleId;
+        logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+        query = localSession.createSQLQuery(sql);
+        query.executeUpdate();
+        // Delete from fn_role_composite
+        sql = "DELETE FROM fn_role_composite WHERE parent_role_id=" + roleId + " OR child_role_id=" + roleId;
+        logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+        query = localSession.createSQLQuery(sql);
+        query.executeUpdate();
+      }
+      // Delete from ep_app_role_function
+      sql = "DELETE FROM ep_app_role_function WHERE role_id=" + roleId;
+      logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+      query = localSession.createSQLQuery(sql);
+      query.executeUpdate();
+      // Delete from ep_role_notification
+      sql = "DELETE FROM ep_role_notification WHERE role_id=" + roleId;
+      logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+      query = localSession.createSQLQuery(sql);
+      query.executeUpdate();
+      // Delete from fn_user_pseudo_role
+      sql = "DELETE FROM fn_user_pseudo_role WHERE pseudo_role_id=" + roleId;
+      logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+      query = localSession.createSQLQuery(sql);
+      query.executeUpdate();
+      // Delete form EP_WIDGET_CATALOG_ROLE
+      sql = "DELETE FROM EP_WIDGET_CATALOG_ROLE WHERE role_id=" + roleId;
+      logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+      query = localSession.createSQLQuery(sql);
+      query.executeUpdate();
+      // Delete form EP_WIDGET_CATALOG_ROLE
+      sql = "DELETE FROM ep_user_roles_request_det WHERE requested_role_id=" + roleId;
+      logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+      query = localSession.createSQLQuery(sql);
+      query.executeUpdate();
+      if (!isPortalRequest) {
+        // Delete form fn_menu_functional_roles
+        sql = "DELETE FROM fn_menu_functional_roles WHERE role_id=" + roleId;
+        logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
+        query = localSession.createSQLQuery(sql);
+        query.executeUpdate();
+      }
+    } catch (Exception e) {
+      logger.debug(EELFLoggerDelegate.debugLogger, "deleteRoleDependeciesRecord: failed ", e);
+      throw new DeleteDomainObjectFailedException("delete Failed" + e.getMessage());
+    }
+  }
+
+  private void checkIfRoleInactive(FnRole epRole) throws Exception {
+    if (!epRole.getActiveYn()) {
+      throw new Exception(epRole.getRoleName() + " role is unavailable");
+    }
+  }
+
+  public boolean setAppsWithAdminRoleStateForUser(AppsListWithAdminRole newAppsListWithAdminRoles) {
+    boolean result = false;
+    // No changes if no new roles list or no userId.
+    if (!org.apache.cxf.common.util.StringUtils.isEmpty(newAppsListWithAdminRoles.getOrgUserId())
+        && newAppsListWithAdminRoles.getAppsRoles() != null) {
+      synchronized (syncRests) {
+        List<FnApp> apps = fnAppService.getAppsFullList();
+        HashMap<Long, FnApp> enabledApps = new HashMap<>();
+        for (FnApp app : apps) {
+          enabledApps.put(app.getId(), app);
+        }
+        List<AppNameIdIsAdmin> newAppsWhereUserIsAdmin = new ArrayList<>();
+        for (AppNameIdIsAdmin adminRole : newAppsListWithAdminRoles.getAppsRoles()) {
+          // user Admin role may be added only for enabled apps
+          if (adminRole.getIsAdmin() && enabledApps.containsKey(adminRole.getId())) {
+            newAppsWhereUserIsAdmin.add(adminRole);
+          }
+        }
+        FnUser user = null;
+        boolean createNewUser = false;
+        String orgUserId = newAppsListWithAdminRoles.getOrgUserId().trim();
+        List<FnUser> localUserList = fnUserService.getUserWithOrgUserId(orgUserId);
+        List<FnUserRole> oldAppsWhereUserIsAdmin = new ArrayList<>();
+        if (localUserList.size() > 0) {
+          FnUser tmpUser = localUserList.get(0);
+          oldAppsWhereUserIsAdmin = fnUserRoleService.retrieveByUserIdAndRoleId(tmpUser.getId(), ACCOUNT_ADMIN_ROLE_ID);
+          if (oldAppsWhereUserIsAdmin.size() > 0 || newAppsWhereUserIsAdmin.size() > 0) {
+            user = tmpUser;
+          }
+        } else if (newAppsWhereUserIsAdmin.size() > 0) {
+          // we create new user only if he has Admin Role for any App
+          createNewUser = true;
+        }
+        result = isResult(result, enabledApps, newAppsWhereUserIsAdmin, user, createNewUser, orgUserId,
+            oldAppsWhereUserIsAdmin);
+      }
+    }
+
+    return result;
+  }
+
+  @Transactional
+  public boolean isResult(boolean result, HashMap<Long, FnApp> enabledApps,
+      List<AppNameIdIsAdmin> newAppsWhereUserIsAdmin, FnUser user, boolean createNewUser, String orgUserId,
+      List<FnUserRole> oldAppsWhereUserIsAdmin) {
+    if (user != null || createNewUser) {
+      if (createNewUser) {
+        user = fnUserService.getUserWithOrgUserId(orgUserId).stream().findFirst().get();
+        if (user != null) {
+          user.setActiveYn(true);
+        }
+      }
+      for (FnUserRole oldUserApp : oldAppsWhereUserIsAdmin) {
+        // user Admin role may be deleted only for enabled
+        // apps
+        if (enabledApps.containsKey(oldUserApp.getFnAppId())) {
+          fnUserRoleService.saveOne(oldUserApp);
+        }
+      }
+      for (AppNameIdIsAdmin appNameIdIsAdmin : newAppsWhereUserIsAdmin) {
+        FnApp app = fnAppService.getById(appNameIdIsAdmin.getId());
+        FnRole role = fnRoleService.getById(ACCOUNT_ADMIN_ROLE_ID);
+        FnUserRole newUserApp = new FnUserRole();
+        newUserApp.setUserId(user);
+        newUserApp.setFnAppId(app);
+        newUserApp.setRoleId(role);
+        fnUserRoleService.saveOne(newUserApp);
+      }
+      if (EcompPortalUtils.checkIfRemoteCentralAccessAllowed()) {
+        addAdminRoleInExternalSystem(user, newAppsWhereUserIsAdmin);
+        result = true;
+      }
+    }
+    return result;
+  }
+
+  @Transactional()
+  public boolean addAdminRoleInExternalSystem(FnUser user, List<AppNameIdIsAdmin> newAppsWhereUserIsAdmin) {
+    boolean result = false;
+    try {
+      // Reset All admin role for centralized applications
+      List<FnApp> appList = fnAppService.getCentralizedApps();
+      HttpHeaders headers = EcompPortalUtils.base64encodeKeyForAAFBasicAuth();
+      for (FnApp app : appList) {
+        String name = "";
+        if (EPCommonSystemProperties
+            .containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN)) {
+          name = user.getOrgUserId() + SystemProperties
+              .getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN);
+        }
+        String extRole = app.getAuthNamespace() + "." + PortalConstants.ADMIN_ROLE.replaceAll(" ", "_");
+        HttpEntity<String> entity = new HttpEntity<>(headers);
+        logger.debug(EELFLoggerDelegate.debugLogger, "Connecting to External Access system");
+        try {
+          ResponseEntity<String> getResponse = template
+              .exchange(SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                  + "roles/" + extRole, HttpMethod.GET, entity, String.class);
+
+          if (getResponse.getBody().equals("{}")) {
+            String addDesc = "{\"name\":\"" + extRole + "\"}";
+            HttpEntity<String> roleEntity = new HttpEntity<>(addDesc, headers);
+            template.exchange(
+                SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                    + "role",
+                HttpMethod.POST, roleEntity, String.class);
+          } else {
+            try {
+              HttpEntity<String> deleteUserRole = new HttpEntity<>(headers);
+              template.exchange(
+                  SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                      + "userRole/" + name + "/" + extRole,
+                  HttpMethod.DELETE, deleteUserRole, String.class);
+            } catch (Exception e) {
+              logger.error(EELFLoggerDelegate.errorLogger,
+                  " Role not found for this user may be it gets deleted before", e);
+            }
+          }
+        } catch (Exception e) {
+          if (e.getMessage().equalsIgnoreCase("404 Not Found")) {
+            logger.debug(EELFLoggerDelegate.debugLogger, "Application Not found for app {}",
+                app.getAuthNamespace(), e.getMessage());
+          } else {
+            logger.error(EELFLoggerDelegate.errorLogger, "Application Not found for app {}",
+                app.getAuthNamespace(), e);
+          }
+        }
+      }
+      for (AppNameIdIsAdmin appNameIdIsAdmin : newAppsWhereUserIsAdmin) {
+        FnApp app = fnAppService.getById(appNameIdIsAdmin.getId());
+        try {
+          if (app.getAuthCentral()) {
+            String extRole = app.getAuthNamespace() + "." + PortalConstants.ADMIN_ROLE.replaceAll(" ", "_");
+            HttpEntity<String> entity = new HttpEntity<>(headers);
+            String name = "";
+            if (EPCommonSystemProperties
+                .containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN)) {
+              name = user.getOrgUserId() + SystemProperties
+                  .getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_USER_DOMAIN);
+            }
+            logger.debug(EELFLoggerDelegate.debugLogger, "Connecting to External Access system");
+            ResponseEntity<String> getUserRolesResponse = template.exchange(
+                SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL)
+                    + "userRoles/user/" + name,
+                HttpMethod.GET, entity, String.class);
+            logger.debug(EELFLoggerDelegate.debugLogger, "Connected to External Access system");
+            if (!getUserRolesResponse.getBody().equals("{}")) {
+              JSONObject jsonObj = new JSONObject(getUserRolesResponse.getBody());
+              JSONArray extRoles = jsonObj.getJSONArray("userRole");
+              final Map<String, JSONObject> extUserRoles = new HashMap<>();
+              for (int i = 0; i < extRoles.length(); i++) {
+                String userRole = extRoles.getJSONObject(i).getString("role");
+                if (userRole.startsWith(app.getAuthNamespace() + ".")
+                    && !userRole.equals(app.getAuthNamespace() + ".admin")
+                    && !userRole.equals(app.getAuthNamespace() + ".owner")) {
+
+                  extUserRoles.put(userRole, extRoles.getJSONObject(i));
+                }
+              }
+              if (!extUserRoles.containsKey(extRole)) {
+                // Assign with new apps user admin
+                try {
+                  ExternalAccessUser extUser = new ExternalAccessUser(name, extRole);
+                  // Assign user role for an application in external access system
+                  ObjectMapper addUserRoleMapper = new ObjectMapper();
+                  String userRole = addUserRoleMapper.writeValueAsString(extUser);
+                  HttpEntity<String> addUserRole = new HttpEntity<>(userRole, headers);
+                  template.exchange(
+                      SystemProperties.getProperty(
+                          EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "userRole",
+                      HttpMethod.POST, addUserRole, String.class);
+                } catch (Exception e) {
+                  logger.error(EELFLoggerDelegate.errorLogger, "Failed to add user admin role", e);
+                }
+
               }
-              return false;
-       }
+            }
+          }
+          result = true;
+        } catch (Exception e) {
+          if (e.getMessage().equalsIgnoreCase("404 Not Found")) {
+            logger.debug(EELFLoggerDelegate.errorLogger,
+                "Application name space not found in External system for app {} due to bad rquest name space ",
+                app.getAuthNamespace(), e.getMessage());
+          } else {
+            logger.error(EELFLoggerDelegate.errorLogger, "Failed to assign admin role for application {}",
+                app.getAuthNamespace(), e);
+            result = false;
+          }
+        }
+      }
+    } catch (Exception e) {
+      result = false;
+      logger.error(EELFLoggerDelegate.errorLogger, "Failed to assign admin roles operation", e);
+    }
+    return result;
+  }
 }