Source:
<code>public NotificationResponse doFilter(HttpServletRequest request, INotificationServiceFilterChain chain) { final NotificationResponse response = chain.doFilter(); final String readFilterParameter = request.getParameter(READ_PARAMETER_NAME); final NotificationResponse rslt = response.cloneIfNotCloned(); for (NotificationCategory category : rslt.getCategories()) { for (NotificationEntry entry : category.getEntries()) { if (StringUtils.isBlank(entry.getId())) { continue; } final String username = usernameFinder.findUsername(request); final List<EventDTO> history = jpaServices.getHistory(entry, username); logger.trace("Found the following history for username='{}' and entryId='{}': {}", username, entry.getId(), history); final List<NotificationAttribute> attributes = new ArrayList<>(entry.getAttributes()); final boolean isRead = history.stream() .anyMatch(event -> NotificationState.READ.equals(event.getState())); attributes.add(isRead ? READ_ATTRIBUTE : UNREAD_ATTRIBUTE); entry.setAttributes(attributes); if (!isRead) { final List<NotificationAction> currentActions = entry.getAvailableActions(); boolean hasReadActionAlready = currentActions.stream() .anyMatch(action -> ReadAction.class.isInstance(action)); if (!hasReadActionAlready) { final List<NotificationAction> replacementList = new ArrayList<>(currentActions); replacementList.add(new MarkAsReadAndRedirectAction()); entry.setAvailableActions(replacementList); } } } } if (StringUtils.isNotBlank(readFilterParameter)) { boolean readFilterValue = Boolean.parseBoolean(readFilterParameter); return rslt.filter( entry -> { boolean isRead = entry.getAttributes() .stream() .anyMatch( <START> event -> <END> NotificationState.READ.equals( event.getValues())); return isRead == readFilterValue; }); } return rslt; }</code><technical_language>This change 95% great, I a mismatch here. IIRC object passed anyMatch() of type NotificationAttribute, is tremendously produce a true response passed NotificationState.READ.equals()</technical_language>

Target:
public NotificationResponse doFilter(HttpServletRequest request, INotificationServiceFilterChain chain) { final NotificationResponse response = chain.doFilter(); final String readFilterParameter = request.getParameter(READ_PARAMETER_NAME); final NotificationResponse rslt = response.cloneIfNotCloned(); for (NotificationCategory category : rslt.getCategories()) { for (NotificationEntry entry : category.getEntries()) { if (StringUtils.isBlank(entry.getId())) { continue; } final String username = usernameFinder.findUsername(request); final List<EventDTO> history = jpaServices.getHistory(entry, username); logger.trace("Found the following history for username='{}' and entryId='{}': {}", username, entry.getId(), history); final List<NotificationAttribute> attributes = new ArrayList<>(entry.getAttributes()); final boolean isRead = history.stream() .anyMatch(event -> NotificationState.READ.equals(event.getState())); attributes.add(isRead ? READ_ATTRIBUTE : UNREAD_ATTRIBUTE); entry.setAttributes(attributes); if (!isRead) { final List<NotificationAction> currentActions = entry.getAvailableActions(); boolean hasReadActionAlready = currentActions.stream() .anyMatch(action -> ReadAction.class.isInstance(action)); if (!hasReadActionAlready) { final List<NotificationAction> replacementList = new ArrayList<>(currentActions); replacementList.add(new MarkAsReadAndRedirectAction()); entry.setAvailableActions(replacementList); } } } } if (StringUtils.isNotBlank(readFilterParameter)) { boolean readFilterValue = Boolean.parseBoolean(readFilterParameter); return rslt.filter( entry -> { boolean isRead = entry.getAttributes() .stream() .anyMatch(attribute -> attribute.equals(READ_ATTRIBUTE)); return isRead == readFilterValue; }); } return rslt; }