diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 223707b1e..408ef3987 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = False -current_version = v7.7.0 +current_version = v7.8.0 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P[a-z]+)(?P\d+))? serialize = {major}.{minor}.{patch}-{release}{build} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 899813a38..14988274b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,19 @@ on: - main pull_request: +permissions: + actions: write + checks: write + contents: read + deployments: read + issues: write + discussions: write + packages: none + pages: write + pull-requests: write + security-events: write + statuses: write + jobs: build: runs-on: ${{ matrix.os }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 05909e3b1..4e9583404 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,6 +2,20 @@ name: Publish to Nexus on: release: types: [published] + +permissions: + actions: write + checks: write + contents: write + deployments: read + issues: write + discussions: write + packages: write + pages: write + pull-requests: write + security-events: write + statuses: write + jobs: build: runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aba9e4ee..9ff391fc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +# [7.8.0] - 2023-09-07 +- Added capability to configure request timeouts (default is 60 seconds) +- Deprecated custom HTTP client implementation setting +- Internal refactoring of Numbers, Conversion and Number Insight implementations + # [7.7.0] - 2023-08-10 - Added Users API implementation - Major refactoring of how endpoints are implemented internally diff --git a/README.md b/README.md index 0c4571b1a..1222ec356 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,9 @@ See all of our SDKs and integrations on the [Vonage Developer portal](https://de ## Installation -Releases are published to [Maven Central](https://central.sonatype.com/artifact/com.vonage/client/7.7.0/snippets). +Releases are published to [Maven Central](https://central.sonatype.com/artifact/com.vonage/client/7.8.0/snippets). Instructions for your build system can be found in the snippets section. -They're also available from [here](https://mvnrepository.com/artifact/com.vonage/client/7.7.0). +They're also available from [here](https://mvnrepository.com/artifact/com.vonage/client/7.8.0). Release notes can be found in the [changelog](CHANGELOG.md). ### Build It Yourself @@ -85,65 +85,63 @@ to your project's classpath. ## Configuration -### Customize the Base URI -By default, the client will use https://api.nexmo.com, https://rest.nexmo.com, https://sns.nexmo.com and https://api-eu.vonage.com as base URIs for the various endpoints. To customize these you can instantiate `VonageClient` with an `HttpConfig` object. - -`HttpConfig.Builder` has been created to assist in building this object. Usage is as follows: +## Typical Instantiation +For default configuration, you just need to specify your Vonage account credentials using API key and secret, private +key and application ID or both. For maximum compatibility with all APIs, it is recommended that you specify both +authentication methods, like so: ```java -HttpConfig httpConfig = HttpConfig.builder() - .apiBaseUri("https://api.example.com") - .restBaseUri("https://rest.example.com") - .snsBaseUri("https://sns.example.com") - .apiEuBaseUri("https://api-eu.example.com") - .build(); - VonageClient client = VonageClient.builder() + .applicationId(APPLICATION_ID) + .privateKeyPath(PRIVATE_KEY_PATH) .apiKey(API_KEY) .apiSecret(API_SECRET) - .httpConfig(httpConfig) .build(); ``` -If you do not specify a property, it will take on whatever the default value is. You can also set all three with a single method: +### Customize the Base URI +By default, the client will use https://api.nexmo.com, https://rest.nexmo.com, https://sns.nexmo.com and https://api-eu.vonage.com as base URIs for the various endpoints. To customize these you can instantiate `VonageClient` with an `HttpConfig` object. + +`HttpConfig.Builder` has been created to assist in building this object. Usage is as follows: ```java -HttpConfig httpConfig = HttpConfig.builder().baseUri("http://example.com").build(); +HttpConfig httpConfig = HttpConfig.builder() + .apiBaseUri("https://api.example.com") + .restBaseUri("https://rest.example.com") + .snsBaseUri("https://sns.example.com") + .apiEuBaseUri("https://api-eu.example.com") + .build(); VonageClient client = VonageClient.builder() - .apiKey(API_KEY) - .apiSecret(API_SECRET) + .apiKey(API_KEY).apiSecret(API_SECRET) .httpConfig(httpConfig) .build(); ``` -To keep the default values, you can use `HttpConfig.defaultConfig()`: +If you do not specify a property, it will take on whatever the default value is. You can also set all three with a single method: ```java -HttpConfig httpConfig = HttpConfig.defaultConfig(); +HttpConfig httpConfig = HttpConfig.builder().baseUri("http://example.com").build(); VonageClient client = VonageClient.builder() - .apiKey(API_KEY) - .apiSecret(API_SECRET) + .apiKey(API_KEY).apiSecret(API_SECRET) .httpConfig(httpConfig) .build(); ``` -You can also instantiate without the parameter: +### Custom Timeout + +By default, the SDK has a 1-minute timeout for requests. +You can change this to be longer or shorter using `HttpConfig`. The following example sets this to 12 seconds: ```java VonageClient client = VonageClient.builder() - .apiKey(API_KEY) - .apiSecret(API_SECRET) + .applicationId(APPLICATION_ID) + .privateKeyPath(PRIVATE_KEY_PATH) + .httpConfig(HttpConfig.builder().timeoutMillis(12_000).build()) .build(); ``` -### Custom HTTP Configuration - -If you need to configure the Apache HttpClient used for making requests, you can -call `VonageClient.Builder.httpClient()` to supply your custom configured object. This -can be useful, for example, if you must use an HTTP proxy to make requests or to configure SSL Certificates. - ## Frequently Asked Questions **Q: What is your policy on thread safety?** diff --git a/build.gradle b/build.gradle index 73cb95e66..54d990ca1 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { group = "com.vonage" archivesBaseName = "client" -version = "7.7.0" +version = "7.8.0" sourceCompatibility = "1.8" targetCompatibility = "1.8" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17a8ddce2..c30b486a8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/vonage/client/HttpConfig.java b/src/main/java/com/vonage/client/HttpConfig.java index 2fd6c6aef..66bac8bf6 100644 --- a/src/main/java/com/vonage/client/HttpConfig.java +++ b/src/main/java/com/vonage/client/HttpConfig.java @@ -22,15 +22,29 @@ public class HttpConfig { DEFAULT_SNS_BASE_URI = "https://sns.nexmo.com", DEFAULT_API_EU_BASE_URI = "https://api-eu.vonage.com"; + private final int timeoutMillis; private final String apiBaseUri, restBaseUri, snsBaseUri, apiEuBaseUri; private HttpConfig(Builder builder) { + if ((timeoutMillis = builder.timeoutMillis) < 10) { + throw new IllegalArgumentException("Timeout must be greater than 10ms."); + } apiBaseUri = builder.apiBaseUri; restBaseUri = builder.restBaseUri; snsBaseUri = builder.snsBaseUri; apiEuBaseUri = builder.apiEuBaseUri; } + /** + * Gets the timeout setting for the underlying HTTP client configuration. + * + * @return The request timeout in milliseconds. + * @since 7.8.0 + */ + public int getTimeoutMillis() { + return timeoutMillis; + } + public String getApiBaseUri() { return apiBaseUri; } @@ -95,12 +109,31 @@ public static Builder builder() { } public static class Builder { + private int timeoutMillis = 60_000; private String apiBaseUri = DEFAULT_API_BASE_URI, restBaseUri = DEFAULT_REST_BASE_URI, snsBaseUri = DEFAULT_SNS_BASE_URI, apiEuBaseUri = DEFAULT_API_EU_BASE_URI; + /** + * Sets the socket timeout for requests. By default, this is one minute (60000 ms). + *
+ * Note that this timeout applies to both the connection and socket; therefore, it defines + * the maximum time for each stage of the request. For example, if set to 30 seconds, then + * establishing a connection may take 29 seconds and receiving a response may take 29 seconds + * without timing out (therefore a total of 58 seconds for the request). + * + * @param timeoutMillis The timeout in milliseconds. + * + * @return The Builder to keep building. + * @since 7.8.0 + */ + public Builder timeoutMillis(int timeoutMillis) { + this.timeoutMillis = timeoutMillis; + return this; + } + /** * @param apiBaseUri The base uri to use in place of {@link HttpConfig#DEFAULT_API_BASE_URI} * @@ -166,7 +199,6 @@ private String sanitizeUri(String uri) { if (uri != null && uri.endsWith("/")) { return uri.substring(0, uri.length() - 1); } - return uri; } } diff --git a/src/main/java/com/vonage/client/HttpWrapper.java b/src/main/java/com/vonage/client/HttpWrapper.java index 9ea039d0b..1d3bc8bb6 100644 --- a/src/main/java/com/vonage/client/HttpWrapper.java +++ b/src/main/java/com/vonage/client/HttpWrapper.java @@ -30,7 +30,7 @@ */ public class HttpWrapper { private static final String CLIENT_NAME = "vonage-java-sdk"; - private static final String CLIENT_VERSION = "7.7.0"; + private static final String CLIENT_VERSION = "7.8.0"; private static final String JAVA_VERSION = System.getProperty("java.version"); private static final String USER_AGENT = String.format("%s/%s java/%s", CLIENT_NAME, CLIENT_VERSION, JAVA_VERSION); @@ -93,7 +93,11 @@ protected HttpClient createHttpClient() { // Need to work out a good value for the following: // threadSafeClientConnManager.setValidateAfterInactivity(); - RequestConfig requestConfig = RequestConfig.custom().build(); + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(httpConfig.getTimeoutMillis()) + .setConnectionRequestTimeout(httpConfig.getTimeoutMillis()) + .setSocketTimeout(httpConfig.getTimeoutMillis()) + .build(); return HttpClientBuilder.create() .setConnectionManager(connectionManager) diff --git a/src/main/java/com/vonage/client/VonageClient.java b/src/main/java/com/vonage/client/VonageClient.java index bbc226fba..4db327b23 100644 --- a/src/main/java/com/vonage/client/VonageClient.java +++ b/src/main/java/com/vonage/client/VonageClient.java @@ -210,6 +210,11 @@ HttpWrapper getHttpWrapper() { return httpWrapper; } + /** + * Entry point for constructing an instance of this class. + * + * @return A new Builder with default initial configuration. + */ public static Builder builder() { return new Builder(); } @@ -218,15 +223,12 @@ public static class Builder { private AuthCollection authCollection; private HttpConfig httpConfig = HttpConfig.defaultConfig(); private HttpClient httpClient; - private String applicationId; - private String apiKey; - private String apiSecret; - private String signatureSecret; + private String applicationId, apiKey, apiSecret, signatureSecret; private byte[] privateKeyContents; private HashUtil.HashType hashType = HashUtil.HashType.MD5; /** - * @param httpConfig Configuration options for the {@link HttpWrapper} + * @param httpConfig Configuration options for the {@link HttpWrapper}. * * @return This builder. */ @@ -239,7 +241,10 @@ public Builder httpConfig(HttpConfig httpConfig) { * @param httpClient Custom implementation of {@link HttpClient}. * * @return This builder. + * + * @deprecated This method will be removed in the next major release. */ + @Deprecated public Builder httpClient(HttpClient httpClient) { this.httpClient = httpClient; return this; diff --git a/src/test/java/com/vonage/client/AbstractMethodTest.java b/src/test/java/com/vonage/client/AbstractMethodTest.java index dd96c4322..e030be48b 100644 --- a/src/test/java/com/vonage/client/AbstractMethodTest.java +++ b/src/test/java/com/vonage/client/AbstractMethodTest.java @@ -15,6 +15,7 @@ */ package com.vonage.client; +import com.sun.net.httpserver.HttpServer; import com.vonage.client.auth.AuthCollection; import com.vonage.client.auth.AuthMethod; import com.vonage.client.auth.JWTAuthMethod; @@ -31,17 +32,19 @@ import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; +import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import static org.mockito.Mockito.*; +import java.io.*; +import java.net.InetSocketAddress; +import java.net.SocketTimeoutException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Scanner; +import java.util.concurrent.Executors; import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.*; public class AbstractMethodTest { @@ -60,7 +63,7 @@ protected Class[] getAcceptableAuthMethods() { } @Override - public RequestBuilder makeRequest(String request) { + public RequestBuilder makeRequest(String request) throws UnsupportedEncodingException { return RequestBuilder.get(request); } @@ -87,6 +90,7 @@ static String getEntityContentsAsString(HttpEntity entity) throws IOException { } } + private HttpServer httpServer; private HttpWrapper mockWrapper; private HttpClient mockHttpClient; private AuthCollection mockAuthMethods; @@ -114,6 +118,20 @@ public void setUp() throws Exception { when(mockWrapper.getAuthCollection()).thenReturn(mockAuthMethods); } + ConcreteMethod mockJsonResponse(String json, boolean failing) throws Exception { + ConcreteMethod method = spy(failing ? + new ConcreteMethodFailingParse(mockWrapper) : new ConcreteMethod(mockWrapper) + ); + RequestBuilder builder = RequestBuilder.put("") + .setHeader("Content-Type", "application/json") + .setHeader("Accept", "application/json") + .setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); + + when(method.makeRequest(any(String.class))).thenReturn(builder); + when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); + return method; + } + @Test public void testExecuteHeaders() throws Exception { when(mockHttpClient.execute(any(HttpUriRequest.class))).thenAnswer(invocation -> { @@ -155,15 +173,7 @@ public void testApplyAuth() { @Test public void testUsingUtf8Encoding() throws Exception { String json = "{\"text\":\"Questo è un test di chiamata\",\"loop\":0,\"voice_name\":\"Kimberly\"}"; - RequestBuilder builder = RequestBuilder - .put("") - .setHeader("Content-Type", "application/json") - .setHeader("Accept", "application/json") - .setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); - - ConcreteMethod method = spy(new ConcreteMethod(mockWrapper)); - when(method.makeRequest(any(String.class))).thenReturn(builder); - when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); + ConcreteMethod method = mockJsonResponse(json, false); method.execute(""); @@ -177,14 +187,7 @@ public void testUsingUtf8Encoding() throws Exception { @Test public void testUsingUtf8EncodingChinese() throws Exception { String json = "{\"text\":\"您的纳控猫设备异常,请登录查看。\",\"loop\":0,\"voice_name\":\"Kimberly\"}"; - RequestBuilder builder = RequestBuilder - .put("") - .setCharset(StandardCharsets.UTF_8) - .setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); - - ConcreteMethod method = spy(new ConcreteMethod(mockWrapper)); - when(method.makeRequest(any(String.class))).thenReturn(builder); - when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); + ConcreteMethod method = mockJsonResponse(json, false); method.execute(""); @@ -197,16 +200,9 @@ public void testUsingUtf8EncodingChinese() throws Exception { @Test public void rse() throws Exception { - ConcreteMethodFailingParse method = spy(new ConcreteMethodFailingParse(mockWrapper)); String json = "{\"text\":\"Hello World\",\"loop\":0,\"voice_name\":\"Kimberly\"}"; - RequestBuilder builder = RequestBuilder - .put("") - .setCharset(StandardCharsets.UTF_8) - .setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); - when(method.makeRequest(any(String.class))).thenReturn(builder); - when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); - try{ - + ConcreteMethod method = mockJsonResponse(json, true); + try { method.execute(""); Assert.isTrue(false,"Should have gotten a Parsing exception"); } @@ -217,14 +213,8 @@ public void rse() throws Exception { @Test public void testFailedHttpExecute() throws Exception { - ConcreteMethodFailingParse method = spy(new ConcreteMethodFailingParse(mockWrapper)); String json = "{\"text\":\"Hello World\",\"loop\":0,\"voice_name\":\"Kimberly\"}"; - RequestBuilder builder = RequestBuilder - .put("") - .setCharset(StandardCharsets.UTF_8) - .setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); - when(method.makeRequest(any(String.class))).thenReturn(builder); - when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); + ConcreteMethod method = mockJsonResponse(json, true); IOException ex = new IOException("This is a test exception thrown from the HttpClient Execute method"); when(mockHttpClient.execute(any(HttpUriRequest.class))).thenThrow(ex); try { @@ -235,4 +225,80 @@ public void testFailedHttpExecute() throws Exception { Assert.isTrue(e.getCause() instanceof IOException, "The cause of the exception was not correct"); } } + + private ConcreteMethod mockServerAndMethod(int clientTimeout, int serverTimeout) throws Exception { + if (httpServer != null) { + httpServer.stop(0); + httpServer = null; + } + mockWrapper = new HttpWrapper(); + mockWrapper.setHttpConfig(HttpConfig.builder().timeoutMillis(clientTimeout).build()); + final int port = 8049; + String endpointPath = "/test"; + httpServer = HttpServer.create(new InetSocketAddress(port), 0); + httpServer.createContext(endpointPath, exchange -> { + if (serverTimeout > 0) { + try { + Thread.sleep(serverTimeout); + } + catch (InterruptedException ex) { + fail(ex.getMessage()); + } + } + + String response = new Scanner(exchange.getRequestBody()).useDelimiter("\\A").next(); + exchange.sendResponseHeaders(200, response.length()); + try (OutputStream os = exchange.getResponseBody()) { + os.write(response.getBytes()); + } + }); + httpServer.setExecutor(Executors.newSingleThreadExecutor()); + httpServer.start(); + + RequestBuilder builder = RequestBuilder.get("http://localhost:" + port + endpointPath); + class LocalMethod extends ConcreteMethod { + LocalMethod() { + super(mockWrapper); + } + + @Override + protected AuthMethod getAuthMethod() throws VonageUnexpectedException { + return mockAuthMethod; + } + + @Override + protected AuthMethod getAuthMethod(Class[] acceptableAuthMethods) throws VonageClientException { + return getAuthMethod(); + } + + @Override + public RequestBuilder makeRequest(String request) throws UnsupportedEncodingException { + return builder.setEntity(new StringEntity(request)); + } + } + LocalMethod method = new LocalMethod(); + when(mockAuthMethod.apply(any(RequestBuilder.class))).thenReturn(builder); + return method; + } + + @Test + public void testSocketTimeout() throws Exception { + ConcreteMethod method = mockServerAndMethod(9000, 0); + String requestBody = "Hello, World!"; + assertEquals(requestBody, method.execute(requestBody)); + + method = mockServerAndMethod(970, 1200); + try { + method.execute(requestBody); + fail("Expected VonageClientException"); + } + catch (VonageClientException ex) { + assertEquals(SocketTimeoutException.class, ex.getCause().getClass()); + } + method = mockServerAndMethod(3000, 144); + requestBody = "Hello again..."; + assertEquals(requestBody, method.execute(requestBody)); + + assertThrows(IllegalArgumentException.class, () -> mockServerAndMethod(0, 1)); + } } \ No newline at end of file diff --git a/src/test/java/com/vonage/client/BugRepro.java b/src/test/java/com/vonage/client/BugRepro.java index 1d0c36512..329bb70a9 100644 --- a/src/test/java/com/vonage/client/BugRepro.java +++ b/src/test/java/com/vonage/client/BugRepro.java @@ -27,6 +27,7 @@ public class BugRepro { public static void main(String[] args) throws Throwable { VonageClient client = VonageClient.builder() + .httpConfig(HttpConfig.builder().timeoutMillis(12_000).build()) .apiKey(System.getenv("VONAGE_API_KEY")) .apiSecret(System.getenv("VONAGE_API_SECRET")) .applicationId(System.getenv("VONAGE_APPLICATION_ID")) diff --git a/src/test/java/com/vonage/client/HttpConfigTest.java b/src/test/java/com/vonage/client/HttpConfigTest.java index 3b6d7f8d3..aacdcf52e 100644 --- a/src/test/java/com/vonage/client/HttpConfigTest.java +++ b/src/test/java/com/vonage/client/HttpConfigTest.java @@ -19,19 +19,22 @@ import static org.junit.Assert.assertEquals; public class HttpConfigTest { - private static final String EXPECTED_DEFAULT_API_BASE_URI = "https://api.nexmo.com"; - private static final String EXPECTED_DEFAULT_REST_BASE_URI = "https://rest.nexmo.com"; - private static final String EXPECTED_DEFAULT_SNS_BASE_URI = "https://sns.nexmo.com"; - - @Test - public void testDefaultFactoryMethod() { - HttpConfig config = HttpConfig.defaultConfig(); + static final String EXPECTED_DEFAULT_API_BASE_URI = "https://api.nexmo.com"; + static final String EXPECTED_DEFAULT_REST_BASE_URI = "https://rest.nexmo.com"; + static final String EXPECTED_DEFAULT_SNS_BASE_URI = "https://sns.nexmo.com"; + static void assertDefaults(HttpConfig config) { + assertEquals(60000, config.getTimeoutMillis()); assertEquals(EXPECTED_DEFAULT_API_BASE_URI, config.getApiBaseUri()); assertEquals(EXPECTED_DEFAULT_REST_BASE_URI, config.getRestBaseUri()); assertEquals(EXPECTED_DEFAULT_SNS_BASE_URI, config.getSnsBaseUri()); } + @Test + public void testDefaultFactoryMethod() { + assertDefaults(HttpConfig.defaultConfig()); + } + @Test public void testApiBaseUriOnly() { HttpConfig config = HttpConfig.builder().apiBaseUri("https://example.com").build(); diff --git a/src/test/java/com/vonage/client/HttpWrapperTest.java b/src/test/java/com/vonage/client/HttpWrapperTest.java index cf9f84f14..0378ff6c2 100644 --- a/src/test/java/com/vonage/client/HttpWrapperTest.java +++ b/src/test/java/com/vonage/client/HttpWrapperTest.java @@ -22,10 +22,6 @@ import static org.junit.Assert.assertNotNull; public class HttpWrapperTest { - private static final String EXPECTED_DEFAULT_API_BASE_URI = "https://api.nexmo.com"; - private static final String EXPECTED_DEFAULT_REST_BASE_URI = "https://rest.nexmo.com"; - private static final String EXPECTED_DEFAULT_SNS_BASE_URI = "https://sns.nexmo.com"; - private HttpWrapper wrapper; @Before @@ -45,16 +41,10 @@ public void testAuthMethodAccessors() { assertEquals(auths, wrapper.getAuthCollection()); } - @Test - public void testHttpConfigAccessor() { - assertNotNull(wrapper.getHttpConfig()); - } - @Test public void testDefaultConstructorSetsDefaultConfigValues() { HttpConfig config = wrapper.getHttpConfig(); - assertEquals(EXPECTED_DEFAULT_API_BASE_URI, config.getApiBaseUri()); - assertEquals(EXPECTED_DEFAULT_REST_BASE_URI, config.getRestBaseUri()); - assertEquals(EXPECTED_DEFAULT_SNS_BASE_URI, config.getSnsBaseUri()); + assertNotNull(config); + HttpConfigTest.assertDefaults(config); } } diff --git a/src/test/java/com/vonage/client/auth/RequestSigningTest.java b/src/test/java/com/vonage/client/auth/RequestSigningTest.java index 3d33abb49..0ea6a72b7 100644 --- a/src/test/java/com/vonage/client/auth/RequestSigningTest.java +++ b/src/test/java/com/vonage/client/auth/RequestSigningTest.java @@ -20,7 +20,6 @@ import org.apache.http.message.BasicNameValuePair; import static org.junit.Assert.*; import org.junit.Test; -import org.mockito.Mockito; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import javax.servlet.ReadListener; @@ -235,9 +234,9 @@ private HttpServletRequest constructDummyRequest() { private HttpServletRequest constructDummyRequestJson() throws Exception { - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + HttpServletRequest request = mock(HttpServletRequest.class); String dummyJson = "{\"a\":\"alphabet\",\"b\":\"bananas\",\"timestamp\":\"2100\",\"sig\":\"b7f749de27b4adcf736cc95c9a7e059a16c85127\"}"; - Mockito.when(request.getContentType()).thenReturn("application/json"); + when(request.getContentType()).thenReturn("application/json"); final byte[] contentBytes = dummyJson.getBytes(StandardCharsets.UTF_8); ServletInputStream servletInputStream = new ServletInputStream() { private int index = 0;