diff --git a/pom.xml b/pom.xml index f2d2187..9530796 100644 --- a/pom.xml +++ b/pom.xml @@ -125,6 +125,13 @@ + + src/main/resources + true + + com/volcengine/ark/runtime/sdk-version.properties + + ${project.basedir} META-INF diff --git a/src/main/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptor.java b/src/main/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptor.java index b55f094..a1fc031 100644 --- a/src/main/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptor.java +++ b/src/main/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptor.java @@ -6,7 +6,6 @@ import com.volcengine.ark.runtime.Const; import com.volcengine.ark.runtime.exception.ArkAPIError; import com.volcengine.ark.runtime.exception.ArkHttpException; -import com.volcengine.version.Version; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @@ -52,6 +51,6 @@ private static String getUserAgent() { String jdkInfo = "java-" + System.getProperty("java.version"); String arch = System.getProperty("os.arch"); - return String.format(format, Version.SDK_NAME, Version.SDK_VERSION, jdkInfo, osInfo, arch); + return String.format(format, "ark-runtime-java", SdkVersion.VERSION, jdkInfo, osInfo, arch); } } diff --git a/src/main/java/com/volcengine/ark/runtime/interceptor/SdkVersion.java b/src/main/java/com/volcengine/ark/runtime/interceptor/SdkVersion.java new file mode 100644 index 0000000..cc71193 --- /dev/null +++ b/src/main/java/com/volcengine/ark/runtime/interceptor/SdkVersion.java @@ -0,0 +1,32 @@ +// Copyright (c) 2026 ByteDance Ltd. and/or its affiliates. +// SPDX-License-Identifier: Apache-2.0 + +package com.volcengine.ark.runtime.interceptor; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +final class SdkVersion { + static final String VERSION = loadVersion(); + + private SdkVersion() {} + + private static String loadVersion() { + // Maven filters this resource from project.version and includes it in the JAR. + try (InputStream input = SdkVersion.class.getResourceAsStream( + "/com/volcengine/ark/runtime/sdk-version.properties")) { + if (input != null) { + Properties properties = new Properties(); + properties.load(input); + String version = properties.getProperty("version", "").trim(); + if (!version.isEmpty() && !version.contains("${")) { + return version; + } + } + } catch (IOException ignored) { + // Source-only builds may omit the generated metadata; requests still work. + } + return "unknown"; + } +} diff --git a/src/main/resources/com/volcengine/ark/runtime/sdk-version.properties b/src/main/resources/com/volcengine/ark/runtime/sdk-version.properties new file mode 100644 index 0000000..defbd48 --- /dev/null +++ b/src/main/resources/com/volcengine/ark/runtime/sdk-version.properties @@ -0,0 +1 @@ +version=${project.version} diff --git a/src/test/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptorTest.java b/src/test/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptorTest.java new file mode 100644 index 0000000..0848655 --- /dev/null +++ b/src/test/java/com/volcengine/ark/runtime/interceptor/RequestIdInterceptorTest.java @@ -0,0 +1,63 @@ +// Copyright (c) 2026 ByteDance Ltd. and/or its affiliates. +// SPDX-License-Identifier: Apache-2.0 + +package com.volcengine.ark.runtime.interceptor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.volcengine.ark.runtime.Const; +import java.io.File; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPathFactory; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.junit.Test; + +public class RequestIdInterceptorTest { + @Test + public void outgoingRequestUsesProjectVersionAndPreservesRuntimeSuffix() throws Exception { + Request request = new Request.Builder() + .url("https://example.com/api/v3/chat/completions") + .header("User-Agent", "custom-agent") + .header(Const.CLIENT_REQUEST_HEADER, "provided-request-id") + .build(); + Request outgoing = intercept(request); + String version = XPathFactory.newInstance().newXPath().evaluate("/project/version", + DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("pom.xml"))); + assertTrue(!version.isEmpty()); + assertEquals("ark-runtime-java/" + version + "/(java-" + System.getProperty("java.version") + + ";" + System.getProperty("os.name") + "-" + System.getProperty("os.version") + + ";" + System.getProperty("os.arch") + ")", outgoing.header("User-Agent")); + assertEquals(1, outgoing.headers("User-Agent").size()); + assertEquals("provided-request-id", outgoing.header(Const.CLIENT_REQUEST_HEADER)); + } + + @Test + public void outgoingRequestStillGeneratesClientRequestId() throws Exception { + Request outgoing = intercept(new Request.Builder().url("https://example.com").build()); + assertNotNull(outgoing.header(Const.CLIENT_REQUEST_HEADER)); + assertEquals(34, outgoing.header(Const.CLIENT_REQUEST_HEADER).length()); + assertTrue(outgoing.header("User-Agent").startsWith("ark-runtime-java/")); + } + + private Request intercept(Request request) throws Exception { + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(new RequestIdInterceptor()) + .addInterceptor(chain -> new Response.Builder() + .request(chain.request()) + .protocol(Protocol.HTTP_1_1) + .code(200) + .message("OK") + .body(ResponseBody.create(null, "{}")) + .build()) + .build(); + try (Response response = client.newCall(request).execute()) { + return response.request(); + } + } +}