From 2383aaaa3de618696d6b6624193fa402de000975 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Mon, 27 Sep 2021 12:01:22 -0400 Subject: [PATCH] Update ClusterLuaScript formatting --- .../textsecuregcm/redis/ClusterLuaScript.java | 132 ++++++------- .../redis/ClusterLuaScriptTest.java | 174 +++++++++--------- 2 files changed, 162 insertions(+), 144 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java b/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java index b813ca941..bb7a22efc 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScript.java @@ -19,76 +19,84 @@ import java.util.List; public class ClusterLuaScript { - private final FaultTolerantRedisCluster redisCluster; - private final ScriptOutputType scriptOutputType; - private final String script; - private final String sha; + private final FaultTolerantRedisCluster redisCluster; + private final ScriptOutputType scriptOutputType; + private final String script; + private final String sha; - private static final String[] STRING_ARRAY = new String[0]; - private static final byte[][] BYTE_ARRAY_ARRAY = new byte[0][]; + private static final String[] STRING_ARRAY = new String[0]; + private static final byte[][] BYTE_ARRAY_ARRAY = new byte[0][]; - private static final Logger log = LoggerFactory.getLogger(ClusterLuaScript.class); + private static final Logger log = LoggerFactory.getLogger(ClusterLuaScript.class); - public static ClusterLuaScript fromResource(final FaultTolerantRedisCluster redisCluster, final String resource, final ScriptOutputType scriptOutputType) throws IOException { - try (final InputStream inputStream = LuaScript.class.getClassLoader().getResourceAsStream(resource); - final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + public static ClusterLuaScript fromResource(final FaultTolerantRedisCluster redisCluster, + final String resource, + final ScriptOutputType scriptOutputType) throws IOException { - byte[] buffer = new byte[4096]; - int read; + try (final InputStream inputStream = LuaScript.class.getClassLoader().getResourceAsStream(resource); + final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - while ((read = inputStream.read(buffer)) != -1) { - baos.write(buffer, 0, read); - } + byte[] buffer = new byte[4096]; + int read; - return new ClusterLuaScript(redisCluster, new String(baos.toByteArray()), scriptOutputType); + while ((read = inputStream.read(buffer)) != -1) { + baos.write(buffer, 0, read); + } + + return new ClusterLuaScript(redisCluster, new String(baos.toByteArray()), scriptOutputType); + } + } + + @VisibleForTesting + ClusterLuaScript(final FaultTolerantRedisCluster redisCluster, + final String script, + final ScriptOutputType scriptOutputType) { + + this.redisCluster = redisCluster; + this.scriptOutputType = scriptOutputType; + this.script = script; + this.sha = redisCluster.withCluster(connection -> connection.sync().scriptLoad(script)); + } + + public Object execute(final List keys, final List args) { + return redisCluster.withCluster(connection -> { + try { + final RedisAdvancedClusterCommands clusterCommands = connection.sync(); + + try { + return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY)); + } catch (final RedisNoScriptException e) { + reloadScript(); + return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY)); } - } + } catch (final Exception e) { + log.warn("Failed to execute script", e); + throw e; + } + }); + } - @VisibleForTesting - ClusterLuaScript(final FaultTolerantRedisCluster redisCluster, final String script, final ScriptOutputType scriptOutputType) { - this.redisCluster = redisCluster; - this.scriptOutputType = scriptOutputType; - this.script = script; - this.sha = redisCluster.withCluster(connection -> connection.sync().scriptLoad(script)); - } + public Object executeBinary(final List keys, final List args) { + return redisCluster.withBinaryCluster(connection -> { + try { + final RedisAdvancedClusterCommands binaryCommands = connection.sync(); - public Object execute(final List keys, final List args) { - return redisCluster.withCluster(connection -> { - try { - final RedisAdvancedClusterCommands clusterCommands = connection.sync(); + try { + return binaryCommands + .evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY)); + } catch (final RedisNoScriptException e) { + reloadScript(); + return binaryCommands + .evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY)); + } + } catch (final Exception e) { + log.warn("Failed to execute script", e); + throw e; + } + }); + } - try { - return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY)); - } catch (final RedisNoScriptException e) { - reloadScript(); - return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY)); - } - } catch (final Exception e) { - log.warn("Failed to execute script", e); - throw e; - } - }); - } - - public Object executeBinary(final List keys, final List args) { - return redisCluster.withBinaryCluster(connection -> { - try { - final RedisAdvancedClusterCommands binaryCommands = connection.sync(); - - try { - return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY)); - } catch (final RedisNoScriptException e) { - reloadScript(); - return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY)); - } - } catch (final Exception e) { - log.warn("Failed to execute script", e); - throw e; - } - }); - } - - private void reloadScript() { - redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptLoad(script)); - } + private void reloadScript() { + redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptLoad(script)); + } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScriptTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScriptTest.java index c8c524f3f..3553a998e 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScriptTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/redis/ClusterLuaScriptTest.java @@ -24,117 +24,127 @@ import org.whispersystems.textsecuregcm.tests.util.RedisClusterHelper; public class ClusterLuaScriptTest extends AbstractRedisClusterTest { - @Test - public void testExecuteMovedKey() { - final String key = "key"; - final String value = "value"; + @Test + public void testExecuteMovedKey() { + final String key = "key"; + final String value = "value"; - final FaultTolerantRedisCluster redisCluster = getRedisCluster(); + final FaultTolerantRedisCluster redisCluster = getRedisCluster(); - final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", ScriptOutputType.VALUE); + final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", + ScriptOutputType.VALUE); - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - final int slot = SlotHash.getSlot(key); + final int slot = SlotHash.getSlot(key); - final int sourcePort = redisCluster.withCluster(connection -> connection.sync().nodes(node -> node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)).node(0).getUri().getPort()); - final RedisCommands sourceCommands = redisCluster.withCluster(connection -> connection.sync().nodes(node -> node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)).commands(0)); - final RedisCommands destinationCommands = redisCluster.withCluster(connection -> connection.sync().nodes(node -> !node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)).commands(0)); + final int sourcePort = redisCluster.withCluster( + connection -> connection.sync().nodes(node -> node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)) + .node(0).getUri().getPort()); + final RedisCommands sourceCommands = redisCluster.withCluster( + connection -> connection.sync().nodes(node -> node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)) + .commands(0)); + final RedisCommands destinationCommands = redisCluster.withCluster(connection -> connection.sync() + .nodes(node -> !node.hasSlot(slot) && node.is(RedisClusterNode.NodeFlag.UPSTREAM)).commands(0)); - destinationCommands.clusterSetSlotImporting(slot, sourceCommands.clusterMyId()); + destinationCommands.clusterSetSlotImporting(slot, sourceCommands.clusterMyId()); - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - sourceCommands.clusterSetSlotMigrating(slot, destinationCommands.clusterMyId()); + sourceCommands.clusterSetSlotMigrating(slot, destinationCommands.clusterMyId()); - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - for (final String migrateKey : sourceCommands.clusterGetKeysInSlot(slot, Integer.MAX_VALUE)) { - destinationCommands.migrate("127.0.0.1", sourcePort, migrateKey, 0, 1000); - } - - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - - destinationCommands.clusterSetSlotNode(slot, destinationCommands.clusterMyId()); - - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + for (final String migrateKey : sourceCommands.clusterGetKeysInSlot(slot, Integer.MAX_VALUE)) { + destinationCommands.migrate("127.0.0.1", sourcePort, migrateKey, 0, 1000); } - @Test - public void testExecute() { - final RedisAdvancedClusterCommands commands = mock(RedisAdvancedClusterCommands.class); - final FaultTolerantRedisCluster mockCluster = RedisClusterHelper.buildMockRedisCluster(commands); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])"; - final String sha = "abc123"; - final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE; - final List keys = List.of("key"); - final List values = List.of("value"); + destinationCommands.clusterSetSlotNode(slot, destinationCommands.clusterMyId()); - when(commands.scriptLoad(script)).thenReturn(sha); - when(commands.evalsha(any(), any(), any(), any())).thenReturn("OK"); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + } - new ClusterLuaScript(mockCluster, script, scriptOutputType).execute(keys, values); + @Test + public void testExecute() { + final RedisAdvancedClusterCommands commands = mock(RedisAdvancedClusterCommands.class); + final FaultTolerantRedisCluster mockCluster = RedisClusterHelper.buildMockRedisCluster(commands); - verify(commands).scriptLoad(script); - verify(commands).evalsha(sha, scriptOutputType, keys.toArray(new String[0]), values.toArray(new String[0])); - } + final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])"; + final String sha = "abc123"; + final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE; + final List keys = List.of("key"); + final List values = List.of("value"); - @Test - public void testExecuteNoScriptException() { - final String key = "key"; - final String value = "value"; + when(commands.scriptLoad(script)).thenReturn(sha); + when(commands.evalsha(any(), any(), any(), any())).thenReturn("OK"); - final FaultTolerantRedisCluster redisCluster = getRedisCluster(); + new ClusterLuaScript(mockCluster, script, scriptOutputType).execute(keys, values); - final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", ScriptOutputType.VALUE); + verify(commands).scriptLoad(script); + verify(commands).evalsha(sha, scriptOutputType, keys.toArray(new String[0]), values.toArray(new String[0])); + } - // Remove the scripts created by the CLusterLuaScript constructor - redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush()); + @Test + public void testExecuteNoScriptException() { + final String key = "key"; + final String value = "value"; - assertEquals("OK", script.execute(List.of(key), List.of(value))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - } + final FaultTolerantRedisCluster redisCluster = getRedisCluster(); - @Test - public void testExecuteBinary() { - final RedisAdvancedClusterCommands stringCommands = mock(RedisAdvancedClusterCommands.class); - final RedisAdvancedClusterCommands binaryCommands = mock(RedisAdvancedClusterCommands.class); - final FaultTolerantRedisCluster mockCluster = RedisClusterHelper.buildMockRedisCluster(stringCommands, binaryCommands); + final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", + ScriptOutputType.VALUE); - final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])"; - final String sha = "abc123"; - final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE; - final List keys = List.of("key".getBytes(StandardCharsets.UTF_8)); - final List values = List.of("value".getBytes(StandardCharsets.UTF_8)); + // Remove the scripts created by the CLusterLuaScript constructor + redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush()); - when(stringCommands.scriptLoad(script)).thenReturn(sha); - when(binaryCommands.evalsha(any(), any(), any(), any())).thenReturn("OK".getBytes(StandardCharsets.UTF_8)); + assertEquals("OK", script.execute(List.of(key), List.of(value))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + } - new ClusterLuaScript(mockCluster, script, scriptOutputType).executeBinary(keys, values); + @Test + public void testExecuteBinary() { + final RedisAdvancedClusterCommands stringCommands = mock(RedisAdvancedClusterCommands.class); + final RedisAdvancedClusterCommands binaryCommands = mock(RedisAdvancedClusterCommands.class); + final FaultTolerantRedisCluster mockCluster = RedisClusterHelper + .buildMockRedisCluster(stringCommands, binaryCommands); - verify(stringCommands).scriptLoad(script); - verify(binaryCommands).evalsha(sha, scriptOutputType, keys.toArray(new byte[0][]), values.toArray(new byte[0][])); - } + final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])"; + final String sha = "abc123"; + final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE; + final List keys = List.of("key".getBytes(StandardCharsets.UTF_8)); + final List values = List.of("value".getBytes(StandardCharsets.UTF_8)); - @Test - public void testExecuteBinaryNoScriptException() { - final String key = "key"; - final String value = "value"; + when(stringCommands.scriptLoad(script)).thenReturn(sha); + when(binaryCommands.evalsha(any(), any(), any(), any())).thenReturn("OK".getBytes(StandardCharsets.UTF_8)); - final FaultTolerantRedisCluster redisCluster = getRedisCluster(); + new ClusterLuaScript(mockCluster, script, scriptOutputType).executeBinary(keys, values); - final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", ScriptOutputType.VALUE); + verify(stringCommands).scriptLoad(script); + verify(binaryCommands).evalsha(sha, scriptOutputType, keys.toArray(new byte[0][]), values.toArray(new byte[0][])); + } - // Remove the scripts created by the CLusterLuaScript constructor - redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush()); + @Test + public void testExecuteBinaryNoScriptException() { + final String key = "key"; + final String value = "value"; - assertArrayEquals("OK".getBytes(StandardCharsets.UTF_8), (byte[])script.executeBinary(List.of(key.getBytes(StandardCharsets.UTF_8)), List.of(value.getBytes(StandardCharsets.UTF_8)))); - assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); - } + final FaultTolerantRedisCluster redisCluster = getRedisCluster(); + + final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", + ScriptOutputType.VALUE); + + // Remove the scripts created by the CLusterLuaScript constructor + redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush()); + + assertArrayEquals("OK".getBytes(StandardCharsets.UTF_8), (byte[]) script + .executeBinary(List.of(key.getBytes(StandardCharsets.UTF_8)), List.of(value.getBytes(StandardCharsets.UTF_8)))); + assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key))); + } }