[PORTAL-7] Rebase
[portal.git] / ecomp-portal-BE-os / 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
100                                         .valueOf(SystemProperties.getProperty(EPSystemProperties.ACCOUNT_ADMIN_ROLE_ID));
101                 } catch (Exception e) {
102                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
103                 }
104         }
105
106         private static HashMap<Long, EcompRole> hashMapFromEcompRoles(EcompRole[] ecompRoles) {
107                 HashMap<Long, EcompRole> result = new HashMap<Long, EcompRole>();
108                 if (ecompRoles != null) {
109                         for (int i = 0; i < ecompRoles.length; i++) {
110                                 if (ecompRoles[i].getId() != null) {
111                                         result.put(ecompRoles[i].getId(), ecompRoles[i]);
112                                 }
113                         }
114                 }
115                 return result;
116         }
117
118         private void createLocalUserIfNecessary(String orgUserId) {
119                 if (StringUtils.isEmpty(orgUserId)) {
120                         logger.error(EELFLoggerDelegate.errorLogger, "createLocalUserIfNecessary : empty orgUserId!");
121                         return;
122                 }
123                 Session localSession = null;
124                 Transaction transaction = null;
125                 try {
126                         localSession = sessionFactory.openSession();
127                         transaction = localSession.beginTransaction();
128                         @SuppressWarnings("unchecked")
129                         List<EPUser> userList = localSession
130                                         .createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list();
131                         if (userList.size() == 0) {
132                                 EPUser client = searchService.searchUserByUserId(orgUserId);
133                                 if (client == null) {
134                                         String msg = "cannot create user " + orgUserId + ", because he cannot be found in phonebook";
135                                         logger.error(EELFLoggerDelegate.errorLogger, msg);
136                                 } else {
137                                         client.setLoginId(orgUserId);
138                                         client.setActive(true);
139                                         localSession.save(client);
140                                 }
141                         }
142                         transaction.commit();
143                 } catch (Exception e) {
144                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
145                         EcompPortalUtils.rollbackTransaction(transaction, "searchOrCreateUser rollback, exception = " + e);
146                 } finally {
147                         EcompPortalUtils.closeLocalSession(localSession, "searchOrCreateUser");
148                 }
149         }
150
151         private static void syncUserRoles(SessionFactory sessionFactory, String orgUserId, Long appId,
152                         EcompRole[] userAppRoles) throws Exception {
153                 HashMap<Long, EcompRole> newUserAppRolesMap = hashMapFromEcompRoles(userAppRoles);
154                 boolean result = false;
155                 Session localSession = null;
156                 Transaction transaction = null;
157
158                 try {
159                         localSession = sessionFactory.openSession();
160                         transaction = localSession.beginTransaction();
161                         @SuppressWarnings("unchecked")
162                         List<EPUser> userList = localSession
163                                         .createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list();
164                         if (userList.size() > 0) {
165                                 EPUser client = userList.get(0);
166                                 @SuppressWarnings("unchecked")
167                                 List<EPUserApp> userRoles = localSession.createQuery("from " + EPUserApp.class.getName()
168                                                 + " where app.id=" + appId + " and userId=" + client.getId()).list();
169                                 for (EPUserApp userRole : userRoles) {
170                                         if (!userRole.getRoleId().equals(ACCOUNT_ADMIN_ROLE_ID)) {
171
172                                                 Long userAppRoleId = userRole.getAppRoleId();
173                                                 if (!newUserAppRolesMap.containsKey(userAppRoleId)) {
174                                                         localSession.delete(userRole);
175                                                 } else {
176                                                         newUserAppRolesMap.remove(userAppRoleId);
177                                                 }
178                                         }
179                                 }
180                                 Collection<EcompRole> newRolesToAdd = newUserAppRolesMap.values();
181                                 if (newRolesToAdd.size() > 0) {
182                                         EPApp app = (EPApp) localSession.get(EPApp.class, appId);
183                                         @SuppressWarnings("unchecked")
184                                         List<EPRole> roles = localSession
185                                                         .createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list();
186                                         HashMap<Long, EPRole> rolesMap = new HashMap<Long, EPRole>();
187                                         for (EPRole role : roles) {
188                                                 rolesMap.put(role.getAppRoleId(), role);
189                                         }
190                                         for (EcompRole userRole : newRolesToAdd) {
191                                                 EPUserApp userApp = new EPUserApp();
192                                                 userApp.setUserId(client.getId());
193                                                 userApp.setApp(app);
194                                                 userApp.setRole(rolesMap.get(userRole.getId()));
195                                                 localSession.save(userApp);
196                                         }
197                                 }
198                         }
199                         transaction.commit();
200                         result = true;
201                 } catch (Exception e) {
202                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
203                         EcompPortalUtils.rollbackTransaction(transaction,
204                                         "Exception occurred in syncUserRoles, Details: " + EcompPortalUtils.getStackTrace(e));
205                 } finally {
206                         localSession.close();
207                         if (!result) {
208                                 throw new Exception(
209                                                 "Exception occurred in syncUserRoles while closing database session for app: '" + appId + "'.");
210                         }
211                 }
212         }
213
214         // Called when getting the list of roles for the user
215         private List<RoleInAppForUser> constructRolesInAppForUserGet(EcompRole[] appRoles, EcompRole[] userAppRoles) {
216                 List<RoleInAppForUser> rolesInAppForUser = new ArrayList<RoleInAppForUser>();
217
218                 Set<Long> userAppRolesMap = new HashSet<Long>();
219                 if (userAppRoles != null) {
220                         for (EcompRole ecompRole : userAppRoles) {
221                                 userAppRolesMap.add(ecompRole.getId());
222                         }
223                 } else {
224                         String message = String
225                                         .format("UserRolesServiceImpl.constructRolesInAppForUserGet has received userAppRoles list empty.");
226                         logger.info(EELFLoggerDelegate.errorLogger, message);
227                 }
228
229                 if (appRoles != null) {
230                         for (EcompRole ecompRole : appRoles) {
231                                 RoleInAppForUser roleForUser = new RoleInAppForUser(ecompRole.getId(), ecompRole.getName());
232                                 roleForUser.isApplied = userAppRolesMap.contains(ecompRole.getId());
233                                 rolesInAppForUser.add(roleForUser);
234                         }
235                 } else {
236                         String message = String
237                                         .format("UserRolesServiceImpl.constructRolesInAppForUser has received appRoles list empty.");
238                         logger.info(EELFLoggerDelegate.errorLogger, message);
239                 }
240                 return rolesInAppForUser;
241         }
242
243         public List<RoleInAppForUser> getAppRolesForUser(Long appId, String orgUserId) {
244                 List<RoleInAppForUser> rolesInAppForUser = null;
245                 try {
246                         EcompRole[] appRoles = applicationsRestClientService.get(EcompRole[].class, appId, "/roles");
247
248                         // Test this error case, for generating an internal Ecomp Portal
249                         // error
250                         // EcompRole[] appRoles = null;
251                         // If there is an exception in the rest client api, then null will
252                         // be returned.
253                         if (appRoles != null) {
254                                 syncAppRoles(sessionFactory, appId, appRoles);
255                                 EcompRole[] userAppRoles;
256                                 try {
257                                         userAppRoles = applicationsRestClientService.get(EcompRole[].class, appId,
258                                                         String.format("/user/%s/roles", orgUserId));
259                                         if (userAppRoles == null) {
260                                                 if (EcompPortalUtils.getExternalAppResponseCode() == 400) {
261                                                         EcompPortalUtils.setExternalAppResponseCode(200);
262                                                         logger.error(EELFLoggerDelegate.errorLogger,
263                                                                         "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.");
264                                                         logger.debug(EELFLoggerDelegate.debugLogger,
265                                                                         "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.");
266                                                 }
267                                         }
268                                         // If the remote application isn't down we MUST to sync user
269                                         // roles here in case we have this user here!
270                                         syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles);
271                                 } catch (Exception e) {
272                                         // TODO: we may need to check if user exists, maybe remote
273                                         // app is down.
274                                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
275                                         logger.error(EELFLoggerDelegate.errorLogger,
276                                                         "LR: user " + orgUserId + " does not exist in remote application: " + appId + ".");
277                                         userAppRoles = new EcompRole[0];
278                                 }
279                                 rolesInAppForUser = constructRolesInAppForUserGet(appRoles, userAppRoles);
280                                 // Test this error case, for generating an external app error
281                                 // EcompPortalUtils.setResponseCode(404);
282                         }
283                 } catch (Exception e) {
284                         String message = String.format(
285                                         "Received an exception while performing getAppRolesForUser for the User %s, and for the AppId %s, Details: %s",
286                                         orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e));
287                         logger.error(EELFLoggerDelegate.errorLogger, message);
288                 }
289                 return rolesInAppForUser;
290
291         }
292
293         // copies of methods in GetAppsWithUserRoleState
294         private void syncAppRoles(SessionFactory sessionFactory, Long appId, EcompRole[] appRoles) throws Exception {
295                 logger.debug(EELFLoggerDelegate.debugLogger, "entering syncAppRoles for appId: " + appId);
296                 HashMap<Long, EcompRole> newRolesMap = hashMapFromEcompRoles(appRoles);
297                 boolean result = false;
298                 Session localSession = null;
299                 Transaction transaction = null;
300
301                 try {
302                         localSession = sessionFactory.openSession();
303                         transaction = localSession.beginTransaction();
304                         // Attention! All roles from remote application supposed to be
305                         // active!
306                         @SuppressWarnings("unchecked")
307                         List<EPRole> currentAppRoles = localSession
308                                         .createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list();
309                         List<EPRole> obsoleteRoles = new ArrayList<EPRole>();
310                         for (int i = 0; i < currentAppRoles.size(); i++) {
311                                 EPRole oldAppRole = currentAppRoles.get(i);
312                                 if (oldAppRole.getAppRoleId() != null) {
313                                         EcompRole role = null;
314                                         role = newRolesMap.get(oldAppRole.getAppRoleId());
315                                         if (role != null) {
316                                                 if (!(role.getName() == null || oldAppRole.getName().equals(role.getName()))) {
317                                                         oldAppRole.setName(role.getName());
318                                                         localSession.update(oldAppRole);
319                                                 }
320                                                 newRolesMap.remove(oldAppRole.getAppRoleId());
321                                         } else {
322                                                 obsoleteRoles.add(oldAppRole);
323                                         }
324                                 } else {
325                                         obsoleteRoles.add(oldAppRole);
326                                 }
327                         }
328                         Collection<EcompRole> newRolesToAdd = newRolesMap.values();
329                         for (EcompRole role : newRolesToAdd) {
330                                 logger.debug(EELFLoggerDelegate.debugLogger, "about to add missing role: " + role.toString());
331                                 EPRole newRole = new EPRole();
332                                 // Attention! All roles from remote application supposed to be
333                                 // active!
334                                 newRole.setActive(true);
335                                 newRole.setName(role.getName());
336                                 newRole.setAppId(appId);
337                                 newRole.setAppRoleId(role.getId());
338                                 localSession.save(newRole);
339                         }
340                         if (obsoleteRoles.size() > 0) {
341                                 logger.debug(EELFLoggerDelegate.debugLogger, "we have obsolete roles to delete");
342                                 for (EPRole role : obsoleteRoles) {
343                                         logger.debug(EELFLoggerDelegate.debugLogger, "obsolete role: " + role.toString());
344                                         Long roleId = role.getId();
345                                         // delete obsolete roles here
346                                         // Must delete all records with foreign key constraints on
347                                         // fn_role:
348                                         // fn_user_role, fn_role_composite, fn_role_function,
349                                         // fn_user_pseudo_role, fn_menu_functional_roles.
350                                         // And for fn_menu_functional, if no other roles for that
351                                         // menu item, remove the url.
352
353                                         // Delete from fn_user_role
354                                         @SuppressWarnings("unchecked")
355                                         List<EPUserApp> userRoles = localSession.createQuery(
356                                                         "from " + EPUserApp.class.getName() + " where app.id=" + appId + " and role_id=" + roleId)
357                                                         .list();
358
359                                         logger.debug(EELFLoggerDelegate.debugLogger, "number of userRoles to delete: " + userRoles.size());
360                                         for (EPUserApp userRole : userRoles) {
361                                                 logger.debug(EELFLoggerDelegate.debugLogger,
362                                                                 "about to delete userRole: " + userRole.toString());
363                                                 localSession.delete(userRole);
364                                                 logger.debug(EELFLoggerDelegate.debugLogger,
365                                                                 "finished deleting userRole: " + userRole.toString());
366                                         }
367
368                                         // Delete from fn_menu_functional_roles
369                                         @SuppressWarnings("unchecked")
370                                         List<FunctionalMenuRole> funcMenuRoles = localSession
371                                                         .createQuery("from " + FunctionalMenuRole.class.getName() + " where roleId=" + roleId)
372                                                         .list();
373                                         int numMenuRoles = funcMenuRoles.size();
374                                         logger.debug(EELFLoggerDelegate.debugLogger,
375                                                         "number of funcMenuRoles for roleId: " + roleId + ": " + numMenuRoles);
376                                         for (FunctionalMenuRole funcMenuRole : funcMenuRoles) {
377                                                 Long menuId = funcMenuRole.menuId;
378                                                 // If this is the only role for this menu item, then the
379                                                 // app and roles will be gone,
380                                                 // so must null out the url too, to be consistent
381                                                 @SuppressWarnings("unchecked")
382                                                 List<FunctionalMenuRole> funcMenuRoles2 = localSession
383                                                                 .createQuery("from " + FunctionalMenuRole.class.getName() + " where menuId=" + menuId)
384                                                                 .list();
385                                                 int numMenuRoles2 = funcMenuRoles2.size();
386                                                 logger.debug(EELFLoggerDelegate.debugLogger,
387                                                                 "number of funcMenuRoles for menuId: " + menuId + ": " + numMenuRoles2);
388                                                 localSession.delete(funcMenuRole);
389                                                 if (numMenuRoles2 == 1) {
390                                                         // If this is the only role for this menu item, then
391                                                         // the app and roles will be gone,
392                                                         // so must null out the url too, to be consistent
393                                                         logger.debug(EELFLoggerDelegate.debugLogger,
394                                                                         "There is exactly 1 menu item for this role, so emptying the url");
395                                                         @SuppressWarnings("unchecked")
396                                                         List<FunctionalMenuItem> funcMenuItems = localSession
397                                                                         .createQuery(
398                                                                                         "from " + FunctionalMenuItem.class.getName() + " where menuId=" + menuId)
399                                                                         .list();
400                                                         if (funcMenuItems.size() > 0) {
401                                                                 logger.debug(EELFLoggerDelegate.debugLogger, "got the menu item");
402                                                                 FunctionalMenuItem funcMenuItem = funcMenuItems.get(0);
403                                                                 funcMenuItem.url = "";
404                                                                 localSession.update(funcMenuItem);
405                                                         }
406                                                 }
407                                         }
408
409                                         // Delete from fn_role_function
410                                         String sql = "DELETE FROM fn_role_function WHERE role_id=" + roleId;
411                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
412                                         Query query = localSession.createSQLQuery(sql);
413                                         query.executeUpdate();
414
415                                         // Delete from fn_role_composite
416                                         sql = "DELETE FROM fn_role_composite WHERE parent_role_id=" + roleId + " OR child_role_id="
417                                                         + roleId;
418                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
419                                         query = localSession.createSQLQuery(sql);
420                                         query.executeUpdate();
421
422                                         // Delete from fn_user_pseudo_role
423                                         sql = "DELETE FROM fn_user_pseudo_role WHERE pseudo_role_id=" + roleId;
424                                         logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
425                                         query = localSession.createSQLQuery(sql);
426                                         query.executeUpdate();
427
428                                         logger.debug(EELFLoggerDelegate.debugLogger, "about to delete the role: " + role.toString());
429                                         localSession.delete(role);
430                                         logger.debug(EELFLoggerDelegate.debugLogger, "deleted the role");
431                                 }
432                         }
433                         logger.debug(EELFLoggerDelegate.debugLogger, "about to commit the transaction");
434                         transaction.commit();
435                         logger.debug(EELFLoggerDelegate.debugLogger, "committed the transaction");
436                         result = true;
437                 } catch (Exception e) {
438                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
439                         EcompPortalUtils.rollbackTransaction(transaction,
440                                         "Exception occurred in syncAppRoles, Details: " + EcompPortalUtils.getStackTrace(e));
441                 } finally {
442                         localSession.close();
443                         if (!result) {
444                                 throw new Exception(
445                                                 "Exception occurred in syncAppRoles while closing database session for app: '" + appId + "'.");
446                         }
447                 }
448         }
449
450         // Called when updating the list of roles for the user
451         private RolesInAppForUser constructRolesInAppForUserUpdate(String orgUserId, Long appId,
452                         Set<EcompRole> userRolesInRemoteApp) {
453                 RolesInAppForUser result;
454                 result = new RolesInAppForUser();
455                 result.appId = appId;
456                 result.orgUserId = orgUserId;
457                 for (EcompRole role : userRolesInRemoteApp) {
458                         RoleInAppForUser roleInAppForUser = new RoleInAppForUser();
459                         roleInAppForUser.roleId = role.getId();
460                         roleInAppForUser.roleName = role.getName();
461                         roleInAppForUser.isApplied = new Boolean(true);
462                         result.roles.add(roleInAppForUser);
463                 }
464                 return result;
465         }
466
467         private EPUser getUserFromRemoteApp(String orgUserId, EPApp app,
468                         ApplicationsRestClientService applicationsRestClientService) throws HTTPException {
469                 EPUser user = applicationsRestClientService.get(EPUser.class, app.getId(),
470                                 String.format("/user/%s", orgUserId));
471                 return user;
472         }
473
474         private boolean remoteUserShouldBeCreated(List<RoleInAppForUser> roleInAppForUserList) {
475                 for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
476                         if (roleInAppForUser.isApplied.booleanValue()) {
477                                 return true;
478                         }
479                 }
480                 return false;
481         }
482
483         private Set<EcompRole> postUsersRolesToRemoteApp(List<RoleInAppForUser> roleInAppForUserList, ObjectMapper mapper,
484                         ApplicationsRestClientService applicationsRestClientService, Long appId, String orgUserId)
485                         throws JsonProcessingException, HTTPException {
486                 Set<EcompRole> updatedUserRoles = constructUsersEcompRoles(roleInAppForUserList);
487                 String userRolesAsString = mapper.writeValueAsString(updatedUserRoles);
488                 applicationsRestClientService.post(EcompRole.class, appId, userRolesAsString,
489                                 String.format("/user/%s/roles", orgUserId));
490                 // TODO: We should add code that verifies that the post operation did
491                 // succeed. Because the SDK may still return 200 OK with an html page
492                 // even when it fails!
493                 return updatedUserRoles;
494         }
495
496         private Set<EcompRole> constructUsersEcompRoles(List<RoleInAppForUser> roleInAppForUserList) {
497                 Set<EcompRole> existingUserRoles = new TreeSet<EcompRole>();
498                 for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) {
499                         if (roleInAppForUser.isApplied) {
500                                 EcompRole ecompRole = new EcompRole();
501                                 ecompRole.setId(roleInAppForUser.roleId);
502                                 ecompRole.setName(roleInAppForUser.roleName);
503                                 existingUserRoles.add(ecompRole);
504                         }
505                 }
506                 return existingUserRoles;
507         }
508
509         private static void createNewUserOnRemoteApp(String orgUserId, EPApp app,
510                         ApplicationsRestClientService applicationsRestClientService, SearchService searchService,
511                         ObjectMapper mapper) throws Exception {
512                 EPUser client = searchService.searchUserByUserId(orgUserId);
513                 if (client == null) {
514                         String msg = "cannot create user " + orgUserId + ", because he/she cannot be found in phonebook.";
515                         logger.error(EELFLoggerDelegate.errorLogger, msg);
516                         throw new Exception(msg);
517                 }
518                 client.setLoginId(orgUserId);
519                 client.setActive(true);
520                 // The remote doesn't care about other apps, and this has caused
521                 // serialization problems - infinite recursion.
522                 client.getEPUserApps().clear();
523                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
524                 String userAsString = mapper.writeValueAsString(client);
525                 logger.debug(EELFLoggerDelegate.debugLogger,
526                                 "about to post new client to remote application, users json = " + userAsString);
527                 applicationsRestClientService.post(EPUser.class, app.getId(), userAsString, String.format("/user", orgUserId));
528         }
529
530         public String updateRemoteUserProfile(String orgUserId, Long appId) {
531
532                 ObjectMapper mapper = new ObjectMapper();
533                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
534                 EPUser client = searchService.searchUserByUserId(orgUserId);
535                 EPUser newUser = new EPUser();
536                 newUser.setActive(client.getActive());
537                 newUser.setFirstName(client.getFirstName());
538                 newUser.setLastName(client.getLastName());
539                 newUser.setLoginId(client.getLoginId());
540                 newUser.setLoginPwd(client.getLoginPwd());
541                 newUser.setMiddleInitial(client.getMiddleInitial());
542                 newUser.setEmail(client.getEmail());
543                 newUser.setOrgUserId(client.getLoginId());
544                 try {
545                         String userAsString = mapper.writeValueAsString(newUser);
546                         List<EPApp> appList = appsService.getUserRemoteApps(client.getId().toString());
547                         // applicationsRestClientService.post(EPUser.class, appId,
548                         // userAsString, String.format("/user", orgUserId));
549                         for (EPApp eachApp : appList) {
550                                 try {
551                                         applicationsRestClientService.post(EPUser.class, eachApp.getId(), userAsString,
552                                                         String.format("/user/%s", orgUserId));
553                                 } catch (Exception e) {
554                                         logger.error(EELFLoggerDelegate.errorLogger, "Failed to update user: " + client.getOrgUserId()
555                                                         + " in remote app. appId = " + eachApp.getId());
556                                 }
557                         }
558                 } catch (Exception e) {
559                         // TODO Auto-generated catch block
560                         e.printStackTrace();
561                         return "failure";
562                 }
563
564                 return "success";
565
566         }
567
568         private static final Object syncRests = new Object();
569
570         @Override
571         public boolean setAppWithUserRoleStateForUser(EPUser user, AppWithRolesForUser newAppRolesForUser) {
572                 boolean result = false;
573                 String orgUserId = "";
574                 if (newAppRolesForUser != null && newAppRolesForUser.orgUserId != null) {
575                         orgUserId = newAppRolesForUser.orgUserId.trim();
576                 }
577                 Long appId = newAppRolesForUser.appId;
578                 List<RoleInAppForUser> roleInAppForUserList = newAppRolesForUser.appRoles;
579                 if (orgUserId.length() > 0) {
580                         ObjectMapper mapper = new ObjectMapper();
581                         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
582
583                         try {
584                                 EPApp app = appsService.getApp(appId);
585                                 EPUser remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService);
586                                 if (remoteAppUser == null) {
587                                         if (remoteUserShouldBeCreated(roleInAppForUserList)) {
588                                                 createNewUserOnRemoteApp(orgUserId, app, applicationsRestClientService, searchService, mapper);
589                                                 // If we succeed, we know that the new user was
590                                                 // persisted on remote app.
591                                                 remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService);
592                                                 if (remoteAppUser == null) {
593                                                         logger.error(EELFLoggerDelegate.errorLogger,
594                                                                         "Failed to persist new user: " + orgUserId + " in remote app. appId = " + appId);
595                                                         // return null;
596                                                 }
597                                         }
598                                 }
599                                 if (remoteAppUser != null) {
600                                         Set<EcompRole> userRolesInRemoteApp = postUsersRolesToRemoteApp(roleInAppForUserList, mapper,
601                                                         applicationsRestClientService, appId, orgUserId);
602                                         RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(orgUserId, appId,
603                                                         userRolesInRemoteApp);
604                                         result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser);
605                                 }
606                         } catch (Exception e) {
607                                 String message = String.format(
608                                                 "Failed to create user or update user roles for the User %s, and for the AppId %s, Details: %s",
609                                                 orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e));
610                                 logger.error(EELFLoggerDelegate.errorLogger, message);
611                                 result = false;
612                         }
613
614                 }
615                 return result;
616         }
617
618         // This is for a single app
619         private boolean applyChangesInUserRolesForAppToEcompDB(RolesInAppForUser rolesInAppForUser) {
620                 boolean result = false;
621                 String orgUserId = rolesInAppForUser.orgUserId;
622                 Long appId = rolesInAppForUser.appId;
623                 synchronized (syncRests) {
624                         if (rolesInAppForUser != null) {
625                                 createLocalUserIfNecessary(orgUserId);
626                         }
627
628                         if (rolesInAppForUser != null) {
629                                 EcompRole[] userAppRoles = new EcompRole[rolesInAppForUser.roles.size()];
630                                 for (int i = 0; i < rolesInAppForUser.roles.size(); i++) {
631                                         RoleInAppForUser roleInAppForUser = rolesInAppForUser.roles.get(i);
632                                         EcompRole role = new EcompRole();
633                                         role.setId(roleInAppForUser.roleId);
634                                         role.setName(roleInAppForUser.roleName);
635                                         userAppRoles[i] = role;
636                                 }
637                                 try {
638                                         syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles);
639                                         result = true;
640                                 } catch (Exception e) {
641                                         logger.error(EELFLoggerDelegate.errorLogger,
642                                                         "applyChangesInUserRolesForAppToEcompDB syncUserRoles, orgUserId = " + orgUserId);
643                                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
644                                 }
645                         }
646                 }
647                 return result;
648         }
649
650         @Override
651         public List<UserApplicationRoles> getUsersFromAppEndpoint(Long appId) throws HTTPException {
652                 RemoteUserWithRoles[] remoteUsers = applicationsRestClientService.get(RemoteUserWithRoles[].class, appId,
653                                 "/users");
654                 ArrayList<UserApplicationRoles> userApplicationRoles = new ArrayList<UserApplicationRoles>();
655                 for (RemoteUserWithRoles remoteUser : remoteUsers) {
656                         UserApplicationRoles userWithRemoteAppRoles = convertToUserApplicationRoles(appId, remoteUser);
657                         if(userWithRemoteAppRoles.getRoles()!=null && userWithRemoteAppRoles.getRoles().size()>0) {
658                                 userApplicationRoles.add(userWithRemoteAppRoles);
659                         } else {
660                                 logger.debug(EELFLoggerDelegate.debugLogger, "User " + userWithRemoteAppRoles.getOrgUserId()
661                                                 + " doesn't have any roles assigned to any app.");
662
663                         }
664                 }
665
666                 return userApplicationRoles;
667         }
668
669         private UserApplicationRoles convertToUserApplicationRoles(Long appId, RemoteUserWithRoles remoteUser) {
670                 UserApplicationRoles userWithRemoteAppRoles = new UserApplicationRoles();
671                 userWithRemoteAppRoles.setAppId(appId);
672                 userWithRemoteAppRoles.setOrgUserId(remoteUser.getLoginId());
673                 userWithRemoteAppRoles.setFirstName(remoteUser.getFirstName());
674                 userWithRemoteAppRoles.setLastName(remoteUser.getLastName());
675                 userWithRemoteAppRoles.setRoles(remoteUser.getRoles());
676                 return userWithRemoteAppRoles;
677         }
678
679         public static void persistExternalRoleInEcompDb(EPRole externalAppRole, Long appId, EPRoleService roleService) {
680                 externalAppRole.setAppId(appId);
681                 externalAppRole.setAppRoleId(externalAppRole.getId());
682                 externalAppRole.setId(null); // We will persist a new role, with ecomp
683                                                                                 // role id which will be different than
684                                                                                 // external app role id.
685
686                 roleService.saveRole(externalAppRole);
687                 logger.debug(EELFLoggerDelegate.debugLogger,
688                                 String.format("ECOMP persists role from app:%d, app roleId: %d, roleName: %s", appId,
689                                                 externalAppRole.getAppRoleId(), externalAppRole.getName()));
690         }
691
692         @Override
693         public List<EPRole> importRolesFromRemoteApplication(Long appId) throws HTTPException {
694                 EPRole[] appRolesFull = applicationsRestClientService.get(EPRole[].class, appId, "/rolesFull");
695                 List<EPRole> rolesList = Arrays.asList(appRolesFull);
696                 for (EPRole externalAppRole : rolesList) {
697
698                         // Try to find an existing extern role for the app in the local
699                         // ecomp DB. If so, then use its id to update the existing external
700                         // application role record.
701                         Long externAppId = externalAppRole.getId();
702                         EPRole existingAppRole = epRoleService.getRole(appId, externAppId);
703                         if (existingAppRole != null) {
704                                 logger.debug(EELFLoggerDelegate.debugLogger,
705                                                 String.format("ecomp role already exists for app=%s; appRoleId=%s. No need to import this one.",
706                                                                 appId, externAppId));
707                                 continue;
708                         }
709                         // persistExternalRoleInEcompDb(externalAppRole, appId,
710                         // roleService);
711                 }
712
713                 return rolesList;
714         }
715
716         @Override
717         public List<EPUserApp> getCachedAppRolesForUser(Long appId, Long userId) {
718                 // Find the records for this user-app combo, if any
719                 String filter = " where user_id = " + Long.toString(userId) + " and app_id = " + Long.toString(appId);
720                 @SuppressWarnings("unchecked")
721                 List<EPUserApp> roleList = dataAccessService.getList(EPUserApp.class, filter, null, null);
722                 logger.debug(EELFLoggerDelegate.debugLogger, "getCachedAppRolesForUser: list size is {}", roleList.size());
723                 return roleList;
724         }
725
726 }