From a0a0fd67d90350bef2d24559f579aec69fd5f2e6 Mon Sep 17 00:00:00 2001 From: Jeremy Plichta Date: Wed, 19 Mar 2025 21:51:59 -0600 Subject: [PATCH] add parseHex and parseUuid spel functions to return byte arrays --- docs/guide/src/docs/asciidoc/import.adoc | 4 ++ .../com/redis/riot/EvaluationContextArgs.java | 5 +++ .../main/java/com/redis/riot/SpelUtils.java | 37 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 plugins/riot/src/main/java/com/redis/riot/SpelUtils.java diff --git a/docs/guide/src/docs/asciidoc/import.adoc b/docs/guide/src/docs/asciidoc/import.adoc index b5506d3b..977a0440 100644 --- a/docs/guide/src/docs/asciidoc/import.adoc +++ b/docs/guide/src/docs/asciidoc/import.adoc @@ -30,6 +30,10 @@ The `replicate` command exposes 2 command objects named `source` and `target`. `geo`:: Convenience function that takes a longitude and a latitude to produce a RediSearch geo-location string in the form `longitude,latitude` (e.g. `location=#geo(lon,lat)`) +`parseHex`:: Parse a hexadecimal string to a byte array. + +`parseUuid`:: Parse a UUID string to a byte array. + .Processor example [source,console] ---- diff --git a/plugins/riot/src/main/java/com/redis/riot/EvaluationContextArgs.java b/plugins/riot/src/main/java/com/redis/riot/EvaluationContextArgs.java index a68cc180..dc3adae0 100644 --- a/plugins/riot/src/main/java/com/redis/riot/EvaluationContextArgs.java +++ b/plugins/riot/src/main/java/com/redis/riot/EvaluationContextArgs.java @@ -24,6 +24,8 @@ public class EvaluationContextArgs { public static final String VAR_DATE = "date"; public static final String VAR_NUMBER = "number"; public static final String VAR_FAKER = "faker"; + public static final String PARSE_HEX = "parseHex"; + public static final String PARSE_UUID = "parseUuid"; @Option(arity = "1..*", names = "--var", description = "SpEL expressions for context variables, in the form var=\"exp\". For details see https://docs.spring.io/spring-framework/reference/core/expressions.html", paramLabel = "") private Map varExpressions = new LinkedHashMap<>(); @@ -39,6 +41,9 @@ public class EvaluationContextArgs { public StandardEvaluationContext evaluationContext() { StandardEvaluationContext context = new StandardEvaluationContext(); RiotUtils.registerFunction(context, "geo", GeoLocation.class, "toString", String.class, String.class); + RiotUtils.registerFunction(context, PARSE_HEX, SpelUtils.class, "parseHex", String.class); + RiotUtils.registerFunction(context, PARSE_UUID, SpelUtils.class, "parseUuid", String.class); + context.setVariable(VAR_DATE, new SimpleDateFormat(dateFormat)); context.setVariable(VAR_NUMBER, new DecimalFormat(numberFormat)); context.setVariable(VAR_FAKER, new Faker()); diff --git a/plugins/riot/src/main/java/com/redis/riot/SpelUtils.java b/plugins/riot/src/main/java/com/redis/riot/SpelUtils.java new file mode 100644 index 00000000..b6dca654 --- /dev/null +++ b/plugins/riot/src/main/java/com/redis/riot/SpelUtils.java @@ -0,0 +1,37 @@ +package com.redis.riot; + +public class SpelUtils { + + public static String parseHex(String hexVal) { + if (hexVal == null) { + return null; + } + if (hexVal.startsWith("0x")) { + hexVal = hexVal.substring(2); + } + byte[] bytes = new byte[hexVal.length() / 2]; + for (int i = 0; i < bytes.length; i++) { + byte b = (byte) Integer.parseInt(hexVal.substring(2 * i, 2 * i + 2), 16); + bytes[i] = b; + } + + return new String(bytes); + } + + public static String parseUuid(String uuid) { + if (uuid == null) { + return null; + } + + java.util.UUID uuidObj = java.util.UUID.fromString(uuid); + byte[] bytes = new byte[16]; + long msb = uuidObj.getMostSignificantBits(); + long lsb = uuidObj.getLeastSignificantBits(); + for (int i = 0; i < 8; i++) { + bytes[i] = (byte) (msb >>> (8 * (7 - i))); + bytes[8 + i] = (byte) (lsb >>> (8 * (7 - i))); + } + + return new String(bytes); + } +}