nexus site path corrected
[portal.git] / ecomp-portal-BE / src / main / java / org / openecomp / portalapp / portal / service / UserRolesServiceImpl.java
1 /*-
2  * ================================================================================
3  * eCOMP Portal
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ================================================================================
19  */
20 package org.openecomp.portalapp.portal.service;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.TreeSet;
30
31 import javax.annotation.PostConstruct;
32
33 import org.apache.commons.lang.StringUtils;
34 import org.apache.cxf.transport.http.HTTPException;
35 import org.hibernate.Query;
36 import org.hibernate.Session;
37 import org.hibernate.SessionFactory;
38 import org.hibernate.Transaction;
39 import org.openecomp.portalapp.portal.domain.EPApp;
40 import org.openecomp.portalapp.portal.domain.EPRole;
41 import org.openecomp.portalapp.portal.domain.EPUser;
42 import org.openecomp.portalapp.portal.domain.EPUserApp;
43 import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
44 import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
45 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
46 import org.openecomp.portalapp.portal.transport.AppWithRolesForUser;
47 import org.openecomp.portalapp.portal.transport.FunctionalMenuItem;
48 import org.openecomp.portalapp.portal.transport.FunctionalMenuRole;
49 import org.openecomp.portalapp.portal.transport.RemoteUserWithRoles;
50 import org.openecomp.portalapp.portal.transport.RoleInAppForUser;
51 import org.openecomp.portalapp.portal.transport.RolesInAppForUser;
52 import org.openecomp.portalapp.portal.transport.UserApplicationRoles;
53 import org.openecomp.portalapp.portal.utils.EPSystemProperties;
54 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
55 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
56 import org.openecomp.portalsdk.core.restful.domain.EcompRole;
57 import org.openecomp.portalsdk.core.service.DataAccessService;
58 import org.openecomp.portalsdk.core.service.UserProfileService;
59 import org.openecomp.portalsdk.core.util.SystemProperties;
60 import org.springframework.beans.factory.annotation.Autowired;
61 import org.springframework.context.annotation.EnableAspectJAutoProxy;
62 import org.springframework.stereotype.Service;
63 import org.springframework.transaction.annotation.Transactional;
64
65 import com.fasterxml.jackson.core.JsonProcessingException;
66 import com.fasterxml.jackson.databind.DeserializationFeature;
67 import com.fasterxml.jackson.databind.ObjectMapper;
68
69 @Service("userRolesService")
70 @Transactional
71 @org.springframework.context.annotation.Configuration
72 @EnableAspectJAutoProxy
73 @EPMetricsLog
74 public class UserRolesServiceImpl implements UserRolesService {
75         private static Long ACCOUNT_ADMIN_ROLE_ID = 999L;
76
77         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(UserRolesServiceImpl.class);
78         
79         @Autowired
80         private SessionFactory sessionFactory;
81         @Autowired
82         private DataAccessService dataAccessService;
83         @Autowired
84         SearchService searchService;
85         @Autowired
86         EPAppService appsService;
87         @Autowired
88         EPLdapService ldapService;
89         @Autowired
90         ApplicationsRestClientService applicationsRestClientService;
91         @Autowired
92         EPRoleService epRoleService;
93         @Autowired
94         UserProfileService userProfileService;
95         
96         @PostConstruct
97         private void init() {
98                 try {
99                         ACCOUNT_ADMIN_ROLE_ID = Long.valueOf(SystemProperties.getProperty(EPSystemProperties.ACCOUNT_ADMIN_ROLE_ID));
100                 } catch(Exception e) {
101                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
102                 }
103         }
104         
105         private static HashMap<Long, EcompRole> hashMapFromEcompRoles(EcompRole[] ecompRoles) {
106                 HashMap<Long, EcompRole> result = new HashMap<Long, EcompRole>();
107                 if (ecompRoles!=null) {
108                         for (int i = 0; i < ecompRoles.length; i++) {
109                                 if (ecompRoles[i].getId() != null) {
110                                         result.put(ecompRoles[i].getId(), ecompRoles[i]);
111                                 }
112                         }
113                 }
114                 return result;
115         }
116
117         private void createLocalUserIfNecessary(String orgUserId) {
118                 if (StringUtils.isEmpty(orgUserId)) {
119                         logger.error(EELFLoggerDelegate.errorLogger, "createLocalUserIfNecessary : empty orgUserId!");
120                         return;
121                 }
122                 Session localSession = null;
123                 Transaction transaction = null;
124                 try {
125                         localSession = sessionFactory.openSession();
126                         transaction = localSession.beginTransaction();
127                         @SuppressWarnings("unchecked")
128                         List<EPUser> userList = localSession.createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list();
129                         if (userList.size() == 0) {
130                                 EPUser client = searchService.searchUserByUserId(orgUserId);
131                                 if (client == null) {
132                                         String msg = "cannot create user " + orgUserId + ", because he cannot be found in phonebook";
133                                         logger.error(EELFLoggerDelegate.errorLogger, msg);
134                                 } else {
135                                         client.setLoginId(orgUserId);
136                                         client.setActive(true);
137                                         localSession.save(client);
138                                 }
139                         }
140                         transaction.commit();
141                 } catch (Exception e) {
142                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
143                         EcompPortalUtils.rollbackTransaction(transaction, "searchOrCreateUser rollback, exception = " + e);
144                 } finally {
145                         EcompPortalUtils.closeLocalSession(localSession, "searchOrCreateUser");
146                 }
147         }
148
149         private static void syncUserRoles(SessionFactory sessionFactory, String orgUserId, Long appId, EcompRole[] userAppRoles) throws Exception {
150                 HashMap<Long, EcompRole> newUserAppRolesMap = hashMapFromEcompRoles(userAppRoles);
151                 boolean result = false;
152                 Session localSession = null;
153                 Transaction transaction = null;
154                 
155                 try {
156                         localSession = sessionFactory.openSession();
157                         transaction = localSession.beginTransaction();
158                         @SuppressWarnings("unchecked")
159                         List<EPUser> userList = localSession.createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list();
160                         if (userList.size() > 0) {
161                                 EPUser client = userList.get(0);
162                                 @SuppressWarnings("unchecked")
163                                 List<EPUserApp> userRoles = localSession
164                                                 .createQuery("from " + EPUserApp.class.getName() + " where app.id=" + appId + " and userId=" + client.getId()).list();
165                                 for (EPUserApp userRole : userRoles) {
166                                                 if (! userRole.getRoleId().equals(ACCOUNT_ADMIN_ROLE_ID)) {
167                                         
168                                                         Long userAppRoleId = userRole.getAppRoleId(); 
169                                                         if (!newUserAppRolesMap.containsKey(userAppRoleId)) {
170                                                                 localSession.delete(userRole);
171                                                         } else {
172                                                                 newUserAppRolesMap.remove(userAppRoleId);
173                                                         }
174                                                 }
175                                 }
176                                 Collection<EcompRole> newRolesToAdd = newUserAppRolesMap.values();
177                                 if (newRolesToAdd.size() > 0) {
178                                         EPApp app = (EPApp) localSession.get(EPApp.class, appId);
179                                         @SuppressWarnings("unchecked")
180                                         List<EPRole> roles = localSession.createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list();
181                                         HashMap<Long, EPRole> rolesMap = new HashMap<Long, EPRole>();
182                                         for (EPRole role : roles) {
183                                                 rolesMap.put(role.getAppRoleId(), role);
184                                         }
185                                         for (EcompRole userRole : newRolesToAdd) {
186                                                 EPUserApp userApp = new EPUserApp();
187                                                 userApp.setUserId(client.getId());
188                                                 userApp.setApp(app);
189                                                 userApp.setRole(rolesMap.get(userRole.getId()));
190                                                 localSession.save(userApp);
191                                         }
192                                 }
193                         }
194                         transaction.commit();
195                         result = true;
196                 } catch (Exception e) {
197                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
198                         EcompPortalUtils.rollbackTransaction(transaction, "Exception occurred in syncUserRoles, Details: " + EcompPortalUtils.getStackTrace(e));
199                 } finally {
200                         localSession.close();
201                         if (!result) {
202                                 throw new Exception("Exception occurred in syncUserRoles while closing database session for app: '" + appId + "'.");
203                         }
204                 }
205         }
206
207         // Called when getting the list of roles for the user
208         private List<RoleInAppForUser> constructRolesInAppForUserGet(EcompRole[] appRoles, EcompRole[] userAppRoles) {
209                 List<RoleInAppForUser> rolesInAppForUser = new ArrayList<RoleInAppForUser>();
210
211                 Set<Long> userAppRolesMap = new HashSet<Long>();
212                 if (userAppRoles!=null) {
213                         for (EcompRole ecompRole : userAppRoles) {
214                                 userAppRolesMap.add(ecompRole.getId());
215                         }
216                 } else {
217                         String message = String.format("UserRolesServiceImpl.constructRolesInAppForUserGet has received userAppRoles list empty.");
218                         logger.info(EELFLoggerDelegate.errorLogger, message);
219                 }
220
221                 if (appRoles!=null) {
222                         for (EcompRole ecompRole : appRoles) {
223                                 RoleInAppForUser roleForUser = new RoleInAppForUser(ecompRole.getId(), ecompRole.getName());
224                                 roleForUser.isApplied = userAppRolesMap.contains(ecompRole.getId());
225                                 rolesInAppForUser.add(roleForUser);
226                         }
227                 } else {
228                         String message = String.format("UserRolesServiceImpl.constructRolesInAppForUser has received appRoles list empty.");
229                         logger.info(EELFLoggerDelegate.errorLogger, message);
230                 }
231                 return rolesInAppForUser;
232         }
233         public List<RoleInAppForUser> getAppRolesForUser(Long appId, String orgUserId) {
234                 List<RoleInAppForUser> rolesInAppForUser = null;
235                 try {
236                         EcompRole[] appRoles = applicationsRestClientService.get(EcompRole[].class, appId, "/roles");
237
238                         // Test this error case, for generating an internal Ecomp Portal error
239 //                      EcompRole[] appRoles = null;
240                         // If there is an exception in the rest client api, then null will be returned.
241                         if (appRoles != null) {
242                                 syncAppRoles(sessionFactory, appId, appRoles);
243                                 EcompRole[] userAppRoles;
244                                 try {
245                                         userAppRoles = applicationsRestClientService.get(EcompRole[].class, appId, String.format("/user/%s/roles", orgUserId));
246                                         if (userAppRoles == null) {
247                                                 if (EcompPortalUtils.getExternalAppResponseCode() == 400) {
248                                                     EcompPortalUtils.setExternalAppResponseCode(200);
249                                                     logger.error(EELFLoggerDelegate.errorLogger, "400 returned from /user/{userid}/roles, assuming user doesn't exist, app is framework SDK based, and things are ok. Overriding to 200 until framework SDK returns a useful response.");
250                                                     logger.debug(EELFLoggerDelegate.debugLogger, "400 returned from /user/{userid}/roles, assuming user doesn't exist, app is framework SDK based, and things are ok. Overriding to 200 until framework SDK returns a useful response.");
251                                                 }
252                                         }
253                                         // If the remote application isn't down we MUST to sync user roles here in case we have this user here!
254                                         syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles);
255                                 } catch (Exception e) {
256                                         // TODO: we may need to check if user exists, maybe remote app is down.
257                                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
258                                         logger.error(EELFLoggerDelegate.errorLogger, "LR: user " + orgUserId + " does not exist in remote application: " + appId + ".");
259                                         userAppRoles = new EcompRole[0];
260                                 }
261                                 rolesInAppForUser = constructRolesInAppForUserGet(appRoles, userAppRoles);
262                                 // Test this error case, for generating an external app error
263 //                              EcompPortalUtils.setResponseCode(404);
264                         }
265                 } catch (Exception e) {
266                         String message = String.format("Received an exception while performing getAppRolesForUser for the User %s, and for the AppId %s, Details: %s", 
267                                                                                         orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e));
268                         logger.error(EELFLoggerDelegate.errorLogger, message);
269                 }
270                 return rolesInAppForUser;
271
272         }
273         
274         // copies of methods in GetAppsWithUserRoleState
275         private void syncAppRoles(SessionFactory sessionFactory, Long appId, EcompRole[] appRoles) throws Exception {
276                 logger.debug(EELFLoggerDelegate.debugLogger, "entering syncAppRoles for appId: "+appId);
277                 HashMap<Long, EcompRole> newRolesMap = hashMapFromEcompRoles(appRoles);
278                 boolean result = false;
279                 Session localSession = null;
280                 Transaction transaction = null;
281                 
282                 try {
283                         localSession = sessionFactory.openSession();
284                         transaction = localSession.beginTransaction();
285                         // Attention! All roles from remote application supposed to be active!
286                         @SuppressWarnings("unchecked")
287                         List<EPRole> currentAppRoles = localSession.createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list();
288                         List<EPRole> obsoleteRoles = new ArrayList<EPRole>();
289                         for (int i = 0; i < currentAppRoles.size(); i++) {
290                                 EPRole oldAppRole = currentAppRoles.get(i);
291                                 if (oldAppRole.getAppRoleId() != null) {
292                                         EcompRole role = null;
293                                         role = newRolesMap.get(oldAppRole.getAppRoleId());
294                                         if (role != null) {
295                                                 if (!(role.getName() == null || oldAppRole.getName().equals(role.getName()))) {
296                                                         oldAppRole.setName(role.getName());
297                                                         localSession.update(oldAppRole);
298                                                 }
299                                                 newRolesMap.remove(oldAppRole.getAppRoleId());
300                                         } else {
301                                                 obsoleteRoles.add(oldAppRole);
302                                         }
303                                 } else {
304                                         obsoleteRoles.add(oldAppRole);
305                                 }
306                         }
307                         Collection<EcompRole> newRolesToAdd = newRolesMap.values();
308                         for (EcompRole role : newRolesToAdd) {
309                                 logger.debug(EELFLoggerDelegate.debugLogger, "about to add missing role: "+role.toString());
310                                 EPRole newRole = new EPRole();
311                                 // Attention! All roles from remote application supposed to be active!
312                                 newRole.setActive(true);
313                                 newRole.setName(role.getName());
314                                 newRole.setAppId(appId);
315                                 newRole.setAppRoleId(role.getId());
316                                 localSession.save(newRole);
317                         }
318                         if (obsoleteRoles.size() > 0) {
319                                 logger.debug(EELFLoggerDelegate.debugLogger, "we have obsolete roles to delete");
320                                 for (EPRole role : obsoleteRoles) {
321                                         logger.debug(EELFLoggerDelegate.debugLogger, "obsolete role: "+role.toString());
322                                         Long roleId = role.getId();
323                                      // delete obsolete roles here
324                                         // Must delete all records with foreign key constraints on fn_role:
325                                         // fn_user_role, fn_role_composite, fn_role_function, fn_user_pseudo_role, fn_menu_functional_roles.
326                                         // And for fn_menu_functional, if no other roles for that menu item, remove the url.
327                                         
328                                         // Delete from fn_user_role
329                                          @SuppressWarnings("unchecked")
330                                         List<EPUserApp> userRoles = localSession
331                                                                 .createQuery("from " + EPUserApp.class.getName() + " where app.id=" + appId + " and role_id=" + roleId).list();
332                                         
333                                         logger.debug(EELFLoggerDelegate.debugLogger, "number of userRoles to delete: "+userRoles.size());
334                                         for (EPUserApp userRole : userRoles) {
335                                                 logger.debug(EELFLoggerDelegate.debugLogger, "about to delete userRole: "+userRole.toString());
336                                                 localSession.delete(userRole);
337                                                 logger.debug(EELFLoggerDelegate.debugLogger, "finished deleting userRole: "+userRole.toString());
338                                         }
339                                         
340                                         // Delete from fn_menu_functional_roles
341                                         @SuppressWarnings("unchecked")
342                                         List<FunctionalMenuRole> funcMenuRoles = localSession
343                                                 .createQuery("from " + FunctionalMenuRole.class.getName() + " where roleId=" + roleId).list();
344                                         int numMenuRoles = funcMenuRoles.size();
345                                         logger.debug(EELFLoggerDelegate.debugLogger, "number of funcMenuRoles for roleId: "+roleId+": "+numMenuRoles);
346                                         for (FunctionalMenuRole funcMenuRole : funcMenuRoles) {
347                                                 Long menuId = funcMenuRole.menuId;
348                                                 // If this is the only role for this menu item, then the app and roles will be gone,
349                                                 // so must null out the url too, to be consistent
350                                                 @SuppressWarnings("unchecked")
351                                                 List<FunctionalMenuRole> funcMenuRoles2 = localSession
352                                                         .createQuery("from " + FunctionalMenuRole.class.getName() + " where menuId=" + menuId).list();
353                                                 int numMenuRoles2 = funcMenuRoles2.size();
354                                                 logger.debug(EELFLoggerDelegate.debugLogger, "number of funcMenuRoles for menuId: "+menuId+": "+numMenuRoles2);
355                                                 localSession.delete(funcMenuRole);
356                                                 if (numMenuRoles2 == 1) {
357                                                         // If this is the only role for this menu item, then the app and roles will be gone,
358                                                         // so must null out the url too, to be consistent
359                                                         logger.debug(EELFLoggerDelegate.debugLogger, "There is exactly 1 menu item for this role, so emptying the url");
360                                                         @SuppressWarnings("unchecked")
361                                                         List<FunctionalMenuItem> funcMenuItems = localSession
362                                                                         .createQuery("from " + FunctionalMenuItem.class.getName() + " where menuId=" + menuId).list();
363                                                         if (funcMenuItems.size() > 0) {
364                                                                 logger.debug(EELFLoggerDelegate.debugLogger, "got the menu item");
365                                                                 FunctionalMenuItem funcMenuItem = funcMenuItems.get(0);
366                                                                 funcMenuItem.url = "";
367                                                                 localSession.update(funcMenuItem);
368                                                         }
369                                                 }
370                                         }
371                                         
372                                         // Delete from fn_role_function
373                                         String sql = "DELETE FROM fn_role_function WHERE role_id="+roleId;
374                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
375                                         Query query = localSession.createSQLQuery(sql);
376                                         query.executeUpdate();
377
378                                         // Delete from fn_role_composite
379                                         sql = "DELETE FROM fn_role_composite WHERE parent_role_id="+roleId+" OR child_role_id="+roleId;
380                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
381                                         query = localSession.createSQLQuery(sql);
382                                         query.executeUpdate();
383
384                                         // Delete from fn_user_pseudo_role
385                                         sql = "DELETE FROM fn_user_pseudo_role WHERE pseudo_role_id="+roleId;
386                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
387                                         query = localSession.createSQLQuery(sql);
388                                         query.executeUpdate();
389                                         
390                                         logger.debug(EELFLoggerDelegate.debugLogger, "about to delete the role: "+role.toString());
391                                         localSession.delete(role);
392                                         logger.debug(EELFLoggerDelegate.debugLogger, "deleted the role");
393                                 }
394                         }
395                         logger.debug(EELFLoggerDelegate.debugLogger, "about to commit the transaction");
396                         transaction.commit();
397                         logger.debug(EELFLoggerDelegate.debugLogger, "committed the transaction");
398                         result = true;
399                 } catch (Exception e) {
400                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
401                         EcompPortalUtils.rollbackTransaction(transaction, "Exception occurred in syncAppRoles, Details: " + EcompPortalUtils.getStackTrace(e));
402                 } finally {
403                         localSession.close();
404                         if (!result) {
405                                 throw new Exception("Exception occurred in syncAppRoles while closing database session for app: '" + appId + "'.");
406                         }
407                 }
408         }
409
410         // Called when updating the list of roles for the user
411         private RolesInAppForUser constructRolesInAppForUserUpdate(String orgUserId, Long appId, Set<EcompRole> userRolesInRemoteApp) {
412                 RolesInAppForUser result;
413                 result = new RolesInAppForUser();
414                 result.appId = appId;
415                 result.orgUserId = orgUserId;
416                 for (EcompRole role : userRolesInRemoteApp) {
417                         RoleInAppForUser roleInAppForUser = new RoleInAppForUser();
418                         roleInAppForUser.roleId = role.getId();
419                         roleInAppForUser.roleName = role.getName();
420                         roleInAppForUser.isApplied = new Boolean(true);
421                         result.roles.add(roleInAppForUser);
422                 }
423                 return result;
424         }
425
426         private EPUser getUserFromRemoteApp(String orgUserId, EPApp app, ApplicationsRestClientService applicationsRestClientService) throws HTTPException {
427                 EPUser user = applicationsRestClientService.get(EPUser.class, app.getId(), String.format("/user/%s", orgUserId));
428                 return user;
429         }
430
431         private boolean remoteUserShouldBeCreated(List<RoleInAppForUser> roleInAppForUserList) {
432                 for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
433                         if (roleInAppForUser.isApplied.booleanValue()) {
434                                 return true;
435                         }
436                 }
437                 return false;
438         }
439
440         private Set<EcompRole> postUsersRolesToRemoteApp(List<RoleInAppForUser> roleInAppForUserList, ObjectMapper mapper,
441                         ApplicationsRestClientService applicationsRestClientService, Long appId, String orgUserId) throws JsonProcessingException, HTTPException {
442                 Set<EcompRole> updatedUserRoles = constructUsersEcompRoles(roleInAppForUserList);
443                 String userRolesAsString = mapper.writeValueAsString(updatedUserRoles);
444                 applicationsRestClientService.post(EcompRole.class, appId, userRolesAsString, String.format("/user/%s/roles", orgUserId));
445                 // TODO: We should add code that verifies that the post operation did succeed. Because the SDK may still return 200 OK with an html page even when it fails!
446                 return updatedUserRoles;
447         }
448
449         private Set<EcompRole> constructUsersEcompRoles(List<RoleInAppForUser> roleInAppForUserList) {
450                 Set<EcompRole> existingUserRoles = new TreeSet<EcompRole>();
451                 for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
452                         if (roleInAppForUser.isApplied) {
453                                 EcompRole ecompRole = new EcompRole();
454                                 ecompRole.setId(roleInAppForUser.roleId);
455                                 ecompRole.setName(roleInAppForUser.roleName);
456                                 existingUserRoles.add(ecompRole);
457                         }
458                 }
459                 return existingUserRoles;
460         }
461
462         private static void createNewUserOnRemoteApp(String orgUserId, EPApp app, ApplicationsRestClientService applicationsRestClientService,
463                         SearchService searchService, ObjectMapper mapper) throws Exception {
464                 EPUser client = searchService.searchUserByUserId(orgUserId);
465                 if (client == null) {
466                         String msg = "cannot create user " + orgUserId + ", because he/she cannot be found in phonebook.";
467                         logger.error(EELFLoggerDelegate.errorLogger, msg);
468                         throw new Exception(msg);
469                 }
470                 client.setLoginId(orgUserId);
471                 client.setActive(true);
472                 // The remote doesn't care about other apps, and this has caused serialization problems - infinite recursion.
473                 client.getEPUserApps().clear();
474                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
475                 String userAsString = mapper.writeValueAsString(client);
476                 logger.debug(EELFLoggerDelegate.debugLogger, "about to post new client to remote application, users json = " + userAsString);
477                 applicationsRestClientService.post(EPUser.class, app.getId(), userAsString, String.format("/user", orgUserId));
478         }
479         
480         public String updateRemoteUserProfile(String orgUserId, Long appId){
481                 
482                 ObjectMapper mapper = new ObjectMapper();
483                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
484                 EPUser client = searchService.searchUserByUserId(orgUserId);
485                 EPUser newUser = new EPUser();
486                 newUser.setActive(client.getActive());
487                 newUser.setFirstName(client.getFirstName());
488                 newUser.setLastName(client.getLastName());
489                 newUser.setLoginId(client.getLoginId());
490                 newUser.setLoginPwd(client.getLoginPwd());
491                 newUser.setMiddleInitial(client.getMiddleInitial());
492                 newUser.setEmail(client.getEmail());
493                 newUser.setOrgUserId(client.getLoginId());
494                 try {
495                         String userAsString = mapper.writeValueAsString(newUser);
496                         List<EPApp> appList = appsService.getUserRemoteApps(client.getId().toString());
497                         //applicationsRestClientService.post(EPUser.class, appId, userAsString, String.format("/user", orgUserId));
498                         for(EPApp eachApp : appList){
499                                 try{
500                                  applicationsRestClientService.post(EPUser.class, eachApp.getId(), userAsString, String.format("/user/%s", orgUserId));
501                                 }catch(Exception e){
502                                         logger.error(EELFLoggerDelegate.errorLogger, "Failed to update user: " + client.getOrgUserId() + " in remote app. appId = " + eachApp.getId());
503                                 }
504                         }
505                 } catch (Exception e) {
506                         // TODO Auto-generated catch block
507                         e.printStackTrace();
508                         return "failure"; 
509                 }
510                 
511                 return "success";
512                 
513         }
514
515         private static final Object syncRests = new Object();
516
517         @Override
518         public boolean setAppWithUserRoleStateForUser(EPUser user, AppWithRolesForUser newAppRolesForUser) {
519                 boolean result = false;
520                 String orgUserId = "";
521                 if (newAppRolesForUser != null && newAppRolesForUser.orgUserId != null) {
522                         orgUserId = newAppRolesForUser.orgUserId.trim();
523                 }
524                 Long appId = newAppRolesForUser.appId;
525                 List<RoleInAppForUser> roleInAppForUserList = newAppRolesForUser.appRoles;
526                 if (orgUserId.length() > 0) {
527                         ObjectMapper mapper = new ObjectMapper();
528                         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
529
530                         try {
531                                 EPApp app = appsService.getApp(appId);
532                                 EPUser remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService);
533                                 if (remoteAppUser == null) {
534                                         if (remoteUserShouldBeCreated(roleInAppForUserList)) {
535                                                 createNewUserOnRemoteApp(orgUserId, app, applicationsRestClientService, searchService, mapper);
536                                                 // If we succeed, we know that the new user was persisted on remote app.
537                                                 remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService);
538                                                 if (remoteAppUser == null) {
539                                                         logger.error(EELFLoggerDelegate.errorLogger, "Failed to persist new user: " + orgUserId + " in remote app. appId = " + appId);
540 //                                                      return null;
541                                                 }
542                                         }
543                                 }
544                                 if (remoteAppUser != null) {
545                                         Set<EcompRole> userRolesInRemoteApp = postUsersRolesToRemoteApp(roleInAppForUserList, mapper, applicationsRestClientService, appId, orgUserId);
546                                         RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(orgUserId, appId, userRolesInRemoteApp);
547                                         result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser);
548                                 }
549                         } catch (Exception e) {
550                                 String message = String.format("Failed to create user or update user roles for the User %s, and for the AppId %s, Details: %s", 
551                                                 orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e));
552                                 logger.error(EELFLoggerDelegate.errorLogger, message);
553                                 result = false;
554                         }
555
556                 }
557                 return result;
558         }
559
560         // This is for a single app
561         private boolean applyChangesInUserRolesForAppToEcompDB(RolesInAppForUser rolesInAppForUser) {
562                 boolean result = false;
563                 String orgUserId = rolesInAppForUser.orgUserId;
564                 Long appId = rolesInAppForUser.appId;
565                 synchronized (syncRests) {
566                         if (rolesInAppForUser != null) {
567                                 createLocalUserIfNecessary(orgUserId);
568                         }
569                         
570                         if (rolesInAppForUser != null) {
571                                 EcompRole[] userAppRoles = new EcompRole[rolesInAppForUser.roles.size()];
572                                 for (int i = 0; i < rolesInAppForUser.roles.size(); i++) {
573                                         RoleInAppForUser roleInAppForUser = rolesInAppForUser.roles.get(i);
574                                         EcompRole role = new EcompRole();
575                                         role.setId(roleInAppForUser.roleId);
576                                         role.setName(roleInAppForUser.roleName);
577                                         userAppRoles[i] = role;
578                                 }
579                                 try {
580                                         syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles);
581                                         result = true;
582                                 } catch (Exception e) {
583                                         logger.error(EELFLoggerDelegate.errorLogger, "applyChangesInUserRolesForAppToEcompDB syncUserRoles, orgUserId = " + orgUserId);
584                                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
585                                 }
586                         }
587                 }
588                 return result;
589         }
590
591         @Override
592         public List<UserApplicationRoles> getUsersFromAppEndpoint(Long appId) throws HTTPException {
593                 RemoteUserWithRoles[] remoteUsers = applicationsRestClientService.get(RemoteUserWithRoles[].class, appId, "/users");
594                 ArrayList<UserApplicationRoles> userApplicationRoles = new ArrayList<UserApplicationRoles>();
595                 for (RemoteUserWithRoles remoteUser : remoteUsers) {
596                         UserApplicationRoles userWithRemoteAppRoles = convertToUserApplicationRoles(appId, remoteUser);
597                         if(userWithRemoteAppRoles.roles!=null && userWithRemoteAppRoles.roles.size()>0) {
598                                 userApplicationRoles.add(userWithRemoteAppRoles);
599                         } else {
600                                 logger.debug(EELFLoggerDelegate.debugLogger, "User " + userWithRemoteAppRoles.orgUserId + " doesn't have any roles assigned to any app.");
601                         }
602                 }
603                 
604                 return userApplicationRoles;
605         }
606
607         private UserApplicationRoles convertToUserApplicationRoles(Long appId, RemoteUserWithRoles remoteUser) {
608                 UserApplicationRoles userWithRemoteAppRoles = new UserApplicationRoles();
609                 userWithRemoteAppRoles.appId = appId;
610                 userWithRemoteAppRoles.orgUserId = remoteUser.loginId;
611                 userWithRemoteAppRoles.firstName = remoteUser.firstName;
612                 userWithRemoteAppRoles.lastName = remoteUser.lastName;
613                 userWithRemoteAppRoles.roles = remoteUser.roles;
614                 return userWithRemoteAppRoles;
615         }
616
617         public static void persistExternalRoleInEcompDb(EPRole externalAppRole, Long appId, EPRoleService roleService) {
618                 externalAppRole.setAppId(appId);
619                 externalAppRole.setAppRoleId(externalAppRole.getId());
620                 externalAppRole.setId(null); // We will persist a new role, with ecomp role id which will be different than external app role id.
621
622                 roleService.saveRole(externalAppRole);
623                 logger.debug(EELFLoggerDelegate.debugLogger, String.format("ECOMP persists role from app:%d, app roleId: %d, roleName: %s", appId, externalAppRole.getAppRoleId(), externalAppRole.getName()));
624         }
625
626         @Override
627         public List<EPRole> importRolesFromRemoteApplication(Long appId) throws HTTPException {
628                 EPRole[] appRolesFull = applicationsRestClientService.get(EPRole[].class, appId, "/rolesFull");
629                 List<EPRole> rolesList = Arrays.asList(appRolesFull);
630                 for (EPRole externalAppRole : rolesList) {
631
632                         // Try to find an existing extern role for the app in the local ecomp DB. If so, then use its id to update the existing external application role record.
633                         Long externAppId = externalAppRole.getId();
634                         EPRole existingAppRole = epRoleService.getRole(appId, externAppId);
635                         if (existingAppRole != null) {
636                                 logger.debug(EELFLoggerDelegate.debugLogger, String.format("ecomp role already exists for app=%s; appRoleId=%s. No need to import this one.", appId, externAppId));
637                                 continue;
638                         }
639                         // persistExternalRoleInEcompDb(externalAppRole, appId, roleService);
640                 }
641                 
642                 return rolesList;
643         }
644
645         @Override
646         public List<EPUserApp> getCachedAppRolesForUser(Long appId, Long userId)  {
647                 // Find the records for this user-app combo, if any
648                 String filter = " where user_id = " + Long.toString(userId) + " and app_id = " + Long.toString(appId);
649                 @SuppressWarnings("unchecked")
650                 List<EPUserApp> roleList = dataAccessService.getList(EPUserApp.class, filter, null, null);
651                 logger.debug(EELFLoggerDelegate.debugLogger, "getCachedAppRolesForUser: list size is {}", 
652                                 roleList.size());
653                 return roleList;
654         }
655
656 }