Account for maven central occasional request slow response

This commit is contained in:
aboyko
2023-02-02 13:32:36 -05:00
parent 3175d5d3c2
commit d32e17451c
2 changed files with 40 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022 VMware, Inc.
* Copyright (c) 2022, 2023 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
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.validation.generations;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -20,6 +21,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
@@ -32,21 +34,21 @@ public class BootVersionsFromMavenCentral {
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() throws Exception {
public static List<Version> getBootVersions() throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(MediaType.parseMediaTypes("application/json"));
HttpEntity<?> entity = new HttpEntity(headers);
HttpEntity<?> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
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();
HttpStatusCode status = responseEntity.getStatusCode();
log.info("search maven central response code: " + status);
log.info("search maven central response code: " + status.value());
if (status == 200) {
if (status.is2xxSuccessful()) {
Map<String, Object> json = responseEntity.getBody();
Map<String, Object> response = (Map<String, Object>) json.get("response");
if (response != null) {
@@ -71,11 +73,11 @@ public class BootVersionsFromMavenCentral {
return versions;
}
else {
throw new Exception("unable to access Spring Boot versions from Maven Central, empty response");
throw new IOException("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);
throw new IOException("Failed to fetch versions from Maven Central, status = " + status.value());
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022 VMware, Inc.
* Copyright (c) 2022, 2023 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
@@ -10,8 +10,14 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.validation.generations;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,31 +34,45 @@ public class CachedBootVersionsFromMavenCentral {
private static final String KEY = "cacheKey";
private static final Duration EXPIRES_AFTER = Duration.ofMinutes(60);
private static final int ATTEMPTS_NUMBER = 5;
private static final long RESPONSE_WAIT_TIME_MS = 1000;
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 List<Version> load(String key) throws Exception {
for (int i = 0; i < ATTEMPTS_NUMBER; i++) {
try {
return getFuture().get(RESPONSE_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
} catch (ExecutionException | TimeoutException e) {
// ignore exception - ask maven central again
}
}
throw new Exception("Failed to fetch versions from Maven Central after " + ATTEMPTS_NUMBER + " tries.");
}
});
public static List<Version> getBootVersions() {
public static synchronized List<Version> getBootVersions() {
try {
return cache.get(KEY);
}
catch (Exception e) {
log.error("failed to load Spring Boot release information from maven central", e);
catch (ExecutionException e) {
log.error("Failed to load Spring Boot release information from maven central", e);
return ImmutableList.of();
}
}
private static CompletableFuture<List<Version>> getFuture() {
return CompletableFuture.supplyAsync(() -> {
try {
return BootVersionsFromMavenCentral.getBootVersions();
} catch (IOException e) {
throw new CompletionException(e);
}
});
}
}