Query migration to db done - Query persistence in cache is also done
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -173,16 +173,6 @@
|
||||
<build>
|
||||
<finalName>matrix</finalName>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<!-- Queries are supplied by the cloud query catalog at runtime. -->
|
||||
<exclude>matrix/nimble/conf/nimble.qry</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@@ -16,11 +16,16 @@ public class OnPremRedisConfiguration {
|
||||
@Value("${REDIS_HOST:192.168.0.111}") String host,
|
||||
@Value("${REDIS_PORT:7901}") int port,
|
||||
@Value("${REDIS_PASSWORD:}") String password,
|
||||
@Value("${REDIS_DATABASE:1}") int database,
|
||||
@Value("${REDIS_SSL:false}") boolean ssl,
|
||||
@Value("${REDIS_CONNECT_TIMEOUT_SECONDS:3}") long connectTimeoutSeconds) {
|
||||
if (database < 0) {
|
||||
throw new IllegalArgumentException("REDIS_DATABASE must be zero or greater");
|
||||
}
|
||||
RedisURI.Builder uri = RedisURI.builder()
|
||||
.withHost(host)
|
||||
.withPort(port)
|
||||
.withDatabase(database)
|
||||
.withSsl(ssl)
|
||||
.withTimeout(Duration.ofSeconds(connectTimeoutSeconds));
|
||||
if (password != null && !password.isBlank()) {
|
||||
|
||||
@@ -11,7 +11,7 @@ public final class CloudQuerySource implements QuerySource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetch(String queryId) {
|
||||
public String fetch(int queryId) {
|
||||
return client.fetchQuery(queryId)
|
||||
.map(response -> response.query())
|
||||
.blockOptional()
|
||||
@@ -20,4 +20,3 @@ public final class CloudQuerySource implements QuerySource {
|
||||
"Cloud query was empty: " + queryId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,5 @@ package matrix.nimble.query;
|
||||
|
||||
public interface QueryProvider {
|
||||
|
||||
String getQuery(String queryId);
|
||||
|
||||
default String getQuery(int queryId) {
|
||||
return getQuery("Query" + queryId);
|
||||
}
|
||||
String getQuery(int queryId);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,5 @@ package matrix.nimble.query;
|
||||
@FunctionalInterface
|
||||
public interface QuerySource {
|
||||
|
||||
String fetch(String queryId);
|
||||
String fetch(int queryId);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,27 +30,27 @@ public final class RedisCachingQueryProvider implements QueryProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuery(String queryId) {
|
||||
String normalized = normalize(queryId);
|
||||
Optional<String> cached = cached(normalized);
|
||||
public String getQuery(int queryId) {
|
||||
String cacheKey = cacheKey(queryId);
|
||||
Optional<String> cached = cached(cacheKey);
|
||||
if (cached.isPresent()) {
|
||||
return cached.get();
|
||||
}
|
||||
|
||||
synchronized (lock(normalized)) {
|
||||
cached = cached(normalized);
|
||||
synchronized (lock(cacheKey)) {
|
||||
cached = cached(cacheKey);
|
||||
if (cached.isPresent()) {
|
||||
return cached.get();
|
||||
}
|
||||
try {
|
||||
String query = cloudSource.fetch(normalized);
|
||||
cache.put(normalized, cipher.encrypt(normalized, query), QUERY_TTL);
|
||||
String query = cloudSource.fetch(queryId);
|
||||
cache.put(cacheKey, cipher.encrypt(cacheKey, query), QUERY_TTL);
|
||||
return query;
|
||||
} catch (QueryProviderException exception) {
|
||||
throw exception;
|
||||
} catch (RuntimeException exception) {
|
||||
throw new QueryProviderException(
|
||||
"Unable to retrieve query: " + normalized, exception);
|
||||
"Unable to retrieve query: " + queryId, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,10 +72,10 @@ public final class RedisCachingQueryProvider implements QueryProvider {
|
||||
return locks[(queryId.hashCode() & Integer.MAX_VALUE) % locks.length];
|
||||
}
|
||||
|
||||
private String normalize(String queryId) {
|
||||
if (queryId == null || !queryId.matches("^[A-Za-z0-9._-]+$")) {
|
||||
private String cacheKey(int queryId) {
|
||||
if (queryId <= 0) {
|
||||
throw new IllegalArgumentException("Invalid query ID");
|
||||
}
|
||||
return queryId;
|
||||
return Integer.toString(queryId);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -12,6 +12,6 @@ class FileFunctionsQueryCacheTest {
|
||||
void delegatesLegacyQueryLookupToQueryProvider() throws Exception {
|
||||
QueryProviders.install(queryId -> "provided:" + queryId);
|
||||
FileFunctions files = new FileFunctions("TEST");
|
||||
assertEquals("provided:Query3", files.GetQuery(3));
|
||||
assertEquals("provided:3", files.GetQuery(3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ class AesGcmQueryCipherTest {
|
||||
Arrays.fill(key, (byte) 7);
|
||||
AesGcmQueryCipher cipher = new AesGcmQueryCipher(key);
|
||||
|
||||
String encrypted = cipher.encrypt("Query3", "select * from portfolio");
|
||||
String encrypted = cipher.encrypt("3", "select * from portfolio");
|
||||
|
||||
assertNotEquals("select * from portfolio", encrypted);
|
||||
assertTrue(encrypted.startsWith("v1."));
|
||||
org.junit.jupiter.api.Assertions.assertEquals(
|
||||
"select * from portfolio", cipher.decrypt("Query3", encrypted));
|
||||
"select * from portfolio", cipher.decrypt("3", encrypted));
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> cipher.decrypt("Query4", encrypted));
|
||||
() -> cipher.decrypt("4", encrypted));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ class RedisCachingQueryProviderTest {
|
||||
},
|
||||
cipher);
|
||||
|
||||
assertEquals("select!C0L!select 1", provider.getQuery("Query10"));
|
||||
assertEquals("select!C0L!select 1", provider.getQuery("Query10"));
|
||||
assertEquals("select!C0L!select 1", provider.getQuery(10));
|
||||
assertEquals("select!C0L!select 1", provider.getQuery(10));
|
||||
|
||||
assertEquals(1, cloudCalls.get());
|
||||
assertEquals(Duration.ofHours(3), cache.ttl.get());
|
||||
org.junit.jupiter.api.Assertions.assertNotEquals(
|
||||
"select!C0L!select 1", cache.values.get("Query10"));
|
||||
"select!C0L!select 1", cache.values.get("10"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -55,7 +55,7 @@ class RedisCachingQueryProviderTest {
|
||||
var executor = Executors.newFixedThreadPool(8);
|
||||
try {
|
||||
for (int index = 0; index < 20; index++) {
|
||||
executor.submit(() -> provider.getQuery("Query20"));
|
||||
executor.submit(() -> provider.getQuery(20));
|
||||
}
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
|
||||
Reference in New Issue
Block a user