cache boot version results from maven central to avoid too many unnecessary requests

This commit is contained in:
Martin Lippert
2022-11-25 19:14:36 +01:00
parent 6541f21d4a
commit e4a2ee7905
4 changed files with 82 additions and 16 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
public class BootVersionValidator {
private static final Logger log = LoggerFactory.getLogger(BootVersionValidator.class);
private SimpleLanguageServer server;
private BootJavaConfig config;

View File

@@ -15,6 +15,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -26,26 +28,32 @@ import org.springframework.web.client.RestTemplate;
public class BootVersionsFromMavenCentral {
private static final Logger log = LoggerFactory.getLogger(BootVersionsFromMavenCentral.class);
private static final String URL = "https://search.maven.org/solrsearch/select?q=g:org.springframework.boot+AND+a:spring-boot-starter-parent&core=gav&rows=200&wt=json";
@SuppressWarnings({ "rawtypes", "unchecked" })
public static List<Version> getBootVersions() {
public static List<Version> getBootVersions() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(MediaType.parseMediaTypes("application/json"));
HttpEntity<?> entity = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
try {
ResponseEntity<Map> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, Map.class);
log.info("search maven central for Spring Boot release information via: " + URL);
ResponseEntity<Map> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, Map.class);
int status = responseEntity.getStatusCodeValue();
log.info("search maven central response code: " + status);
if (status == 200) {
Map<String, Object> json = responseEntity.getBody();
Map<String, Object> response = (Map<String, Object>) json.get("response");
if (response != null) {
List<Version> versions = new ArrayList<>();
Object docs = response.get("docs");
if (docs instanceof List) {
for (Object o : (List<?>) docs) {
if (o instanceof Map) {
Map<String, Object> e = (Map<String, Object>) o;
@@ -62,10 +70,13 @@ public class BootVersionsFromMavenCentral {
Collections.sort(versions);
return versions;
}
} catch (Exception e) {
// Error case
else {
throw new Exception("unable to access Spring Boot versions from Maven Central, empty response");
}
}
else {
throw new Exception("unable to access Spring Boot versions from Maven Central, query returned " + status);
}
return null;
}
}

View File

@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2022 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.validation.generations;
import java.time.Duration;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.java.Version;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
public class CachedBootVersionsFromMavenCentral {
private static final Logger log = LoggerFactory.getLogger(CachedBootVersionsFromMavenCentral.class);
private static final String KEY = "cacheKey";
private static final Duration EXPIRES_AFTER = Duration.ofMinutes(60);
private static final LoadingCache<String, List<Version>> cache = CacheBuilder.newBuilder()
.expireAfterWrite(EXPIRES_AFTER)
.build(new CacheLoader<String, List<Version>>() {
@Override
public List<Version> load(String key) {
try {
return BootVersionsFromMavenCentral.getBootVersions();
}
catch (Exception e) {
return ImmutableList.of();
}
}
});
public static List<Version> getBootVersions() {
try {
return cache.get(KEY);
}
catch (Exception e) {
log.error("failed to load Spring Boot release information from maven central", e);
return ImmutableList.of();
}
}
}

View File

@@ -12,7 +12,7 @@ package org.springframework.ide.vscode.boot.validation.generations.json;
import java.util.List;
import org.springframework.ide.vscode.boot.validation.generations.BootVersionsFromMavenCentral;
import org.springframework.ide.vscode.boot.validation.generations.CachedBootVersionsFromMavenCentral;
import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient;
import org.springframework.ide.vscode.commons.java.Version;
@@ -22,7 +22,6 @@ public class ResolvedSpringProject extends SpringProject {
private final SpringProjectsClient client;
private Generations generations;
private List<Version> releases;
public ResolvedSpringProject(SpringProject project, SpringProjectsClient client) {
this.client = client;
@@ -53,10 +52,7 @@ public class ResolvedSpringProject extends SpringProject {
* @throws Exception
*/
public List<Version> getReleases() throws Exception {
// cache the releases to prevent frequent calls to the client
if (this.releases == null) {
this.releases = BootVersionsFromMavenCentral.getBootVersions();
}
return this.releases != null ? this.releases : ImmutableList.of();
return CachedBootVersionsFromMavenCentral.getBootVersions();
}
}