Skip to content

Commit

Permalink
Optimize method for initializing cache of versions of OpenTofu (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
baixinsui authored Nov 5, 2024
1 parent 94e4a04 commit 5e1b1ea
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public Set<String> getAvailableVersions() {
try {
return versionsFetcher.fetchAvailableVersionsFromOpenTofuWebsite();
} catch (Exception e) {
log.error("Failed to fetch versions from website for OpenTofu, get "
+ "versions from default config.", e);
return versionsFetcher.getDefaultVersionsFromConfig();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
package org.eclipse.xpanse.tofu.maker.opentofu.tool;


import jakarta.annotation.PostConstruct;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import java.util.Objects;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
Expand All @@ -20,19 +22,24 @@
*/
@Slf4j
@Component
public class OpenTofuVersionsCacheManager {
public class OpenTofuVersionsCacheManager implements ApplicationListener<ApplicationStartedEvent> {

@Resource
private OpenTofuVersionsCache versionsCache;

@Resource
private OpenTofuVersionsFetcher versionsFetcher;

@Override
public void onApplicationEvent(@Nonnull ApplicationStartedEvent event) {
initializeCache();
}

/**
* Initialize the cache of available versions of OpenTofu.
*/
@PostConstruct
public void initializeCache() {
private void initializeCache() {
log.info("Initializing OpenTofu versions cache.");
Set<String> versions = versionsCache.getAvailableVersions();
log.info("Initialized OpenTofu versions cache with versions:{}.", versions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
package org.eclipse.xpanse.tofu.maker.opentofu.tool;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
Expand All @@ -20,8 +24,11 @@
import org.kohsuke.github.PagedIterable;
import org.kohsuke.github.connector.GitHubConnectorResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.support.RetrySynchronizationManager;
import org.springframework.stereotype.Component;

/**
Expand Down Expand Up @@ -49,28 +56,56 @@ public class OpenTofuVersionsFetcher {
maxAttemptsExpression = "${spring.retry.max-attempts}",
backoff = @Backoff(delayExpression = "${spring.retry.delay-millions}"))
public Set<String> fetchAvailableVersionsFromOpenTofuWebsite() throws Exception {
int retryCount = Objects.isNull(RetrySynchronizationManager.getContext())
? 0 : RetrySynchronizationManager.getContext().getRetryCount();
log.info("Start to fetch available versions from website for OpenTofu."
+ " Retry count: {}", retryCount);
Set<String> allVersions = new HashSet<>();
GitHub gitHub = new GitHubBuilder()
.withEndpoint(openTofuGithubApiEndpoint)
.withRateLimitHandler(getGithubRateLimitHandler())
.build();
GHRepository repository = gitHub.getRepository(openTofuGithubRepository);
PagedIterable<GHTag> tags = repository.listTags();
tags.forEach(tag -> {
String version = tag.getName();
if (OFFICIAL_VERSION_PATTERN.matcher(version).matches()) {
// remove the prefix 'v'
allVersions.add(version.substring(1));
try {
if (!isEndpointReachable(openTofuGithubApiEndpoint)) {
String errorMsg = "OpenTofu website is not reachable.";
log.error(errorMsg);
throw new IOException(errorMsg);
}
});
log.info("Get available versions: {} from OpenTofu website.", allVersions);
GitHub gitHub = new GitHubBuilder()
.withEndpoint(openTofuGithubApiEndpoint)
.withRateLimitHandler(getGithubRateLimitHandler())
.build();
GHRepository repository = gitHub.getRepository(openTofuGithubRepository);
PagedIterable<GHTag> tags = repository.listTags();
tags.forEach(tag -> {
String version = tag.getName();
if (OFFICIAL_VERSION_PATTERN.matcher(version).matches()) {
// remove the prefix 'v'
allVersions.add(version.substring(1));
}
});
} catch (Exception e) {
log.error("Failed to fetch available versions from OpenTofu website. Retry count: {}",
retryCount, e);
throw e;
}
log.info("Get available versions: {} from OpenTofu website. Retry count: {}", allVersions,
retryCount);
if (allVersions.isEmpty()) {
String errorMsg = "No available versions found from OpenTofu website.";
throw new InvalidOpenTofuToolException(errorMsg);
}
return allVersions;
}

private boolean isEndpointReachable(String endpoint) throws IOException {
try {
URL url = URI.create(endpoint).toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.setRequestMethod(HttpMethod.HEAD.name());
return connection.getResponseCode() == HttpStatus.OK.value();
} catch (IOException e) {
throw new IOException("Failed to connect to the endpoint: " + endpoint);
}
}


/**
* Get default versions from config.
Expand Down

0 comments on commit 5e1b1ea

Please sign in to comment.