-
Notifications
You must be signed in to change notification settings - Fork 39
fix: Resolve client version at runtime from pom.xml #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v2
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,21 +13,107 @@ | |
|
|
||
| package com.amazonaws.secretsmanager.caching.cache.internal; | ||
|
|
||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.util.Properties; | ||
|
|
||
| /** | ||
| * This class specifies the versioning system for the AWS SecretsManager caching | ||
| * client. | ||
| * | ||
| * <p> | ||
| * The library version is defined in a single place ({@code pom.xml}) and made | ||
| * available at runtime through the {@code version.properties} classpath resource, | ||
| * whose {@code ${project.version}} placeholder is substituted at build time via | ||
| * Maven resource filtering. This avoids the version drift that occurs when the | ||
| * version has to be maintained in more than one place. | ||
| */ | ||
| public class VersionInfo { | ||
| public final class VersionInfo { | ||
|
|
||
| /** Placeholder returned when the version cannot be resolved at runtime. */ | ||
| public static final String UNKNOWN_VERSION = "unknown"; | ||
|
|
||
| /** Prefix identifying this caching client in the SDK UserAgent header. */ | ||
| public static final String USER_AGENT_PREFIX = "AwsSecretCache/"; | ||
|
|
||
| /** Name of the filtered classpath resource holding the version. */ | ||
| static final String VERSION_RESOURCE = "version.properties"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any risk of name collision? |
||
|
|
||
| /** Properties key under which the version is stored. */ | ||
| static final String VERSION_KEY = "version"; | ||
|
|
||
| /** | ||
| * Library version number | ||
| * Library version number, resolved at runtime from {@code pom.xml} via the | ||
| * filtered {@code version.properties} resource. Falls back to | ||
| * {@link #UNKNOWN_VERSION} when the resource is unavailable. | ||
| */ | ||
| public static final String RELEASE_VERSION = "2.1.0"; | ||
| public static final String RELEASE_VERSION = resolveVersion(); | ||
|
|
||
| /** | ||
| * User agent for AWS Secrets Manager API calls. | ||
| */ | ||
| public static final String USER_AGENT = "AwsSecretCache/" + RELEASE_VERSION; | ||
| public static final String USER_AGENT = USER_AGENT_PREFIX + RELEASE_VERSION; | ||
|
|
||
| private VersionInfo() { | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Resolves the library version from the filtered {@code version.properties} | ||
| * classpath resource. Never throws; returns {@link #UNKNOWN_VERSION} if the | ||
| * resource is missing or unreadable, so that a failure to resolve the version | ||
| * can never break secret retrieval. | ||
| * | ||
| * @return the resolved version, or {@link #UNKNOWN_VERSION}. | ||
| */ | ||
| private static String resolveVersion() { | ||
| return readVersion(VersionInfo.class.getResourceAsStream(VERSION_RESOURCE)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have we tested that this indeed picks up the library's version number and not the top level maven package's version number? Ex: package my-custom-app version 1.0.0 takes a dependency on aws-secretsmanager-caching-java:2.1.0 |
||
| } | ||
|
|
||
| /** | ||
| * Parses the {@code version} property from the given stream, closing the | ||
| * stream before returning. | ||
| * | ||
| * @param in the properties stream (may be {@code null}); this method takes | ||
| * ownership and closes it. | ||
| * @return the version value, or {@link #UNKNOWN_VERSION} when the stream is | ||
| * {@code null}, unreadable, missing the key, blank, or still contains | ||
| * an unsubstituted Maven placeholder. | ||
| */ | ||
| public static String readVersion(final InputStream in) { | ||
| if (in == null) { | ||
| return UNKNOWN_VERSION; | ||
| } | ||
| try (InputStream stream = in) { | ||
| Properties properties = new Properties(); | ||
| properties.load(stream); | ||
| String version = properties.getProperty(VERSION_KEY); | ||
| if (version == null) { | ||
| return UNKNOWN_VERSION; | ||
| } | ||
| version = version.trim(); | ||
| if (version.isEmpty() || version.contains("${")) { | ||
| return UNKNOWN_VERSION; | ||
| } | ||
| return version; | ||
| } catch (IOException e) { | ||
| return UNKNOWN_VERSION; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Builds the UserAgent suffix for the caching client, preserving any suffix a | ||
| * caller has already configured. When a caller suffix is present, the caching | ||
| * identifier is appended to it ({@code "<caller> AwsSecretCache/<version>"}); | ||
| * otherwise the caching identifier is returned on its own. | ||
| * | ||
| * @param callerSuffix the caller-provided UserAgent suffix (may be {@code null} | ||
| * or blank). | ||
| * @return the combined UserAgent suffix. | ||
| */ | ||
| public static String userAgentSuffix(final String callerSuffix) { | ||
| if (callerSuffix == null || callerSuffix.trim().isEmpty()) { | ||
| return USER_AGENT; | ||
| } | ||
| return callerSuffix + " " + USER_AGENT; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| version=${project.version} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not saying you have to do this but as an alternative we could have a github action whose job is to fetch the latest version number from maven and open a PR to update the readme.