From fd87a0024bf559b242b7115500d8a64f1879d3fe Mon Sep 17 00:00:00 2001 From: Henry Avetisyan Date: Mon, 6 Nov 2023 13:28:05 -0800 Subject: [PATCH] new bit to disable notifications over a week away Signed-off-by: Henry Avetisyan --- .../notification/DisableNotificationEnum.java | 4 +- .../GroupMemberExpiryNotificationTask.java | 12 +++ .../zms/notification/NotificationUtils.java | 4 + .../RoleMemberExpiryNotificationTask.java | 5 + .../RoleMemberNotificationCommon.java | 30 +++++- .../RoleMemberReviewNotificationTask.java | 5 + ...GroupMemberExpiryNotificationTaskTest.java | 93 ++++++++++++++++++ .../RoleMemberExpiryNotificationTaskTest.java | 95 +++++++++++++++++++ .../RoleMemberReviewNotificationTaskTest.java | 90 ++++++++++++++++++ 9 files changed, 333 insertions(+), 5 deletions(-) diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/DisableNotificationEnum.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/DisableNotificationEnum.java index e3ed045b587..0b53cfbb1d0 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/DisableNotificationEnum.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/DisableNotificationEnum.java @@ -26,7 +26,9 @@ import java.util.function.Function; public enum DisableNotificationEnum { - USER, ADMIN; + USER, // disable notifications to the users + ADMIN, // disable notifications to the admins + OVER_ONE_WEEK; // disable notifications to the users/admins if the expiry is more than a week out public static EnumSet getEnumSet(long mask) { return EnumUtils.processBitVector(DisableNotificationEnum.class, mask); diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTask.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTask.java index 9c76c75372d..e272002f227 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTask.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTask.java @@ -122,6 +122,18 @@ private Map processGroupReminder(Map> continue; } + // check to see if the administrator has configured to generate notifications + // only for members that are expiring in less than a week + + if (disabledNotificationState.contains(DisableNotificationEnum.OVER_ONE_WEEK)) { + Timestamp notificationTimestamp = memberGroup.getExpiration(); + if (notificationTimestamp == null || notificationTimestamp.millis() - System.currentTimeMillis() > NotificationUtils.WEEK_EXPIRY_CHECK) { + LOGGER.info("Notification skipped for group {}, domain {}, notification date is more than a week way", + memberGroup.getGroupName(), memberGroup.getDomainName()); + continue; + } + } + final String domainName = memberGroup.getDomainName(); // first we're going to update our expiry details string diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/NotificationUtils.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/NotificationUtils.java index 1ca7d6b1473..6be2f7db077 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/NotificationUtils.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/NotificationUtils.java @@ -24,11 +24,15 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import static com.yahoo.athenz.common.server.notification.impl.MetricNotificationService.*; public class NotificationUtils { + // we're going to use 8 days max for our week expiry disable check + public static final long WEEK_EXPIRY_CHECK = TimeUnit.MILLISECONDS.convert(8, TimeUnit.DAYS); + public static NotificationMetric getNotificationAsMetrics(Notification notification, Timestamp currentTime, final String notificationType, final String keyName, final String objectType, final String timeType, NotificationToMetricConverterCommon notificationToMetricConverterCommon) { diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTask.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTask.java index a5c8a188363..e676a598308 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTask.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTask.java @@ -107,6 +107,11 @@ public StringBuilder getDetailString(MemberRole memberRole) { detailsRow.append(memberRole.getExpiration()); return detailsRow; } + + @Override + public Timestamp getNotificationTimestamp(MemberRole memberRole) { + return memberRole.getExpiration(); + } } class ReviewDisableRoleMemberNotificationFilter implements RoleMemberNotificationCommon.DisableRoleMemberNotificationFilter { diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberNotificationCommon.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberNotificationCommon.java index 7c2236845d7..6261766e0b5 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberNotificationCommon.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberNotificationCommon.java @@ -24,6 +24,7 @@ import com.yahoo.athenz.zms.DomainRoleMember; import com.yahoo.athenz.zms.MemberRole; import com.yahoo.athenz.zms.utils.ZMSUtils; +import com.yahoo.rdl.Timestamp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,11 +35,12 @@ public class RoleMemberNotificationCommon { + private static final Logger LOGGER = LoggerFactory.getLogger(RoleMemberNotificationCommon.class); + private final String userDomainPrefix; private final boolean consolidatedNotifications; private final NotificationCommon notificationCommon; private final DomainRoleMembersFetcher domainRoleMembersFetcher; - private static final Logger LOGGER = LoggerFactory.getLogger(RoleMemberNotificationCommon.class); public RoleMemberNotificationCommon(DBService dbService, String userDomainPrefix, boolean consolidatedNotifications) { this.userDomainPrefix = userDomainPrefix; @@ -291,6 +293,19 @@ private Map processRoleReminder(Map> do LOGGER.info("Notification disabled for role {}, domain {}", memberRole.getRoleName(), memberRole.getDomainName()); continue; } + + // check to see if the administrator has configured to generate notifications + // only for members that are expiring in less than a week + + if (disabledNotificationState.contains(DisableNotificationEnum.OVER_ONE_WEEK)) { + Timestamp notificationTimestamp = roleMemberDetailStringer.getNotificationTimestamp(memberRole); + if (notificationTimestamp == null || notificationTimestamp.millis() - System.currentTimeMillis() > NotificationUtils.WEEK_EXPIRY_CHECK) { + LOGGER.info("Notification skipped for role {}, domain {}, notification date is more than a week way", + memberRole.getRoleName(), memberRole.getDomainName()); + continue; + } + } + final String domainName = memberRole.getDomainName(); // first we're going to update our expiry details string @@ -361,12 +376,19 @@ List printNotificationDetailsToLog(List notification */ public interface RoleMemberDetailStringer { /** - * - * @param memberRole member role - * @return Details extracted from the memberRole with a semicolon (;) between them + * Get the details extracted from the memberRole with a semicolon (;) between them * These details should fit in the notification template (for example, the html of an email body) + * @param memberRole member role + * @return StringBuilder object that contains details */ StringBuilder getDetailString(MemberRole memberRole); + + /** + * Returns the notification date (expiry or review date) for a given role + * @param memberRole member role + * @return notification date + */ + Timestamp getNotificationTimestamp(MemberRole memberRole); } /** diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTask.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTask.java index 69a2807e788..e5290cfc21f 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTask.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTask.java @@ -85,6 +85,11 @@ public StringBuilder getDetailString(MemberRole memberRole) { detailsRow.append(memberRole.getReviewReminder()); return detailsRow; } + + @Override + public Timestamp getNotificationTimestamp(MemberRole memberRole) { + return memberRole.getReviewReminder(); + } } class ReviewDisableRoleMemberNotificationFilter implements RoleMemberNotificationCommon.DisableRoleMemberNotificationFilter { diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTaskTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTaskTest.java index ac1c7e0a0e5..fc75fd1c2c2 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTaskTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/GroupMemberExpiryNotificationTaskTest.java @@ -24,6 +24,7 @@ import org.testng.annotations.Test; import java.util.*; +import java.util.concurrent.TimeUnit; import static com.yahoo.athenz.common.ServerCommonConsts.USER_DOMAIN_PREFIX; import static com.yahoo.athenz.common.server.notification.NotificationServiceConstants.*; @@ -158,6 +159,98 @@ public void testSendGroupMemberExpiryReminders() { notificationManager.shutdown(); } + @Test + public void testSendGroupMemberExpiryRemindersDisabledOverOneWeek() { + + DBService dbsvc = Mockito.mock(DBService.class); + NotificationToEmailConverterCommon notificationToEmailConverterCommon = new NotificationToEmailConverterCommon(null); + NotificationService mockNotificationService = Mockito.mock(NotificationService.class); + NotificationServiceFactory testfact = () -> mockNotificationService; + + Timestamp twoWeekExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(14, TimeUnit.DAYS)); + Timestamp oneDayExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); + + List memberGroups = new ArrayList<>(); + memberGroups.add(new GroupMember().setGroupName("group1") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setExpiration(twoWeekExpiry)); + memberGroups.add(new GroupMember().setGroupName("group2") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setExpiration(oneDayExpiry)); + DomainGroupMember domainGroupMember = new DomainGroupMember() + .setMemberName("user.joe") + .setMemberGroups(memberGroups); + Map expiryMembers = new HashMap<>(); + expiryMembers.put("user.joe", domainGroupMember); + + // we're going to return null for our first thread which will + // run during init call and then the real data for the second + // call + + Mockito.when(dbsvc.getGroupExpiryMembers(1)) + .thenReturn(null) + .thenReturn(expiryMembers); + + NotificationManager notificationManager = getNotificationManager(dbsvc, testfact); + + ZMSTestUtils.sleep(1000); + + AthenzDomain domain = new AthenzDomain("athenz1"); + List roleMembers = new ArrayList<>(); + roleMembers.add(new RoleMember().setMemberName("user.jane")); + Role adminRole = new Role().setName("athenz1:role.admin").setRoleMembers(roleMembers); + List roles = new ArrayList<>(); + roles.add(adminRole); + domain.setRoles(roles); + + Mockito.when(dbsvc.getRolesByDomain("athenz1")).thenReturn(domain.getRoles()); + Mockito.when(dbsvc.getRole("athenz1", "admin", Boolean.FALSE, Boolean.TRUE, Boolean.FALSE)) + .thenReturn(adminRole); + + Map tags = new HashMap<>(); + TagValueList tagValueList = new TagValueList().setList(Collections.singletonList("4")); + tags.put(ZMSConsts.DISABLE_REMINDER_NOTIFICATIONS_TAG, tagValueList); + Group group = new Group().setTags(tags); + Mockito.when(dbsvc.getGroup("athenz1", "group1", false, false)).thenReturn(group); + Mockito.when(dbsvc.getGroup("athenz1", "group2", false, false)).thenReturn(group); + + List notifications = new GroupMemberExpiryNotificationTask(dbsvc, USER_DOMAIN_PREFIX, + notificationToEmailConverterCommon, false).getNotifications(); + + // we should get 2 notifications - one for user and one for domain + // group1 should be excluded and group2 should be included + + assertEquals(notifications.size(), 2); + + // Verify contents of notifications is as expected + Notification expectedFirstNotification = new Notification(); + expectedFirstNotification.addRecipient("user.joe"); + expectedFirstNotification.addDetails(NOTIFICATION_DETAILS_ROLES_LIST, "athenz1;group2;user.joe;" + oneDayExpiry); + expectedFirstNotification.addDetails("member", "user.joe"); + expectedFirstNotification.setNotificationToEmailConverter( + new GroupMemberExpiryNotificationTask.GroupExpiryPrincipalNotificationToEmailConverter( + notificationToEmailConverterCommon)); + expectedFirstNotification.setNotificationToMetricConverter( + new GroupMemberExpiryNotificationTask.GroupExpiryPrincipalNotificationToToMetricConverter()); + + Notification expectedSecondNotification = new Notification(); + expectedSecondNotification.addRecipient("user.jane"); + expectedSecondNotification.addDetails(NOTIFICATION_DETAILS_MEMBERS_LIST, "athenz1;group2;user.joe;" + oneDayExpiry); + expectedSecondNotification.addDetails("domain", "athenz1"); + expectedSecondNotification.setNotificationToEmailConverter( + new GroupMemberExpiryNotificationTask.GroupExpiryDomainNotificationToEmailConverter( + notificationToEmailConverterCommon)); + expectedSecondNotification.setNotificationToMetricConverter( + new GroupMemberExpiryNotificationTask.GroupExpiryDomainNotificationToMetricConverter()); + + assertEquals(notifications.get(0), expectedFirstNotification); + assertEquals(notifications.get(1), expectedSecondNotification); + + notificationManager.shutdown(); + } + @Test public void testSendGroupMemberExpiryRemindersNoValidDomain() { diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTaskTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTaskTest.java index 157ec4f3185..48c925dd357 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTaskTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberExpiryNotificationTaskTest.java @@ -24,6 +24,7 @@ import org.testng.annotations.Test; import java.util.*; +import java.util.concurrent.TimeUnit; import static com.yahoo.athenz.common.ServerCommonConsts.USER_DOMAIN_PREFIX; import static com.yahoo.athenz.common.server.notification.NotificationServiceConstants.*; @@ -84,6 +85,7 @@ public void testSendRoleMemberExpiryRemindersEmptySet() { notificationManager.shutdown(); } + @Test public void testSendRoleMemberExpiryReminders() { @@ -162,6 +164,99 @@ public void testSendRoleMemberExpiryReminders() { notificationManager.shutdown(); } + @Test + public void testSendRoleMemberExpiryRemindersDisabledOverOneWeek() { + + DBService dbsvc = Mockito.mock(DBService.class); + NotificationService mockNotificationService = Mockito.mock(NotificationService.class); + NotificationServiceFactory testfact = () -> mockNotificationService; + + Timestamp twoWeekExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(14, TimeUnit.DAYS)); + Timestamp oneDayExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); + + List memberRoles = new ArrayList<>(); + memberRoles.add(new MemberRole().setRoleName("role1") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setExpiration(twoWeekExpiry)); + memberRoles.add(new MemberRole().setRoleName("role2") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setExpiration(oneDayExpiry)); + DomainRoleMember domainRoleMember = new DomainRoleMember() + .setMemberName("user.joe") + .setMemberRoles(memberRoles); + Map expiryMembers = new HashMap<>(); + expiryMembers.put("user.joe", domainRoleMember); + + // we're going to return null for our first thread which will + // run during init call and then the real data for the second + // call + + Mockito.when(dbsvc.getRoleExpiryMembers(1, false)) + .thenReturn(null) + .thenReturn(expiryMembers); + + NotificationManager notificationManager = getNotificationManager(dbsvc, testfact); + + ZMSTestUtils.sleep(1000); + + AthenzDomain domain = new AthenzDomain("athenz1"); + List roleMembers = new ArrayList<>(); + roleMembers.add(new RoleMember().setMemberName("user.jane")); + Role adminRole = new Role() + .setName("athenz1:role.admin") + .setRoleMembers(roleMembers); + List roles = new ArrayList<>(); + roles.add(adminRole); + domain.setRoles(roles); + + Mockito.when(dbsvc.getRolesByDomain("athenz1")).thenReturn(domain.getRoles()); + Mockito.when(dbsvc.getRole("athenz1", "admin", Boolean.FALSE, Boolean.TRUE, Boolean.FALSE)) + .thenThrow(new UnsupportedOperationException()); + + Map tags = new HashMap<>(); + TagValueList tagValueList = new TagValueList().setList(Collections.singletonList("4")); + tags.put(ZMSConsts.DISABLE_EXPIRATION_NOTIFICATIONS_TAG, tagValueList); + Role role = new Role().setTags(tags); + Mockito.when(dbsvc.getRole("athenz1", "role1", false, false, false)).thenReturn(role); + Mockito.when(dbsvc.getRole("athenz1", "role2", false, false, false)).thenReturn(role); + + List notifications = new RoleMemberExpiryNotificationTask(dbsvc, USER_DOMAIN_PREFIX, + new NotificationToEmailConverterCommon(null), false).getNotifications(); + + // we should get 2 notifications - one for user and one for domain + // role1 should be excluded and role2 should be included + + assertEquals(notifications.size(), 2); + + // Verify contents of notifications is as expected + Notification expectedFirstNotification = new Notification(); + expectedFirstNotification.addRecipient("user.joe"); + expectedFirstNotification.addDetails(NOTIFICATION_DETAILS_ROLES_LIST, "athenz1;role2;user.joe;" + oneDayExpiry); + expectedFirstNotification.addDetails("member", "user.joe"); + expectedFirstNotification.setNotificationToEmailConverter( + new RoleMemberExpiryNotificationTask.RoleExpiryPrincipalNotificationToEmailConverter( + new NotificationToEmailConverterCommon(null))); + expectedFirstNotification.setNotificationToMetricConverter( + new RoleMemberExpiryNotificationTask.RoleExpiryPrincipalNotificationToMetricConverter()); + + Notification expectedSecondNotification = new Notification(); + expectedSecondNotification.addRecipient("user.jane"); + expectedSecondNotification.addDetails(NOTIFICATION_DETAILS_MEMBERS_LIST, "athenz1;role2;user.joe;" + oneDayExpiry); + expectedSecondNotification.addDetails("domain", "athenz1"); + expectedSecondNotification.setNotificationToEmailConverter( + new RoleMemberExpiryNotificationTask.RoleExpiryDomainNotificationToEmailConverter( + new NotificationToEmailConverterCommon(null))); + expectedSecondNotification.setNotificationToMetricConverter( + new RoleMemberExpiryNotificationTask.RoleExpiryDomainNotificationToMetricConverter()); + + assertEquals(notifications.get(0), expectedFirstNotification); + assertEquals(notifications.get(1), expectedSecondNotification); + + notificationManager.shutdown(); + } + @Test public void testSendRoleMemberExpiryRemindersNoValidDomain() { diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTaskTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTaskTest.java index 09bb70bd60d..282085c5769 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTaskTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/notification/RoleMemberReviewNotificationTaskTest.java @@ -24,6 +24,7 @@ import org.testng.annotations.Test; import java.util.*; +import java.util.concurrent.TimeUnit; import static com.yahoo.athenz.common.ServerCommonConsts.USER_DOMAIN_PREFIX; import static com.yahoo.athenz.common.server.notification.NotificationServiceConstants.*; @@ -158,6 +159,95 @@ public void testSendRoleMemberReviewReminders() { notificationManager.shutdown(); } + @Test + public void testSendRoleMemberReviewRemindersDisabledOverOneWeek() { + + DBService dbsvc = Mockito.mock(DBService.class); + NotificationService mockNotificationService = Mockito.mock(NotificationService.class); + NotificationServiceFactory testfact = () -> mockNotificationService; + + Timestamp twoWeekExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(14, TimeUnit.DAYS)); + Timestamp oneDayExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); + + List memberRoles = new ArrayList<>(); + memberRoles.add(new MemberRole().setRoleName("role1") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setReviewReminder(twoWeekExpiry)); + memberRoles.add(new MemberRole().setRoleName("role2") + .setDomainName("athenz1") + .setMemberName("user.joe") + .setReviewReminder(oneDayExpiry)); + DomainRoleMember domainRoleMember = new DomainRoleMember() + .setMemberName("user.joe") + .setMemberRoles(memberRoles); + Map reviewMembers = new HashMap<>(); + reviewMembers.put("user.joe", domainRoleMember); + + // we're going to return null for our first thread which will + // run during init call and then the real data for the second + // call + + Mockito.when(dbsvc.getRoleReviewMembers(1)) + .thenReturn(null) + .thenReturn(reviewMembers); + + NotificationManager notificationManager = getNotificationManager(dbsvc, testfact); + + ZMSTestUtils.sleep(1000); + + AthenzDomain domain = new AthenzDomain("athenz1"); + List roleMembers = new ArrayList<>(); + roleMembers.add(new RoleMember().setMemberName("user.jane")); + Role adminRole = new Role() + .setName("athenz1:role.admin") + .setRoleMembers(roleMembers); + List roles = new ArrayList<>(); + roles.add(adminRole); + domain.setRoles(roles); + + Mockito.when(dbsvc.getRolesByDomain("athenz1")).thenReturn(domain.getRoles()); + Mockito.when(dbsvc.getRole("athenz1", "admin", Boolean.FALSE, Boolean.TRUE, Boolean.FALSE)) + .thenReturn(adminRole); + + Map tags = new HashMap<>(); + TagValueList tagValueList = new TagValueList().setList(Collections.singletonList("4")); + tags.put(ZMSConsts.DISABLE_REMINDER_NOTIFICATIONS_TAG, tagValueList); + Role role = new Role().setTags(tags); + Mockito.when(dbsvc.getRole("athenz1", "role1", false, false, false)).thenReturn(role); + Mockito.when(dbsvc.getRole("athenz1", "role2", false, false, false)).thenReturn(role); + + List notifications = new RoleMemberReviewNotificationTask(dbsvc, + USER_DOMAIN_PREFIX, notificationToEmailConverterCommon, false).getNotifications(); + + // we should get 2 notifications - one for user and one for domain + // role1 should be excluded and role2 should be included + + assertEquals(notifications.size(), 2); + + // Verify contents of notifications is as expected + Notification expectedFirstNotification = new Notification(); + expectedFirstNotification.addRecipient("user.joe"); + expectedFirstNotification.addDetails(NOTIFICATION_DETAILS_ROLES_LIST, "athenz1;role2;user.joe;" + oneDayExpiry); + expectedFirstNotification.addDetails("member", "user.joe"); + expectedFirstNotification.setNotificationToEmailConverter(new RoleMemberReviewNotificationTask.RoleReviewPrincipalNotificationToEmailConverter(notificationToEmailConverterCommon)); + expectedFirstNotification.setNotificationToMetricConverter(new RoleMemberReviewNotificationTask.RoleReviewPrincipalNotificationToMetricConverter()); + + Notification expectedSecondNotification = new Notification(); + expectedSecondNotification.addRecipient("user.jane"); + expectedSecondNotification.addDetails(NOTIFICATION_DETAILS_MEMBERS_LIST, "athenz1;role2;user.joe;" + oneDayExpiry); + expectedSecondNotification.addDetails("domain", "athenz1"); + expectedSecondNotification.setNotificationToEmailConverter( + new RoleMemberReviewNotificationTask.RoleReviewDomainNotificationToEmailConverter(notificationToEmailConverterCommon)); + expectedSecondNotification.setNotificationToMetricConverter( + new RoleMemberReviewNotificationTask.RoleReviewDomainNotificationToMetricConverter()); + + assertEquals(notifications.get(0), expectedFirstNotification); + assertEquals(notifications.get(1), expectedSecondNotification); + + notificationManager.shutdown(); + } + @Test public void testSendRoleMemberReviewRemindersNoValidDomain() {