I want to be able to check if a script exists in a Redis cluster. If it doesn't, I will need to load a new script from my resources folder
and save the corresponding SHA value of that new script. I would like to save that SHA value for next time the application starts up, inside of the application.properties
. This would ideally be done by overwriting the previous entry for the sha value
I know that the properties file is read once during startup, but this does not matter as I only want to save that SHA value to the application.properties
for use next time, ie preventing the overhead of checking for a script and loading each time.
This is my method for preparing the scripts
static String prepareScripts() throws ExecutionException, InterruptedException, IOException {
List <Boolean> list = (List) asyncCommands.scriptExists(sha).get();
shaDigest = sha;
if (list.get(0) == false) {
URL url = AbstractRedisDao.class.getClassLoader().getResource("script.txt");
File file = new File(url.getPath());
String str = FileUtils.readFileToString(file, "ISO_8859_1");
shaDigest = (String) asyncCommands.scriptLoad(str).get();
Properties properties = new Properties();
try {
FileWriter writer = new FileWriter("application.properties");
BufferedWriter bw = new BufferedWriter(writer);
Iterator propertyIt = properties.entrySet().iterator();
while (propertyIt.hasNext() ) {
Map.Entry nextHolder = (Map.Entry) propertyIt.next();
while (nextHolder.getKey() != ("redis.scriptActiveDev")) {
bw.write(nextHolder.getKey() + "=" + nextHolder.getValue());
}
}
bw.write("redis.scriptActiveDev=" + shaDigest);
} catch (IOException e) {
System.err.format("IOException: %s%n", e);
}
return shaDigest;
} else {
return shaDigest;
}
}
these are the details for redis in application.properties:
redis.enabled=true
redis.hostname=xxxx
redis.port=xxxx
redis.password=xxxx
redis.sha=xxxx
Is this on the right track? also, how would i go about saving the application.properties
back to the resources
folder after rebuilding it with the new property? Is there a more efficient way to do this without recreating the whole application.properties
just to add one line?
There is no need to store SHA digests for Lua scripts in application.properties
.
Use the API of your Redis client to get SHA digest on application startup.
For instance, Lettuce provides the following API for scripting:
String digest(V script)
String scriptLoad(V script)
List<Boolean> scriptExists(String... digests)
You can execute the following code on each application startup to get the digest for your script:
public String sha(String script) {
String shaDigest = redisScriptingCommands.digest(script);
boolean scriptExists = redisScriptingCommands.scriptExists(shaDigest).get(0);
if (!scriptExists) {
redisScriptingCommands.scriptLoad(script);
}
return shaDigest;
}