Skip to content

Commit c743ded

Browse files
authored
feat: auto fetch the latest version of sdk (#23)
* feat: auto fetch the latest version of sdk
1 parent d439548 commit c743ded

3 files changed

Lines changed: 170 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.featureprobe.api.base.config;
2+
3+
import org.springframework.context.annotation.ComponentScan;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.scheduling.annotation.EnableScheduling;
6+
7+
@Configuration
8+
@EnableScheduling
9+
@ComponentScan(basePackageClasses = {
10+
com.featureprobe.api.util.SdkVersionUtil.class,
11+
})
12+
public class ScheduleConfig {
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.featureprobe.api.controller;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.PathVariable;
5+
import org.springframework.web.bind.annotation.RequestMapping;
6+
import org.springframework.web.bind.annotation.RestController;
7+
8+
import com.featureprobe.api.base.doc.DefaultApiResponses;
9+
import com.featureprobe.api.util.SdkVersionUtil;
10+
11+
@RequestMapping("/misc")
12+
@RestController
13+
@DefaultApiResponses
14+
public class MiscController {
15+
16+
@GetMapping("/sdk/{key}")
17+
public String querySdkVersion(@PathVariable("key") String key) {
18+
return String.format("\"%s\"", SdkVersionUtil.latestVersions.get(key));
19+
}
20+
21+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package com.featureprobe.api.util;
2+
3+
import org.apache.commons.lang3.StringUtils;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
import java.util.Objects;
8+
import java.util.concurrent.TimeUnit;
9+
10+
import javax.annotation.PostConstruct;
11+
12+
import org.springframework.scheduling.annotation.Scheduled;
13+
import org.springframework.stereotype.Component;
14+
15+
import com.fasterxml.jackson.databind.JsonNode;
16+
import com.fasterxml.jackson.databind.ObjectMapper;
17+
18+
import lombok.extern.slf4j.Slf4j;
19+
20+
import okhttp3.ConnectionPool;
21+
import okhttp3.OkHttpClient;
22+
import okhttp3.Request;
23+
import okhttp3.Response;
24+
25+
26+
@Slf4j
27+
@Component
28+
public class SdkVersionUtil {
29+
30+
private static final String JAVA_SDK_VERSION = "java_sdk_version";
31+
private static final String RUST_SDK_VERSION = "rust_sdk_version";
32+
private static final String ANDROID_SDK_VERSION = "android_sdk_version";
33+
34+
public static final Map<String, String> latestVersions = new HashMap<>(3);
35+
36+
private static final OkHttpClient httpClient =
37+
new OkHttpClient.Builder().connectionPool(new ConnectionPool()).callTimeout(10, TimeUnit.SECONDS)
38+
.retryOnConnectionFailure(true).build();
39+
40+
private static final ObjectMapper mapper = new ObjectMapper();
41+
42+
@Scheduled(cron = "0 0 0 * * ?") // every day at 0:00
43+
@PostConstruct
44+
public void fetchLatestJavaSdkVersion() {
45+
String latestVersion = getSdkVersionFromSearchMavenOrg("server-sdk-java");
46+
if (StringUtils.isBlank(latestVersion)) {
47+
latestVersion = getSdkVersionFromDeveloperAliyunCom("server-sdk-java");
48+
}
49+
latestVersions.put(JAVA_SDK_VERSION, latestVersion);
50+
}
51+
52+
@Scheduled(cron = "0 1 0 * * ?") // every day at 0:01
53+
@PostConstruct
54+
public void fetchLatestAndroidSdkVersion() {
55+
String latestVersion = getSdkVersionFromSearchMavenOrg("client-sdk-android");
56+
if (StringUtils.isBlank(latestVersion)) {
57+
latestVersion = getSdkVersionFromDeveloperAliyunCom("client-sdk-android");
58+
}
59+
latestVersions.put(ANDROID_SDK_VERSION, latestVersion);
60+
}
61+
62+
@Scheduled(cron = "0 2 0 * * ?") // every day at 0:02
63+
@PostConstruct
64+
public void fetchLatestRustSdkVersion() {
65+
String latestVersion = getRustSdkVersionFromCratesIo();
66+
latestVersions.put(RUST_SDK_VERSION, latestVersion);
67+
}
68+
69+
private String getRustSdkVersionFromCratesIo() {
70+
Request request =
71+
new Request.Builder()
72+
.url("https://crates.io/api/v1/crates/feature-probe-server-sdk")
73+
.get()
74+
.build();
75+
76+
String latestVersion = null;
77+
try (Response resp = httpClient.newCall(request).execute()) {
78+
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
79+
latestVersion = respRoot
80+
.path("crate")
81+
.path("max_stable_version")
82+
.asText();
83+
log.info("Query version info of 'server-sdk-rust' from 'crates.io': latest version {}", latestVersion);
84+
} catch (Exception e) {
85+
log.warn("Fail to fetch latest sdk version from 'crates.io'", e);
86+
}
87+
return latestVersion;
88+
}
89+
90+
91+
private String getSdkVersionFromSearchMavenOrg(String artifact) {
92+
Request request = new Request.Builder()
93+
.url("https://search.maven.org/solrsearch/select?q=com.featureprobe." + artifact)
94+
.get()
95+
.build();
96+
97+
String latestVersion = null;
98+
try (Response resp = httpClient.newCall(request).execute()) {
99+
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
100+
latestVersion = respRoot
101+
.path("response")
102+
.path("docs")
103+
.path(0)
104+
.path("latestVersion")
105+
.asText();
106+
log.info("Query version info of '{}' from 'search.maven.org': latest version {}", artifact, latestVersion);
107+
} catch (Exception e) {
108+
log.warn("Fail to fetch latest sdk version from 'search.maven.org'", e);
109+
}
110+
return latestVersion;
111+
}
112+
113+
private String getSdkVersionFromDeveloperAliyunCom(String artifact) {
114+
Request request = new Request.Builder()
115+
.url("https://developer.aliyun.com/artifact/aliyunMaven/searchArtifactByGav" +
116+
"?groupId=com.featureprobe&version=&repoId=central&artifactId=" + artifact)
117+
.get()
118+
.build();
119+
120+
String latestVersion = null;
121+
try (Response resp = httpClient.newCall(request).execute()) {
122+
JsonNode respRoot = mapper.readTree(Objects.requireNonNull(resp.body()).byteStream());
123+
latestVersion = respRoot
124+
.path("object")
125+
.path(0)
126+
.path("version")
127+
.asText();
128+
log.info("Query version info of '{}' from 'developer.aliyun.com': latest version {}", artifact,
129+
latestVersion);
130+
} catch (Exception e) {
131+
log.warn("Fail to fetch latest sdk version from 'developer.aliyun.com'", e);
132+
}
133+
return latestVersion;
134+
}
135+
136+
}

0 commit comments

Comments
 (0)