Skip to content

Commit 2ad0411

Browse files
authored
Implement cache for helm packages (#603)
1 parent 65919a2 commit 2ad0411

4 files changed

Lines changed: 88 additions & 12 deletions

File tree

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,16 @@ Configurable properties :
8080
| `security.cors.allowed_origins` | | To indicate which origins are allowed by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) |
8181

8282
### HTTP configuration
83-
| Key | Default | Description |
84-
| --------------------- | ------- | ------------------------------------------------------------------ |
85-
| `http.proxyHost` | | Proxy hostname (e.g : proxy.example.com) |
86-
| `http.proxyPort` | 80 for `HTTP`, 443 for `HTTPS` | Proxy port |
87-
| `http.noProxy` | | Hosts that should not use the proxy (e.g : `localhost,host.example.com`) |
88-
| `http.proxyUsername` | | Username if the proxy requires authentication |
89-
| `http.proxyPassword` | | Password if the proxy requires authentication |
83+
| Key | Default | Description |
84+
| --------------------- |--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
85+
| `http.proxyHost` | | Proxy hostname (e.g : proxy.example.com) |
86+
| `http.proxyPort` | 80 for `HTTP`, 443 for `HTTPS` | Proxy port |
87+
| `http.noProxy` | | Hosts that should not use the proxy (e.g : `localhost,host.example.com`) |
88+
| `http.proxyUsername` | | Username if the proxy requires authentication |
89+
| `http.proxyPassword` | | Password if the proxy requires authentication |
90+
| `http.cacheEnabled` | true | Enable cache for charts retrieval. |
91+
| `http.cacheMaxSizeMB` | 500 | Maximum size (in MB) used by the cache (cleanup will be done automatically if space is not enough) |
92+
| `http.overrideCacheLocation` | `${java.io.tmpdir}/http_cache` (=`/tmp/http_cache` on most setups) | Specify where to store the cache |
9093

9194
### Events
9295
| Key | Default | Description |

onyxia-api/src/main/java/fr/insee/onyxia/api/configuration/HttpClientProvider.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,60 @@
11
package fr.insee.onyxia.api.configuration;
22

33
import fr.insee.onyxia.model.region.Region;
4+
import io.micrometer.common.util.StringUtils;
5+
import java.io.File;
46
import java.io.IOException;
57
import okhttp3.*;
68
import okhttp3.logging.HttpLoggingInterceptor;
79
import org.jetbrains.annotations.NotNull;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
import org.springframework.beans.factory.annotation.Qualifier;
13+
import org.springframework.beans.factory.annotation.Value;
814
import org.springframework.context.annotation.Bean;
915
import org.springframework.context.annotation.Configuration;
1016

1117
@Configuration
1218
public class HttpClientProvider {
1319

20+
@Value("${http.cacheEnabled}")
21+
private boolean cacheEnabled;
22+
23+
@Value("${http.cacheMaxSizeMB}")
24+
private Integer cacheMaxSizeMB;
25+
26+
@Value("${http.overrideCacheLocation}")
27+
private String overrideCacheLocation;
28+
29+
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientProvider.class);
30+
1431
@Bean
1532
public OkHttpClient httpClient() {
1633
OkHttpClient.Builder builder = new OkHttpClient.Builder();
1734
enableDebugFeatureIfEnabled(builder);
1835
return builder.build();
1936
}
2037

38+
@Bean
39+
@Qualifier("withCache")
40+
public OkHttpClient httpClientWithCache() {
41+
OkHttpClient.Builder builder = new OkHttpClient.Builder();
42+
enableDebugFeatureIfEnabled(builder);
43+
if (cacheEnabled) {
44+
File httpCacheDirectory;
45+
if (StringUtils.isNotBlank(overrideCacheLocation)) {
46+
httpCacheDirectory = new File(overrideCacheLocation);
47+
} else {
48+
httpCacheDirectory = new File(System.getProperty("java.io.tmpdir"), "http_cache");
49+
}
50+
LOGGER.info("Caching helm packages at {}", httpCacheDirectory.getAbsolutePath());
51+
long cacheSize = cacheMaxSizeMB * 1024L * 1024L;
52+
Cache cache = new Cache(httpCacheDirectory, cacheSize);
53+
builder.cache(cache);
54+
}
55+
return builder.build();
56+
}
57+
2158
public OkHttpClient getClientForRegion(Region region) {
2259
OkHttpClient.Builder builder =
2360
new OkHttpClient.Builder()
@@ -71,4 +108,28 @@ private void enableDebugFeatureIfEnabled(OkHttpClient.Builder builder) {
71108
builder.addInterceptor(logging);
72109
}
73110
}
111+
112+
public void setCacheEnabled(boolean cacheEnabled) {
113+
this.cacheEnabled = cacheEnabled;
114+
}
115+
116+
public boolean isCacheEnabled() {
117+
return cacheEnabled;
118+
}
119+
120+
public void setCacheMaxSizeMB(Integer cacheMaxSizeMB) {
121+
this.cacheMaxSizeMB = cacheMaxSizeMB;
122+
}
123+
124+
public Integer getCacheMaxSizeMB() {
125+
return cacheMaxSizeMB;
126+
}
127+
128+
public void setOverrideCacheLocation(String overrideCacheLocation) {
129+
this.overrideCacheLocation = overrideCacheLocation;
130+
}
131+
132+
public String getOverrideCacheLocation() {
133+
return overrideCacheLocation;
134+
}
74135
}

onyxia-api/src/main/java/fr/insee/onyxia/api/dao/universe/CatalogLoader.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
import java.io.InputStream;
1919
import java.util.*;
2020
import java.util.stream.Collectors;
21-
import okhttp3.Credentials;
22-
import okhttp3.OkHttpClient;
23-
import okhttp3.Request;
21+
import okhttp3.*;
2422
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
2523
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
2624
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
@@ -49,7 +47,7 @@ public class CatalogLoader {
4947
public CatalogLoader(
5048
ResourceLoader resourceLoader,
5149
@Qualifier("helm") ObjectMapper mapperHelm,
52-
OkHttpClient httpClient) {
50+
@Qualifier("withCache") OkHttpClient httpClient) {
5351
this.resourceLoader = resourceLoader;
5452
this.mapperHelm = mapperHelm;
5553
this.httpClient = httpClient;
@@ -69,7 +67,10 @@ private void updateHelmRepository(CatalogWrapper cw) {
6967

7068
try (InputStream stream =
7169
fetchResource(
72-
cw.getLocation() + "/index.yaml", cw.getUsername(), cw.getPassword())) {
70+
cw.getLocation() + "/index.yaml",
71+
cw.getUsername(),
72+
cw.getPassword(),
73+
true)) {
7374
Repository repository = mapperHelm.readValue(stream, Repository.class);
7475

7576
repository.setEntries(
@@ -128,11 +129,19 @@ private void updateHelmRepository(CatalogWrapper cw) {
128129

129130
private InputStream fetchResource(String url, String username, String password)
130131
throws IOException {
132+
return fetchResource(url, username, password, false);
133+
}
134+
135+
private InputStream fetchResource(
136+
String url, String username, String password, boolean skipCache) throws IOException {
131137
if (url.startsWith("http")) {
132138
Request.Builder builder = new Request.Builder().url(url);
133139
if (username != null && password != null) {
134140
builder = builder.addHeader("Authorization", Credentials.basic(username, password));
135141
}
142+
if (skipCache) {
143+
builder.cacheControl(new CacheControl.Builder().noCache().build());
144+
}
136145
return httpClient.newCall(builder.build()).execute().body().byteStream();
137146
} else {
138147
return resourceLoader.getResource(url).getInputStream();

onyxia-api/src/main/resources/application.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ http.proxyPort=
2222
http.noProxy=
2323
http.proxyUsername=
2424
http.proxyPassword=
25+
http.cacheEnabled=true
26+
http.cacheMaxSizeMB=500
27+
http.overrideCacheLocation=
2528
# Enable compression by default for responses > 1k
2629
server.compression.enabled=true
2730
server.compression.min-response-size=1024

0 commit comments

Comments
 (0)