Merge "Add CLI deployment as part of portal"
diff --git a/LICENSE.txt b/LICENSE.txt
index 9532e5b..43866ac 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,19 +1,35 @@
-/*
- * ============LICENSE_START===========================================================
- * ====================================================================================
- * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
- * ====================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=============================================================
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- */
\ No newline at end of file
+============LICENSE_START==========================================
+ONAP Portal
+===================================================================
+Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the "License");
+you may not use this software except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Unless otherwise specified, all documentation contained herein is licensed
+under the Creative Commons License, Attribution 4.0 Intl. (the ¿License¿);
+you may not use this documentation except in compliance with the License.
+You may obtain a copy of the License at
+
+     https://creativecommons.org/licenses/by/4.0/
+
+Unless required by applicable law or agreed to in writing, documentation
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+============LICENSE_END============================================
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
diff --git a/ecomp-portal-BE-common/pom.xml b/ecomp-portal-BE-common/pom.xml
index af828cf..79968b3 100644
--- a/ecomp-portal-BE-common/pom.xml
+++ b/ecomp-portal-BE-common/pom.xml
@@ -12,27 +12,31 @@
 		<hibernate.version>4.3.11.Final</hibernate.version>
 		<eelf.version>1.0.0</eelf.version>
 		<fasterxml.version>2.7.4</fasterxml.version>
-		<epsdk.version>1.3.0-SNAPSHOT</epsdk.version>
+		<epsdk.version>1.3.0</epsdk.version>
 		<encoding>UTF-8</encoding>
 		<!-- Tests usually require some setup that maven cannot do, so skip. -->
 		<skipTests>true</skipTests>
 		<nexusproxy>https://nexus.onap.org</nexusproxy>
 		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+		<stagingNexusPath>content/repositories/staging/</stagingNexusPath>
 		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
 	</properties>
 
 	<repositories>
 		<repository>
-		        <!-- Releases repository has ECOMP release artifacts -->
-		        <id>ecomp-releases</id>
-		        <name>OpenECOMP - Release Repository</name>
-		        <url>${nexusproxy}/${releaseNexusPath}</url>
+			<id>onap-releases</id>
+			<name>ONAP - Release Repository</name>
+			<url>${nexusproxy}/${releaseNexusPath}</url>
 		</repository>
 		<repository>
-		        <!-- Snapshots repository has ECOMP snapshot artifacts -->
-		        <id>ecomp-snapshots</id>
-		        <name>OpenECOMP - Snapshot Repository</name>
-		        <url>${nexusproxy}/${snapshotNexusPath}</url>
+			<id>onap-staging</id>
+			<name>ONAP - Staging Repository</name>
+			<url>${nexusproxy}/${stagingNexusPath}</url>
+		</repository>
+		<repository>
+			<id>onap-snapshots</id>
+			<name>ONAP - Snapshot Repository</name>
+			<url>${nexusproxy}/${snapshotNexusPath}</url>
 		</repository>
 	</repositories>
 
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/AuditLogController.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/AuditLogController.java
index 8d6b8e6..14ba94f 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/AuditLogController.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/AuditLogController.java
@@ -36,6 +36,8 @@
 import org.openecomp.portalapp.portal.logging.aop.EPEELFLoggerAdvice;
 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
+import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
+import org.openecomp.portalapp.portal.utils.PortalConstants;
 import org.openecomp.portalapp.util.EPUserUtils;
 
 @RestController
@@ -83,7 +85,7 @@
 				 * valid
 				 */
 				if (comment != null && !comment.equals("") && !comment.equals("undefined"))
-					auditLog.setComments(comment);
+					auditLog.setComments(EcompPortalUtils.truncateString(comment, PortalConstants.AUDIT_LOG_COMMENT_SIZE));
 				if (affectedAppId != null && !affectedAppId.equals("") && !affectedAppId.equals("undefined"))
 					auditLog.setAffectedRecordId(affectedAppId);
 				long userId = EPUserUtils.getUserId(request);
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/DashboardController.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/DashboardController.java
index 81a61d5..1c22576 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/DashboardController.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/DashboardController.java
@@ -44,6 +44,7 @@
 import org.openecomp.portalapp.portal.transport.CommonWidgetMeta;
 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
+import org.openecomp.portalapp.portal.utils.PortalConstants;
 import org.openecomp.portalapp.util.EPUserUtils;
 import org.openecomp.portalsdk.core.domain.AuditLog;
 import org.openecomp.portalsdk.core.domain.support.CollaborateList;
@@ -244,7 +245,7 @@
 				AuditLog auditLog = new AuditLog();
 				auditLog.setUserId(user.getId());
 				auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_SEARCH);
-				auditLog.setComments(searchString);
+				auditLog.setComments(EcompPortalUtils.truncateString(searchString, PortalConstants.AUDIT_LOG_COMMENT_SIZE));
 				MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,EPEELFLoggerAdvice.getCurrentDateTimeUTC());		
 				auditService.logActivity(auditLog, null);
 				MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP,EPEELFLoggerAdvice.getCurrentDateTimeUTC());
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/PortalAdminController.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/PortalAdminController.java
index b98a7cb..7bb6c45 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/PortalAdminController.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/PortalAdminController.java
@@ -111,8 +111,11 @@
 				auditLog.setUserId(user.getId());
 				auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_ADD_PORTAL_ADMIN);
 				auditLog.setAffectedRecordId(userId);
-				auditService.logActivity(auditLog, null);
-
+				try {
+					auditService.logActivity(auditLog, null);
+				} catch (Exception e) {
+					logger.error(EELFLoggerDelegate.errorLogger, "createPortalAdmin: failed for save audit log", e);
+				}
 				MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				EcompPortalUtils.calculateDateTimeDifferenceForLog(
@@ -164,7 +167,7 @@
 				auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_DELETE_PORTAL_ADMIN);
 				auditLog.setAffectedRecordId(sbcid);
 				auditService.logActivity(auditLog, null);
-
+				
 				MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				EcompPortalUtils.calculateDateTimeDifferenceForLog(
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/TicketEventController.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/TicketEventController.java
index 102f770..222f450 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/TicketEventController.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/TicketEventController.java
@@ -180,15 +180,16 @@
 		JsonNode application = ticketEventNotif.get("application");
 		JsonNode event = ticketEventNotif.get("event");
 		JsonNode header = event.get("header");
+		JsonNode eventSource=header.get("eventSource");
 		JsonNode body = event.get("body");
 		JsonNode SubscriberInfo = ticketEventNotif.get("SubscriberInfo");
 		JsonNode userList = SubscriberInfo.get("UserList");
 
-		if (application == null)
+		if (application == null||application.asText().length()==0||application.asText().equalsIgnoreCase("null"))
 			return "Application is mandatory";
 		if (body == null)
 			return "body is mandatory";
-		if (header.get("eventSource") == null)
+		if (eventSource == null||eventSource.asText().trim().length()==0||eventSource.asText().equalsIgnoreCase("null"))
 			return "Message Source is mandatory";
 		if (userList == null)
 			return "At least one user Id is mandatory";
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/UserRolesController.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/UserRolesController.java
index 7bcd584..4bb447d 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/UserRolesController.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/controller/UserRolesController.java
@@ -52,6 +52,7 @@
 import org.openecomp.portalapp.portal.transport.UserApplicationRoles;
 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
+import org.openecomp.portalapp.portal.utils.PortalConstants;
 import org.openecomp.portalapp.util.EPUserUtils;
 import org.openecomp.portalsdk.core.domain.AuditLog;
 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
@@ -213,7 +214,7 @@
 			auditLog.setUserId(user.getId());
 			auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_UPDATE_ACCOUNT_ADMIN);
 			auditLog.setAffectedRecordId(newAppsListWithAdminRoles.orgUserId);
-			auditLog.setComments(newAppRoles.toString());
+			auditLog.setComments(EcompPortalUtils.truncateString(newAppRoles.toString(), PortalConstants.AUDIT_LOG_COMMENT_SIZE));
 			auditService.logActivity(auditLog, null);
 
 			MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
@@ -344,13 +345,15 @@
 				logger.info(EELFLoggerDelegate.applicationLogger,
 						"putAppWithUserRoleStateForUser: succeeded for app {}, user {}", newAppRolesForUser.appId,
 						newAppRolesForUser.orgUserId);
+
+				MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				AuditLog auditLog = new AuditLog();
 				auditLog.setUserId(user.getId());
 				auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_UPDATE_USER);
 				auditLog.setAffectedRecordId(newAppRolesForUser.orgUserId);
-				auditLog.setComments(sbUserApps.toString());
-				MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
+				auditLog.setComments(EcompPortalUtils.truncateString(sbUserApps.toString(), PortalConstants.AUDIT_LOG_COMMENT_SIZE));
 				auditService.logActivity(auditLog, null);
+				
 				MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, EPEELFLoggerAdvice.getCurrentDateTimeUTC());
 				EcompPortalUtils.calculateDateTimeDifferenceForLog(
 						MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPAppMessagesEnum.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPAppMessagesEnum.java
index 6251953..eaac6ed 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPAppMessagesEnum.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPAppMessagesEnum.java
@@ -186,7 +186,16 @@
     
     InternalUnexpectedFatal(EPErrorCodesEnum.INTERNALUNEXPECTEDFATAL_ONE_ARGUMENT, ErrorTypeEnum.SYSTEM_ERROR, AlarmSeverityEnum.CRITICAL, ErrorSeverityEnum.FATAL,
     							"ERR999F", "Unexpected error", "Details: {0}.", "Please check logs for more information."),
-	
+    
+    ExternalAuthAccessConnectionError(EPErrorCodesEnum.EXTERNALAUTHACCESS_CONNECTIONERROR, ErrorTypeEnum.CONNECTION_PROBLEM, AlarmSeverityEnum.MAJOR, ErrorSeverityEnum.ERROR,
+			"ERR220E", "AAF Connection problem", "Details: {0}.", "Please check logs for more information."),
+
+    ExternalAuthAccessAuthenticationError(EPErrorCodesEnum.EXTERNALAUTHACCESS_AUTHENTICATIONERROR, ErrorTypeEnum.AUTHENTICATION_PROBLEM, AlarmSeverityEnum.MAJOR, ErrorSeverityEnum.ERROR,
+			"ERR120E", "AAF authentication problem", "Details: {0}.", "Please check logs for more information."),
+    
+    ExternalAuthAccessGeneralError(EPErrorCodesEnum.EXTERNALAUTHACCESS_GENERALERROR, ErrorTypeEnum.SYSTEM_ERROR, AlarmSeverityEnum.MAJOR, ErrorSeverityEnum.ERROR,
+			"ERR520E", "Unexpected error", "Details: {0}.", "Please check logs for more information."),
+
 	;
 	
 	ErrorTypeEnum eType;
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPErrorCodesEnum.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPErrorCodesEnum.java
index 99a6c34..ca4cdec 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPErrorCodesEnum.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/format/EPErrorCodesEnum.java
@@ -82,6 +82,10 @@
 	INTERNALUNEXPECTEDWARNING_ONE_ARGUMENT,
 	INTERNALUNEXPECTEDERROR_ONE_ARGUMENT,
 	INTERNALUNEXPECTEDFATAL_ONE_ARGUMENT,
+	
+	EXTERNALAUTHACCESS_CONNECTIONERROR,
+	EXTERNALAUTHACCESS_AUTHENTICATIONERROR,
+	EXTERNALAUTHACCESS_GENERALERROR,
 	;
 	
 	/**
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/logic/EPLogUtil.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/logic/EPLogUtil.java
index ebda67e..2c6b330 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/logic/EPLogUtil.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/logging/logic/EPLogUtil.java
@@ -29,6 +29,7 @@
 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
 import org.openecomp.portalsdk.core.web.support.UserUtils;
 import org.slf4j.MDC;
+import org.springframework.http.HttpStatus;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
@@ -282,4 +283,15 @@
 		return auditLogStoreAnalyticsMsg.toString();
 	}
 
+	public static void logExternalAuthAccessAlarm(EELFLoggerDelegate logger, HttpStatus res) {
+		if (res.equals(HttpStatus.UNAUTHORIZED) || res.equals(HttpStatus.FORBIDDEN)) {
+			EPLogUtil.logEcompError(logger, EPAppMessagesEnum.ExternalAuthAccessAuthenticationError);
+		} else if (res.equals(HttpStatus.NOT_FOUND) || res.equals(HttpStatus.NOT_ACCEPTABLE)
+				|| res.equals(HttpStatus.CONFLICT) || res.equals(HttpStatus.BAD_REQUEST)) {
+			EPLogUtil.logEcompError(logger, EPAppMessagesEnum.ExternalAuthAccessConnectionError);
+		} else if (!res.equals(HttpStatus.ACCEPTED) && !res.equals(HttpStatus.OK)) {
+			EPLogUtil.logEcompError(logger, EPAppMessagesEnum.ExternalAuthAccessGeneralError);
+		}
+	}
+
 }
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/ExternalAccessRolesServiceImpl.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/ExternalAccessRolesServiceImpl.java
index 17d9ceb..cddd1c2 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/ExternalAccessRolesServiceImpl.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/ExternalAccessRolesServiceImpl.java
@@ -24,6 +24,7 @@
 import org.openecomp.portalapp.portal.domain.EPUserApp;
 import org.openecomp.portalapp.portal.domain.ExternalRoleDetails;
 import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
+import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
 import org.openecomp.portalapp.portal.transport.BulkUploadRoleFunction;
 import org.openecomp.portalapp.portal.transport.BulkUploadUserRoles;
 import org.openecomp.portalapp.portal.transport.CentralApp;
@@ -52,6 +53,7 @@
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestTemplate;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -444,15 +446,15 @@
 					List <EPRole> getRoleCreated = null;
 					if (!app.getId().equals(PortalConstants.PORTAL_APP_ID)) {
 						List<EPRole> roleCreated =  dataAccessService.getList(EPRole.class,
-								" where role_name = '" + addRoleInDB.getName() +"'", null, null);	
+								" where role_name = '" + addRoleInDB.getName() +"' and app_id = "+ app.getId(), null, null);	
 						EPRole epUpdateRole = roleCreated.get(0);
 						epUpdateRole.setAppRoleId(epUpdateRole.getId());
 						dataAccessService.saveDomainObject(epUpdateRole, null);
 						getRoleCreated =  dataAccessService.getList(EPRole.class,
-								" where role_name = '" + addRoleInDB.getName() +"'", null, null);	
+								" where role_name = '" + addRoleInDB.getName() +"' and app_id = "+ app.getId() , null, null);	
 					} else{
 						getRoleCreated =  dataAccessService.getList(EPRole.class,
-								" where role_name = '" + addRoleInDB.getName() +"'", null, null);	
+								" where role_name = '" + addRoleInDB.getName() +"' and app_id is null", null, null);	
 					}
 				// Add role in External Access system
 				boolean response = addNewRoleInExternalSystem(getRoleCreated, app);
@@ -611,7 +613,7 @@
 					if (((epApp.getId().equals(app.getId()))
 							&& (!userApp.getRole().getId().equals(PortalConstants.ACCOUNT_ADMIN_ROLE_ID)))
 							|| ((epApp.getId().equals(PortalConstants.PORTAL_APP_ID))
-									&& (globalRole.startsWith("global_")))) {
+									&& (globalRole.toLowerCase().startsWith("global_")))) {
 						CentralUserApp cua = new CentralUserApp();
 						cua.setUserId(null);
 						CentralApp cenApp = new CentralApp(1L, epApp.getCreated(), epApp.getModified(),
@@ -633,7 +635,13 @@
 									roleFunc.getCode(), roleFunc.getName(), null, null);
 							roleFunctionSet.add(cenRoleFunc);
 						}
-						CentralRole cenRole = new CentralRole(userApp.getRole().getAppRoleId(),
+						Long userRoleId = null;
+						if(globalRole.toLowerCase().startsWith("global_") && epApp.getId().equals(PortalConstants.PORTAL_APP_ID)){
+							userRoleId = userApp.getRole().getId();
+						} else{
+							userRoleId = userApp.getRole().getAppRoleId();
+						}
+						CentralRole cenRole = new CentralRole(userRoleId,
 								userApp.getRole().getCreated(), userApp.getRole().getModified(),
 								userApp.getRole().getCreatedId(), userApp.getRole().getModifiedId(),
 								userApp.getRole().getRowNum(), userApp.getRole().getName(),
@@ -750,7 +758,7 @@
 
 		} catch (Exception e) {
 			logger.error(EELFLoggerDelegate.errorLogger, "getRoleFunction failed", e);
-			throw new Exception("getRoleFunction failed");
+			throw new Exception("getRoleFunction failed", e);
 		}
 		return getRoleFuncList.get(0);
 	}
@@ -791,6 +799,7 @@
 						+ app.getNameSpace() + "." + checkType + "/" + roleFuncName + "/*",
 				HttpMethod.GET, getSinglePermEntity, String.class);
 		if (getResponse.getStatusCode().value() != 200) {
+			EPLogUtil.logExternalAuthAccessAlarm(logger, getResponse.getStatusCode());
 			throw new Exception(getResponse.getBody());
 		}
 		logger.debug(EELFLoggerDelegate.debugLogger, "Connected to External Access system");
@@ -808,8 +817,11 @@
 					SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "perm",
 					HttpMethod.POST, entity, String.class);
 			logger.debug(EELFLoggerDelegate.debugLogger, "Connected to External Access system");
+			}catch(HttpClientErrorException e){
+				logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to add function in external central auth system", e);
+				EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
 			}catch(Exception e){
-				logger.error(EELFLoggerDelegate.errorLogger, "Failed to add fucntion in external central auth system", e);
+				logger.error(EELFLoggerDelegate.errorLogger, "Failed to add function in external central auth system", e);
 			}
 		} else {
 			try{
@@ -824,8 +836,11 @@
 					SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "perm",
 					HttpMethod.PUT, entity, String.class);
 			logger.debug(EELFLoggerDelegate.debugLogger, "Connected to External Access system");
-			} catch(Exception e){
-				logger.error(EELFLoggerDelegate.errorLogger, "Failed to add fucntion in external central auth system", e);
+			}catch(HttpClientErrorException e){
+				logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to add function in external central auth system", e);
+				EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
+			}catch(Exception e){
+				logger.error(EELFLoggerDelegate.errorLogger, "Failed to add function in external central auth system", e);
 
 			}
 		}
@@ -869,6 +884,9 @@
 		template.exchange(
 				SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "perm?force=true",
 				HttpMethod.DELETE, entity, String.class);
+		} catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to delete functions in External System", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
 		} catch(Exception e){
 			if(e.getMessage().equalsIgnoreCase("404 Not Found")){
 			logger.debug(EELFLoggerDelegate.debugLogger, " It seems like function is already deleted in external central auth system  but exists in local DB", e.getMessage());
@@ -926,6 +944,7 @@
 					+ epRoleList.get(0).getName().replaceAll(" ", "_") + "\"}";
 			deleteResponse = deleteRoleInExternalSystem(deleteRoleKey);
 			if (deleteResponse.getStatusCode().value() != 200) {
+				EPLogUtil.logExternalAuthAccessAlarm(logger, deleteResponse.getStatusCode());
 				throw new Exception("Failed to delete role in external access system!");
 			}
 			logger.debug(EELFLoggerDelegate.debugLogger, "about to commit the transaction");
@@ -1032,7 +1051,10 @@
 			transaction.commit();
 			logger.debug(EELFLoggerDelegate.debugLogger, "committed the transaction");
 			result = true;
-		} catch (Exception e) {
+		}catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to deleteRoleDependeciesRecord", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
+		}catch (Exception e) {
 			EcompPortalUtils.rollbackTransaction(transaction,
 					"deleteDependcyRoleRecord rollback, exception = " + e);
 			logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
@@ -1168,7 +1190,10 @@
 				addRoleFunctionInExternalSystem(cenRoleFunc, app);
 				functionsAdded++;
 			}
-		} catch (Exception e) {
+		}catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - bulkUploadFunctions failed", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
+		}catch (Exception e) {
 			logger.error(EELFLoggerDelegate.errorLogger, "bulkUploadFunctions failed", e.getMessage(), e);
 		}
 		return functionsAdded;
@@ -1206,7 +1231,10 @@
 		template.exchange(
 				SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "role",
 				HttpMethod.POST, entity, String.class);
-		} catch(Exception e){
+		}catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to addRoleInExternalSystem", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
+		}catch(Exception e){
 			if (e.getMessage().equalsIgnoreCase("409 Conflict")) {
 				logger.error(EELFLoggerDelegate.errorLogger, "Role already exits but does not break functionality");
 			} else {
@@ -1232,6 +1260,9 @@
 					}
 				}
 			}
+		} catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to bulkUploadRolesFunctions", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
 		} catch (Exception e) {
 			logger.error(EELFLoggerDelegate.errorLogger, "bulkUploadRolesFunctions failed", e);
 		}
@@ -1542,6 +1573,9 @@
 			}
 		
 		logger.debug(EELFLoggerDelegate.debugLogger, "Finished SyncApplicationRolesWithEcompDB");
+		}catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "Failed to SyncApplicationRolesWithEcompDB", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
 		}catch(Exception e){
 			logger.error(EELFLoggerDelegate.errorLogger, "Failed to SyncApplicationRolesWithEcompDB", e);
 		}
@@ -1591,7 +1625,10 @@
 		template.exchange(
 				SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_ACCESS_URL) + "userRole",
 				HttpMethod.POST, entity, String.class);
-		} catch (Exception e) {
+		}catch(HttpClientErrorException e){
+			logger.error(EELFLoggerDelegate.errorLogger, "HttpClientErrorException - Failed to addUserRoleInExternalSystem", e);
+			EPLogUtil.logExternalAuthAccessAlarm(logger, e.getStatusCode());
+		}catch (Exception e) {
 			if (e.getMessage().equalsIgnoreCase("409 Conflict")) {
 				logger.error(EELFLoggerDelegate.errorLogger, "UserRole already exits but does not break functionality");
 			} else {
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/UserRolesCommonServiceImpl.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/UserRolesCommonServiceImpl.java
index 1315c5e..7e7a55a 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/UserRolesCommonServiceImpl.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/service/UserRolesCommonServiceImpl.java
@@ -771,9 +771,10 @@
 	 * @param mapper
 	 * @param searchService
 	 * @param applicationsRestClientService
+	 * @return 
 	 * @throws Exception
 	 */
-	private void addRemoteUser(List<RoleInAppForUser> roleInAppForUserList, String userId, EPApp app, ObjectMapper mapper, SearchService searchService, ApplicationsRestClientService applicationsRestClientService) throws Exception{
+	private EPUser addRemoteUser(List<RoleInAppForUser> roleInAppForUserList, String userId, EPApp app, ObjectMapper mapper, SearchService searchService, ApplicationsRestClientService applicationsRestClientService) throws Exception{
 		EPUser addRemoteUser = null;
 		if (remoteUserShouldBeCreated(roleInAppForUserList)) {
 			
@@ -787,6 +788,7 @@
 				// return null;
 			}
 		}
+		return addRemoteUser;
 	}
 	
 	/**
@@ -882,7 +884,7 @@
 						remoteAppUser = checkIfRemoteUserExits(userId, app, applicationsRestClientService);
 		
 						if (remoteAppUser == null) {
-							addRemoteUser(roleInAppForUserList, userId, app, mapper, searchService, applicationsRestClientService);
+							remoteAppUser = addRemoteUser(roleInAppForUserList, userId, app, mapper, searchService, applicationsRestClientService);
 						}
 						if (remoteAppUser != null) {
 							Set<EcompRole> userRolesInRemoteApp = postUsersRolesToRemoteApp(roleInAppForUserList, mapper,
@@ -1336,7 +1338,7 @@
 					EPUser remoteAppUser = null;
 						remoteAppUser = checkIfRemoteUserExits(userId.getOrgUserId(), app, applicationsRestClientService);
 					if (remoteAppUser == null) {
-						addRemoteUser(roleInAppForUserList, userId.getOrgUserId(), app, mapper, searchService, applicationsRestClientService);
+						remoteAppUser =	addRemoteUser(roleInAppForUserList, userId.getOrgUserId(), app, mapper, searchService, applicationsRestClientService);
 						reqMessage = "Saved Successfully";
 					}
 						if (remoteAppUser != null) {
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/EcompPortalUtils.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/EcompPortalUtils.java
index 0284452..f29f9d9 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/EcompPortalUtils.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/EcompPortalUtils.java
@@ -414,4 +414,14 @@
 		return result;
 	}
 
+	public static String truncateString(String originString, int size){
+		if(originString.length()>=size){
+			StringBuilder stringBuilder = new StringBuilder();
+			stringBuilder.append(originString);
+			stringBuilder.setLength(size);
+			stringBuilder.append("...");
+			return stringBuilder.toString();
+		}
+		return originString;
+	}
 }
diff --git a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/PortalConstants.java b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/PortalConstants.java
index 57bb543..56bb542 100644
--- a/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/PortalConstants.java
+++ b/ecomp-portal-BE-common/src/main/java/org/openecomp/portalapp/portal/utils/PortalConstants.java
@@ -27,4 +27,5 @@
 	public static final Long SYS_ADMIN_ROLE_ID = 1L;
 	public static final String ADMIN_ROLE = "Account Administrator";
 	public static final String PORTAL_ADMIN_ROLE = "System Administrator";
+	public static final Integer AUDIT_LOG_COMMENT_SIZE = 990;
 }
diff --git a/ecomp-portal-BE-common/src/main/webapp/WEB-INF/fusion/orm/EP.hbm.xml b/ecomp-portal-BE-common/src/main/webapp/WEB-INF/fusion/orm/EP.hbm.xml
index 342a6e8..1574a9a 100644
--- a/ecomp-portal-BE-common/src/main/webapp/WEB-INF/fusion/orm/EP.hbm.xml
+++ b/ecomp-portal-BE-common/src/main/webapp/WEB-INF/fusion/orm/EP.hbm.xml
@@ -1911,9 +1911,12 @@
 			<return alias="getUserRolesListForLeftMenu" class="org.openecomp.portalapp.portal.domain.UserRole" />
 	
 		<![CDATA[ 
-				
-        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 INNER JOIN fn_user user ON user.USER_ID = userrole.USER_ID INNER JOIN fn_role role ON role.ROLE_ID = userrole.ROLE_ID WHERE user.org_user_id =:org_user_id and (userrole.app_id = 1 or role.role_id =   999)   
-         ;
+  		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 
+        INNER JOIN fn_user user ON user.USER_ID = userrole.USER_ID 
+        INNER JOIN fn_app app ON app.app_id= userrole.app_id
+        INNER JOIN fn_role role ON role.ROLE_ID = userrole.ROLE_ID 
+        WHERE user.org_user_id =:org_user_id and (userrole.app_id = 1 or role.role_id =   999) and (app.enabled='Y'  or app.app_id=1)
+        ;
 		]]>
 	</sql-query>
 	
diff --git a/ecomp-portal-BE-os/pom.xml b/ecomp-portal-BE-os/pom.xml
index 22b1374..00e77c2 100644
--- a/ecomp-portal-BE-os/pom.xml
+++ b/ecomp-portal-BE-os/pom.xml
@@ -7,63 +7,50 @@
 	<version>1.1</version>
 
 	<properties>
+		<portal.version>1.3.0-SNAPSHOT</portal.version>
+		<epsdk.version>1.3.0</epsdk.version>
+		<!-- Jenkins SHOULD invoke mvn with argument -Dbuild.number=${BUILD_NUMBER} -->
+		<build.number>0</build.number>
 		<springframework.version>4.2.0.RELEASE</springframework.version>
 		<hibernate.version>4.3.11.Final</hibernate.version>
 		<eelf.version>1.0.0</eelf.version>
-		<epsdk.version>1.3.0-SNAPSHOT</epsdk.version>
-		<portal.version>1.3.0-SNAPSHOT</portal.version>
 		<encoding>UTF-8</encoding>
-		<!-- If Skiptests is false use mvn clean jacoco:prepare-agent install jacoco:report 
-			to run jacoco report -->
+		<!-- If skipTests is false use this command to generate the report:
+			mvn clean jacoco:prepare-agent install jacoco:report  -->
 		<skipTests>false</skipTests>
 		<skipCoverage>true</skipCoverage>		
-		<!-- Jenkins SHOULD invoke mvn with argument -Dbuild.number=${BUILD_NUMBER} -->
-		<build.number>0</build.number>
+		<jacoco.data.file>${project.build.directory}/coverage-reports/jacoco-ut.exec</jacoco.data.file>
+		<sonar-jacoco-listeners.version>3.8</sonar-jacoco-listeners.version>
+		<sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
+		<sonar.jacoco.reportPath>${project.build.directory}/code-coverage/jacoco.exec</sonar.jacoco.reportPath>
+		<sonar.jacoco.itReportPath>${project.build.directory}/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+		<!-- Note: This list should match jacoco-maven-plugin's exclusion list below -->
 		<sonar.exclusions>**.js</sonar.exclusions>
 		<nexusproxy>https://nexus.onap.org</nexusproxy>
 		<snapshotNexusPath>content/repositories/snapshots/</snapshotNexusPath>
+		<stagingNexusPath>content/repositories/staging/</stagingNexusPath>
 		<releaseNexusPath>content/repositories/releases/</releaseNexusPath>
 	</properties>
 
-	<reporting>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-javadoc-plugin</artifactId>
-				<version>2.10.4</version>
-				<configuration>
-					<failOnError>false</failOnError>
-					<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
-					<docletArtifact>
-						<groupId>org.umlgraph</groupId>
-						<artifactId>umlgraph</artifactId>
-						<version>5.6</version>
-					</docletArtifact>
-					<additionalparam>-views</additionalparam>
-					<useStandardDocletOptions>true</useStandardDocletOptions>
-				</configuration>
-			</plugin>
-			
-		</plugins>
-	</reporting>
-	<distributionManagement>
-		<site>
-			<id>ecomp-site</id>
-			<url>dav:${nexusproxy}/content/sites/site/org/onap/portal/${project.version}</url>
-		</site>
-	</distributionManagement>
 	<repositories>
 		<repository>
 			<id>onap-releases</id>
+			<name>ONAP - Release Repository</name>
 			<url>${nexusproxy}/${releaseNexusPath}</url>
 		</repository>
 		<repository>
+			<id>onap-staging</id>
+			<name>ONAP - Staging Repository</name>
+			<url>${nexusproxy}/${stagingNexusPath}</url>
+		</repository>
+		<repository>
 			<id>onap-snapshots</id>
+			<name>ONAP - Snapshot Repository</name>
 			<url>${nexusproxy}/${snapshotNexusPath}</url>
 		</repository>
 		<repository>
 			<id>onap-public</id>
-			<url>https://nexus.onap.org/content/groups/public</url>
+			<url>${nexusproxy}/content/groups/public</url>
 		</repository>
 	</repositories>
 
@@ -98,28 +85,25 @@
 					<target>1.8</target>
 				</configuration>
 			</plugin>
-            <plugin>
+			<plugin>
 				<groupId>org.jacoco</groupId>
 				<artifactId>jacoco-maven-plugin</artifactId>
 				<version>0.7.5.201505241946</version>
 				<executions>
-
 					<!-- Prepares the property pointing to the JaCoCo runtime agent which 
-						is passed as VM argument when Maven the Surefire plugin is executed. -->
+					     is passed as VM argument when Maven the Surefire plugin is executed. -->
 					<execution>
 						<id>pre-unit-test</id>
 						<goals>
 							<goal>prepare-agent</goal>
 						</goals>
 						<configuration>
-							<!-- Sets the path to the file which contains the execution data. -->
-							<destFile>${basedir}/target/coverage-reports/jacoco-ut.exec</destFile>
-							<!-- Sets the name of the property containing the settings for JaCoCo 
-								runtime agent. -->
+							<!-- path to the file which contains the execution data. -->
+							<destFile>${jacoco.data.file}</destFile>
+							<!-- name of the property containing the settings for JaCoCo runtime agent. -->
 							<propertyName>surefireArgLine</propertyName>
 							<skip>${skipCoverage}</skip>
 						</configuration>
-
 					</execution>
 					<!-- Ensures that the code coverage report for unit tests is created 
 						after unit tests have been run. -->
@@ -130,12 +114,11 @@
 							<goal>report</goal>
 						</goals>
 						<configuration>
-							<!-- Sets the path to the file which contains the execution data. -->
-							<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
-							<!-- Sets the output directory for the code coverage report. -->
+							<!-- path to the file which contains the execution data. -->
+							<dataFile>${jacoco.data.file}</dataFile>
+							<!-- output directory for the code coverage report. -->
 							<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
 							<skip>${skipCoverage}</skip>
-
 						</configuration>
 					</execution>
 					<!-- Will see build errors while running the test cases because of dual 
@@ -800,4 +783,34 @@
 		</dependency>
 
 	</dependencies>
+
+	<reporting>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<version>2.10.4</version>
+				<configuration>
+					<failOnError>false</failOnError>
+					<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
+					<docletArtifact>
+						<groupId>org.umlgraph</groupId>
+						<artifactId>umlgraph</artifactId>
+						<version>5.6</version>
+					</docletArtifact>
+					<additionalparam>-views</additionalparam>
+					<useStandardDocletOptions>true</useStandardDocletOptions>
+				</configuration>
+			</plugin>
+			
+		</plugins>
+	</reporting>
+
+	<distributionManagement>
+		<site>
+			<id>ecomp-site</id>
+			<url>dav:${nexusproxy}/content/sites/site/org/onap/portal/${project.version}</url>
+		</site>
+	</distributionManagement>
+
 </project>
diff --git a/ecomp-portal-FE-common/README.md b/ecomp-portal-FE-common/README.md
index c4ac1e8..e69e32a 100644
--- a/ecomp-portal-FE-common/README.md
+++ b/ecomp-portal-FE-common/README.md
@@ -8,8 +8,6 @@
 separate Maven projects that copy in ("overlay") the contents of this project
 at package time.
 
-## Static files
+Release Notes
 
-Static files should be entered into the ecomp-portal-FE-common/home directory, 
-whereby home = the webserver html root directory.  The files and directories 
-will be copied exactly as they are placed.
+ - PORTAL-86 remove "home" subdirectory with static files
diff --git a/ecomp-portal-FE-common/client/app/router.js b/ecomp-portal-FE-common/client/app/router.js
index 190ed57..7a3d3a7 100644
--- a/ecomp-portal-FE-common/client/app/router.js
+++ b/ecomp-portal-FE-common/client/app/router.js
@@ -241,7 +241,7 @@
             url: '/error404',
             views: {
                 'content@': {
-                    templateUrl: 'app/views/errors/error.404.tpl.html',
+                    templateUrl: 'app/views/errors/error.tpl.html',
                     controller: 'ErrorCtrl',
                     controllerAs: 'error'
                 }
diff --git a/ecomp-portal-FE-common/client/app/views/errors/error.controller.js b/ecomp-portal-FE-common/client/app/views/errors/error.controller.js
new file mode 100644
index 0000000..5f4f410
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/errors/error.controller.js
@@ -0,0 +1,20 @@
+'use strict';
+(function () {
+    class ErrorCtrl {
+        constructor($log, $scope,$state) {
+        	$scope.errorState = $state.current.name;
+        	if($scope.errorState=='root.error404'){
+        		$scope.errorTitle="Page Not Found";
+        		$scope.errorMsg="The page you are looking for cannot be found";
+        	}else if($scope.errorState=='noUserError'){
+        		$scope.errorTitle="Authorization denied";
+        		$scope.errorMsg= "Please Contact Your Administrator for the page access";
+        	}else {
+        		$scope.errorTitle="Something went wrong";
+        		$scope.errorMsg= "Please go back to the previous page";
+        	}	     	
+        }
+    }
+    ErrorCtrl.$inject = ['$log','$scope','$state'];
+    angular.module('ecompApp').controller('ErrorCtrl', ErrorCtrl);
+})();
\ No newline at end of file
diff --git a/ecomp-portal-FE-common/client/app/views/errors/error.tpl.html b/ecomp-portal-FE-common/client/app/views/errors/error.tpl.html
new file mode 100644
index 0000000..44b43ce
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/errors/error.tpl.html
@@ -0,0 +1,31 @@
+<!--
+  ================================================================================
+  ECOMP Portal
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ================================================================================
+  -->
+<div class="w-ecomp-admins-page-main">
+	<div id="page-content">
+		<div id="title" class="w-ecomp-main-view-title">
+			<h1 class="heading-page">{{errorTitle}}</h1>
+		</div>
+		<div class="errorContent">
+			<p>{{errorMsg}}</p>
+		</div>
+
+	</div>
+
+</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/role.html b/ecomp-portal-FE-common/client/app/views/role/role.html
index 9febc97..63073ae 100644
--- a/ecomp-portal-FE-common/client/app/views/role/role.html
+++ b/ecomp-portal-FE-common/client/app/views/role/role.html
@@ -94,30 +94,7 @@
 				</div>		
 				
 				<a id="manage-role"  href="roleFunctions">Manage Role Functions</a><br><br>
-				
-				<div id="page-title-child" class="pageTitle">
-					<label>Child Roles</label>
-					<a id="add-child-role"  ng-click="addNewChildRoleModalPopup();" ng-style="{'cursor':'pointer'}" class="icon-primary-accordion-plus" size="small"></a>
-				</div>
-				
-				<div b2b-table table-data="role.childRoles"  ng-hide="users.isLoadingTable"	search-string="users.searchString" class="b2b-table-div">
-					<table>
-						<thead b2b-table-row type="header">
-							<tr >
-								<th id="table-header-name" b2b-table-header key="firstName" sortable="true" >Name</th>
-								<th id="table-header-remove" b2b-table-header key="lastName" sortable="true" >Remove</th>
-							</tr>
-						</thead>
-						<tbody b2b-table-row type="body" 	row-repeat="role in role.childRoles">
-							<tr >
-								<td id="role-function-{{role.name}}" b2b-table-body id="rowheader_t1_{{$index}}" headers="col1" ng-bind="role.name"></td>
-								<td b2b-table-body headers="rowheader_t1_{{$index}} col4" id="{{$index}}-button-remove-role" >
-					    			<div ng-click="removeChildRole(role);" ><a href="javascript:void(0)" class="icon-misc-trash"></a></div>
-								</td>							
-							</tr>
-						</tbody>
-					</table>
-				</div>					
+									
 			</div>
 			</div>
 		</div>
diff --git a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.controller.js b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.controller.js
index 48f7d9d..366fb21 100644
--- a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.controller.js
+++ b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.controller.js
@@ -19,11 +19,11 @@
  */
 'use strict';
 
-(function () {
+(function() {
 
     class userNotificationsModalCtrl {
-        constructor($scope, $log, functionalMenuService, confirmBoxService, notificationService, $modal, ngDialog, $state, $filter,items) {
-        	this.debug = false;
+        constructor($scope, $log, functionalMenuService, confirmBoxService, notificationService, $modal, ngDialog, $state, $filter, items) {
+            this.debug = false;
             $scope.newNotifModel = {
                 'isOnlineUsersOnly': null,
                 'isForAllRolesOptions': null,
@@ -34,10 +34,12 @@
                 'msgHeader': null,
                 'msgDescription': null,
                 'roleIds': null,
-                'anyTreeItemSelected':false,
-                'roleObj': {notificationRoleIds:null}
+                'anyTreeItemSelected': false,
+                'roleObj': {
+                    notificationRoleIds: null
+                }
             };
-            
+
             $scope.notificationId = null;
             $scope.selectedCat = null;
             $scope.selectedEcompFunc = null;
@@ -45,42 +47,72 @@
                 "Y": 0,
                 "N": 1
             }
-            
-            $scope.onlineAllUsersOptions = [
-                { "index": 0, "value": "Y", "title": "Online Users Only" },
-                { "index": 1, "value": "N", "title": "Online & Offline Users" }
-                
+
+            $scope.onlineAllUsersOptions = [{
+                    "index": 0,
+                    "value": "Y",
+                    "title": "Online Users Only"
+                },
+                {
+                    "index": 1,
+                    "value": "N",
+                    "title": "Online & Offline Users"
+                }
+
             ];
 
-            $scope.isForAllRolesOptions = [
-                { "index": 0, "value": "Y", "title": "Yes" },
-                { "index": 1, "value": "N", "title": "No" }
+            $scope.isForAllRolesOptions = [{
+                    "index": 0,
+                    "value": "Y",
+                    "title": "Yes"
+                },
+                {
+                    "index": 1,
+                    "value": "N",
+                    "title": "No"
+                }
             ];
 
-            $scope.priorityOptions  = [
-                { "index": 0, "value": 1, "title": "Normal" },
-                { "index": 1, "value": 2, "title": "Important" }
+            $scope.priorityOptions = [{
+                    "index": 0,
+                    "value": 1,
+                    "title": "Normal"
+                },
+                {
+                    "index": 1,
+                    "value": 2,
+                    "title": "Important"
+                }
             ];
 
-            $scope.isActiveOptions = [
-                { "index": 0, "value": "Y", "title": "Yes" },
-                { "index": 1, "value": "N", "title": "No" }
+            $scope.isActiveOptions = [{
+                    "index": 0,
+                    "value": "Y",
+                    "title": "Yes"
+                },
+                {
+                    "index": 1,
+                    "value": "N",
+                    "title": "No"
+                }
             ];
             $scope.newNotifModel.isActive = $scope.isActiveOptions[0];
             $scope.newNotifModel.selectPriority = $scope.priorityOptions[0];
             $scope.newNotifModel.isOnlineUsersOnly = $scope.onlineAllUsersOptions[1];
-            $scope.newNotifModel.isForAllRoles=$scope.isForAllRolesOptions[0].value;
-          $scope.newNotifModel.isFunctionalMenu ="Y";
+            $scope.newNotifModel.isForAllRoles = $scope.isForAllRolesOptions[0].value;
+            $scope.newNotifModel.isFunctionalMenu = "Y";
 
-          $scope.newNotifModel.selectedPriority=$scope.priorityOptions[0].value;
-          $scope.newNotifModel.msgHeader = '';
-          $scope.newNotifModel.msgDescription = '';
-            $scope.newNotifModel.treeTitle="Functional Menu";
-            $scope.newNotifModel.notifObj= {isCategoriesFunctionalMenu:true};
+            $scope.newNotifModel.selectedPriority = $scope.priorityOptions[0].value;
+            $scope.newNotifModel.msgHeader = '';
+            $scope.newNotifModel.msgDescription = '';
+            $scope.newNotifModel.treeTitle = "Functional Menu";
+            $scope.newNotifModel.notifObj = {
+                isCategoriesFunctionalMenu: true
+            };
 
             let init = () => {
-            	if(this.debug)
-            		$log.debug('userNotificationsModalCtrl::init');
+                if (this.debug)
+                    $log.debug('userNotificationsModalCtrl::init');
                 this.isSaving = false;
                 var today = new Date();
                 $scope.minDate = today.toISOString().substring(0, 10);
@@ -88,10 +120,12 @@
                 threeMonthsFromNow.setMonth(threeMonthsFromNow.getMonth() + 3);
                 $scope.maxDate = threeMonthsFromNow.toISOString().substring(0, 10);
                 if (items && items.notif) {
-                	if(this.debug)
-                		$log.debug('userNotificationsModalCtrl:init:: Edit notification mode for', items.notif);
+                    if (this.debug)
+                        $log.debug('userNotificationsModalCtrl:init:: Edit notification mode for', items.notif);
                     $scope.isEditMode = true;
-                    $scope.editModeObj = {isEditMode: true};
+                    $scope.editModeObj = {
+                        isEditMode: true
+                    };
                     this.notif = _.clone(items.notif);
                     $scope.modalPgTitle = 'View Notification'
                     $scope.newNotifModel.isOnlineUsersOnly = $scope.onlineAllUsersOptions[this.YN_index_mapping[this.notif.isForOnlineUsers]];
@@ -104,24 +138,30 @@
                     $scope.newNotifModel.msgDescription = this.notif.msgDescription;
                     $scope.notificationId = this.notif.notificationId;
                     $scope.newNotifModel.notificationRoleIds = this.notif.roleIds;
-                    $scope.roleObj = {notificationRoleIds:this.notif.roleIds};
+                    $scope.roleObj = {
+                        notificationRoleIds: this.notif.roleIds
+                    };
                 } else {
-                	if(this.debug)
-                		$log.debug('AppDetailsModalCtrl:init:: New app mode');
+                    if (this.debug)
+                        $log.debug('AppDetailsModalCtrl:init:: New app mode');
                     $scope.isEditMode = false;
-                    $scope.editModeObj = {isEditMode: false};
+                    $scope.editModeObj = {
+                        isEditMode: false
+                    };
                     $scope.modalPgTitle = 'Add a New Notification'
                     this.notif = _.clone($scope.newNotifModel);
-                    $scope.roleObj = {notificationRoleIds:null};
+                    $scope.roleObj = {
+                        notificationRoleIds: null
+                    };
                 }
             };
             this.conflictMessages = {};
             this.scrollApi = {};
             let handleConflictErrors = err => {
-                if(!err.data){
+                if (!err.data) {
                     return;
                 }
-                if(!err.data.length){ // support objects
+                if (!err.data.length) { // support objects
                     err.data = [err.data]
                 }
                 _.forEach(err.data, item => {
@@ -139,42 +179,66 @@
 
             let resetConflict = fieldName => {
                 delete this.conflictMessages[fieldName];
-                if($scope.appForm[fieldName]){
+                if ($scope.appForm[fieldName]) {
                     $scope.appForm[fieldName].$setValidity('conflict', true);
                 }
             };
-            $scope.addUserNotificationValidation = function () {
-				// // pre-processing
-				if (!($scope.isEditMode)) {                    
-					var validation=false;
-					if($scope.isDateValid($scope.newNotifModel.startTime) && $scope.isDateValid($scope.newNotifModel.endTime) && $scope.newNotifModel.msgHeader != '' && $scope.newNotifModel.msgDescription != '' && ($scope.newNotifModel.startTime<$scope.newNotifModel.endTime)){
-						validation=true;
-						if( $scope.newNotifModel.isForAllRoles=='N'){
-							validation =  $scope.checkTreeSelect();
-						}
-					}
-					else{
-						validation=false;
-					}
-					return !validation; 
-				}
-			}
-            
+            $scope.addUserNotificationValidation = function() {
+                // // pre-processing
+                if (!($scope.isEditMode)) {
+                    var validation = false;
+                    if ($scope.isStartDateValidFromToday($scope.newNotifModel.startTime)&&$scope.isStartDateValidFromToday($scope.newNotifModel.endTime)&&$scope.isDateValid($scope.newNotifModel.startTime) && $scope.isDateValid($scope.newNotifModel.endTime) && $scope.newNotifModel.msgHeader != '' && $scope.newNotifModel.msgDescription != '' && ($scope.newNotifModel.startTime < $scope.newNotifModel.endTime)) {
+                        validation = true;
+                        if ($scope.newNotifModel.isForAllRoles == 'N') {
+                            validation = $scope.checkTreeSelect();
+                        }
+                    } else {
+                        validation = false;
+                    }
+                    return !validation;
+                }
+            }
+
             /* format the value for viewing a notification */
-            $scope.formatStartDate = function () {
-            	if ($scope.newNotifModel.startTime) {
-            		$scope.newNotifModel.startTime = $filter('date')($scope.startTime, 'medium'); 
-           	}            	
+            $scope.formatStartDate = function() {
+                if ($scope.newNotifModel.startTime) {
+                    $scope.newNotifModel.startTime = $filter('date')($scope.startTime, 'medium');
+                }
+            }
+
+            /* format the value for viewing a notification */
+            $scope.formatEndDate = function() {
+                if ($scope.newNotifModel.endTime) {
+                    $scope.newNotifModel.endTime = $filter('date')($scope.endTime, 'medium');
+                }
             }
             
-            /* format the value for viewing a notification */
-            $scope.formatEndDate = function () {
-            	if($scope.newNotifModel.endTime){
-            		$scope.newNotifModel.endTime = $filter('date')($scope.endTime, 'medium');
-            	}
-            }
+            /*To validate the manual entry of date in MM/DD/YYYY Format*/
+
+            $scope.isDateValid = function(time) {
+                if (time == undefined) {
+                    return false;
+                }
+                if (typeof time == 'object') {
+                    return true;
+                }
+                var startDateformat = time.split('/');
+                if (startDateformat.length != 3) return false;
+                var day = startDateformat[1];
+                var month = startDateformat[0];
+                month = parseInt(month) - 1;
+                var year = startDateformat[2];
+                if (year.length != 4) return false;
+                var composedDate = new Date(year, month, day);
+                 return composedDate.getDate() == day &&
+                         composedDate.getMonth() == month &&
+                         composedDate.getFullYear() == year;
+            };
             
-            $scope.isDateValid = function (time) {
+         /*The manual and drop down calendar should be consistent.
+         Start date must be greater than or equal to current date.The end dates are not allowed after the 3 months from current dates*/
+            
+            $scope.isStartDateValidFromToday = function (time) {
             	if(time == undefined){
                     return false;
                 }
@@ -182,309 +246,317 @@
             		return true;
             	}
                 var startDateformat	=time.split('/');
-                if (startDateformat.length != 3) return false;
+                if (startDateformat.length != 3) return true;
                 var day = startDateformat[1];
                 var month = startDateformat[0];
                  month= parseInt(month)-1;
                 var year = startDateformat[2];
-                if(year.length!=4) return false;
+                if(year.length!=4) return true;
                 var composedDate = new Date(year, month, day);
-                 return composedDate.getDate() == day &&
-                         composedDate.getMonth() == month &&
-                         composedDate.getFullYear() == year;
-              
+              /* As end dates are not allowed after the 3 months from current dates*/
+                var x = 3; //or whatever offset
+                var CurrentDate = new Date();
+                /*If composed date is less than the current date,error message should display*/
+                if(composedDate<CurrentDate)
+                	return false;
+                CurrentDate.setMonth(CurrentDate.getMonth() + x);
+                if(composedDate>CurrentDate)
+                	return false;
+                 return true;
             };
-            
-           
-            $scope.addUserNotification = function () {
-            	$scope.notificationRoleIds = [];
-				// pre-processing
-
-				for(var fi=0;fi<$scope.treedata.length;fi++){
-					var fLevel = $scope.treedata[fi];
-					if(fLevel){
-						var fLevelChild = fLevel.child;
-						for(var si=0;si<fLevelChild.length;si++){
-							var sLevel = fLevelChild[si];
-							if(sLevel){
-								var sLevelChild = sLevel.child;
-								if(sLevelChild){
-									for(var ti=0;ti< sLevelChild.length;ti++){
-										var tLevel = sLevelChild[ti];
-										if(tLevel.isSelected && tLevel.roleId){
-											$scope.newNotifModel.anyTreeItemSelected=true;
-											for(var i in tLevel.roleId)
-												$scope.notificationRoleIds.push(tLevel.roleId[i]);
-										}
-									}
-								}
-							}
-							if(sLevel.isSelected && sLevel.roleId){
-								for(var i in sLevel.roleId)
-									$scope.notificationRoleIds.push(sLevel.roleId[i]);
-							}
-						}
-					}               	
-				}
-
-				$scope.notificationRoleIds.sort();
-				if (($scope.newNotifModel.isOnlineUsersOnly) && ($scope.newNotifModel.isForAllRoles) && ($scope.newNotifModel.selectedPriority) && ($scope.newNotifModel.isActive)
-						&& ($scope.newNotifModel.startTime) && ($scope.newNotifModel.endTime) && ($scope.newNotifModel.msgHeader != '') && ($scope.newNotifModel.msgDescription != '')) {
-					this.newUserNotification =
-					{
-							'notificationId':$scope.notificationId,
-							'isForOnlineUsers': $scope.newNotifModel.isOnlineUsersOnly.value,
-							'isForAllRoles': $scope.newNotifModel.isForAllRoles,
-							'priority': $scope.newNotifModel.selectedPriority,
-							'activeYn': $scope.newNotifModel.isActive.value,
-							'startTime': $scope.newNotifModel.startTime,
-							'endTime': $scope.newNotifModel.endTime,
-							'msgHeader': $scope.newNotifModel.msgHeader,
-							'msgDescription': $scope.newNotifModel.msgDescription,
-							'roleIds': $scope.notificationRoleIds,
-							'createdDate': new Date()
-					};
-
-					// POST ajax call here;
-					if ($scope.isEditMode) {
-						notificationService.updateAdminNotification(this.newUserNotification)
-						.then(() => {
-							if(this.debug)
-								$log.debug('NotificationService:updateAdminNotification:: Admin notification update succeeded!');
-							$scope.closeThisDialog(true);
-						}).catch(err => {
-							$log.error('notificationService.updateAdminNotfication failed: ' + JSON.stringify(err));
-							switch (err.status) {
-							case '409':         // Conflict
-								// handleConflictErrors(err);
-								break;
-							case '500':         // Internal Server Error
-								confirmBoxService.showInformation('There was a problem updating the notification. ' +
-										'Please try again later. Error: ' + err.status).then(isConfirmed => { });
-								break;
-							case '403':         // Forbidden... possible
-								// webjunction error to
-								// try again
-								confirmBoxService.showInformation('There was a problem updating the notification. ' +
-										'Please try again. If the problem persists, then try again later. Error: ' + err.status).then(isConfirmed => { });
-								break;
-							default:
-								confirmBoxService.showInformation('There was a problem updating the notification. ' +
-										'Please try again. If the problem persists, then try again later. Error: ' + err.status).then(isConfirmed => { });
-							}
-						}).finally(() => {
-							// for bug in IE 11
-							var objOffsetVersion = objAgent.indexOf("MSIE");
-							if (objOffsetVersion != -1) {
-								if(this.debug)
-									$log.debug('AppDetailsModalCtrl:updateOnboardingApp:: Browser is IE, forcing Refresh');
-								$window.location.reload();   
-							}
-							// for bug in IE 11
-						});
-
-					} else {
-						notificationService.addAdminNotification(this.newUserNotification)
-						.then((res) => {
-							if(this.debug)
-								$log.debug('notificationService:addAdminNotification:: Admin notification creation succeeded!,',res);
-							if(res.status=='ERROR'){
-								confirmBoxService.showInformation('There was a problem adding the notification. ' +
-										' Error: ' + res.response).then(isConfirmed => { });
 
 
-							}
-							else{
-								//$scope.closeThisDialog(true);
-								$scope.$dismiss('cancel');
-							}
+            $scope.addUserNotification = function() {
+                $scope.notificationRoleIds = [];
+                // pre-processing
 
-							// emptyCookies();
-						}).catch(err => {
-							switch (err.status) {
-							case '409':         // Conflict
-								// handleConflictErrors(err);
-								break;
-							case '500':         // Internal Server Error
-								confirmBoxService.showInformation('There was a problem adding the notification. ' +
-										'Please try again later. Error: ' + err.status).then(isConfirmed => { });
-								break;
-							default:
-								confirmBoxService.showInformation('There was a problem adding the notification. ' +
-										'Please try again. If the problem persists, then try again later. Error: ' +
-										err.status).then(isConfirmed => { });
-							}
-							$log.error('notificationService:addAdminNotification error:: ' + JSON.stringify(err));
-						})
-					}
+                for (var fi = 0; fi < $scope.treedata.length; fi++) {
+                    var fLevel = $scope.treedata[fi];
+                    if (fLevel) {
+                        var fLevelChild = fLevel.child;
+                        if (fLevelChild) {
+                            for (var si = 0; si < fLevelChild.length; si++) {
+                                var sLevel = fLevelChild[si];
+                                if (sLevel) {
+                                    var sLevelChild = sLevel.child;
+                                    if (sLevelChild) {
+                                        for (var ti = 0; ti < sLevelChild.length; ti++) {
+                                            var tLevel = sLevelChild[ti];
+                                            if (tLevel.isSelected && tLevel.roleId) {
+                                                $scope.newNotifModel.anyTreeItemSelected = true;
+                                                for (var i in tLevel.roleId)
+                                                    $scope.notificationRoleIds.push(tLevel.roleId[i]);
+                                            }
+                                        }
+                                    }
+                                }
+                                if (sLevel.isSelected && sLevel.roleId) {
+                                    for (var i in sLevel.roleId)
+                                        $scope.notificationRoleIds.push(sLevel.roleId[i]);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                $scope.notificationRoleIds.sort();
+                if (($scope.newNotifModel.isOnlineUsersOnly) && ($scope.newNotifModel.isForAllRoles) && ($scope.newNotifModel.selectedPriority) && ($scope.newNotifModel.isActive) &&
+                    ($scope.newNotifModel.startTime) && ($scope.newNotifModel.endTime) && ($scope.newNotifModel.msgHeader != '') && ($scope.newNotifModel.msgDescription != '')) {
+                    this.newUserNotification = {
+                        'notificationId': $scope.notificationId,
+                        'isForOnlineUsers': $scope.newNotifModel.isOnlineUsersOnly.value,
+                        'isForAllRoles': $scope.newNotifModel.isForAllRoles,
+                        'priority': $scope.newNotifModel.selectedPriority,
+                        'activeYn': $scope.newNotifModel.isActive.value,
+                        'startTime': $scope.newNotifModel.startTime,
+                        'endTime': $scope.newNotifModel.endTime,
+                        'msgHeader': $scope.newNotifModel.msgHeader,
+                        'msgDescription': $scope.newNotifModel.msgDescription,
+                        'roleIds': $scope.notificationRoleIds,
+                        'createdDate': new Date()
+                    };
+
+                    // POST ajax call here;
+                    if ($scope.isEditMode) {
+                        notificationService.updateAdminNotification(this.newUserNotification)
+                            .then(() => {
+                                if (this.debug)
+                                    $log.debug('NotificationService:updateAdminNotification:: Admin notification update succeeded!');
+                                $scope.closeThisDialog(true);
+                            }).catch(err => {
+                                $log.error('notificationService.updateAdminNotfication failed: ' + JSON.stringify(err));
+                                switch (err.status) {
+                                    case '409': // Conflict
+                                        // handleConflictErrors(err);
+                                        break;
+                                    case '500': // Internal Server Error
+                                        confirmBoxService.showInformation('There was a problem updating the notification. ' +
+                                            'Please try again later. Error: ' + err.status).then(isConfirmed => {});
+                                        break;
+                                    case '403': // Forbidden... possible
+                                        // webjunction error to
+                                        // try again
+                                        confirmBoxService.showInformation('There was a problem updating the notification. ' +
+                                            'Please try again. If the problem persists, then try again later. Error: ' + err.status).then(isConfirmed => {});
+                                        break;
+                                    default:
+                                        confirmBoxService.showInformation('There was a problem updating the notification. ' +
+                                            'Please try again. If the problem persists, then try again later. Error: ' + err.status).then(isConfirmed => {});
+                                }
+                            }).finally(() => {
+                                // for bug in IE 11
+                                var objOffsetVersion = objAgent.indexOf("MSIE");
+                                if (objOffsetVersion != -1) {
+                                    if (this.debug)
+                                        $log.debug('AppDetailsModalCtrl:updateOnboardingApp:: Browser is IE, forcing Refresh');
+                                    $window.location.reload();
+                                }
+                                // for bug in IE 11
+                            });
+
+                    } else {
+                        notificationService.addAdminNotification(this.newUserNotification)
+                            .then((res) => {
+                                if (this.debug)
+                                    $log.debug('notificationService:addAdminNotification:: Admin notification creation succeeded!,', res);
+                                if (res.status == 'ERROR') {
+                                    confirmBoxService.showInformation('There was a problem adding the notification. ' +
+                                        ' Error: ' + res.response).then(isConfirmed => {});
 
 
-				} else {
-					$log.warn('please fill in all required fields');
-					confirmBoxService.showInformation('Please fill in all required fields').then(isConfirmed => { });
-				}
+                                } else {
+                                    // $scope.closeThisDialog(true);
+                                    $scope.$dismiss('cancel');
+                                }
+
+                                // emptyCookies();
+                            }).catch(err => {
+                                switch (err.status) {
+                                    case '409': // Conflict
+                                        // handleConflictErrors(err);
+                                        break;
+                                    case '500': // Internal Server Error
+                                        confirmBoxService.showInformation('There was a problem adding the notification. ' +
+                                            'Please try again later. Error: ' + err.status).then(isConfirmed => {});
+                                        break;
+                                    default:
+                                        confirmBoxService.showInformation('There was a problem adding the notification. ' +
+                                            'Please try again. If the problem persists, then try again later. Error: ' +
+                                            err.status).then(isConfirmed => {});
+                                }
+                                $log.error('notificationService:addAdminNotification error:: ' + JSON.stringify(err));
+                            })
+                    }
+
+
+                } else {
+                    $log.warn('please fill in all required fields');
+                    confirmBoxService.showInformation('Please fill in all required fields').then(isConfirmed => {});
+                }
             }
-            $scope.functionalMenuRes={};
-            $scope.checkTreeSelect = function(){
-				if($scope.treedata){
-					for(var fi=0; fi<$scope.treedata.length;fi++){
-						var fLevel = $scope.treedata[fi];
-						if(fLevel.isSelected){
-							return true;
-						}                		
-						var sLevel = fLevel.child;
-						if(sLevel){
-							for(var si=0;si<sLevel.length;si++){
-								if(sLevel[si].isSelected){
-									return true;
-								}  
-								var tLevel = sLevel[si].child;
-								if(tLevel){
-									for(var ti=0;ti<tLevel.length;ti++){
-										if(tLevel[ti].isSelected){
-											return true;
-										}	
-									}                   		
-								}	
-							}
-						}
-					} 
-				}
-				return false;
-			}
+            $scope.functionalMenuRes = {};
+            $scope.checkTreeSelect = function() {
+                if ($scope.treedata) {
+                    for (var fi = 0; fi < $scope.treedata.length; fi++) {
+                        var fLevel = $scope.treedata[fi];
+                        if (fLevel.isSelected) {
+                            return true;
+                        }
+                        var sLevel = fLevel.child;
+                        if (sLevel) {
+                            for (var si = 0; si < sLevel.length; si++) {
+                                if (sLevel[si].isSelected) {
+                                    return true;
+                                }
+                                var tLevel = sLevel[si].child;
+                                if (tLevel) {
+                                    for (var ti = 0; ti < tLevel.length; ti++) {
+                                        if (tLevel[ti].isSelected) {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                return false;
+            }
             // Populate the category list for category dropdown list
             let getFunctionalMenu = () => {
-            	this.isLoadingTable = true;
-            	if(this.debug)
-            		$log.debug('getFunctionalMenu:init');
+                this.isLoadingTable = true;
+                if (this.debug)
+                    $log.debug('getFunctionalMenu:init');
 
-				functionalMenuService.getFunctionalMenuRole().then(role_res => {
-					var menu_role_dict = {};
-					if(this.debug)
-	            		$log.debug('functionalMenuService:getFunctionalMenuRole:: getting result', role_res);
+                functionalMenuService.getFunctionalMenuRole().then(role_res => {
+                    var menu_role_dict = {};
+                    if (this.debug)
+                        $log.debug('functionalMenuService:getFunctionalMenuRole:: getting result', role_res);
 
-					for (var i in role_res) {
-						// if first time appear in menu_role_dict
-						if (!(role_res[i].menuId in menu_role_dict)) {
-							menu_role_dict[role_res[i].menuId] = [role_res[i].roleId];
-						} else {
-							menu_role_dict[role_res[i].menuId].push(role_res[i].roleId);
-						}
-					}
-					
-					functionalMenuService.getManagedFunctionalMenuForNotificationTree().then(res => {
-						if(this.debug)
-		            		$log.debug('functionalMenuService:getManagedFunctionalMenuForNotificationTree:: getting result', res);
-						var exclude_list = ['Favorites'];
-						let actualData=[];
-						$scope.functionalMenuRes=res;
-						
-						//Adding children and label attribute to all objects in res
-						for(let i = 0; i < res.length; i++){
-							res[i].child=[];
-							res[i].name=res[i].text;
-							res[i].id=res[i].text;
-							res[i].displayCheckbox= true;	                         
-							$scope.checkBoxObj = {isAnyRoleSelected:false};
-							res[i].roleId = menu_role_dict[res[i].menuId];
-							res[i].onSelect = function () {
-								$scope.$apply(function () {
-									$scope.newNotifModel.anyTreeItemSelected=$scope.checkTreeSelect();
-								})
-							};
-							
-							if (res[i].roleId && res[i].roleId.length==_.intersection(res[i].roleId, $scope.roleObj.notificationRoleIds).length){
-								res[i].isSelected= true;
-								res[i].selected= true;	
-								res[i].indeterminate= false;
-							}else{
-								/*default*/
-								res[i].isSelected= false;
-								res[i].selected= false;
-								res[i].indeterminate= false;		                     
-							}
-						}
+                    for (var i in role_res) {
+                        // if first time appear in menu_role_dict
+                        if (!(role_res[i].menuId in menu_role_dict)) {
+                            menu_role_dict[role_res[i].menuId] = [role_res[i].roleId];
+                        } else {
+                            menu_role_dict[role_res[i].menuId].push(role_res[i].roleId);
+                        }
+                    }
 
-						// Adding actual child items to children array in res
-						// objects
-						$scope.parentChildDict ={};
-						$scope.parentChildRoleIdDict ={};
-						for (let i = 0; i < res.length; i++) {
-							let parentId = res[i].menuId;
-							$scope.parentChildDict[parentId] = [];
-							$scope.parentChildRoleIdDict[parentId]=[];
-							for (let j = 0; j < res.length; j++) {
-								let childId = res[j].parentMenuId;
-								if (parentId === childId) {
-									res[i].child.push(res[j]);
-									$scope.parentChildDict[parentId].push(res[j].menuId);
-									//if res[j].roleId is defined
-									if (res[j].roleId) {
-										for (let k in res[j].roleId) {
-											$scope.parentChildRoleIdDict[parentId].push(res[j].roleId[k]);
-										}
+                    functionalMenuService.getManagedFunctionalMenuForNotificationTree().then(res => {
+                        if (this.debug)
+                            $log.debug('functionalMenuService:getManagedFunctionalMenuForNotificationTree:: getting result', res);
+                        var exclude_list = ['Favorites'];
+                        let actualData = [];
+                        $scope.functionalMenuRes = res;
 
-									}
-								}
-							}
-						}
-						//check if grand children exist
-						for (var key in $scope.parentChildDict){
-							var child = $scope.parentChildDict[key];
-							var isGrandParent = false;
-							if (child.length>0) {
-								for (var i in child) {
-									if ($scope.parentChildDict[child[i]].length>0){
-										isGrandParent = true;
-										break;
-									}
-								}
-							}
-							if (isGrandParent) {
-								for (var i in child) {
-									// if the child has children
-									if ($scope.parentChildDict[child[i]].length>0) {
-										for (var j in $scope.parentChildRoleIdDict[child[i]]) {
-											if ($scope.parentChildRoleIdDict[key].indexOf($scope.parentChildRoleIdDict[child[i]][j]) === -1) {
-												$scope.parentChildRoleIdDict[key].push($scope.parentChildRoleIdDict[child[i]][j]);
-											}
-										}
-									} 
-								}
-							}
+                        //Adding children and label attribute to all objects in res
+                        for (let i = 0; i < res.length; i++) {
+                            res[i].child = [];
+                            res[i].name = res[i].text;
+                            res[i].id = res[i].text;
+                            res[i].displayCheckbox = true;
+                            $scope.checkBoxObj = {
+                                isAnyRoleSelected: false
+                            };
+                            res[i].roleId = menu_role_dict[res[i].menuId];
+                            res[i].onSelect = function() {
+                                $scope.$apply(function() {
+                                    $scope.newNotifModel.anyTreeItemSelected = $scope.checkTreeSelect();
+                                })
+                            };
 
-						};     
+                            if (res[i].roleId && res[i].roleId.length == _.intersection(res[i].roleId, $scope.roleObj.notificationRoleIds).length) {
+                                res[i].isSelected = true;
+                                res[i].selected = true;
+                                res[i].indeterminate = false;
+                            } else {
+                                /*default*/
+                                res[i].isSelected = false;
+                                res[i].selected = false;
+                                res[i].indeterminate = false;
+                            }
+                        }
 
-						// Sort the top-level menu items in order based on the column
-						res.sort(function(a, b) {
-							return a.column-b.column;
-						});
+                        // Adding actual child items to children array in res
+                        // objects
+                        $scope.parentChildDict = {};
+                        $scope.parentChildRoleIdDict = {};
+                        for (let i = 0; i < res.length; i++) {
+                            let parentId = res[i].menuId;
+                            $scope.parentChildDict[parentId] = [];
+                            $scope.parentChildRoleIdDict[parentId] = [];
+                            for (let j = 0; j < res.length; j++) {
+                                let childId = res[j].parentMenuId;
+                                if (parentId === childId) {
+                                    res[i].child.push(res[j]);
+                                    $scope.parentChildDict[parentId].push(res[j].menuId);
+                                    //if res[j].roleId is defined
+                                    if (res[j].roleId) {
+                                        for (let k in res[j].roleId) {
+                                            $scope.parentChildRoleIdDict[parentId].push(res[j].roleId[k]);
+                                        }
 
-						// Sort all the child in order based on the column
-						for(let i = 0; i < res.length; i++){
-							res[i].child.sort(function(a, b){
-								return a.column-b.column;
-							});
-						}
+                                    }
+                                }
+                            }
+                        }
+                        //check if grand children exist
+                        for (var key in $scope.parentChildDict) {
+                            var child = $scope.parentChildDict[key];
+                            var isGrandParent = false;
+                            if (child.length > 0) {
+                                for (var i in child) {
+                                    if ($scope.parentChildDict[child[i]].length > 0) {
+                                        isGrandParent = true;
+                                        break;
+                                    }
+                                }
+                            }
+                            if (isGrandParent) {
+                                for (var i in child) {
+                                    // if the child has children
+                                    if ($scope.parentChildDict[child[i]].length > 0) {
+                                        for (var j in $scope.parentChildRoleIdDict[child[i]]) {
+                                            if ($scope.parentChildRoleIdDict[key].indexOf($scope.parentChildRoleIdDict[child[i]][j]) === -1) {
+                                                $scope.parentChildRoleIdDict[key].push($scope.parentChildRoleIdDict[child[i]][j]);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
 
-						//Forming actual parent items
-						for(let i = 0; i < res.length; i++){
-							let parentId=res[i].parentMenuId;
-							if(parentId===null){
-								actualData.push(res[i]);
-							}
-						}
-						var treedata = actualData[0].child;
-						$scope.treedata = [];
+                        };
 
-						/*Remove favorite from the list */
-						for (var i in treedata) {
-							if (!(treedata[i].name.indexOf(exclude_list) > -1)) {
-								$scope.treedata.push(treedata[i])
-							}
-						}
-						//setting b2b tree parameter
-						$scope.settingTreeParam();
+                        // Sort the top-level menu items in order based on the column
+                        res.sort(function(a, b) {
+                            return a.column - b.column;
+                        });
+
+                        // Sort all the child in order based on the column
+                        for (let i = 0; i < res.length; i++) {
+                            res[i].child.sort(function(a, b) {
+                                return a.column - b.column;
+                            });
+                        }
+
+                        //Forming actual parent items
+                        for (let i = 0; i < res.length; i++) {
+                            let parentId = res[i].parentMenuId;
+                            if (parentId === null) {
+                                actualData.push(res[i]);
+                            }
+                        }
+                        var treedata = actualData[0].child;
+                        $scope.treedata = [];
+
+                        /*Remove favorite from the list */
+                        for (var i in treedata) {
+                            if (!(treedata[i].name.indexOf(exclude_list) > -1)) {
+                                $scope.treedata.push(treedata[i])
+                            }
+                        }
+                        //setting b2b tree parameter
+                        $scope.settingTreeParam();
 
                     }).catch(err => {
                         $log.error('FunctionalMenuCtrl:getFunctionalMenu:: error ', err);
@@ -494,244 +566,247 @@
 
                 }).catch(err => {
                     $log.error('FunctionalMenuCtrl:getFunctionalMenu:: error ', err);
-                })
-                    ;
+                });
             }
-     
-            
+
+
             let getAppRoleIds = () => {
-            	$scope.notifObj= {isCategoriesFunctionalMenu:false};
-				notificationService.getAppRoleIds().then(res => {
-					if(this.debug)
-	            		$log.debug('notificationService:getAppRoleIds:: getting result', res);
-					res = res.data;
-					let actualData = [];
-					var app_id_name_list = {};
-					$scope.checkBoxObj = {isAnyRoleSelected:false};
-					for (let i = 0; i < res.length; i++) {
-						if (!(res[i].appId in app_id_name_list)) {
-							app_id_name_list[res[i].appId] = res[i].appName;
-						}
-						res[i].child=[];
-						res[i].name=res[i].roleName;
-						res[i].displayCheckbox= true;
-						res[i].id = res[i].roleId;
-						res[i].menuId = res[i].roleId;
-						res[i].parentMenuId = res[i].appId;
-						res[i].can_check = true;
-						res[i].roleId = [res[i].roleId];
-						res[i].onSelect = function () {
-							$scope.$apply(function () {
-								$scope.newNotifModel.anyTreeItemSelected=$scope.checkTreeSelect();
-							})
-						};
-						/*assigning selected value*/
-						if (res[i].roleId && res[i].roleId.length==_.intersection(res[i].roleId, $scope.roleObj.notificationRoleIds).length){
-							res[i].isSelected= true;
-							res[i].selected= true;	
-							res[i].indeterminate= false;
-						}else{
-							/*default*/
-							res[i].isSelected= false;
-							res[i].selected= false;
-							res[i].indeterminate= false;		                     
-						}  
-					}
+                $scope.notifObj = {
+                    isCategoriesFunctionalMenu: false
+                };
+                notificationService.getAppRoleIds().then(res => {
+                    if (this.debug)
+                        $log.debug('notificationService:getAppRoleIds:: getting result', res);
+                    res = res.data;
+                    let actualData = [];
+                    var app_id_name_list = {};
+                    $scope.checkBoxObj = {
+                        isAnyRoleSelected: false
+                    };
+                    for (let i = 0; i < res.length; i++) {
+                        if (!(res[i].appId in app_id_name_list)) {
+                            app_id_name_list[res[i].appId] = res[i].appName;
+                        }
+                        res[i].child = [];
+                        res[i].name = res[i].roleName;
+                        res[i].displayCheckbox = true;
+                        res[i].id = res[i].roleId;
+                        res[i].menuId = res[i].roleId;
+                        res[i].parentMenuId = res[i].appId;
+                        res[i].can_check = true;
+                        res[i].roleId = [res[i].roleId];
+                        res[i].onSelect = function() {
+                            $scope.$apply(function() {
+                                $scope.newNotifModel.anyTreeItemSelected = $scope.checkTreeSelect();
+                            })
+                        };
+                        /*assigning selected value*/
+                        if (res[i].roleId && res[i].roleId.length == _.intersection(res[i].roleId, $scope.roleObj.notificationRoleIds).length) {
+                            res[i].isSelected = true;
+                            res[i].selected = true;
+                            res[i].indeterminate = false;
+                        } else {
+                            /*default*/
+                            res[i].isSelected = false;
+                            res[i].selected = false;
+                            res[i].indeterminate = false;
+                        }
+                    }
 
-					for (var app_id in app_id_name_list) {
-						var new_res = {};
-						new_res.child = [];
-						new_res.name = app_id_name_list[app_id];
-						new_res.id = app_id;
-						new_res.displayCheckbox= true;
-						new_res.menuId = app_id;
-						new_res.parentMenuId = null;
-						new_res.appId = null;
-						new_res.can_check = true;
-						new_res.roleId = null;
-						new_res.onSelect = function () {
-							$scope.$apply(function () {
-								$scope.newNotifModel.anyTreeItemSelected=$scope.checkTreeSelect();
-							})
-						};
-						res.push(new_res);
-					}
-					$scope.parentChildRoleIdDict ={};
-					//Adding actual child items to child array in res objects
-					for (let i = 0; i < res.length; i++) {
-						let parentId = res[i].menuId;
-						$scope.parentChildRoleIdDict[parentId]=[];
-						for (let j = 0; j < res.length; j++) {
-							let childId = res[j].parentMenuId;
-							if (parentId == childId) {
-								res[i].child.push(res[j]);
-								if (res[j].roleId) {
-									for (let k in res[j].roleId) {
-										$scope.parentChildRoleIdDict[parentId].push(res[j].roleId[k]);
-									}
+                    for (var app_id in app_id_name_list) {
+                        var new_res = {};
+                        new_res.child = [];
+                        new_res.name = app_id_name_list[app_id];
+                        new_res.id = app_id;
+                        new_res.displayCheckbox = true;
+                        new_res.menuId = app_id;
+                        new_res.parentMenuId = null;
+                        new_res.appId = null;
+                        new_res.can_check = true;
+                        new_res.roleId = null;
+                        new_res.onSelect = function() {
+                            $scope.$apply(function() {
+                                $scope.newNotifModel.anyTreeItemSelected = $scope.checkTreeSelect();
+                            })
+                        };
+                        res.push(new_res);
+                    }
+                    $scope.parentChildRoleIdDict = {};
+                    //Adding actual child items to child array in res objects
+                    for (let i = 0; i < res.length; i++) {
+                        let parentId = res[i].menuId;
+                        $scope.parentChildRoleIdDict[parentId] = [];
+                        for (let j = 0; j < res.length; j++) {
+                            let childId = res[j].parentMenuId;
+                            if (parentId == childId) {
+                                res[i].child.push(res[j]);
+                                if (res[j].roleId) {
+                                    for (let k in res[j].roleId) {
+                                        $scope.parentChildRoleIdDict[parentId].push(res[j].roleId[k]);
+                                    }
 
-								}
-							}
-						}
-					}
-					//Forming actual parent items
-					for (let i = 0; i < res.length; i++) {
-						let parentId = res[i].parentMenuId;
-						if (parentId === null) {
-							actualData.push(res[i]);
-						}
-					}
+                                }
+                            }
+                        }
+                    }
+                    //Forming actual parent items
+                    for (let i = 0; i < res.length; i++) {
+                        let parentId = res[i].parentMenuId;
+                        if (parentId === null) {
+                            actualData.push(res[i]);
+                        }
+                    }
 
-					$scope.treedata = actualData;                       
-					//setting correct parameters for b2b tree
-					$scope.settingTreeParam();
+                    $scope.treedata = actualData;
+                    //setting correct parameters for b2b tree
+                    $scope.settingTreeParam();
                 }).catch(err => {
                     $log.error('FunctionalMenuCtrl:getFunctionalMenu:: error ', err);
                 }).finally(() => {
                     this.isLoadingTable = false;
                 })
             }
-            $scope.getFunctionalMenu= function() {
-            $scope.treeTitle="Functional Menu";
-            getFunctionalMenu();
+            $scope.getFunctionalMenu = function() {
+                $scope.treeTitle = "Functional Menu";
+                getFunctionalMenu();
             }
             $scope.getAppRoleIds = function() {
-            $scope.treeTitle="Applications/Roles";
+                $scope.treeTitle = "Applications/Roles";
                 getAppRoleIds();
             }
-             
-            
-            
-            $scope.settingTreeParam = function(){
-            	/**************first level****************/
-				for(var fi=0; fi<$scope.treedata.length;fi++){
-					var fLevel = $scope.treedata[fi];
-					var sLevel = $scope.treedata[fi].child;
-					var sLevelSelectedCount =0;
-					var sLevelChildNumber =0
-					if(fLevel.child.length==0 && fLevel.roleId==null){
-						delete fLevel.child;
-					}else if(sLevel){
-						/**************Second level****************/
-						var sLevelDelArray=[]; 
-						for(var si=0;si<sLevel.length;si++){     
-							var deletThisSLev= false;
-							if(sLevel[si].child.length==0 && sLevel[si].roleId==null){
-								sLevel[si].displayCheckbox=false;
-								sLevelDelArray.push(sLevel[si].name);
-								sLevel[si].name = '';
-								sLevel[si].active=false;
-								delete sLevel[si].child;
-							} else if(sLevel[si].child.length==0){
-								delete sLevel[si].child;
-							}else{
-								/**************Third level****************/
-								var tLevel = sLevel[si].child;
-								var tLevelSelectedCount =0;
-								var tLevelChildNumber =0;
-								if(tLevel){
-									var tLevelDelArray=[]; 
-									var tLevelLen = tLevel.length;
-									var tLevelRoleIdUndefined =0;
-									for(var ti=0;ti<tLevel.length;ti++){
-										delete tLevel[ti].child;
-										if(tLevel[ti].roleId==null){
-											tLevel[ti].displayCheckbox=false;
-											tLevelDelArray.push(tLevel[ti].name);
-											tLevel[ti].name = '';
-											tLevel[ti].active=false;										
-											tLevelRoleIdUndefined++
-										}else{
-											if(tLevel[ti].isSelected)
-												tLevelSelectedCount++;
 
-											if(tLevel[ti].displayCheckbox)
-												tLevelChildNumber++;
-										} 	
-									}
-									if(tLevelRoleIdUndefined==tLevelLen)
-										deletThisSLev=true;
-									if(tLevelSelectedCount==tLevelChildNumber){
-										sLevel[si].isSelected=true;
-										sLevel[si].indeterminate=false;
-										sLevel[si].active=true;
-									}else if(tLevelSelectedCount>0){
-										sLevel[si].indeterminate=true;
-										sLevel[si].active=true;
-									}	
-									
-									/*Cleanup unused third level items*/
-									for(var i=0;i<tLevelDelArray.length;i++){
-										var name = tLevelDelArray[i];
-										for(var ti=0;ti<tLevel.length;ti++){
-											if(name==tLevel[ti].text){
-												tLevel.splice(ti,1);
-												break;
-											}
-										}
-									}
-								}	
-							}
-							if(deletThisSLev){ //remove the whole second level item if all it's child has no roleId
-								sLevel[si].displayCheckbox=false;
-								sLevelDelArray.push(sLevel[si].name);
-								sLevel[si].name = '';
-								sLevel[si].active=false;
-							}else{
-								if(sLevel[si].isSelected)
-									sLevelSelectedCount++;	
-								if(sLevel[si].displayCheckbox)
-									sLevelChildNumber++;
-							}
-						}
-						if(sLevelSelectedCount==sLevelChildNumber && sLevelChildNumber!=0){
-							fLevel.isSelected=true;
-							fLevel.indeterminate=false;
-							fLevel.active=true;
-						}else if(sLevelSelectedCount>0){
-							fLevel.indeterminate=true;
-							fLevel.active=true;
-						}else{
-							//fLevel.active=false;
-							fLevel.indeterminate=false;
-						}
-						/*Cleanup unused second level items*/
-						for(var i=0;i<sLevelDelArray.length;i++){
-							var name = sLevelDelArray[i];
-							for(var si=0;si<sLevel.length;si++){
-								if(name==sLevel[si].text){
-									sLevel.splice(si,1);
-									break;
-								}
-							}
-						}
-					}
-				}
+
+
+            $scope.settingTreeParam = function() {
+                /**************first level****************/
+                for (var fi = 0; fi < $scope.treedata.length; fi++) {
+                    var fLevel = $scope.treedata[fi];
+                    var sLevel = $scope.treedata[fi].child;
+                    var sLevelSelectedCount = 0;
+                    var sLevelChildNumber = 0
+                    if (fLevel.child.length == 0 && fLevel.roleId == null) {
+                        delete fLevel.child;
+                    } else if (sLevel) {
+                        /**************Second level****************/
+                        var sLevelDelArray = [];
+                        for (var si = 0; si < sLevel.length; si++) {
+                            var deletThisSLev = false;
+                            if (sLevel[si].child.length == 0 && sLevel[si].roleId == null) {
+                                sLevel[si].displayCheckbox = false;
+                                sLevelDelArray.push(sLevel[si].name);
+                                sLevel[si].name = '';
+                                sLevel[si].active = false;
+                                delete sLevel[si].child;
+                            } else if (sLevel[si].child.length == 0) {
+                                delete sLevel[si].child;
+                            } else {
+                                /**************Third level****************/
+                                var tLevel = sLevel[si].child;
+                                var tLevelSelectedCount = 0;
+                                var tLevelChildNumber = 0;
+                                if (tLevel) {
+                                    var tLevelDelArray = [];
+                                    var tLevelLen = tLevel.length;
+                                    var tLevelRoleIdUndefined = 0;
+                                    for (var ti = 0; ti < tLevel.length; ti++) {
+                                        delete tLevel[ti].child;
+                                        if (tLevel[ti].roleId == null) {
+                                            tLevel[ti].displayCheckbox = false;
+                                            tLevelDelArray.push(tLevel[ti].name);
+                                            tLevel[ti].name = '';
+                                            tLevel[ti].active = false;
+                                            tLevelRoleIdUndefined++
+                                        } else {
+                                            if (tLevel[ti].isSelected)
+                                                tLevelSelectedCount++;
+
+                                            if (tLevel[ti].displayCheckbox)
+                                                tLevelChildNumber++;
+                                        }
+                                    }
+                                    if (tLevelRoleIdUndefined == tLevelLen)
+                                        deletThisSLev = true;
+                                    if (tLevelSelectedCount == tLevelChildNumber) {
+                                        sLevel[si].isSelected = true;
+                                        sLevel[si].indeterminate = false;
+                                        sLevel[si].active = true;
+                                    } else if (tLevelSelectedCount > 0) {
+                                        sLevel[si].indeterminate = true;
+                                        sLevel[si].active = true;
+                                    }
+
+                                    /*Cleanup unused third level items*/
+                                    for (var i = 0; i < tLevelDelArray.length; i++) {
+                                        var name = tLevelDelArray[i];
+                                        for (var ti = 0; ti < tLevel.length; ti++) {
+                                            if (name == tLevel[ti].text) {
+                                                tLevel.splice(ti, 1);
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            if (deletThisSLev) { //remove the whole second level item if all it's child has no roleId
+                                sLevel[si].displayCheckbox = false;
+                                sLevelDelArray.push(sLevel[si].name);
+                                sLevel[si].name = '';
+                                sLevel[si].active = false;
+                            } else {
+                                if (sLevel[si].isSelected)
+                                    sLevelSelectedCount++;
+                                if (sLevel[si].displayCheckbox)
+                                    sLevelChildNumber++;
+                            }
+                        }
+                        if (sLevelSelectedCount == sLevelChildNumber && sLevelChildNumber != 0) {
+                            fLevel.isSelected = true;
+                            fLevel.indeterminate = false;
+                            fLevel.active = true;
+                        } else if (sLevelSelectedCount > 0) {
+                            fLevel.indeterminate = true;
+                            fLevel.active = true;
+                        } else {
+                            //fLevel.active=false;
+                            fLevel.indeterminate = false;
+                        }
+                        /*Cleanup unused second level items*/
+                        for (var i = 0; i < sLevelDelArray.length; i++) {
+                            var name = sLevelDelArray[i];
+                            for (var si = 0; si < sLevel.length; si++) {
+                                if (name == sLevel[si].text) {
+                                    sLevel.splice(si, 1);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
             }
             init();
             getFunctionalMenu();
 
         }
-        
+
     }
-    
-    userNotificationsModalCtrl.$inject = ['$scope', '$log', 'functionalMenuService', 'confirmBoxService', 'notificationService', '$modal', 'ngDialog', '$state', '$filter','items'];
+
+    userNotificationsModalCtrl.$inject = ['$scope', '$log', 'functionalMenuService', 'confirmBoxService', 'notificationService', '$modal', 'ngDialog', '$state', '$filter', 'items'];
     angular.module('ecompApp').controller('userNotificationsModalCtrl', userNotificationsModalCtrl);
-    
+
     angular.module('ecompApp').directive('attDatepickerCustom', ['$log', function($log) {
         return {
             restrict: 'A',
-          require: 'ngModel',
+            require: 'ngModel',
             scope: {},
-            
+
             controller: ['$scope', '$element', '$attrs', '$compile', 'datepickerConfig', 'datepickerService', function($scope, $element, $attrs, $compile, datepickerConfig, datepickerService) {
-               var dateFormatString = angular.isDefined($attrs.dateFormat) ? $scope.$parent.$eval($attrs.dateFormat) : datepickerConfig.dateFormat;
-               var selectedDateMessage = '<div class="sr-focus hidden-spoken" tabindex="-1">the date you selected is {{$parent.current | date : \'' + dateFormatString + '\'}}</div>';
-               $element.removeAttr('att-datepicker-custom');
+                var dateFormatString = angular.isDefined($attrs.dateFormat) ? $scope.$parent.$eval($attrs.dateFormat) : datepickerConfig.dateFormat;
+                var selectedDateMessage = '<div class="sr-focus hidden-spoken" tabindex="-1">the date you selected is {{$parent.current | date : \'' + dateFormatString + '\'}}</div>';
+                $element.removeAttr('att-datepicker-custom');
                 $element.removeAttr('ng-model');
                 $element.attr('ng-value', '$parent.current |  date:"EEEE, MMMM d, y"');
                 $element.attr('aria-describedby', 'datepicker');
-               
+
                 $element.attr('maxlength', 10);
 
                 var wrapperElement = angular.element('<div></div>');
@@ -763,10 +838,10 @@
                 ctrl.$render = function() {
                     scope.current = ctrl.$viewValue;
                 };
-              
+
             }
         };
     }]);
 
-    
-})();
+
+})();
\ No newline at end of file
diff --git a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.less b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.less
index 79c2bae..17bbdab 100644
--- a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.less
+++ b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.less
@@ -169,3 +169,16 @@
     right: 10px;
     top: 8px;
 }     
+
+.date-validation{
+	top:185px;
+	color: #cf2a2a;
+	font-size: 10px;
+	position:absolute;
+}
+.endDate-validation{
+	top:270px;
+	color: #cf2a2a;
+	font-size: 10px;
+	position:absolute;
+}
\ No newline at end of file
diff --git a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.page.html b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.page.html
index 57433c1..5d1698e 100644
--- a/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.page.html
+++ b/ecomp-portal-FE-common/client/app/views/user-notifications-admin/user.notifications.modal.page.html
@@ -131,10 +131,14 @@
 							ng-model="newNotifModel.startTime" b2b-datepicker min="minDate" max="maxDate" 
 							required />
 					</div>
-					<div id="user-startdate-required" ng-show="!isDateValid(newNotifModel.startTime)">
-						<small class="mandatory-categories">Please enter valid date in MM/DD/YYYY format!</small>
+					<div style="{{( isEditMode )? 'opacity : 0; pointer-events: none;':' '}}">
+						<div id="user-startdate-required" ng-show="!isDateValid(newNotifModel.startTime)">
+							<small class="mandatory-categories">Please enter valid date in MM/DD/YYYY format!</small>
+						</div>
+						<div id="user-startdate-required" ng-show="!isStartDateValidFromToday(newNotifModel.startTime)">
+							<small class="date-validation">Date should be greater than or equal to current date!</small>
+						</div>
 					</div>
-					
 				</div>
 				<div ng-show="!isEditMode" ng-init="formatStartDate()"></div> 
 			</div>			
@@ -142,18 +146,23 @@
 			<div id="add-user-notif-enddate" class="add-widget-field"
 				style="padding-bottom: 12px; width: 301px !important; {{( isEditMode )? 'opacity : 0.6; pointer-events: none;':' '}}">
 				<div id="user-notification-enddate-label" class="user-notif-label">
-					<span runat="server" ID="required" class="notifcation-label-user-requiredId">*</span> End	Date (Local Time)
+					<span runat="server" ID="required" class="notifcation-label-user-requiredId">*</span> EndDate (Local Time)
 				</div>
 				<div class="datepicker-container">
 					<input class="notif-input-calendar" type="text" id="datepicker-end" 
 						ng-model="newNotifModel.endTime" b2b-datepicker min="minDate" max="maxDate" 
 						required />
 				</div>
-				<div id="user-endDate-required" ng-show="!isDateValid(newNotifModel.endTime)">
+				<div style="{{( isEditMode )? 'opacity : 0; pointer-events: none;':' '}}">
+					<div id="user-endDate-required" ng-show="!isDateValid(newNotifModel.endTime)">
 						<small class="mandatory-categories">Please enter valid date in MM/DD/YYYY format!</small>
 					</div>
-				<div id="user-enddate-error" ng-show="newNotifModel.endTime&&newNotifModel.startTime&&newNotifModel.startTime.getTime()>=newNotifModel.endTime.getTime()" class="user-enddate-error-txt">
-					<small class="mandatory-categories">End Date must be greater than start Date</small>
+					<div id="user-startdate-required"  ng-show="!isStartDateValidFromToday(newNotifModel.endTime)">
+						<small class="endDate-validation">Date should be greater than or equal to current date!</small>
+					</div>
+					<div id="user-enddate-error" ng-show="newNotifModel.endTime&&newNotifModel.startTime&&newNotifModel.startTime.getTime()>=newNotifModel.endTime.getTime()" class="user-enddate-error-txt">
+						<small class="mandatory-categories">End Date must be greater than start Date</small>
+					</div>
 				</div>
 				<div ng-show="!isEditMode" ng-init="formatEndDate()" ></div> 
 			</div>
@@ -181,7 +190,7 @@
 					ng-model="newNotifModel.msgDescription" name="content">
 				</textarea>
 				<div id="user-notif-message-required" ng-show="newNotifModel.msgDescription.length ==0 ">
-				<small class="mandatory-categories">Message is Required</small>
+					<small class="mandatory-categories">Message is Required</small>
 				</div>
 			</div>
 
diff --git a/ecomp-portal-FE-common/home/ecompportal/applicationsHome b/ecomp-portal-FE-common/home/ecompportal/applicationsHome
deleted file mode 100644
index e2a981e..0000000
--- a/ecomp-portal-FE-common/home/ecompportal/applicationsHome
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<body>
-ECOMP Portal has moved to this new location <a href="https://www.e-access.att.com/ecomp_portal/"> https://www.e-access.att.com/ecomp_portal/ </a>
-<p>
-Please update your bookmarks.
-</p>
-</body>
-</html>
-
diff --git a/ecomp-portal-FE-common/home/ecompportal/login.htm b/ecomp-portal-FE-common/home/ecompportal/login.htm
deleted file mode 100644
index e2a981e..0000000
--- a/ecomp-portal-FE-common/home/ecompportal/login.htm
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<body>
-ECOMP Portal has moved to this new location <a href="https://www.e-access.att.com/ecomp_portal/"> https://www.e-access.att.com/ecomp_portal/ </a>
-<p>
-Please update your bookmarks.
-</p>
-</body>
-</html>
-
diff --git a/ecomp-portal-FE-common/home/index.html b/ecomp-portal-FE-common/home/index.html
deleted file mode 100644
index 5e43309..0000000
--- a/ecomp-portal-FE-common/home/index.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<script>
-window.location.href = "ecompui/login.htm"
-</script>
diff --git a/ecomp-portal-FE-os/client/src/app.less b/ecomp-portal-FE-os/client/src/app.less
index 6e7df2a..bf7a96e 100644
--- a/ecomp-portal-FE-os/client/src/app.less
+++ b/ecomp-portal-FE-os/client/src/app.less
@@ -92,4 +92,9 @@
 	z-index: 100;
 	display: none;
 	opacity: 0;
+}
+
+.errorContent p{
+    font-size: 28px;
+    margin-left: 120px;
 }
\ No newline at end of file
diff --git a/ecomp-portal-FE-os/pom.xml b/ecomp-portal-FE-os/pom.xml
index aa85349..ae3921a 100644
--- a/ecomp-portal-FE-os/pom.xml
+++ b/ecomp-portal-FE-os/pom.xml
@@ -22,8 +22,17 @@
 							<directory>${basedir}/client/app</directory>
 						</fileset>
 						<fileset>
+							<directory>${basedir}/dist</directory>
+						</fileset>
+						<fileset>
 							<directory>${basedir}/.tmp</directory>
 						</fileset>
+						<fileset>
+							<directory>${basedir}/node</directory>
+						</fileset>
+						<fileset>
+							<directory>${basedir}/node_modules</directory>
+						</fileset>
 					</filesets>
 				</configuration>
 			</plugin>
diff --git a/ecomp-portal-widget-ms/common-widgets/pom.xml b/ecomp-portal-widget-ms/common-widgets/pom.xml
index a71c5ac..6a6d54b 100644
--- a/ecomp-portal-widget-ms/common-widgets/pom.xml
+++ b/ecomp-portal-widget-ms/common-widgets/pom.xml
@@ -3,7 +3,7 @@
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>org.openecomp.portal</groupId>
-	<artifactId>widget-ms-widgets-os</artifactId>
+	<artifactId>common-widgets</artifactId>
 	<version>1.3.0-SNAPSHOT</version>
 	<packaging>pom</packaging>
 
diff --git a/ecomp-portal-widget-ms/widget-ms/pom.xml b/ecomp-portal-widget-ms/widget-ms/pom.xml
index dcab572..b421ebd 100644
--- a/ecomp-portal-widget-ms/widget-ms/pom.xml
+++ b/ecomp-portal-widget-ms/widget-ms/pom.xml
@@ -25,6 +25,13 @@
 	</properties>
 
 	<dependencies>
+		<!-- This pom pulls in artifacts -->
+		<dependency>
+			<groupId>org.openecomp.portal</groupId>
+			<artifactId>common-widgets</artifactId>
+			<version>${project.version}</version>
+			<type>pom</type>
+		</dependency>
 		<dependency>
 			<!-- Setup Spring Data JPA Repository support -->
 			<groupId>org.springframework.boot</groupId>