SdkVersionScheduler.java
package io.featureprobe.api.component;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class SdkVersionScheduler {
private static final String JAVA_SDK_VERSION = "java_sdk_version";
private static final String RUST_SDK_VERSION = "rust_sdk_version";
private static final String ANDROID_SDK_VERSION = "android_sdk_version";
public static final Map<String, String> latestVersions = new HashMap<>(3);
private static final OkHttpClient httpClient =
new OkHttpClient.Builder().connectionPool(new ConnectionPool()).callTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true).build();
private static final ObjectMapper mapper = new ObjectMapper();
@Scheduled(cron = "0 0 0 * * ?") // every day at 0:00
@EventListener(ApplicationReadyEvent.class)
public void fetchLatestJavaSdkVersion() {
String latestVersion = getSdkVersionFromSearchMavenOrg("server-sdk-java");
if (StringUtils.isBlank(latestVersion)) {
latestVersion = getSdkVersionFromDeveloperAliyunCom("server-sdk-java");
}
latestVersions.put(JAVA_SDK_VERSION, latestVersion);
}
@Scheduled(cron = "0 1 0 * * ?") // every day at 0:01
@EventListener(ApplicationReadyEvent.class)
public void fetchLatestAndroidSdkVersion() {
String latestVersion = getSdkVersionFromSearchMavenOrg("client-sdk-android");
if (StringUtils.isBlank(latestVersion)) {
latestVersion = getSdkVersionFromDeveloperAliyunCom("client-sdk-android");
}
latestVersions.put(ANDROID_SDK_VERSION, latestVersion);
}
@Scheduled(cron = "0 2 0 * * ?") // every day at 0:02
@EventListener(ApplicationReadyEvent.class)
public void fetchLatestRustSdkVersion() {
String latestVersion = getRustSdkVersionFromCratesIo();
latestVersions.put(RUST_SDK_VERSION, latestVersion);
}
private String getRustSdkVersionFromCratesIo() {
Request request =
new Request.Builder()
.url("https://crates.io/api/v1/crates/feature-probe-server-sdk")
.get()
.build();
String latestVersion = null;
try (Response resp = httpClient.newCall(request).execute()) {
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
latestVersion = respRoot
.path("crate")
.path("max_stable_version")
.asText();
log.info("Query version info of 'server-sdk-rust' from 'crates.io': latest version {}", latestVersion);
} catch (Exception e) {
log.warn("Fail to fetch latest sdk version from 'crates.io'", e);
}
return latestVersion;
}
private String getSdkVersionFromSearchMavenOrg(String artifact) {
Request request = new Request.Builder()
.url("https://search.maven.org/solrsearch/select?q=com.featureprobe." + artifact)
.get()
.build();
String latestVersion = null;
try (Response resp = httpClient.newCall(request).execute()) {
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
latestVersion = respRoot
.path("response")
.path("docs")
.path(0)
.path("latestVersion")
.asText();
log.info("Query version info of '{}' from 'search.maven.org': latest version {}", artifact, latestVersion);
} catch (Exception e) {
log.warn("Fail to fetch latest sdk version from 'search.maven.org'", e);
}
return latestVersion;
}
private String getSdkVersionFromDeveloperAliyunCom(String artifact) {
Request request = new Request.Builder()
.url("https://developer.aliyun.com/artifact/aliyunMaven/searchArtifactByGav" +
"?groupId=com.featureprobe&version=&repoId=central&artifactId=" + artifact)
.get()
.build();
String latestVersion = null;
try (Response resp = httpClient.newCall(request).execute()) {
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
latestVersion = respRoot
.path("object")
.path(0)
.path("version")
.asText();
log.info("Query version info of '{}' from 'developer.aliyun.com': latest version {}", artifact,
latestVersion);
} catch (Exception e) {
log.warn("Fail to fetch latest sdk version from 'developer.aliyun.com'", e);
}
return latestVersion;
}
}