From d95ee63dca5fb2988dfa3056639aab3232c3ac97 Mon Sep 17 00:00:00 2001 From: Mark Gunlogson <31893232+noobgramming@users.noreply.github.com> Date: Thu, 7 Aug 2025 10:55:47 -0500 Subject: [PATCH] AUT-5442 custom user-agent, fix flakey tests --- auto-sdk-java-common/pom.xml | 2 +- .../auto/versioning/SdkVersionReader.java | 72 ++++++++++++ auto-sdk-java-config/pom.xml | 2 +- auto-sdk-java-cucumber/pom.xml | 2 +- auto-sdk-java-framework/pom.xml | 2 +- .../auto/framework/keepalive/KeepAlive.java | 40 +++++-- .../KeepAliveTest.java} | 110 +++++++++++++----- auto-sdk-java-helpers/pom.xml | 2 +- auto-sdk-java-integrations/pom.xml | 2 +- auto-sdk-java-page-object/pom.xml | 2 +- auto-sdk-java-reporting/pom.xml | 2 +- ...ionReader.java => SdkVersionVerifier.java} | 52 ++++----- .../auto/reporting/SessionInitializer.java | 2 +- auto-sdk-java-rest-clients/pom.xml | 2 +- .../auto/util/CommonOkhttpInterceptor.java | 22 ++++ .../ApplausePublicApiClient.java | 1 + .../auto/util/autoapi/AutoApiClient.java | 1 + auto-sdk-java-testng/pom.xml | 2 +- pom.xml | 2 +- 19 files changed, 242 insertions(+), 80 deletions(-) create mode 100644 auto-sdk-java-common/src/main/java/com/applause/auto/versioning/SdkVersionReader.java rename auto-sdk-java-framework/src/test/java/com/applause/auto/framework/{KeepAliveHelperTest.java => keepalive/KeepAliveTest.java} (54%) rename auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/{SdkVersionReader.java => SdkVersionVerifier.java} (57%) diff --git a/auto-sdk-java-common/pom.xml b/auto-sdk-java-common/pom.xml index 5fb4815..4ae59fa 100644 --- a/auto-sdk-java-common/pom.xml +++ b/auto-sdk-java-common/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-common diff --git a/auto-sdk-java-common/src/main/java/com/applause/auto/versioning/SdkVersionReader.java b/auto-sdk-java-common/src/main/java/com/applause/auto/versioning/SdkVersionReader.java new file mode 100644 index 0000000..bb02bfa --- /dev/null +++ b/auto-sdk-java-common/src/main/java/com/applause/auto/versioning/SdkVersionReader.java @@ -0,0 +1,72 @@ +/* + * + * Copyright © 2024 Applause App Quality, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.applause.auto.versioning; + +import com.google.common.base.Suppliers; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.function.Supplier; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** Util class to read the SDK version from the VERSION.txt file that we package inside the pom */ +public final class SdkVersionReader { + + private static final String SDK_VERSION_FILE_NAME = "VERSION.txt"; + private static final Logger logger = LogManager.getLogger(); + + /** Supplies the raw SDK Version from the file */ + private static final Supplier rawVersionSupplier = + Suppliers.memoize(SdkVersionReader::loadSdkVersionFromFile); + + private SdkVersionReader() { // utility class + } + + /** + * Gets the raw SDK Version from the packaged file without performing any network validation. + * + * @return The raw SDK Version String, or null if it cannot be read. + */ + public static String getSdkVersion() { + return rawVersionSupplier.get(); + } + + /** + * Performs the file I/O to read the version from the classpath. + * + * @return The version string from the file. + */ + private static String loadSdkVersionFromFile() { + try (InputStream fileUrl = + Thread.currentThread().getContextClassLoader().getResourceAsStream(SDK_VERSION_FILE_NAME)) { + if (fileUrl == null) { + logger.error( + "Could not read current Applause Automation SDK version from classpath. Version file not found"); + throw new RuntimeException( + "Could not read current Applause Automation SDK version from classpath. Version file not found"); + } + return IOUtils.toString(fileUrl, StandardCharsets.UTF_8).trim(); + } catch (IOException e) { + logger.fatal("Could not read current Applause Automation SDK version from classpath", e); + throw new RuntimeException( + "Could not read current Applause Automation SDK version from classpath", e); + } + } +} diff --git a/auto-sdk-java-config/pom.xml b/auto-sdk-java-config/pom.xml index c49adb1..a582a9a 100644 --- a/auto-sdk-java-config/pom.xml +++ b/auto-sdk-java-config/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-config diff --git a/auto-sdk-java-cucumber/pom.xml b/auto-sdk-java-cucumber/pom.xml index 656e787..9ea9c1a 100644 --- a/auto-sdk-java-cucumber/pom.xml +++ b/auto-sdk-java-cucumber/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-cucumber diff --git a/auto-sdk-java-framework/pom.xml b/auto-sdk-java-framework/pom.xml index 69e2604..746fd3d 100644 --- a/auto-sdk-java-framework/pom.xml +++ b/auto-sdk-java-framework/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-framework diff --git a/auto-sdk-java-framework/src/main/java/com/applause/auto/framework/keepalive/KeepAlive.java b/auto-sdk-java-framework/src/main/java/com/applause/auto/framework/keepalive/KeepAlive.java index caa3df4..a029da6 100644 --- a/auto-sdk-java-framework/src/main/java/com/applause/auto/framework/keepalive/KeepAlive.java +++ b/auto-sdk-java-framework/src/main/java/com/applause/auto/framework/keepalive/KeepAlive.java @@ -30,6 +30,7 @@ import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.function.Supplier; +import javax.annotation.Nullable; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.extern.log4j.Log4j2; @@ -45,6 +46,7 @@ public class KeepAlive { private Consumer using = WebDriver::getCurrentUrl; private Duration every = Duration.ofSeconds(5); private Duration maxWait = Duration.ofMinutes(20); + @Nullable private ScheduledExecutorService executor; /** * Sets the drivers. Accepts a maximum of 10 drivers @@ -95,6 +97,18 @@ public KeepAlive withMaxWait(final @NonNull Duration maxWaitDuration) { return this; } + /** + * Provides an external ScheduledExecutorService. If provided, the KeepAlive class will not manage + * the lifecycle (i.e., it will not shut down the executor). + * + * @param providedExecutor The executor to use. + * @return The keep alive + */ + public KeepAlive withExecutor(final ScheduledExecutorService providedExecutor) { + this.executor = providedExecutor; + return this; + } + /** * Polls the keep alive while the provided supplier executes. * @@ -109,11 +123,14 @@ public T executeWhile(final @NonNull Supplier whileFunction) throws ExecutionException, InterruptedException { // Since we shut this down every time it is called, set up a new one each time we call this // function - final ScheduledExecutorService keepAliveExecutors = - new ScheduledThreadPoolExecutor(Math.min(this.keepAliveDrivers.size(), MAX_DRIVERS)); + final boolean isExecutorOwned = this.executor == null; + final ScheduledExecutorService executorToUse = + isExecutorOwned + ? new ScheduledThreadPoolExecutor(Math.min(this.keepAliveDrivers.size(), MAX_DRIVERS)) + : this.executor; // Start the keep alive threads - this.keepAliveDrivers.forEach(driver -> this.setupKeepAlive(driver, keepAliveExecutors)); + this.keepAliveDrivers.forEach(driver -> this.setupKeepAlive(driver, executorToUse)); // Run the execution function final var executionFuture = this.setupExecutorThread(whileFunction); @@ -121,15 +138,14 @@ public T executeWhile(final @NonNull Supplier whileFunction) // Wait for the execution to finish with a max wait of x milliseconds return executionFuture.get(maxWait.toMillis(), TimeUnit.MILLISECONDS); } catch (TimeoutException e) { - // If the function takes too long, then we should inform the user and cancel keep alive - // threads - // This will keep executing the main execution, but stop the keep alive. We can accomplish - // this - // by shutting down the keepAliveExecutors + // If the function takes too long, then we should inform the user. + // If we own the executor, we shut it down to stop the keep-alive threads. log.warn( "While function timed out after {} milliseconds. Ending keep alive threads", maxWait.toMillis()); - keepAliveExecutors.shutdown(); + if (isExecutorOwned) { + executorToUse.shutdown(); + } return executionFuture.get(); } catch (ExecutionException e) { // If an exception or error happens during execution, the CompletableFuture throws an @@ -145,8 +161,10 @@ public T executeWhile(final @NonNull Supplier whileFunction) } throw e; } finally { - // This is a no-op if we already shut it down - keepAliveExecutors.shutdown(); + // Only shut down the executor if this class created it. + if (isExecutorOwned) { + executorToUse.shutdown(); + } } } diff --git a/auto-sdk-java-framework/src/test/java/com/applause/auto/framework/KeepAliveHelperTest.java b/auto-sdk-java-framework/src/test/java/com/applause/auto/framework/keepalive/KeepAliveTest.java similarity index 54% rename from auto-sdk-java-framework/src/test/java/com/applause/auto/framework/KeepAliveHelperTest.java rename to auto-sdk-java-framework/src/test/java/com/applause/auto/framework/keepalive/KeepAliveTest.java index de00dfa..91648bb 100644 --- a/auto-sdk-java-framework/src/test/java/com/applause/auto/framework/KeepAliveHelperTest.java +++ b/auto-sdk-java-framework/src/test/java/com/applause/auto/framework/keepalive/KeepAliveTest.java @@ -15,22 +15,29 @@ * limitations under the License. * */ -package com.applause.auto.framework; +package com.applause.auto.framework.keepalive; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.applause.auto.framework.keepalive.KeepAlive; import java.time.Duration; +import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.mockito.ArgumentCaptor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Test; -public class KeepAliveHelperTest { +public class KeepAliveTest { public WebDriver setupDriver() { final var mockDriver = mock(FirefoxDriver.class); @@ -43,19 +50,32 @@ public WebDriver setupDriver() { @Test public void testKeepAlive() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); + final var runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + + // Use the new public API to inject the mock executor new KeepAlive() .forDrivers(mockDriver) .pollingEvery(Duration.ofSeconds(1)) - .executeWhile( - () -> { - try { - Thread.sleep(5000); - } catch (InterruptedException ignored) { - } - mockDriver.getTitle(); - }); + .withExecutor(mockExecutor) + .executeWhile(mockDriver::getTitle); + + // Verify that the keep-alive task was scheduled + verify(mockExecutor) + .scheduleAtFixedRate( + runnableCaptor.capture(), eq(0L), eq(1000L), eq(TimeUnit.MILLISECONDS)); + + // Manually run the captured keep-alive task to simulate execution over time + final Runnable keepAliveTask = runnableCaptor.getValue(); + for (int i = 0; i < 6; i++) { + keepAliveTask.run(); + } + + // Verify the results verify(mockDriver, times(6)).getCurrentUrl(); verify(mockDriver, times(1)).getTitle(); + // Verify the injected executor was NOT shut down + verify(mockExecutor, never()).shutdown(); mockDriver.quit(); } @@ -64,9 +84,11 @@ public void testKeepAlive() throws InterruptedException, ExecutionException { expectedExceptionsMessageRegExp = "This Should Propagate as a Runtime Exception") public void testKeepAliveErrorPropagation() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); new KeepAlive() .forDrivers(mockDriver) .pollingEvery(Duration.ofSeconds(1)) + .withExecutor(mockExecutor) .executeWhile( () -> { throw new RuntimeException("This Should Propagate as a Runtime Exception"); @@ -78,9 +100,11 @@ public void testKeepAliveErrorPropagation() throws InterruptedException, Executi public void testKeepAliveAssertionFailurePropagation() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); new KeepAlive() .forDrivers(mockDriver) .pollingEvery(Duration.ofSeconds(1)) + .withExecutor(mockExecutor) .executeWhile(() -> Assert.fail("This Should Propagate to the main thread")); } @@ -88,52 +112,86 @@ public void testKeepAliveAssertionFailurePropagation() public void testMultiDriverKeepAlive() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); final WebDriver mockDriver2 = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); + final var runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + new KeepAlive() .forDrivers(mockDriver, mockDriver2) .pollingEvery(Duration.ofSeconds(1)) - .executeWhile( - () -> { - try { - Thread.sleep(5100); - mockDriver.getTitle(); - } catch (InterruptedException ignored) { - } - }); + .withExecutor(mockExecutor) + .executeWhile(mockDriver::getTitle); + + // Verify that keep-alive tasks were scheduled for both drivers + verify(mockExecutor, times(2)) + .scheduleAtFixedRate( + runnableCaptor.capture(), eq(0L), eq(1000L), eq(TimeUnit.MILLISECONDS)); + + // Manually run the captured tasks + final List keepAliveTasks = runnableCaptor.getAllValues(); + for (final Runnable task : keepAliveTasks) { + for (int i = 0; i < 6; i++) { + task.run(); + } + } + + // Verify results for both drivers verify(mockDriver, times(6)).getCurrentUrl(); verify(mockDriver2, times(6)).getCurrentUrl(); verify(mockDriver, times(1)).getTitle(); + // Verify the injected executor was NOT shut down + verify(mockExecutor, never()).shutdown(); mockDriver.quit(); } @Test public void testCustomKeepAlive() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); + final var runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + new KeepAlive() .forDrivers(mockDriver) .pollingEvery(Duration.ofSeconds(1)) .usingKeepAlive(WebDriver::getTitle) - .executeWhile( - () -> { - try { - Thread.sleep(5100); - } catch (InterruptedException ignored) { - } - }); + .withExecutor(mockExecutor) + .executeWhile(() -> {}); // Empty runnable + + // Verify that the custom keep-alive task was scheduled + verify(mockExecutor) + .scheduleAtFixedRate( + runnableCaptor.capture(), eq(0L), eq(1000L), eq(TimeUnit.MILLISECONDS)); + + // Manually run the captured keep-alive task + final Runnable keepAliveTask = runnableCaptor.getValue(); + for (int i = 0; i < 6; i++) { + keepAliveTask.run(); + } + + // Verify the results verify(mockDriver, times(0)).getCurrentUrl(); verify(mockDriver, times(6)).getTitle(); + // Verify the injected executor was NOT shut down + verify(mockExecutor, never()).shutdown(); mockDriver.quit(); } @Test public void testKeepAliveSupplier() throws InterruptedException, ExecutionException { final WebDriver mockDriver = setupDriver(); + final var mockExecutor = mock(ScheduledExecutorService.class); final String result = new KeepAlive() .forDrivers(mockDriver) .pollingEvery(Duration.ofSeconds(1)) .usingKeepAlive(WebDriver::getTitle) + .withExecutor(mockExecutor) .executeWhile(() -> "Done!"); + Assert.assertEquals(result, "Done!"); + // Verify a keep-alive task was scheduled + verify(mockExecutor).scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any()); + // Verify the injected executor was NOT shut down + verify(mockExecutor, never()).shutdown(); mockDriver.quit(); } } diff --git a/auto-sdk-java-helpers/pom.xml b/auto-sdk-java-helpers/pom.xml index 0d992aa..9918429 100644 --- a/auto-sdk-java-helpers/pom.xml +++ b/auto-sdk-java-helpers/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-helpers diff --git a/auto-sdk-java-integrations/pom.xml b/auto-sdk-java-integrations/pom.xml index d6f70b7..4257b0e 100644 --- a/auto-sdk-java-integrations/pom.xml +++ b/auto-sdk-java-integrations/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-integrations diff --git a/auto-sdk-java-page-object/pom.xml b/auto-sdk-java-page-object/pom.xml index 3876d4d..1fb6310 100644 --- a/auto-sdk-java-page-object/pom.xml +++ b/auto-sdk-java-page-object/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-page-object diff --git a/auto-sdk-java-reporting/pom.xml b/auto-sdk-java-reporting/pom.xml index 8a1e6a0..d6b92ed 100644 --- a/auto-sdk-java-reporting/pom.xml +++ b/auto-sdk-java-reporting/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-reporting diff --git a/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionReader.java b/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionVerifier.java similarity index 57% rename from auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionReader.java rename to auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionVerifier.java index 8467432..46ae105 100644 --- a/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionReader.java +++ b/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SdkVersionVerifier.java @@ -18,48 +18,53 @@ package com.applause.auto.reporting; import com.applause.auto.util.autoapi.AutoApi; +import com.applause.auto.versioning.SdkVersionReader; import com.google.common.base.Suppliers; import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; import java.util.function.Supplier; import lombok.AllArgsConstructor; import lombok.NonNull; -import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import retrofit2.Response; -/** Util class to read the SDK version from the VERSION.txt file that we package inside the pom */ +/** A utility class to verify the SDK version against the Applause backend */ @AllArgsConstructor -public final class SdkVersionReader { +public final class SdkVersionVerifier { - // util class - private static final String SDK_VERSION_FILE_NAME = "VERSION.txt"; - private static final Logger logger = LogManager.getLogger(SdkVersionReader.class); + private static final Logger logger = LogManager.getLogger(SdkVersionVerifier.class); private final @NonNull AutoApi autoApi; - private final Supplier loadedVersion = Suppliers.memoize(this::verifySdkVersion); + + /** Supplies the verified SDK Version, performing a network check. */ + private final Supplier verifiedVersionSupplier = + Suppliers.memoize(this::performVerification); /** - * Gets the loaded SDK Version + * Gets the SDK Version and verifies it against the Applause backend. Throws a RuntimeException if + * the version is deprecated or invalid. * - * @return The SDK Version String + * @return The verified SDK Version String */ - public String getSdkVersion() { - return loadedVersion.get(); + public String getVerifiedSdkVersion() { + return verifiedVersionSupplier.get(); } /** - * checks the SDK version using the VERSION.txt file that gets stashed in the JAR by build task + * Performs the network validation of the SDK version. * * @return the sdk version */ - private String verifySdkVersion() { - final var version = loadSdkVersion(); + private String performVerification() { + final var version = SdkVersionReader.getSdkVersion(); + if (version == null) { + throw new RuntimeException("SDK Version could not be read, so it cannot be verified."); + } + Response resp = autoApi.checkDeprecated(version).join(); if (resp.isSuccessful()) { return version; } + String errString; try (var errBody = resp.errorBody()) { errString = errBody != null ? errBody.string() : "null"; @@ -77,19 +82,4 @@ private String verifySdkVersion() { + errString); } } - - private String loadSdkVersion() { - try (InputStream fileUrl = - Thread.currentThread().getContextClassLoader().getResourceAsStream(SDK_VERSION_FILE_NAME)) { - if (fileUrl == null) { - throw new RuntimeException( - "Could not read current Applause Automation SDK version from classpath. Version file not found"); - } - return IOUtils.toString(fileUrl, (Charset) null); - } catch (IOException e) { - logger.fatal("Could not read current Applause Automation SDK version from classpath", e); - throw new RuntimeException( - "Could not read current Applause Automation SDK version from classpath", e); - } - } } diff --git a/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SessionInitializer.java b/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SessionInitializer.java index bb94744..dc5ab69 100644 --- a/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SessionInitializer.java +++ b/auto-sdk-java-reporting/src/main/java/com/applause/auto/reporting/SessionInitializer.java @@ -47,7 +47,7 @@ public class SessionInitializer implements ISessionInitializer { public IApplauseReporter startTestRun(final @NonNull ApplauseRunCreation params) { AutoApi autoApi = AutoApiClient.getClient(config.getAutoApiUrl(), config.getApiKey(), config.getProxy()); - final var sdkVersion = new SdkVersionReader(autoApi).getSdkVersion(); + final var sdkVersion = new SdkVersionVerifier(autoApi).getVerifiedSdkVersion(); TestRunConfigurationParamDto testRunConfigurationParamDto = new TestRunConfigurationParamDto() .setSdkVersion(sdkVersion) diff --git a/auto-sdk-java-rest-clients/pom.xml b/auto-sdk-java-rest-clients/pom.xml index 8bf2282..515ab0b 100644 --- a/auto-sdk-java-rest-clients/pom.xml +++ b/auto-sdk-java-rest-clients/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-rest-clients diff --git a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/CommonOkhttpInterceptor.java b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/CommonOkhttpInterceptor.java index 66647f2..34a9d07 100644 --- a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/CommonOkhttpInterceptor.java +++ b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/CommonOkhttpInterceptor.java @@ -17,6 +17,7 @@ */ package com.applause.auto.util; +import com.applause.auto.versioning.SdkVersionReader; import com.google.common.base.Strings; import java.io.IOException; import java.util.stream.Collectors; @@ -33,6 +34,27 @@ public final class CommonOkhttpInterceptor { private CommonOkhttpInterceptor() {} + /** + * Adds a custom User-Agent header to the request + * + * @param chain The interceptor chain to process + * @return The User-Agent interceptor. + */ + public static Response userAgentChain(final Interceptor.Chain chain) throws IOException { + Request originalRequest = chain.request(); + final String sdkVersion = SdkVersionReader.getSdkVersion(); + + if (Strings.isNullOrEmpty(sdkVersion)) { + // Version not found, proceed without custom user agent + logger.warn("Could not read SDK version; Applause User-Agent header will not be set."); + return chain.proceed(originalRequest); + } + + final String userAgent = "Applause Auto-SDK Java/" + sdkVersion; + Request newRequest = originalRequest.newBuilder().header("User-Agent", userAgent).build(); + return chain.proceed(newRequest); + } + /** * Performs apiKey pre-validation * diff --git a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/applausepublicapi/ApplausePublicApiClient.java b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/applausepublicapi/ApplausePublicApiClient.java index c765fab..b31354e 100644 --- a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/applausepublicapi/ApplausePublicApiClient.java +++ b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/applausepublicapi/ApplausePublicApiClient.java @@ -50,6 +50,7 @@ public static ApplausePublicApi getClient( final String url, final String apiKey, @Nullable final Proxy httpProxy) { OkHttpClient client = new Builder() + .addInterceptor(CommonOkhttpInterceptor::userAgentChain) .addInterceptor(chain -> CommonOkhttpInterceptor.apiKeyAuthChain(chain, apiKey)) .proxy(httpProxy) .connectTimeout(Duration.ofSeconds(60)) // default 10s diff --git a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/autoapi/AutoApiClient.java b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/autoapi/AutoApiClient.java index faf8ac3..6d16397 100644 --- a/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/autoapi/AutoApiClient.java +++ b/auto-sdk-java-rest-clients/src/main/java/com/applause/auto/util/autoapi/AutoApiClient.java @@ -49,6 +49,7 @@ public static AutoApi getClient( // sometimes asset uploads take... forever // ...and sometimes setting up a real device takes even longer. new Builder().readTimeout(20, TimeUnit.MINUTES).writeTimeout(20, TimeUnit.MINUTES); + httpClient.addInterceptor(CommonOkhttpInterceptor::userAgentChain); httpClient.addInterceptor(chain -> CommonOkhttpInterceptor.apiKeyAuthChain(chain, apiKey)); httpClient .addInterceptor(chain -> CommonOkhttpInterceptor.errorHandlerChain(chain, "auto-api")) diff --git a/auto-sdk-java-testng/pom.xml b/auto-sdk-java-testng/pom.xml index 7395ba5..b915954 100644 --- a/auto-sdk-java-testng/pom.xml +++ b/auto-sdk-java-testng/pom.xml @@ -21,7 +21,7 @@ com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT auto-sdk-java-testng diff --git a/pom.xml b/pom.xml index 0847f98..d2b81ed 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 com.applause auto-sdk-java - 6.1.0-SNAPSHOT + 6.1.1-SNAPSHOT pom ${project.artifactId}