### Error Handling and Filtering Source: https://context7.com/daichi-m/notification4j/llms.txt Examples demonstrating advanced notification retrieval with custom error handling and filtering. ```APIDOC ## GET /notifications/errors ### Description Retrieves only the error notifications for a specific user. This is achieved by filtering the results of the main `getNotifications` call. ### Method GET ### Endpoint /notifications/errors ### Parameters #### Query Parameters - **userId** (string) - Required - The unique identifier of the user. ### Response #### Success Response (200) - **List** (List) - A list of Notification objects with severity set to ERROR. #### Response Example ```json [ { "severity": "ERROR", "message": "Failed to process payment.", "status": "NEW", "expiryAt": "2024-07-20T12:00:00Z" } ] ``` ## GET /notifications/unread ### Description Retrieves the count of unacknowledged notifications for a specific user. This includes notifications with status 'NEW' or 'NOT_ACKNOWLEDGED'. ### Method GET ### Endpoint /notifications/unread ### Parameters #### Query Parameters - **userId** (string) - Required - The unique identifier of the user. ### Response #### Success Response (200) - **Long** (long) - The count of unread notifications. #### Response Example ```json 5 ``` ## POST /notifications/fetchWithCustomErrorHandler ### Description Fetches notifications with a custom error handler provided to the client. This allows for specific error handling logic, such as returning cached data or an empty list upon failure. ### Method POST ### Endpoint /notifications/fetchWithCustomErrorHandler ### Parameters #### Query Parameters - **userId** (string) - Required - The unique identifier of the user. ### Request Body (No specific request body is defined for this operation in the provided text, it primarily relies on query parameters and client-side error handling) ### Response #### Success Response (200) - **Collection** (Collection) - A collection of Notification objects processed by the custom logic. #### Response Example ```json [ { "severity": "INFO", "message": "Notification processed successfully.", "status": "PROCESSED", "expiryAt": "2024-08-01T00:00:00Z" } ] ``` ``` -------------------------------- ### Configure JNotify for Redis Sentinel Mode Source: https://context7.com/daichi-m/notification4j/llms.txt Sets up the NotificationConfiguration for Redis Sentinel mode, specifying sentinel addresses, the master name, and connection pool settings. This configuration is used for high-availability Redis setups. ```java import io.github.daichim.notification4J.model.NotificationConfiguration; import java.util.Arrays; // For Redis Sentinel mode NotificationConfiguration sentinelConfig = new NotificationConfiguration() .setRedisSentinels(Arrays.asList("sentinel1:26379", "sentinel2:26379")) .setSentinelMaster("mymaster") .setRedisDatabase(0) .setRedisConnectionTimeout(30000) .setMaxRedisConnections(10); ``` -------------------------------- ### Configure NotifierClient with Guice Source: https://context7.com/daichi-m/notification4j/llms.txt Bind the configuration in a Guice module and inject the client. Requires Netflix Governator for lifecycle management support. ```java import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.model.Notification; import io.github.daichim.notification4J.model.NotificationConfiguration; import javax.inject.Inject; import java.time.Duration; public class NotificationModule extends AbstractModule { @Override protected void configure() { NotificationConfiguration config = new NotificationConfiguration() .setRedisHost("redis.example.com") .setRedisPort(6379) .setRedisDatabase(0) .setRedisConnectionTimeout(5000) .setIdleRedisConnections(3) .setMaxRedisConnections(10) .setBackOffDelayMillis(1000) .setMaxBackOffDelayMillis(30000) .setMaxAttempts(3) .setDefaultExpiry(Duration.ofDays(7)) .setDefaultSource("GuiceApp") .setDefaultSeverity(Notification.Severity.INFO); bind(NotificationConfiguration.class).toInstance(config); } } public class OrderNotificationService { @Inject private NotifierClient notifierClient; public void notifyOrderShipped(String customerId, String orderId, String trackingNumber) { Notification notification = new Notification() .setMesage("Your order #" + orderId + " has shipped!") .setDescription("Tracking number: " + trackingNumber) .setSeverity(Notification.Severity.INFO) .setSource("OrderService") .setDisplayType(Notification.DisplayType.INBOX) .expireAfter(Duration.ofDays(14)); notifierClient.notifyUsers(notification, customerId); } } // Bootstrap with Governator for lifecycle management // Injector injector = LifecycleInjector.builder() // .withModules(new NotificationModule()) // .build().createInjector(); ``` -------------------------------- ### Retrieve and Process User Notifications in Java Source: https://context7.com/daichi-m/notification4j/llms.txt Demonstrates various patterns for fetching, filtering, and handling errors when retrieving notifications using the NotifierClient. ```java import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.model.Notification; import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; public class NotificationRetrievalService { private final NotifierClient client; public NotificationRetrievalService(NotifierClient client) { this.client = client; } // Get all notifications for a user public CompletableFuture> getUserNotifications(String userId) { return client.getNotifications(userId); } // Get notifications with error handling public void fetchAndDisplayNotifications(String userId) { client.getNotifications(userId) .thenAccept(notifications -> { System.out.println("Found " + notifications.size() + " notifications for " + userId); notifications.forEach(n -> { System.out.printf("[%s] %s - %s (expires: %s)%n", n.getSeverity(), n.getMesage(), n.getStatus(), n.getExpiryAt() ); }); }) .exceptionally(ex -> { System.err.println("Failed to fetch notifications: " + ex.getMessage()); return null; }); } // Get notifications filtered by severity public CompletableFuture> getErrorNotifications(String userId) { return client.getNotifications(userId) .thenApply(notifications -> notifications.stream() .filter(n -> n.getSeverity() == Notification.Severity.ERROR) .collect(Collectors.toList()) ); } // Get unacknowledged notifications count public CompletableFuture getUnreadCount(String userId) { return client.getNotifications(userId) .thenApply(notifications -> notifications.stream() .filter(n -> n.getStatus() == Notification.Status.NEW || n.getStatus() == Notification.Status.NOT_ACKNOWLEDGED) .count() ); } // Custom error handler for notification retrieval public void fetchWithCustomErrorHandler(String userId) { client.getNotifications( ex -> { System.err.println("Redis error fetching notifications: " + ex.getMessage()); // Return cached notifications or empty list }, userId ).thenAccept(notifications -> { // Process notifications notifications.forEach(this::processNotification); }); } private void processNotification(Notification notification) { // Custom processing logic System.out.println("Processing: " + notification.getMesage()); } } ``` -------------------------------- ### Create a Basic Notification Source: https://context7.com/daichi-m/notification4j/llms.txt Constructs a basic notification object with message, description, severity, source, status, and display type. It also allows setting an expiration duration and adding redirect URLs for user actions. ```java import io.github.daichim.notification4J.model.Notification; import java.time.Duration; import java.net.URL; // Create a basic notification Notification notification = new Notification() .setMesage("Deployment completed successfully") .setDescription("Your application v2.1.0 has been deployed to production cluster.") .setSeverity(Notification.Severity.SUCCESS) .setSource("DeploymentService") .setStatus(Notification.Status.NEW) .setDisplayType(Notification.DisplayType.BANNER_DISMISS) .expireAfter(Duration.ofHours(24)); // Add redirect URLs for user actions notification.putRedirectURL("View Logs", new URL("https://logs.example.com/deploy/123")) .putRedirectURL("View App", new URL("https://app.example.com")); // Create a warning notification with default expiry Notification warningNotification = new Notification() .setMesage("High CPU usage detected") .setDescription("Server node-5 is experiencing CPU usage above 90%.") .setSeverity(Notification.Severity.WARNING) .setSource("MonitoringService") .setDisplayType(Notification.DisplayType.INBOX) .expireAfter(Duration.ofMinutes(30)); // Available Severity levels: INFO, SUCCESS, WARNING, ERROR // Available Status values: NEW, NOT_ACKNOWLEDGED, ACKNOWLEDGED, DELETED // Available DisplayTypes: INBOX, BANNER_DISMISS, BANNER_NONDISMISS, PAGE, POPUP ``` -------------------------------- ### Create Project Team User Group Source: https://context7.com/daichi-m/notification4j/llms.txt Creates a new user group for project team members using a SQL query template that joins users and project assignments. Requires the admin username. ```java groupClient.createGroup("project_team_members", queryTemplate, adminUser); ``` -------------------------------- ### Configure NotifierClient with Spring Source: https://context7.com/daichi-m/notification4j/llms.txt Define a NotificationConfiguration bean and inject the NotifierClient into a service using standard Spring annotations. ```java import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.model.Notification; import io.github.daichim.notification4J.model.NotificationConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Service; import javax.inject.Inject; import java.time.Duration; @Configuration public class NotificationConfig { @Bean public NotificationConfiguration createNotificationConfig() { return new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(6379) .setRedisDatabase(0) .setRedisConnectionTimeout(1000) .setIdleRedisConnections(3) .setMaxRedisConnections(6) .setBackOffDelayMillis(1000) .setMaxBackOffDelayMillis(10000) .setMaxAttempts(5) .setDefaultExpiry(Duration.ofDays(7)) .setDefaultSource("MyApp") .setDefaultSeverity(Notification.Severity.INFO) .setPurgeEnabled(true); } } @Service public class AlertService { @Inject private NotifierClient notifierClient; public void sendDeploymentAlert(String userId, String appName, String version) { Notification notification = new Notification() .setMesage("Deployment Complete: " + appName) .setDescription("Version " + version + " deployed successfully") .setSeverity(Notification.Severity.SUCCESS) .setSource("DeploymentPipeline") .expireAfter(Duration.ofDays(3)); notifierClient.notifyUsers(notification, userId) .thenAccept(success -> System.out.println("Notification sent: " + success)) .exceptionally(ex -> { System.err.println("Failed to send notification: " + ex.getMessage()); return null; }); } } ``` -------------------------------- ### Create Department User Group Source: https://context7.com/daichi-m/notification4j/llms.txt Creates a new user group named 'department_users' using a SQL query template to select active employees by department. Requires the admin username. ```java import io.github.daichim.notification4J.NotificationGroupClient; import io.github.daichim.notification4J.exception.NotificationException; public class UserGroupManagementService { private final NotificationGroupClient groupClient; public UserGroupManagementService(NotificationGroupClient groupClient) { this.groupClient = groupClient; } // Create a new user group with SQL query template public void createDepartmentGroup(String adminUser) { try { // SQL template with MyBatis-style parameters String queryTemplate = "SELECT user_id FROM employees WHERE department = #{department} AND status = 'active'"; groupClient.createGroup( "department_users", // Group name queryTemplate, // SQL query template adminUser // Creator username ); System.out.println("User group 'department_users' created successfully"); } catch (NotificationException e) { System.err.println("Failed to create group: " + e.getMessage()); } } // Create a group for project team members public void createProjectTeamGroup(String adminUser) { try { String queryTemplate = "SELECT u.user_id FROM users u " + "JOIN project_assignments pa ON u.user_id = pa.user_id " + "WHERE pa.project_id = #{projectId} AND pa.status = 'assigned'"; groupClient.createGroup("project_team_members", queryTemplate, adminUser); } catch (NotificationException e) { System.err.println("Failed to create project team group: " + e.getMessage()); } } // Edit an existing user group public void updateGroupQuery(String adminUser) { try { // Update query to include managers String newQueryTemplate = "SELECT user_id FROM employees " + "WHERE department = #{department} AND (status = 'active' OR role = 'manager')"; groupClient.editGroup( "department_users", // Old group name "department_all_users", // New group name newQueryTemplate, // Updated SQL query adminUser // Editor username ); System.out.println("User group updated successfully"); } catch (NotificationException e) { System.err.println("Failed to update group: " + e.getMessage()); } } // Delete a user group public void removeObsoleteGroup(String groupName, String adminUser) { try { groupClient.deleteGroup(groupName, adminUser); System.out.println("User group '" + groupName + "' deleted"); } catch (NotificationException e) { System.err.println("Failed to delete group: " + e.getMessage()); } } } /* Required database table (MySQL syntax): CREATE TABLE NOTIFICATION_USER_GROUPS( USER_GROUP_ID INT PRIMARY KEY auto_increment, USER_GROUP VARCHAR(50) UNIQUE, USER_GROUP_QUERY VARCHAR(1000) NOT NULL, STATUS VARCHAR(20) NOT NULL DEFAULT 'Active', CREATED_BY VARCHAR(50), CREATED_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP, LAST_UPDATED_BY VARCHAR(20), LAST_UPDATED_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); */ ``` -------------------------------- ### Configure NotificationConfiguration Bean for Spring Source: https://github.com/daichi-m/notification4j/blob/main/README.md Expose a NotificationConfiguration bean in a Spring @Configuration class to initialize the system. ```java @Bean public NotificationConfiguration createNotificationConfig() { return new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(redisServer.ports().get(0)) .setRedisDatabase(0) .setRedisConnectionTimeout(1000) .setIdleRedisConnections(3) .setMaxRedisConnections(6) .setBackOffDelayMillis(1000) .setMaxBackOffDelayMillis(MAX_DELAY) .setMaxAttempts(MAX_ATTEMPTS) .setDefaultExpiry(Duration.ofDays(7)) .setDefaultSource("TEST") .setDefaultSeverity(Notification.Severity.INFO); } ``` -------------------------------- ### Configure NotificationConfiguration in Guice Module Source: https://github.com/daichi-m/notification4j/blob/main/README.md Bind the NotificationConfiguration instance within a Guice AbstractModule. ```java public class AwesomeModule extends AbstractModule { public void configure() { /* Your awesome bindings .... */ NotificationConfiguration config = new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(redisServer.ports().get(0)) .setRedisDatabase(0) .setRedisConnectionTimeout(1000) .setIdleRedisConnections(3) .setMaxRedisConnections(6) .setBackOffDelayMillis(1000) .setMaxBackOffDelayMillis(MAX_DELAY) .setMaxAttempts(MAX_ATTEMPTS) .setDefaultExpiry(Duration.ofDays(7)) .setDefaultSource("TEST") .setDefaultSeverity(Notification.Severity.INFO); bind(NotificationConfiguration.class).toInstance(config); } } ``` -------------------------------- ### Configure Automatic Notification Purge Source: https://context7.com/daichi-m/notification4j/llms.txt Enable automatic purge with default or custom intervals. Disable purge to rely on manual cleanup. ```java import io.github.daichim.notification4J.model.NotificationConfiguration; import io.github.daichim.notification4J.model.Notification; import java.time.Duration; public class PurgeConfigurationExample { // Enable automatic purge with default 30-minute interval public NotificationConfiguration configWithPurge() { return new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(6379) .setMaxRedisConnections(10) .setPurgeEnabled(true) // Enable automatic purge .setPurgeIntervalSeconds(1800); // Run every 30 minutes (default) } // Custom purge interval (every 10 minutes) public NotificationConfiguration configWithFrequentPurge() { return new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(6379) .setMaxRedisConnections(10) .setPurgeEnabled(true) .setPurgeIntervalSeconds(600); // Run every 10 minutes } // Disable automatic purge (manual cleanup only) public NotificationConfiguration configWithoutPurge() { return new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(6379) .setMaxRedisConnections(10) .setPurgeEnabled(false); // Disable automatic purge } // Notifications eligible for automatic purge: // 1. Expired notifications (expiryAt < current time) // 2. Deleted notifications (status == DELETED) // Example: Create notification with short expiry (auto-purged after 1 hour) public Notification shortLivedNotification() { return new Notification() .setMesage("Temporary alert") .setDescription("This notification will be automatically purged after 1 hour") .setSeverity(Notification.Severity.INFO) .setSource("TempAlertService") .expireAfter(Duration.ofHours(1)); // Auto-purged after expiry } } ``` -------------------------------- ### Configure JNotify for Standalone Redis Source: https://context7.com/daichi-m/notification4j/llms.txt Sets up the NotificationConfiguration for a standalone Redis instance, including connection details, pooling, retry policies, and expiry settings. Ensure to replace placeholder values with your actual Redis credentials and desired settings. ```java import io.github.daichim.notification4J.model.NotificationConfiguration; import io.github.daichim.notification4J.model.Notification; import java.time.Duration; // Create configuration for standalone Redis NotificationConfiguration config = new NotificationConfiguration() .setRedisHost("localhost") .setRedisPort(6379) .setRedisDatabase(0) .setRedisPassword("your-password") // Optional .setUseSsl(true) .setRedisConnectionTimeout(30000) .setIdleRedisConnections(3) .setMaxRedisConnections(10) .setBackOffDelayMillis(1000) .setMaxBackOffDelayMillis(10000) .setMaxAttempts(5) .setDefaultExpiry(Duration.ofDays(7)) .setDefaultSource("MyApplication") .setDefaultSeverity(Notification.Severity.INFO) .setPurgeEnabled(true) .setPurgeIntervalSeconds(1800); ``` -------------------------------- ### Push Notifications with NotifierClient Source: https://github.com/daichi-m/notification4j/blob/main/README.md Use notifyUser to send notifications, with options for default or custom error handling. ```java public void somethingHappened() { Notification notfn = new Notification() .setMesage("Something terrible happened") .setDescription("So long and thanks for all the fish.") .setSeverity(Notification.Severity.INFO) .setSource("Vogon") .setStatus(Notification.Status.NOT_ACKNOWLEDGED) .expireAfter(Duration.ofMinutes(10)); // If you want to use the default error handler // (which just logs an error message using Slf4J logger). client.notifyUser("ford_prefect", notfn); // If you want to handle the error yourself. client.notifyUser(ex -> handleError(ex), "ford_prefect", notfn); } ``` -------------------------------- ### Database Table Schema Source: https://context7.com/daichi-m/notification4j/llms.txt MySQL syntax for the NOTIFICATION_USER_GROUPS table, which stores user group information including ID, name, query template, status, and timestamps. ```sql CREATE TABLE NOTIFICATION_USER_GROUPS( USER_GROUP_ID INT PRIMARY KEY auto_increment, USER_GROUP VARCHAR(50) UNIQUE, USER_GROUP_QUERY VARCHAR(1000) NOT NULL, STATUS VARCHAR(20) NOT NULL DEFAULT 'Active', CREATED_BY VARCHAR(50), CREATED_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP, LAST_UPDATED_BY VARCHAR(20), LAST_UPDATED_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` -------------------------------- ### Update Notification Status with NotifierClient Source: https://context7.com/daichi-m/notification4j/llms.txt Demonstrates various ways to update notification statuses including single, bulk, and error-handled operations using the NotifierClient. ```java import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.model.Notification; import java.util.concurrent.CompletableFuture; public class NotificationStatusService { private final NotifierClient client; public NotificationStatusService(NotifierClient client) { this.client = client; } // Mark single notification as acknowledged public CompletableFuture acknowledgeNotification(String userId, String notificationId) { return client.updateStatus( new String[]{notificationId}, userId, Notification.Status.ACKNOWLEDGED ); } // Mark multiple notifications as acknowledged (bulk acknowledge) public CompletableFuture acknowledgeAll(String userId, String[] notificationIds) { return client.updateStatus( notificationIds, userId, Notification.Status.ACKNOWLEDGED ).thenApply(success -> { if (success) { System.out.println("Acknowledged " + notificationIds.length + " notifications"); } return success; }); } // Delete/dismiss a notification public CompletableFuture dismissNotification(String userId, String notificationId) { return client.updateStatus( new String[]{notificationId}, userId, Notification.Status.DELETED ); } // Delete multiple notifications with custom error handler public void deleteNotifications(String userId, String[] notificationIds) { client.updateStatus( ex -> { System.err.println("Failed to delete notifications: " + ex.getMessage()); // Retry or log for manual cleanup }, notificationIds, userId, Notification.Status.DELETED ).thenAccept(success -> { if (success) { System.out.println("Deleted " + notificationIds.length + " notifications for " + userId); } }); } // Available status values: // Notification.Status.NEW - Initial state // Notification.Status.NOT_ACKNOWLEDGED - Delivered but not viewed // Notification.Status.ACKNOWLEDGED - User has viewed the notification // Notification.Status.DELETED - User dismissed or notification removed } ``` -------------------------------- ### Inject NotifierClient in Guice Source: https://github.com/daichi-m/notification4j/blob/main/README.md Inject the NotifierClient into a class using @Inject. ```java public class AwesomeClass { // Can also be Guice's @Inject. @Inject private NotifierClient client; .... } ``` -------------------------------- ### Send Notifications to Department Users Source: https://context7.com/daichi-m/notification4j/llms.txt Sends a notification to all users within a specified department. Requires a 'department_users' group template and a 'department' query parameter. ```java import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.model.Notification; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; public class GroupNotificationService { private final NotifierClient client; public GroupNotificationService(NotifierClient client) { this.client = client; } // Notify all users in a department public CompletableFuture notifyDepartment(String department, String message) { Notification notification = new Notification() .setMesage(message) .setDescription("This notification is for all " + department + " team members.") .setSeverity(Notification.Severity.INFO) .setSource("HRSystem") .expireAfter(Duration.ofDays(3)); // Query params to substitute in the user group SQL template // Example template: SELECT user_id FROM employees WHERE department = #{department} Map queryParams = new HashMap<>(); queryParams.put("department", department); return client.notifyGroup(notification, "department_users", queryParams); } // Notify users by role and location public CompletableFuture notifyByRoleAndLocation(String role, String location) { Notification notification = new Notification() .setMesage("Regional policy update") .setDescription("New compliance requirements effective next month.") .setSeverity(Notification.Severity.WARNING) .setSource("ComplianceService") .setDisplayType(Notification.DisplayType.PAGE) .expireAfter(Duration.ofDays(30)); // For template: SELECT user_id FROM employees WHERE role = #{role} AND location = #{location} Map params = new HashMap<>(); params.put("role", role); params.put("location", location); return client.notifyGroup(notification, "role_location_users", params); } // Notify with custom error handling public void notifyProjectTeam(String projectId) { Notification notification = new Notification() .setMesage("Project deadline approaching") .setDescription("Sprint ends in 2 days. Please update your task status.") .setSeverity(Notification.Severity.WARNING) .setSource("ProjectManagement") .expireAfter(Duration.ofDays(2)); Map params = new HashMap<>(); params.put("projectId", projectId); client.notifyGroup( ex -> System.err.println("Failed to notify project team: " + ex.getMessage()), notification, "project_team_members", params ).thenAccept(success -> System.out.println("Project team notified: " + success)); } } ``` -------------------------------- ### Send Notification with Logging Error Handler Source: https://context7.com/daichi-m/notification4j/llms.txt Uses a lambda-based ErrorHandler to log notification errors to standard error. Ensure the NotifierClient is properly initialized. ```java import io.github.daichim.notification4J.ErrorHandler; import io.github.daichim.notification4J.NotifierClient; import io.github.daichim.notification4J.exception.NotificationException; import io.github.daichim.notification4J.model.Notification; import java.time.Duration; public class CustomErrorHandlingExample { private final NotifierClient client; public CustomErrorHandlingExample(NotifierClient client) { this.client = client; } // Lambda-based error handler public void sendWithLogging(String userId, String message) { Notification notification = new Notification() .setMesage(message) .setSeverity(Notification.Severity.INFO) .expireAfter(Duration.ofDays(1)); ErrorHandler loggingHandler = ex -> { System.err.println("Notification error: " + ex.getMessage()); ex.printStackTrace(); }; client.notifyUsers(loggingHandler, notification, userId); } // Error handler with retry queue public void sendWithRetryQueue(String userId, Notification notification) { ErrorHandler retryHandler = ex -> { System.err.println("Failed to send, adding to retry queue: " + ex.getMessage()); addToRetryQueue(userId, notification, ex); }; client.notifyUsers(retryHandler, notification, userId); } // Error handler with metrics public void sendWithMetrics(String userId, Notification notification) { ErrorHandler metricsHandler = ex -> { incrementErrorCounter("notification_send_failures"); recordErrorType(ex.getClass().getSimpleName()); logToMonitoringSystem(ex); }; client.notifyUsers(metricsHandler, notification, userId); } // Reusable error handler class public static class AlertingErrorHandler implements ErrorHandler { private final String alertChannel; public AlertingErrorHandler(String alertChannel) { this.alertChannel = alertChannel; } @Override public void accept(NotificationException exception) { System.err.println("[" + alertChannel + "] Notification failed: " + exception.getMessage()); // Send alert to Slack, PagerDuty, etc. sendAlert(alertChannel, exception); } private void sendAlert(String channel, NotificationException ex) { // Alert implementation } } // Using the custom error handler class public void sendCriticalNotification(String userId, String message) { Notification notification = new Notification() .setMesage(message) .setSeverity(Notification.Severity.ERROR) .expireAfter(Duration.ofHours(2)); client.notifyUsers(new AlertingErrorHandler("#critical-alerts"), notification, userId); } // Helper methods private void addToRetryQueue(String userId, Notification n, Exception e) { } private void incrementErrorCounter(String metric) { } private void recordErrorType(String type) { } private void logToMonitoringSystem(Exception e) { } } ``` -------------------------------- ### Send Notifications with Custom Error Handling Source: https://context7.com/daichi-m/notification4j/llms.txt Sends a notification to a project team with custom error handling logic. Utilizes a 'project_team_members' group template and accepts a lambda for error callbacks. ```java client.notifyGroup( ex -> System.err.println("Failed to notify project team: " + ex.getMessage()), notification, "project_team_members", params ).thenAccept(success -> System.out.println("Project team notified: " + success)); ``` -------------------------------- ### Send Notifications by Role and Location Source: https://context7.com/daichi-m/notification4j/llms.txt Sends a notification to users based on their role and location. Uses a 'role_location_users' group template with 'role' and 'location' query parameters. ```java // For template: SELECT user_id FROM employees WHERE role = #{role} AND location = #{location} Map params = new HashMap<>(); params.put("role", role); params.put("location", location); return client.notifyGroup(notification, "role_location_users", params); ``` -------------------------------- ### User Notifications API Source: https://context7.com/daichi-m/notification4j/llms.txt This section covers the core functionality of retrieving user notifications. ```APIDOC ## GET /notifications ### Description Retrieves all active (non-expired, non-deleted) notifications for a specific user. This method returns a `CompletableFuture>` for asynchronous retrieval with automatic filtering of stale notifications. ### Method GET ### Endpoint /notifications ### Parameters #### Query Parameters - **userId** (string) - Required - The unique identifier of the user whose notifications are to be retrieved. ### Response #### Success Response (200) - **Collection** (Collection) - A collection of Notification objects. #### Response Example ```json [ { "severity": "INFO", "message": "Your subscription is about to expire.", "status": "NEW", "expiryAt": "2024-12-31T23:59:59Z" }, { "severity": "WARNING", "message": "System maintenance scheduled.", "status": "ACKNOWLEDGED", "expiryAt": "2024-07-15T10:00:00Z" } ] ``` ``` -------------------------------- ### Update User Group Query Source: https://context7.com/daichi-m/notification4j/llms.txt Edits an existing user group by changing its name and updating the SQL query template to include managers. Requires the admin username. ```java groupClient.editGroup( "department_users", // Old group name "department_all_users", // New group name newQueryTemplate, // Updated SQL query adminUser // Editor username ); ``` -------------------------------- ### Inject NotifierClient in Spring Source: https://github.com/daichi-m/notification4j/blob/main/README.md Use JSR-330 @Inject or Spring's @Autowired to inject the NotifierClient into a component. ```java @Component public class TestNotification { // You can also use Spring's @Autowired @javax.inject.Inject private NotifierClient client; ... } ``` -------------------------------- ### Custom AlertingErrorHandler Class Source: https://context7.com/daichi-m/notification4j/llms.txt Defines a reusable ErrorHandler class for sending alerts to a specified channel upon notification failure. Requires an alert channel to be provided during instantiation. ```java public static class AlertingErrorHandler implements ErrorHandler { private final String alertChannel; public AlertingErrorHandler(String alertChannel) { this.alertChannel = alertChannel; } @Override public void accept(NotificationException exception) { System.err.println("[" + alertChannel + "] Notification failed: " + exception.getMessage()); // Send alert to Slack, PagerDuty, etc. sendAlert(alertChannel, exception); } private void sendAlert(String channel, NotificationException ex) { // Alert implementation } } ``` -------------------------------- ### Send Notification to Single User Source: https://context7.com/daichi-m/notification4j/llms.txt Sends a notification to a single user asynchronously. Uses the default error handler. ```java import io.github.daichim.notification4j.NotifierClient; import io.github.daichim.notification4j.ErrorHandler; import io.github.daichim.notification4j.model.Notification; import java.time.Duration; import java.util.concurrent.CompletableFuture; public class TeamNotificationService { private final NotifierClient client; public TeamNotificationService(NotifierClient client) { this.client = client; } // Notify single user with default error handler public CompletableFuture notifySingleUser(String userId) { Notification notification = new Notification() .setMesage("Your weekly report is ready") .setDescription("Click to view your performance metrics for this week.") .setSeverity(Notification.Severity.INFO) .setSource("ReportingService") .expireAfter(Duration.ofDays(7)); return client.notifyUsers(notification, userId); } // Notify multiple users at once public CompletableFuture notifyTeam(String[] teamMembers) { Notification notification = new Notification() .setMesage("Team meeting in 15 minutes") .setDescription("Daily standup meeting starting soon. Join at conference room A.") .setSeverity(Notification.Severity.WARNING) .setSource("CalendarService") .setDisplayType(Notification.DisplayType.BANNER_DISMISS) .expireAfter(Duration.ofMinutes(20)); return client.notifyUsers(notification, teamMembers); } // Notify with custom error handler public void notifyWithCustomErrorHandler(String userId, String message) { Notification notification = new Notification() .setMesage(message) .setSeverity(Notification.Severity.ERROR) .setSource("AlertSystem") .expireAfter(Duration.ofHours(4)); ErrorHandler customHandler = exception -> { System.err.println("Notification failed: " + exception.getMessage()); // Log to monitoring system, retry queue, etc. sendToDeadLetterQueue(userId, notification, exception); }; client.notifyUsers(customHandler, notification, userId) .thenAccept(success -> { if (success) { System.out.println("Alert sent successfully to " + userId); } }); } private void sendToDeadLetterQueue(String userId, Notification n, Exception e) { // Implementation for failed notification handling } } ``` -------------------------------- ### Send Notification with Metrics Error Handler Source: https://context7.com/daichi-m/notification4j/llms.txt Utilizes an ErrorHandler to record metrics for notification send failures, such as incrementing counters and logging error types. ```java ErrorHandler metricsHandler = ex -> { incrementErrorCounter("notification_send_failures"); recordErrorType(ex.getClass().getSimpleName()); logToMonitoringSystem(ex); }; client.notifyUsers(metricsHandler, notification, userId); ``` -------------------------------- ### Send Notification with Retry Queue Error Handler Source: https://context7.com/daichi-m/notification4j/llms.txt Implements an ErrorHandler that adds failed notifications to a retry queue. This is useful for transient failures. ```java ErrorHandler retryHandler = ex -> { System.err.println("Failed to send, adding to retry queue: " + ex.getMessage()); addToRetryQueue(userId, notification, ex); }; client.notifyUsers(retryHandler, notification, userId); ``` -------------------------------- ### Send Critical Notification with Custom Handler Source: https://context7.com/daichi-m/notification4j/llms.txt Instantiates and uses the custom AlertingErrorHandler class to handle critical notification failures, directing alerts to a specific channel. ```java client.notifyUsers(new AlertingErrorHandler("#critical-alerts"), notification, userId); ``` -------------------------------- ### Delete User Group Source: https://context7.com/daichi-m/notification4j/llms.txt Deletes a user group by its name. Requires the admin username. ```java groupClient.deleteGroup(groupName, adminUser); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.