MaintenanceEventMessages.java
package redis.clients.jedis.util.server;
import java.util.List;
/**
* Utility for constructing maintenance event push messages for testing. These messages simulate
* Redis server-initiated notifications about maintenance operations like migrations, failovers, and
* endpoint moves.
* <p>
* Message format follows the latest Redis specification where:
* <ul>
* <li>Sequence numbers and time values are encoded as RESP3 integers</li>
* <li>Shard IDs are encoded as a JSON array string</li>
* </ul>
* <p>
* Usage example:
*
* <pre>
* {
* @code
* // Create MIGRATING push message
* Object[] migrating = MaintenanceEventMessages.migrating(6, 2, Arrays.asList("2", "4"));
* // Results in: ["MIGRATING", 6 (int), 2 (int), "[\"2\", \"4\"]" (string)]
*
* // Create MOVING push message
* Object[] moving = MaintenanceEventMessages.moving(1, 30, "new-host:6380");
* }
* </pre>
*/
public class MaintenanceEventMessages {
private MaintenanceEventMessages() {
// Utility class - no instantiation
}
/**
* Convert shard IDs to JSON array format.
* @param shardIds list of shard IDs
* @return JSON array string, e.g., ["1", "2", "3"]
*/
private static String toJsonArray(List<String> shardIds) {
if (shardIds == null || shardIds.isEmpty()) {
return "[]";
}
StringBuilder json = new StringBuilder("[");
for (int i = 0; i < shardIds.size(); i++) {
if (i > 0) {
json.append(", ");
}
json.append("\"").append(shardIds.get(i)).append("\"");
}
json.append("]");
return json.toString();
}
/**
* Create MIGRATING message: A shard migration is going to start within {@code timeSeconds}
* seconds.
* <p>
* Format: MIGRATING {@code <seq_number> <time_s> <shard_id-s>}
* <p>
* Example: ["MIGRATING", 6 (Integer), 2 (Integer), "[\"2\", \"4\"]" (String)]
* @param sequenceNumber sequence number (encoded as RESP3 integer)
* @param timeSeconds time in seconds until migration starts (encoded as RESP3 integer)
* @param shardIds list of shard IDs (encoded as JSON array string)
* @return push message arguments [MIGRATING, seq (Integer), time (Integer), shardIds (JSON
* String)]
*/
public static Object[] migrating(int sequenceNumber, int timeSeconds, List<String> shardIds) {
return new Object[] { "MIGRATING", sequenceNumber, timeSeconds, toJsonArray(shardIds) };
}
/**
* Create MIGRATED message: A shard migration ended.
* <p>
* Format: MIGRATED {@code <seq_number> <shard_id-s>}
* <p>
* Example: ["MIGRATED", 7 (Integer), "[\"2\", \"4\"]" (String)]
* @param sequenceNumber sequence number (encoded as RESP3 integer)
* @param shardIds list of shard IDs (encoded as JSON array string)
* @return push message arguments [MIGRATED, seq (Integer), shardIds (JSON String)]
*/
public static Object[] migrated(int sequenceNumber, List<String> shardIds) {
return new Object[] { "MIGRATED", sequenceNumber, toJsonArray(shardIds) };
}
/**
* Create FAILING_OVER message: A shard failover of a healthy shard started.
* <p>
* Format: FAILING_OVER {@code <seq_number> <time_s> <shard_id-s>}
* <p>
* Example: ["FAILING_OVER", 6 (Integer), 2 (Integer), "[\"2\", \"4\"]" (String)]
* @param sequenceNumber sequence number (encoded as RESP3 integer)
* @param timeSeconds time in seconds until failover starts (encoded as RESP3 integer)
* @param shardIds list of shard IDs (encoded as JSON array string)
* @return push message arguments [FAILING_OVER, seq (Integer), time (Integer), shardIds (JSON
* String)]
*/
public static Object[] failingOver(int sequenceNumber, int timeSeconds, List<String> shardIds) {
return new Object[] { "FAILING_OVER", sequenceNumber, timeSeconds, toJsonArray(shardIds) };
}
/**
* Create FAILED_OVER message: A shard failover of a healthy shard ended.
* <p>
* Format: FAILED_OVER {@code <seq_number> <shard_id-s>}
* <p>
* Example: ["FAILED_OVER", 7 (Integer), "[\"2\", \"4\"]" (String)]
* @param sequenceNumber sequence number (encoded as RESP3 integer)
* @param shardIds list of shard IDs (encoded as JSON array string)
* @return push message arguments [FAILED_OVER, seq (Integer), shardIds (JSON String)]
*/
public static Object[] failedOver(int sequenceNumber, List<String> shardIds) {
return new Object[] { "FAILED_OVER", sequenceNumber, toJsonArray(shardIds) };
}
/**
* Create MOVING message: A specific endpoint is going to move to another node within
* {@code timeSeconds} seconds.
* <p>
* Format: MOVING {@code <seq_number> <time_s> <endpoint>}
* <p>
* Example: ["MOVING", 30 (Integer), 15 (Integer), "localhost:6380" (String)]
* @param sequenceNumber sequence number (encoded as RESP3 integer)
* @param timeSeconds time in seconds until move (encoded as RESP3 integer)
* @param endpoint target endpoint (host:port)
* @return push message arguments [MOVING, seq (Integer), time (Integer), endpoint (String)]
*/
public static Object[] moving(int sequenceNumber, int timeSeconds, String endpoint) {
return new Object[] { "MOVING", sequenceNumber, timeSeconds, endpoint };
}
}