nexus site path corrected
[portal.git] / ecomp-portal-BE / src / main / java / org / openecomp / portalapp / portal / service / EPAppServiceImpl.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
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.Base64;
29 /*-
30  * ================================================================================
31  * eCOMP Portal
32  * ================================================================================
33  * Copyright (C) 2017 AT&T Intellectual Property
34  * ================================================================================
35  * Licensed under the Apache License, Version 2.0 (the "License");
36  * you may not use this file except in compliance with the License.
37  * You may obtain a copy of the License at
38  * 
39  *      http://www.apache.org/licenses/LICENSE-2.0
40  * 
41  * Unless required by applicable law or agreed to in writing, software
42  * distributed under the License is distributed on an "AS IS" BASIS,
43  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44  * See the License for the specific language governing permissions and
45  * limitations under the License.
46  * ================================================================================
47  */
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.TreeSet;
52
53 import javax.annotation.PostConstruct;
54 import javax.servlet.http.HttpServletResponse;
55
56 import org.apache.commons.lang.StringUtils;
57 import org.hibernate.Query;
58 import org.hibernate.Session;
59 import org.hibernate.SessionFactory;
60 import org.hibernate.Transaction;
61 import org.springframework.beans.factory.annotation.Autowired;
62 import org.springframework.context.annotation.EnableAspectJAutoProxy;
63 import org.springframework.stereotype.Service;
64 import org.springframework.transaction.annotation.Transactional;
65
66 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
67 import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants;
68 import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties;
69 import org.openecomp.portalsdk.core.onboarding.ueb.Helper;
70 import org.openecomp.portalsdk.core.onboarding.ueb.TopicManager;
71 import org.openecomp.portalsdk.core.service.DataAccessService;
72 import org.openecomp.portalsdk.core.util.CipherUtil;
73 import org.openecomp.portalsdk.core.util.SystemProperties;
74 import org.openecomp.portalapp.portal.domain.AdminUserApp;
75 import org.openecomp.portalapp.portal.domain.AdminUserApplications;
76 import org.openecomp.portalapp.portal.domain.AppIdAndNameTransportModel;
77 import org.openecomp.portalapp.portal.domain.AppsResponse;
78 import org.openecomp.portalapp.portal.domain.EPApp;
79 import org.openecomp.portalapp.portal.domain.EPUser;
80 import org.openecomp.portalapp.portal.domain.EcompApp;
81 import org.openecomp.portalapp.portal.domain.UserRole;
82 import org.openecomp.portalapp.portal.domain.UserRoles;
83 import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
84 import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
85 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
86 import org.openecomp.portalapp.portal.transport.FieldsValidator;
87 import org.openecomp.portalapp.portal.transport.FunctionalMenuItem;
88 import org.openecomp.portalapp.portal.transport.LocalRole;
89 import org.openecomp.portalapp.portal.transport.OnboardingApp;
90 import org.openecomp.portalapp.portal.ueb.EPUebHelper;
91 import org.openecomp.portalapp.portal.utils.EPSystemProperties;
92 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
93 import org.openecomp.portalapp.portal.ecomp.model.AppCatalogItem;
94 import com.att.nsa.apiClient.http.HttpException;
95 import com.att.nsa.cambria.client.CambriaClient.CambriaApiException;
96 import com.att.nsa.cambria.client.CambriaClientBuilders;
97 import com.att.nsa.cambria.client.CambriaIdentityManager;
98
99 @Service("epAppService")
100 @Transactional
101 @org.springframework.context.annotation.Configuration
102 @EnableAspectJAutoProxy
103 @EPMetricsLog
104 public class EPAppServiceImpl implements EPAppService {
105
106         private String ECOMP_APP_ID = "1";
107         private String SUPER_ADMIN_ROLE_ID = "1";
108         private String ACCOUNT_ADMIN_ROLE_ID = "999";
109         private String RESTRICTED_APP_ROLE_ID = "900";
110
111         private static final String PATH_SEPARATOR = "/";
112         private static final String webappsBaseFullPath = System.getProperty("catalina.base") + PATH_SEPARATOR
113                         + "wtpwebapps";
114         private static final String imageCacheRelativePath = "images" + PATH_SEPARATOR + "cache";
115         private String ecompportalPath = null;
116         private static final Long DUBLICATED_FIELD_VALUE_ECOMP_ERROR = new Long(
117                         EPSystemProperties.DUBLICATED_FIELD_VALUE_ECOMP_ERROR);
118
119         private static final String urlField = "url";
120
121         private static final String nameField = "name";
122
123         EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(EPAppServiceImpl.class);
124
125         @Autowired
126         AdminRolesService adminRolesService;
127         @Autowired
128         private SessionFactory sessionFactory;
129         @Autowired
130         private DataAccessService dataAccessService;
131         @Autowired
132         EPUebHelper epUebHelper;
133
134         private String constructImagesCachePath() {
135                 String filePath = System.getProperty("catalina.base");
136                 File eclipseWebAppDir = new File(webappsBaseFullPath);
137
138                 if (eclipseWebAppDir.exists()) {
139                         // Eclipse webapps
140                         filePath += PATH_SEPARATOR + "wtpwebapps";
141                 } else {
142                         filePath += PATH_SEPARATOR + "webapps";
143                 }
144                 filePath += PATH_SEPARATOR + SystemProperties.getProperty(EPSystemProperties.ECOMP_CONTEXT_ROOT);;
145
146                 return filePath.toString();
147                 // return SystemProperties.getProperty(SystemProperties.TEMP_PATH);
148         }
149
150         @PostConstruct
151         private void init() {
152                 ecompportalPath = constructImagesCachePath();
153                 writeAppsImagesToDiskCacheIfNecessary();
154
155                 SUPER_ADMIN_ROLE_ID = SystemProperties.getProperty(EPSystemProperties.SYS_ADMIN_ROLE_ID);
156                 ACCOUNT_ADMIN_ROLE_ID = SystemProperties.getProperty(EPSystemProperties.ACCOUNT_ADMIN_ROLE_ID);
157                 ECOMP_APP_ID = SystemProperties.getProperty(EPSystemProperties.ECOMP_APP_ID);
158                 RESTRICTED_APP_ROLE_ID = SystemProperties.getProperty(EPSystemProperties.RESTRICTED_APP_ROLE_ID);
159         }
160
161         @Override
162         public List<EPApp> getUserAsAdminApps(EPUser user) {
163                 if (adminRolesService.isAccountAdmin(user)) {
164                         String sql = "SELECT * FROM FN_APP join FN_USER_ROLE ON FN_USER_ROLE.APP_ID=FN_APP.APP_ID where "
165                                         + "FN_USER_ROLE.USER_ID=" + user.getId() + " AND FN_USER_ROLE.ROLE_ID=" + ACCOUNT_ADMIN_ROLE_ID
166                                         + " AND FN_APP.ENABLED = 'Y'";
167                         logQuery(sql);
168                         try {
169                                 @SuppressWarnings("unchecked")
170                                 List<EPApp> adminApps = dataAccessService.executeSQLQuery(sql, EPApp.class, null);
171                                 return adminApps;
172                         } catch (Exception e) {
173                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
174                                 return null;
175                         }
176                 } else {
177                         logger.error(EELFLoggerDelegate.errorLogger,
178                                         "getUserAsAdminApps: only Account Admin may invoke this function!");
179                         return new ArrayList<EPApp>();
180                 }
181         }
182
183         @Override
184         public List<EPApp> getUserByOrgUserIdAsAdminApps(String orgUserId) {
185                 String format = "SELECT * FROM FN_APP app INNER JOIN FN_USER_ROLE userrole ON userrole.APP_ID=app.APP_ID "
186                                 + "INNER JOIN FN_USER user on user.USER_ID = userrole.USER_ID "
187                                 + "WHERE user.ORG_USER_ID = '%s' AND userrole.ROLE_ID=" + ACCOUNT_ADMIN_ROLE_ID + " AND FN_APP.ENABLED = 'Y'";
188
189                 String sql = String.format(format, orgUserId);
190                 logQuery(sql);
191
192                 try {
193                         @SuppressWarnings("unchecked")
194                         List<EPApp> adminApps = dataAccessService.executeSQLQuery(sql, EPApp.class, null);
195                         return adminApps;
196                 } catch (Exception e) {
197                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
198                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
199                         return null;
200                 }
201         }
202
203         @Override
204         public List<EPApp> getAppsFullList() {
205                 @SuppressWarnings("unchecked")
206                 List<EPApp> apps = dataAccessService.getList(EPApp.class, null);
207                 // Write the image to disk in case if it is missing
208                 for (EPApp app : apps)
209                         writeAppImageToDiskCacheIfNecessary(app);
210                 return apps;
211         }
212
213         @Override
214         public List<EcompApp> getEcompAppAppsFullList() {
215                 return transformAppsToEcompApps(getAppsFullList());
216         }
217
218         @Override
219         public List<EcompApp> transformAppsToEcompApps(List<EPApp> appsList) {
220                 List<EcompApp> ecompAppList = new ArrayList<EcompApp>();
221                 for (EPApp app : appsList) {
222                         EcompApp ecompApp = new EcompApp();
223                         ecompApp.setId(app.getId());
224                         ecompApp.setName(app.getName());
225                         ecompApp.setImageUrl(app.getImageUrl());
226                         ecompApp.setDescription(app.getDescription());
227                         ecompApp.setNotes(app.getNotes());
228                         ecompApp.setUrl(app.getUrl());
229                         ecompApp.setAlternateUrl(app.getAlternateUrl());
230                         ecompApp.setUebTopicName(app.getUebTopicName());
231                         ecompApp.setUebKey(app.getUebKey());
232                         ecompApp.setUebSecret(app.getUebSecret());
233                         ecompApp.setEnabled(app.getEnabled());
234                         ecompApp.setRestrictedApp(app.isRestrictedApp());
235                         ecompAppList.add(ecompApp);
236                 }
237                 return ecompAppList;
238         }
239
240         @Override
241         public EPApp getApp(Long appId) {
242                 try {
243                         @SuppressWarnings("unchecked")
244                         List<EPApp> apps = dataAccessService.getList(EPApp.class, " where id = " + appId, null, null);
245                         return (apps.size() > 0) ? apps.get(0) : null;
246                 } catch (Exception e) {
247                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
248                         return null;
249                 }
250         }
251
252         @SuppressWarnings("unchecked")
253         @Override
254         public List<AppIdAndNameTransportModel> getAdminApps(EPUser user) {
255                 if (adminRolesService.isAccountAdmin(user)) {
256                         String format = "SELECT app.APP_ID, app.APP_NAME, app.APP_TYPE FROM FN_APP app inner join FN_USER_ROLE userrole ON userrole.APP_ID=app.APP_ID "
257                                         + "where userrole.USER_ID = %d AND userrole.ROLE_ID=" + ACCOUNT_ADMIN_ROLE_ID
258                                         + " AND app.ENABLED = 'Y'";
259                         String sql = String.format(format, user.getId());
260                         // sql += " AND app.APP_REST_ENDPOINT IS NOT NULL AND
261                         // app.APP_REST_ENDPOINT <> ''";
262                         logQuery(sql);
263                         try {
264                                 return (ArrayList<AppIdAndNameTransportModel>) dataAccessService.executeSQLQuery(sql,
265                                                 AppIdAndNameTransportModel.class, null);
266                         } catch (Exception e) {
267                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
268                                 logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while fetching the adminApps for user "
269                                                 + user.getLoginId() + ". Details: " + EcompPortalUtils.getStackTrace(e));
270                         }
271                 }
272                 return new ArrayList<AppIdAndNameTransportModel>();
273         }
274
275         @SuppressWarnings("unchecked")
276         @Override
277         public List<AppIdAndNameTransportModel> getAppsForSuperAdminAndAccountAdmin(EPUser user) {
278                 if (adminRolesService.isSuperAdmin(user) || adminRolesService.isAccountAdmin(user)) {
279                         String format = "";
280                         String sql = "";
281                         if (adminRolesService.isSuperAdmin(user)) {
282                                 format = "SELECT app.APP_ID, app.APP_NAME, app.APP_TYPE FROM FN_APP app " + "where app.ENABLED = 'Y'";
283                         } else {
284                                 format = "SELECT app.APP_ID, app.APP_NAME, APP_TYPE FROM FN_APP app inner join FN_USER_ROLE userrole ON userrole.APP_ID=app.APP_ID "
285                                                 + "where userrole.USER_ID = %d AND userrole.ROLE_ID=" + ACCOUNT_ADMIN_ROLE_ID
286                                                 + " AND app.ENABLED = 'Y'";
287                         }
288                         sql = String.format(format, user.getId());
289                         // sql += " AND app.APP_REST_ENDPOINT IS NOT NULL AND
290                         // app.APP_REST_ENDPOINT <> ''";
291                         logQuery(sql);
292                         try {
293                                 return (ArrayList<AppIdAndNameTransportModel>) dataAccessService.executeSQLQuery(sql,
294                                                 AppIdAndNameTransportModel.class, null);
295                         } catch (Exception e) {
296                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
297                                 logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while fetching the adminApps for user "
298                                                 + user.getLoginId() + ". Details: " + EcompPortalUtils.getStackTrace(e));
299                         }
300                 }
301                 return new ArrayList<AppIdAndNameTransportModel>();
302         }
303
304         private void logQuery(String sql) {
305                 logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql);
306         }
307
308         public DataAccessService getDataAccessService() {
309                 return dataAccessService;
310         }
311
312         public void setDataAccessService(DataAccessService dataAccessService) {
313                 this.dataAccessService = dataAccessService;
314         }
315
316         @Override
317         public List<AdminUserApplications> getAppsAdmins() {
318                 String sql = "SELECT apps.APP_NAME, apps.APP_ID, user.USER_ID, user.FIRST_NAME, user.LAST_NAME, user.ORG_USER_ID FROM fn_user_role userrole "
319                                 + "INNER JOIN fn_user user ON user.USER_ID = userrole.USER_ID "
320                                 + "INNER JOIN fn_app apps ON apps.APP_ID = userrole.APP_ID " + "WHERE userrole.ROLE_ID = "
321                                 + ACCOUNT_ADMIN_ROLE_ID + " AND apps.ENABLED = 'Y'";
322                 logQuery(sql);
323                 try {
324                         @SuppressWarnings("unchecked")
325                         List<AdminUserApp> adminApps = dataAccessService.executeSQLQuery(sql, AdminUserApp.class, null); // DataAccessService
326                                                                                                                                                                                                                                 // does
327                                                                                                                                                                                                                                 // not
328                                                                                                                                                                                                                                 // use
329                                                                                                                                                                                                                                 // generic
330                                                                                                                                                                                                                                 // types.
331                         return aggregateRowsResultsByUserId(adminApps);
332                 } catch (Exception e) {
333                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
334                         return null;
335                 }
336         }
337
338         private List<AdminUserApplications> aggregateRowsResultsByUserId(List<AdminUserApp> adminApps) {
339                 HashMap<Long, AdminUserApplications> adminUserApplications = new HashMap<Long, AdminUserApplications>();
340                 for (AdminUserApp app : adminApps) {
341                         Long userId = app.getUser_Id();
342                         if (adminUserApplications.get(userId) == null)
343                                 adminUserApplications.put(userId, new AdminUserApplications(app));
344                         else
345                                 adminUserApplications.get(userId).addApp(app.getAppId(), app.getAppName());
346                 }
347                 return new ArrayList<AdminUserApplications>(adminUserApplications.values());
348         }
349
350         @Override
351         public List<AppsResponse> getAllApps(Boolean all) {
352                 // If all is true, return both active and inactive apps. Otherwise, just
353                 // active apps.
354                 @SuppressWarnings("unchecked")
355                 // Sort the list by application name so the drop-down looks pretty.
356                 List<EPApp> apps = all
357                                 ? (List<EPApp>) dataAccessService.getList(EPApp.class, " where id != " + ECOMP_APP_ID, "name", null)
358                                 : (List<EPApp>) dataAccessService.getList(EPApp.class, " where enabled = 'Y'", "name", null);
359                 List<AppsResponse> appsModified = new ArrayList<AppsResponse>();
360                 for (EPApp app : apps) {
361                         appsModified.add(new AppsResponse(app.getId(), app.getName(), app.isRestrictedApp(), app.getEnabled()));
362
363                         // Write the image to disk in case if it is missing
364                         writeAppImageToDiskCacheIfNecessary(app);
365                 }
366                 return appsModified;
367         }
368
369         @Override
370         public UserRoles getUserProfile(String loginId) {
371                 String format = "SELECT DISTINCT user.USER_ID, role.ROLE_ID, user.ORG_USER_ID, user.FIRST_NAME, user.LAST_NAME, role.ROLE_NAME  FROM fn_user_role userrole "
372                                 + "INNER JOIN fn_user user ON user.USER_ID = userrole.USER_ID "
373                                 + "INNER JOIN fn_role role ON role.ROLE_ID = userrole.ROLE_ID " + "WHERE user.ORG_USER_ID = \"%s\";";
374                 String sql = String.format(format, loginId);
375                 logQuery(sql);
376                 @SuppressWarnings("unchecked")
377                 List<UserRole> userRoleList = dataAccessService.executeSQLQuery(sql, UserRole.class, null);
378                 ArrayList<UserRoles> usersRolesList = aggregateUserProfileRowsResultsByRole(userRoleList);
379                 if (usersRolesList == null || usersRolesList.size() < 1)
380                         return null;
381
382                 return usersRolesList.get(0);
383         }
384
385         private ArrayList<UserRoles> aggregateUserProfileRowsResultsByRole(List<UserRole> userRoleList) {
386                 HashMap<String, UserRoles> userRoles = new HashMap<String, UserRoles>();
387                 for (UserRole user : userRoleList) {
388                         String orgUserId = user.getOrgUserId();
389                         if (userRoles.get(orgUserId) == null)
390                                 userRoles.put(orgUserId, new UserRoles(user));
391                         else
392                                 userRoles.get(orgUserId).addRole(user.getRoleId());
393                 }
394                 return new ArrayList<UserRoles>(userRoles.values());
395         }
396
397         private boolean isRestrictedApp(Long appId) {
398                 EPApp app = getApp(appId);
399                 return app.isRestrictedApp();
400         }
401
402         // For the functional menu edit
403         @Override
404         public List<LocalRole> getAppRoles(Long appId) {
405                 String sql = "";
406                 if (isRestrictedApp(appId)) {
407                         sql = "SELECT ROLE_ID, ROLE_NAME from FN_ROLE where ROLE_ID = '" + RESTRICTED_APP_ROLE_ID + "'";
408                 } else {
409                         sql = "SELECT ROLE_ID, ROLE_NAME from FN_ROLE where APP_ID = '" + appId + "'";
410                 }
411                 logQuery(sql);
412                 @SuppressWarnings("unchecked")
413                 List<LocalRole> appRoles = dataAccessService.executeSQLQuery(sql, LocalRole.class, null);
414                 return appRoles;
415         }
416
417         private String userAppsQuery(EPUser user) {
418                 StringBuilder query = new StringBuilder();
419                 if (adminRolesService.isSuperAdmin(user)) {
420                         query.append("SELECT * FROM FN_APP where FN_APP.ENABLED = 'Y'");
421                 } else {
422                         query.append("SELECT * FROM FN_APP join FN_USER_ROLE ON FN_USER_ROLE.APP_ID = FN_APP.APP_ID where ");
423                         query.append(
424                                         "FN_USER_ROLE.USER_ID = " + user.getId() + " AND FN_USER_ROLE.ROLE_ID != " + SUPER_ADMIN_ROLE_ID);
425                         query.append(" AND FN_APP.ENABLED = 'Y'");
426                 }
427                 return query.toString();
428         }
429
430         @Override
431         public List<EPApp> getUserApps(EPUser user) {
432                 List<EPApp> openApps = getOpenApps();
433                 for (EPApp app : openApps) {
434                         // Write the image to disk in case if it is missing
435                         writeAppImageToDiskCacheIfNecessary(app);
436                 }
437
438                 if (user.isGuest()) {
439                         return openApps;
440                 } else {
441                         String sql = userAppsQuery(user);
442                         logQuery(sql);
443
444                         TreeSet<EPApp> distinctApps = new TreeSet<EPApp>();
445
446                         @SuppressWarnings("unchecked")
447                         List<EPApp> adminApps = dataAccessService.executeSQLQuery(sql, EPApp.class, null);
448                         for (EPApp app : adminApps) {
449                                 // Write the image to disk in case if it is missing
450                                 writeAppImageToDiskCacheIfNecessary(app);
451
452                                 distinctApps.add(app);
453                         }
454
455                         for (EPApp app : openApps) {
456                                 distinctApps.add(app);
457                         }
458
459                         List<EPApp> userApps = new ArrayList<EPApp>();
460                         userApps.addAll(distinctApps);
461                         return userApps;
462                 }
463         }
464
465         @Override
466         public List<EPApp> getPersAdminApps(EPUser user) {
467                 final Map<String, Long> params = new HashMap<>();
468                 params.put("userId", user.getId());
469                 // Named query is stored in EP.hbm.xml, mapped to EPApp
470                 @SuppressWarnings("unchecked")
471                 List<EPApp> list = dataAccessService.executeNamedQuery("getPersAdminApps", params, null);
472                 // Why is this necessary?
473                 for (EPApp app : list) 
474                         writeAppImageToDiskCacheIfNecessary(app);
475                 return list;
476         }
477
478         @Override
479         public List<EPApp> getPersUserApps(EPUser user) {
480                 final Map<String, Long> params = new HashMap<>();
481                 params.put("userId", user.getId());
482                 // Named query is stored in EP.hbm.xml, mapped to EPApp
483                 @SuppressWarnings("unchecked")
484                 List<EPApp> list = dataAccessService.executeNamedQuery("getPersUserApps", params, null);
485                 // Why is this necessary?
486                 for (EPApp app : list) 
487                         writeAppImageToDiskCacheIfNecessary(app);
488                 return list;
489         }
490
491         /*
492          * (non-Javadoc)
493          * @see org.openecomp.portalapp.portal.service.EPAppService#getAppCatalog(org.openecomp.portalapp.portal.domain.EPUser)
494          */
495         @Override
496         public List<AppCatalogItem> getUserAppCatalog(EPUser user) {
497                 final Map<String, Long> params = new HashMap<>();
498                 params.put("userId", user.getId());
499                 // Named query is stored in EP.hbm.xml, mapped to AppCatalogItem
500                 @SuppressWarnings("unchecked")
501                 List<AppCatalogItem> list = dataAccessService.executeNamedQuery("getUserAppCatalog", params, null);
502                 return list;
503         }
504         
505         /*
506          * (non-Javadoc)
507          * @see org.openecomp.portalapp.portal.service.EPAppService#getAdminAppCatalog(org.openecomp.portalapp.portal.domain.EPUser)
508          */
509         @Override
510         public List<AppCatalogItem> getAdminAppCatalog(EPUser user) {
511                 final Map<String, Long> params = new HashMap<>();
512                 params.put("userId", user.getId());
513                 // Named query is stored in EP.hbm.xml, mapped to AppCatalogItem
514                 @SuppressWarnings("unchecked")
515                 List<AppCatalogItem> list = dataAccessService.executeNamedQuery("getAdminAppCatalog", params, null);
516                 return list;
517         }
518
519         private List<EPApp> getOpenApps() {
520                 @SuppressWarnings("unchecked")
521                 List<EPApp> openApps = dataAccessService.getList(EPApp.class, " where open='Y' and enabled='Y'", null, null);
522                 return openApps;
523         }
524
525         @Override
526         public List<OnboardingApp> getOnboardingApps() {
527                 @SuppressWarnings("unchecked")
528                 List<EPApp> apps = (List<EPApp>) dataAccessService.getList(EPApp.class, " where id!=" + ECOMP_APP_ID, null,
529                                 null);
530                 List<OnboardingApp> onboardingAppsList = new ArrayList<OnboardingApp>();
531                 for (EPApp app : apps) {
532                         OnboardingApp onboardingApp = new OnboardingApp();
533                         createOnboardingFromApp(app, onboardingApp);
534                         onboardingAppsList.add(onboardingApp);
535                 }
536                 return onboardingAppsList;
537         }
538
539         @Override
540         public List<OnboardingApp> getEnabledNonOpenOnboardingApps() {
541                 @SuppressWarnings("unchecked")
542                 List<EPApp> apps = (List<EPApp>) dataAccessService.getList(EPApp.class,
543                                 " where enabled = true and open = false and id!=" + ECOMP_APP_ID, null, null);
544                 List<OnboardingApp> onboardingAppsList = new ArrayList<OnboardingApp>();
545                 for (EPApp app : apps) {
546                         OnboardingApp onboardingApp = new OnboardingApp();
547                         createOnboardingFromApp(app, onboardingApp);
548                         onboardingAppsList.add(onboardingApp);
549                 }
550                 return onboardingAppsList;
551         }
552
553         private FieldsValidator onboardingAppFieldsChecker(OnboardingApp onboardingApp) {
554                 FieldsValidator fieldsValidator = new FieldsValidator();
555                 if (onboardingApp.name == null || onboardingApp.name.length() == 0 || onboardingApp.url == null
556                                 || onboardingApp.url.length() == 0 || onboardingApp.restrictedApp == null
557                                 || onboardingApp.isOpen == null || onboardingApp.isEnabled == null
558                                 || (onboardingApp.id != null && onboardingApp.id.equals(ECOMP_APP_ID))
559                                 // For a normal app (appType==1), these fields must be filled
560                                 // in.
561                                 // For a restricted app (appType==2), they will be empty.
562                                 || ((!onboardingApp.restrictedApp) && (onboardingApp.username == null
563                                                 || onboardingApp.username.length() == 0 || onboardingApp.appPassword == null
564                                                 || onboardingApp.appPassword.length() == 0))) {
565                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_BAD_REQUEST);
566                 }
567                 return fieldsValidator;
568         }
569
570         @SuppressWarnings("unchecked")
571         private void validateOnboardingApp(OnboardingApp onboardingApp, FieldsValidator fieldsValidator) {
572                 boolean dublicatedUrl = false;
573                 boolean dublicatedName = false;
574                 List<EPApp> apps;
575                 if (onboardingApp.id == null) {
576                         apps = dataAccessService.getList(EPApp.class,
577                                         " where url = '" + onboardingApp.url + "' or name = '" + onboardingApp.name + "'", null, null);
578                 } else {
579                         apps = dataAccessService.getList(EPApp.class, " where id = " + onboardingApp.id + " or url = '"
580                                         + onboardingApp.url + "' or name = '" + onboardingApp.name + "'", null, null);
581                 }
582                 for (EPApp app : apps) {
583                         if (onboardingApp.id != null && onboardingApp.id.equals(app.getId())) {
584                                 continue;
585                         }
586                         if (!dublicatedUrl && app.getUrl().equalsIgnoreCase(onboardingApp.url)) {
587                                 dublicatedUrl = true;
588                                 if (dublicatedName) {
589                                         break;
590                                 }
591                         }
592                         if (!dublicatedName && app.getName().equalsIgnoreCase(onboardingApp.name)) {
593                                 dublicatedName = true;
594                                 if (dublicatedUrl) {
595                                         break;
596                                 }
597                         }
598                 }
599                 if (dublicatedUrl || dublicatedName) {
600                         if (dublicatedUrl) {
601                                 fieldsValidator.addProblematicFieldName(urlField);
602                         }
603                         if (dublicatedName) {
604                                 fieldsValidator.addProblematicFieldName(nameField);
605                         }
606                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_CONFLICT);
607                         fieldsValidator.errorCode = DUBLICATED_FIELD_VALUE_ECOMP_ERROR;
608                 }
609         }
610
611         @Override
612         public FieldsValidator modifyOnboardingApp(OnboardingApp modifiedOnboardingApp, EPUser user) {
613                 logger.debug(EELFLoggerDelegate.debugLogger, "LR: entering modifyOnboardingApp");
614                 FieldsValidator fieldsValidator = onboardingAppFieldsChecker(modifiedOnboardingApp);
615                 if (fieldsValidator.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
616                         validateOnboardingApp(modifiedOnboardingApp, fieldsValidator);
617                 }
618                 if (fieldsValidator.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
619                         if (modifiedOnboardingApp.id != null) {
620                                 updateApp(modifiedOnboardingApp.id, modifiedOnboardingApp, fieldsValidator, user);
621                         } else {
622                                 fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_BAD_REQUEST);
623                         }
624                 }
625                 return fieldsValidator;
626         }
627
628         @Override
629         public FieldsValidator addOnboardingApp(OnboardingApp newOnboardingApp, EPUser user) {
630                 FieldsValidator fieldsValidator = onboardingAppFieldsChecker(newOnboardingApp);
631                 if (fieldsValidator.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
632                         validateOnboardingApp(newOnboardingApp, fieldsValidator);
633                 }
634                 if (fieldsValidator.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
635                         if (newOnboardingApp.id == null) {
636                                 updateApp(null, newOnboardingApp, fieldsValidator, user);
637                         } else {
638                                 fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_BAD_REQUEST);
639                         }
640                 }
641                 return fieldsValidator;
642         }
643
644         @Override
645         public FieldsValidator deleteOnboardingApp(EPUser user, Long appid) {
646                 FieldsValidator fieldsValidator = new FieldsValidator();
647                 if (!adminRolesService.isSuperAdmin(user)) {
648                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_FORBIDDEN);
649                         return fieldsValidator;
650                 }
651                 Boolean result = false;
652                 Session localSession = null;
653                 Transaction transaction = null;
654                 try {
655                         localSession = sessionFactory.openSession();
656                         transaction = localSession.beginTransaction();
657
658                         // 1) Remove the URL for any functional menu item associated with
659                         // this app
660                         String sql = "UPDATE fn_menu_functional m, fn_menu_functional_roles mr SET m.url='' "
661                                         + " WHERE m.menu_id=mr.menu_id " + " AND mr.app_id='" + appid + "'";
662                         logQuery(sql);
663                         Query query = localSession.createSQLQuery(sql);
664                         query.executeUpdate();
665
666                         // 2) Remove any favorites associated with a menu item that is
667                         // associated with this app
668                         sql = "Delete from fn_menu_favorites " + " using fn_menu_favorites inner join fn_menu_functional_roles "
669                                         + " where fn_menu_functional_roles.app_id='" + appid + "' "
670                                         + " AND fn_menu_functional_roles.menu_id=fn_menu_favorites.menu_id";
671                         logQuery(sql);
672                         query = localSession.createSQLQuery(sql);
673                         query.executeUpdate();
674
675                         // 3) Remove all role,appid records from fn_menu_functional_role
676                         // that are associated with this app
677                         sql = "delete from fn_menu_functional_roles where app_id='" + appid + "'";
678                         logQuery(sql);
679                         query = localSession.createSQLQuery(sql);
680                         query.executeUpdate();
681
682                         // 4) Remove all records from fn_user_role associated with this app
683                         sql = "delete from fn_user_role where app_id='" + appid + "'";
684                         logQuery(sql);
685                         query = localSession.createSQLQuery(sql);
686                         query.executeUpdate();
687
688                         // 5) Remove all records from fn_role associated with this app
689                         sql = "delete from fn_role where app_id='" + appid + "'";
690                         logQuery(sql);
691                         query = localSession.createSQLQuery(sql);
692                         query.executeUpdate();
693
694                         // 6) Remove any widgets associated with this app
695                         sql = "delete from fn_widget where app_id='" + appid + "'";
696                         logQuery(sql);
697                         query = localSession.createSQLQuery(sql);
698                         query.executeUpdate();
699
700                         // Remove any selections in the personalization table
701                         sql = "delete from fn_pers_user_app_sel where app_id='" + appid + "'";
702                         logQuery(sql);
703                         query = localSession.createSQLQuery(sql);
704                         query.executeUpdate();
705                         
706                         // Delete the app
707                         sql = "delete from fn_app where app_id='" + appid + "'";
708                         logQuery(sql);
709                         query = localSession.createSQLQuery(sql);
710                         query.executeUpdate();
711
712                         transaction.commit();
713                         result = true;
714                 } catch (Exception e) {
715                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
716                         EcompPortalUtils.rollbackTransaction(transaction, "deleteOnboardingApp rollback, exception = " + e);
717                 } finally {
718                         EcompPortalUtils.closeLocalSession(localSession, "deleteOnboardingApp");
719                 }
720                 if (!result) {
721                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
722                 }
723                 return fieldsValidator;
724         }
725
726         private static Object syncRests = new Object();
727
728         // An app has been enabled/disabled. Must enable/disable all associated
729         // functional menu items.
730         private void setFunctionalMenuItemsEnabled(Session localSession, Boolean enabled, Long appId) {
731                 String active_yn = enabled ? "Y" : "N";
732                 String sql = "SELECT m.menu_id, m.column_num, m.text, m.parent_menu_id, m.url, m.active_yn "
733                                 + "FROM fn_menu_functional m, fn_menu_functional_roles r " + "WHERE m.menu_id = r.menu_id "
734                                 + " AND r.app_id = '" + appId + "' ";
735                 logQuery(sql);
736                 @SuppressWarnings("unchecked")
737                 List<FunctionalMenuItem> menuItems = dataAccessService.executeSQLQuery(sql, FunctionalMenuItem.class, null);
738                 for (FunctionalMenuItem menuItem : menuItems) {
739                         FunctionalMenuItem myMenuItem = (FunctionalMenuItem) localSession.get(FunctionalMenuItem.class,
740                                         menuItem.menuId);
741                         myMenuItem.active_yn = active_yn;
742                         localSession.save(myMenuItem);
743                 }
744         }
745
746         // Attention! If (appId == null) we use this function to create application
747         // otherwise we use it to modify existing application
748         private void updateApp(Long appId, OnboardingApp onboardingApp, FieldsValidator fieldsValidator, EPUser user) {
749                 logger.debug(EELFLoggerDelegate.debugLogger, "LR: entering updateApp");
750                 // Separate out the code for a restricted app, since it doesn't need any
751                 // of the UEB code.
752                 if (onboardingApp.restrictedApp) {
753                         boolean result = false;
754                         Session localSession = null;
755                         Transaction transaction = null;
756                         try {
757                                 localSession = sessionFactory.openSession();
758                                 transaction = localSession.beginTransaction();
759                                 EPApp app;
760                                 if (appId == null) {
761                                         app = new EPApp();
762                                 } else {
763                                         app = (EPApp) localSession.get(EPApp.class, appId);
764                                         if (app == null || app.getId() == null) { // App is already
765                                                 // deleted!
766                                                 transaction.commit();
767                                                 localSession.close();
768                                                 fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_NOT_FOUND);
769                                                 return;
770                                         }
771                                 }
772                                 createAppFromOnboarding(app, onboardingApp, localSession);
773                                 localSession.saveOrUpdate(app);
774                                 // Enable or disable all menu items associated with this app
775                                 setFunctionalMenuItemsEnabled(localSession, onboardingApp.isEnabled, appId);
776                                 transaction.commit();
777                                 result = true;
778                         } catch (Exception e) {
779                                 EcompPortalUtils.rollbackTransaction(transaction,
780                                                 "updateApp rollback, exception = " + EcompPortalUtils.getStackTrace(e));
781                         } finally {
782                                 EcompPortalUtils.closeLocalSession(localSession, "updateApp");
783                         }
784                         if (!result) {
785                                 fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
786                         }
787
788                 } else {
789                         synchronized (syncRests) {
790                                 boolean result = false;
791                                 Session localSession = null;
792                                 Transaction transaction = null;
793                                 try {
794                                         localSession = sessionFactory.openSession();
795                                         transaction = localSession.beginTransaction();
796                                         EPApp app;
797                                         if (appId == null) {
798                                                 app = new EPApp();
799                                                 // -------------------------------------------------------------------------------------------
800                                                 // Register this App with the UEB communication server.
801                                                 // Save
802                                                 // the App's unique mailbox/topic
803                                                 // name and keys to the FN_APP table. The App's mailbox
804                                                 // and
805                                                 // keys will be visible to the
806                                                 // admin on the ECOMP portal.
807                                                 // -------------------------------------------------------------------------------------------
808                                                 TopicManager topicManager = new TopicManager();
809                                                 final CambriaIdentityManager im = new CambriaClientBuilders.IdentityManagerBuilder()
810                                                                 .usingHosts(Helper.uebUrlList()).build();
811                                                 com.att.nsa.apiClient.credentials.ApiCredential credential = im.createApiKey(user.getEmail(),
812                                                                 "ECOMP Portal Owner");
813                                                 String appKey = credential.getApiKey();
814                                                 String appSecret = credential.getApiSecret();
815                                                 boolean isProductionBuild = EcompPortalUtils.isProductionBuild();
816                                                 String appMailboxName = null;
817
818                                                 int maxNumAttemptsToCreateATopic = 3;
819                                                 boolean successfullyCreatedMailbox = false;
820                                                 for (int i = 0; i < maxNumAttemptsToCreateATopic; i++) {
821                                                         if (isProductionBuild) {
822                                                                 appMailboxName = "ECOMP-PORTAL-OUTBOX-" + (int) (Math.random() * 100000.0);
823                                                         } else {
824                                                                 appMailboxName = "ECOMP-PORTAL-OUTBOX-TEST-" + (int) (Math.random() * 100000.0);
825                                                         }
826
827                                                         try {
828                                                                 topicManager.createTopic(
829                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY),
830                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET),
831                                                                                 appMailboxName, "ECOMP outbox for app" + onboardingApp.name);
832                                                                 successfullyCreatedMailbox = true;
833                                                                 logger.debug(EELFLoggerDelegate.debugLogger,
834                                                                                 "Successfully created " + appMailboxName + " for App " + onboardingApp.name);
835                                                                 logger.debug(EELFLoggerDelegate.debugLogger, "    Key = " + appKey + " Secret = "
836                                                                                 + appSecret + " generated using = " + user.getEmail());
837                                                                 break;
838                                                         } catch (HttpException e) {
839                                                                 String stackTrace = EcompPortalUtils.getStackTrace(e);
840                                                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeUebConnectionError, e.getMessage());
841                                                                 if (e.getStatusCode() == 409) {
842                                                                         logger.error(EELFLoggerDelegate.errorLogger,
843                                                                                         "Topic/mailbox " + appMailboxName
844                                                                                                         + " already exists. Will try using a different name, Details: "
845                                                                                                         + stackTrace);
846                                                                 } else {
847                                                                         logger.error(EELFLoggerDelegate.errorLogger,
848                                                                                         "HttpException when onboarding App: " + stackTrace);
849                                                                 }
850                                                         }
851                                                 }
852
853                                                 if (successfullyCreatedMailbox) {
854                                                         onboardingApp.setUebTopicName(appMailboxName);
855                                                         onboardingApp.setUebKey(appKey);
856                                                         onboardingApp.setUebSecret(appSecret);
857
858                                                         try {
859                                                                 /*
860                                                                  * EP is a publisher to this App's new mailbox
861                                                                  */
862                                                                 topicManager.addPublisher(
863                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY),
864                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET),
865                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY),
866                                                                                 appMailboxName);
867
868                                                                 /*
869                                                                  * This App is a subcriber of it's own mailbox
870                                                                  */
871                                                                 topicManager.addSubscriber(
872                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY),
873                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET), appKey,
874                                                                                 appMailboxName);
875
876                                                                 /*
877                                                                  * This App is a publisher to EP
878                                                                  */
879                                                                 topicManager.addPublisher(
880                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY),
881                                                                                 PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET), appKey,
882                                                                                 PortalApiProperties.getProperty(PortalApiConstants.ECOMP_PORTAL_INBOX_NAME));
883                                                         } catch (HttpException | CambriaApiException | IOException e) {
884                                                                 String stackTrace = EcompPortalUtils.getStackTrace(e);
885                                                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeUebRegisterOnboardingAppError,
886                                                                                 e.getMessage());
887                                                                 logger.error(EELFLoggerDelegate.errorLogger,
888                                                                                 "Error when configuring Publisher/Subscriber for App's new mailbox "
889                                                                                                 + stackTrace);
890                                                                 transaction.commit();
891                                                                 localSession.close();
892                                                                 fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_CONFLICT);
893                                                                 return;
894                                                         }
895                                                 } else {
896                                                         transaction.commit();
897                                                         localSession.close();
898                                                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_CONFLICT);
899                                                         return;
900                                                 }
901                                         } else {
902                                                 app = (EPApp) localSession.get(EPApp.class, appId);
903                                                 if (app == null || app.getId() == null) { // App is
904                                                                                                                                         // already
905                                                         // deleted!
906                                                         transaction.commit();
907                                                         localSession.close();
908                                                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_NOT_FOUND);
909                                                         return;
910                                                 }
911                                         }
912                                         logger.debug(EELFLoggerDelegate.debugLogger, "LR: about to call createAppFromOnboarding");
913                                         createAppFromOnboarding(app, onboardingApp, localSession);
914                                         logger.debug(EELFLoggerDelegate.debugLogger,
915                                                         "LR: updateApp: finished calling createAppFromOnboarding");
916                                         localSession.saveOrUpdate(app);
917                                         logger.debug(EELFLoggerDelegate.debugLogger,
918                                                         "LR: updateApp: finished calling localSession.saveOrUpdate");
919                                         // Enable or disable all menu items associated with this app
920                                         setFunctionalMenuItemsEnabled(localSession, onboardingApp.isEnabled, appId);
921                                         logger.debug(EELFLoggerDelegate.debugLogger,
922                                                         "LR: updateApp: finished calling setFunctionalMenuItemsEnabled");
923                                         transaction.commit();
924                                         logger.debug(EELFLoggerDelegate.debugLogger, "LR: updateApp: finished calling transaction.commit");
925                                         epUebHelper.addPublisher(app);
926                                         logger.debug(EELFLoggerDelegate.debugLogger,
927                                                         "LR: updateApp: finished calling epUebHelper.addPublisher");
928                                         result = true;
929                                 } catch (Exception e) {
930                                         logger.debug(EELFLoggerDelegate.debugLogger, "exception: " + e.toString());
931                                         logger.debug(EELFLoggerDelegate.debugLogger, "exception.cause: " + e.getCause());
932                                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeUebRegisterOnboardingAppError, e.getMessage());
933                                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError);
934                                         EcompPortalUtils.rollbackTransaction(transaction,
935                                                         "updateApp rollback, exception = " + EcompPortalUtils.getStackTrace(e));
936                                 } finally {
937                                         EcompPortalUtils.closeLocalSession(localSession, "updateApp");
938                                 }
939                                 if (!result) {
940                                         fieldsValidator.httpStatusCode = new Long(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
941                                 }
942                         }
943                 }
944         }
945
946         private void createOnboardingFromApp(EPApp app, OnboardingApp onboardingApp) {
947                 onboardingApp.id = app.getId();
948                 onboardingApp.name = app.getName();
949                 onboardingApp.imageUrl = app.getImageUrl();
950                 onboardingApp.description = app.getDescription();
951                 onboardingApp.notes = app.getNotes();
952                 onboardingApp.url = app.getUrl();
953                 onboardingApp.alternateUrl = app.getAlternateUrl();
954                 onboardingApp.restUrl = app.getAppRestEndpoint();
955                 onboardingApp.isOpen = app.getOpen();
956                 onboardingApp.isEnabled = app.getEnabled();
957                 onboardingApp.username = app.getUsername();
958                 onboardingApp.appPassword = this.decryptedPassword(app.getAppPassword(), app);
959                 onboardingApp.uebTopicName = app.getUebTopicName();
960                 onboardingApp.uebKey = app.getUebKey();
961                 onboardingApp.uebSecret = app.getUebSecret();
962                 onboardingApp.setRestrictedApp(app.isRestrictedApp());
963
964                 if (app.getThumbnail() != null) {
965                         onboardingApp.thumbnail = new String(Base64.getEncoder().encode(app.getThumbnail()));
966                         // Write the image to disk in case if it is missing
967                         writeAppImageToDiskCacheIfNecessary(app);
968                 }
969         }
970
971         private EPApp createAppFromOnboarding(EPApp app, OnboardingApp onboardingApp, Session localSession) {
972                 logger.debug(EELFLoggerDelegate.debugLogger, "LR: entering createAppFromOnboarding");
973                 app.setName(onboardingApp.name);
974                 app.setDescription(onboardingApp.description);
975                 app.setNotes(onboardingApp.notes);
976                 app.setUrl(onboardingApp.url);
977                 app.setAlternateUrl(onboardingApp.alternateUrl);
978                 app.setAppRestEndpoint(onboardingApp.restUrl);
979                 app.setOpen(onboardingApp.isOpen);
980                 app.setEnabled(onboardingApp.isEnabled);
981                 app.setUsername(onboardingApp.username);
982                 app.setAppPassword(this.encryptedPassword(onboardingApp.appPassword, app));
983                 app.setUebTopicName(onboardingApp.uebTopicName);
984                 app.setUebKey(onboardingApp.uebKey);
985                 app.setUebSecret(onboardingApp.uebSecret);
986                 app.setRestrictedApp(onboardingApp.restrictedApp);
987                 if (!StringUtils.isEmpty(onboardingApp.thumbnail)) {
988                         logger.debug(EELFLoggerDelegate.debugLogger, "LR: onboarding thumbnail is NOT empty");
989                         String[] splitBase64Thumbnail = onboardingApp.thumbnail.split("base64,");
990                         if (splitBase64Thumbnail != null) {
991                                 logger.debug(EELFLoggerDelegate.debugLogger,
992                                                 "LR: length of splitBase64Thumbnail: " + splitBase64Thumbnail.length);
993                         }
994                         if (splitBase64Thumbnail.length > 1) {
995                                 // This occurs when we have a new image, not an existing image
996                                 byte[] decodedImage = Base64.getDecoder().decode(splitBase64Thumbnail[1].getBytes());
997                                 logger.debug(EELFLoggerDelegate.debugLogger, "LR: finished calling decode");
998                                 deleteOldImageFromDisk(app);
999                                 saveNewImageToDisk(app, onboardingApp, decodedImage);
1000                                 app.setThumbnail(decodedImage);
1001                         }
1002                 } else if (app.getThumbnail() != null) {
1003                         // The thumbnail that came in from the json is empty; the previous
1004                         // thumbnail is NOT empty. Must delete it.
1005                         logger.debug(EELFLoggerDelegate.debugLogger, "LR: onboarding thumbnail is empty; db thumbnail is NOT null");
1006                         deleteOldImageFromDisk(app);
1007                         app.setThumbnail(null);
1008                 } else {
1009                         logger.debug(EELFLoggerDelegate.debugLogger, "LR: onboarding thumbnail is empty; db thumbnail is null");
1010                 }
1011                 return app;
1012         }
1013
1014         private void deleteOldImageFromDisk(EPApp app) {
1015                 if (app.getImageUrl() != null) {
1016                         String oldImageFullFilePath = ecompportalPath + PATH_SEPARATOR + app.getImageUrl();
1017                         try {
1018                                 File oldFile = new File(oldImageFullFilePath);
1019                                 if (oldFile.exists() && oldFile.delete()) {
1020                                         app.setImageUrl(null);
1021                                         logger.debug(EELFLoggerDelegate.debugLogger,
1022                                                         "old file " + oldImageFullFilePath + " was successfully deleted");
1023                                 }
1024                         } catch (Exception e) {
1025                                 logger.error(EELFLoggerDelegate.errorLogger, "old file " + oldImageFullFilePath + " delete failure",
1026                                                 EcompPortalUtils.getStackTrace(e));
1027                         }
1028                 }
1029         }
1030
1031         // No need to optimize this code since it happens only when adding/modifying
1032         // an application.
1033         private void saveNewImageToDisk(EPApp app, OnboardingApp onboardingApp, byte[] decodedImage) {
1034                 // Notice!!!
1035                 // using separator did not worked on WINDOWS as the database was saved
1036                 // as assets\images\tmp\ which the UI did not understand thus ichanged
1037                 // it to "/"
1038                 String imageFileName = constructImageName(onboardingApp);
1039                 String imageRelativeFilePath = imageCacheRelativePath + PATH_SEPARATOR + imageFileName;
1040                 String imageFullFilePath = ecompportalPath + PATH_SEPARATOR + imageRelativeFilePath;
1041                 logger.debug(EELFLoggerDelegate.debugLogger,
1042                                 "saving app " + onboardingApp.name + " image to " + imageFullFilePath);
1043
1044                 FileOutputStream osf = null;
1045                 try {
1046                         // Base64 Image example: 'data:image/png;base64,AAAFBfj42Pj4'
1047                         logger.info(EELFLoggerDelegate.debugLogger, "Saving new image: " + decodedImage);
1048                         osf = writeImageAsBase64(decodedImage, imageFullFilePath);
1049                         app.setImageUrl(imageRelativeFilePath);
1050                         logger.debug(EELFLoggerDelegate.debugLogger,
1051                                         "saveBlobImageToDisk onboardingAppImageUrl = " + imageRelativeFilePath);
1052                 } catch (IOException e) {
1053                         logger.error(EELFLoggerDelegate.errorLogger, "failed to save image to " + imageFullFilePath,
1054                                         EcompPortalUtils.getStackTrace(e));
1055                 } finally {
1056                         if (osf != null) {
1057                                 try {
1058                                         osf.close();
1059                                 } catch (IOException e) {
1060                                         logger.error(EELFLoggerDelegate.errorLogger,
1061                                                         "failed to close outpoot stream for image " + imageFullFilePath,
1062                                                         EcompPortalUtils.getStackTrace(e));
1063                                 }
1064                         }
1065                 }
1066         }
1067
1068         private FileOutputStream writeImageAsBase64(byte[] decodedImage, String imageFullFilePath)
1069                         throws FileNotFoundException, IOException {
1070                 FileOutputStream osf;
1071                 File of = new File(imageFullFilePath);
1072                 osf = new FileOutputStream(of);
1073                 osf.write(decodedImage);
1074                 osf.flush();
1075                 return osf;
1076         }
1077
1078         private String constructImageName(OnboardingApp onboardingApp) {
1079                 return "portal" + String.valueOf(onboardingApp.url.hashCode() + "_" + (int) (Math.random() * 100000.0))
1080                                 + ".png";
1081         }
1082
1083         // Don't encrypt or decrypt the password if it is null or the empty string
1084         private String decryptedPassword(String encryptedAppPwd, EPApp app) {
1085                 String result = "";
1086                 if (encryptedAppPwd != null & encryptedAppPwd.length() > 0) {
1087                         try {
1088                                 result = CipherUtil.decrypt(encryptedAppPwd,
1089                                                 SystemProperties.getProperty(SystemProperties.Decryption_Key));
1090                         } catch (Exception e) {
1091                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to decrypt, App name = " + app.getName(),
1092                                                 EcompPortalUtils.getStackTrace(e));
1093                         }
1094                 }
1095                 return result;
1096         }
1097
1098         private String encryptedPassword(String decryptedAppPwd, EPApp app) {
1099                 String result = "";
1100                 if (decryptedAppPwd != null & decryptedAppPwd.length() > 0) {
1101                         try {
1102                                 result = CipherUtil.encrypt(decryptedAppPwd,
1103                                                 SystemProperties.getProperty(SystemProperties.Decryption_Key));
1104                         } catch (Exception e) {
1105                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to encrypt, App name = " + app,
1106                                                 EcompPortalUtils.getStackTrace(e));
1107                         }
1108                 }
1109                 return result;
1110         }
1111
1112         public void writeAppsImagesToDiskCacheIfNecessary() {
1113                 List<EPApp> apps = getAppsFullList();
1114                 for (EPApp app : apps) {
1115                         String imageFullFilePath = ecompportalPath + PATH_SEPARATOR + app.getImageUrl();
1116                         File f = new File(imageFullFilePath);
1117                         if (f.exists() && !f.isDirectory()) {
1118                                 continue;// logger.debug("verified existence.");
1119                         }
1120
1121                         if (app.getThumbnail() == null) {
1122                                 logger.debug(EELFLoggerDelegate.debugLogger,
1123                                                 "no thumbnail blob available for this app, cannot write to disk " + app.getName());
1124                                 continue;
1125                         }
1126
1127                         FileOutputStream osf = null;
1128                         try {
1129                                 logger.info(EELFLoggerDelegate.debugLogger,
1130                                                 "Rewriting image for " + app.getName() + " from db to: " + imageFullFilePath);
1131                                 osf = writeImageAsBase64(app.getThumbnail(), imageFullFilePath);
1132                                 logger.debug(EELFLoggerDelegate.debugLogger, "missing, wrote to disk.");
1133                         } catch (IOException e) {
1134                                 logger.error(EELFLoggerDelegate.errorLogger, "failed to save image to " + imageFullFilePath,
1135                                                 EcompPortalUtils.getStackTrace(e));
1136                         } finally {
1137                                 try {
1138                                         if (osf != null)
1139                                                 osf.close();
1140                                 } catch (IOException e) {
1141                                         logger.error(EELFLoggerDelegate.errorLogger,
1142                                                         "writeAppsImagesToDiskCacheIfNecessary: failed to close output stream for image "
1143                                                                         + imageFullFilePath,
1144                                                         EcompPortalUtils.getStackTrace(e));
1145                                 }
1146                         }
1147                 }
1148         }
1149
1150         private void writeAppImageToDiskCacheIfNecessary(EPApp app) {
1151                 if (app == null || app.getImageUrl() == null) {
1152                         return;
1153                 }
1154
1155                 String imageFullFilePath = ecompportalPath + PATH_SEPARATOR + app.getImageUrl();
1156                 File f = new File(imageFullFilePath);
1157
1158                 // Image file
1159                 if (f.exists() && !f.isDirectory()) {
1160                         return;// logger.debug("verified existence.");
1161                 }
1162
1163                 if (app.getThumbnail() == null) {
1164                         logger.debug(EELFLoggerDelegate.debugLogger,
1165                                         "no thumbnail blob available for this app, cannot write to disk " + app.getName());
1166                         return;
1167                 }
1168
1169                 FileOutputStream osf = null;
1170                 try {
1171                         logger.info(EELFLoggerDelegate.debugLogger,
1172                                         "Rewriting image for " + app.getName() + " from db to: " + imageFullFilePath);
1173                         osf = writeImageAsBase64(app.getThumbnail(), imageFullFilePath);
1174                         logger.debug(EELFLoggerDelegate.debugLogger, "missing, wrote to disk.");
1175                 } catch (IOException e) {
1176                         logger.error(EELFLoggerDelegate.errorLogger, "failed to save image to " + imageFullFilePath,
1177                                         EcompPortalUtils.getStackTrace(e));
1178                 } finally {
1179                         try {
1180                                 if (osf != null)
1181                                         osf.close();
1182                         } catch (IOException e) {
1183                                 logger.error(EELFLoggerDelegate.errorLogger,
1184                                                 "writeAppsImagesToDiskCacheIfNecessary: failed to close output stream for image "
1185                                                                 + imageFullFilePath,
1186                                                 EcompPortalUtils.getStackTrace(e));
1187                         }
1188                 }
1189         }
1190
1191         @Override
1192         public List<EPApp> getUserRemoteApps(String id) {
1193                 
1194                         StringBuilder query = new StringBuilder();
1195                 
1196                         query.append("SELECT * FROM FN_APP join FN_USER_ROLE ON FN_USER_ROLE.APP_ID = FN_APP.APP_ID where ");
1197                         query.append(
1198                                                 "FN_USER_ROLE.USER_ID = " + id + " AND FN_USER_ROLE.ROLE_ID != " + SUPER_ADMIN_ROLE_ID);
1199                         query.append(" AND FN_APP.ENABLED = 'Y'");
1200
1201                         TreeSet<EPApp> distinctApps = new TreeSet<EPApp>();
1202
1203                         @SuppressWarnings("unchecked")
1204                         List<EPApp> adminApps = dataAccessService.executeSQLQuery(query.toString(), EPApp.class, null);
1205                         for (EPApp app : adminApps) {
1206                                 // Write the image to disk in case if it is missing
1207                                 writeAppImageToDiskCacheIfNecessary(app);
1208
1209                                 distinctApps.add(app);
1210                         }
1211
1212                         List<EPApp> userApps = new ArrayList<EPApp>();
1213                         userApps.addAll(distinctApps);
1214                         return userApps;
1215         
1216         }
1217         
1218 }