diff --git a/README.md b/README.md
index a6bd0e2..b95685b 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ Add the below dependency to the project's POM:
com.factset.sdk
utils
- 1.0.1
+ 1.1.0-SNAPSHOT
```
@@ -32,10 +32,49 @@ repositories {
}
dependencies {
- implementation "com.factset.sdk:utils:1.0.1"
+ implementation "com.factset.sdk:utils:1.1.0-SNAPSHOT"
}
```
+### Snapshot Releases
+
+To be able to install snapshot releases of the sdk an additional repository must be added to the maven or gradle config.
+
+#### Maven Snapshot Repository
+
+```xml
+
+
+ sonatype
+ sonatype-snapshot
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+ true
+
+
+ false
+
+
+
+```
+
+#### Gradle Snapshot Repository
+
+```groovy
+repositories {
+ mavenCentral()
+ maven {
+ url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
+ mavenContent {
+ snapshotsOnly()
+ }
+ }
+}
+```
+
+Snapshot releases are cached by gradle for some time, for details see: [Gradle Dynamic Versions](https://docs.gradle.org/current/userguide/dynamic_versions.html#sub:declaring_dependency_with_changing_version)
+
+
## Usage
This library contains multiple modules, sample usage of each module is below.
@@ -100,6 +139,45 @@ public class Console {
}
```
+### Configure a Proxy
+
+The Confidential Client accepts an additional optional parameter called `RequestOptions`. This can be created to specify a proxy for the client to use. Below is an example of how to do this:
+
+```java
+Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080));
+RequestOptions requestOptions = RequestOptions.builder().proxy(proxy).build();
+
+// Pass this into client
+ConfidentialClient confidentialClient = new ConfidentialClient("./path/to/config.json", requestOptions);
+```
+
+### Custom SSL Certificate
+
+If you are making requests to a server which is using custom TLS certificates, you are able to verify the validity of the certificate via the `RequestOptions` configuration.
+
+#### Hostname Verifier
+
+You can pass in a custom hostname verifier to modify the details of the verification with a custom implementation. Otherwise, the `RequestOptions` will use the default one which checks the hostname in the certificate, located in the JRE keystore, and compares it to the hostname of the URL that is being hit by the client.
+
+#### SSL Socket Factory
+
+You can pass in a custom SSL Socket Factory and modify the `SSLContext` for a specific user use case. Otherwise, the `RequestOptions` uses a default `SSLSocketFactory` as described [here](https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/HttpsURLConnection.html#getDefaultHostnameVerifier()).
+
+#### Example
+
+```java
+SSLContext sslContext = SSLContext.getInstance("TLS");
+sslContext.init(...); // Configure this based on application's needs
+
+SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+HostnameVerifier hostnameVerifier = ((hostname, session) -> ...); // Configure this based on application's needs
+
+RequestOptions reqOpt = RequestOptions.builder()
+ .hostnameVerifier(hostnameVerifier)
+ .sslSocketFactory(sslSocketFactory)
+ .build();
+```
+
## Modules
Information about the various utility modules contained in this library can be found below.
diff --git a/build.gradle b/build.gradle
index 142e729..4b7f058 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ apply plugin: 'jacoco'
apply plugin: 'maven-publish'
group 'com.factset.sdk'
-version '1.0.1'
+version '1.1.0-SNAPSHOT'
dependencies {
implementation 'org.slf4j:slf4j-api:1.7.36'
@@ -26,6 +26,11 @@ dependencies {
testImplementation "org.hamcrest:hamcrest:2.2"
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
testRuntimeOnly 'ch.qos.logback:logback-core:1.2.11'
+
+ compileOnly 'org.projectlombok:lombok:1.18.30'
+ annotationProcessor 'org.projectlombok:lombok:1.18.30'
+ testCompileOnly 'org.projectlombok:lombok:1.18.30'
+ testAnnotationProcessor 'org.projectlombok:lombok:1.18.30'
}
task sourcesJar(type: Jar) {
diff --git a/src/main/java/com/factset/sdk/utils/authentication/ConfidentialClient.java b/src/main/java/com/factset/sdk/utils/authentication/ConfidentialClient.java
index 4ad490b..a1324df 100644
--- a/src/main/java/com/factset/sdk/utils/authentication/ConfidentialClient.java
+++ b/src/main/java/com/factset/sdk/utils/authentication/ConfidentialClient.java
@@ -26,6 +26,9 @@
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import java.io.IOException;
import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import javax.net.ssl.HttpsURLConnection;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -42,7 +45,8 @@ public class ConfidentialClient implements OAuth2Client {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfidentialClient.class);
private final Configuration config;
- private final OIDCProviderMetadata providerMetadata;
+ private OIDCProviderMetadata providerMetadata;
+ private final RequestOptions requestOptions;
private TokenRequestBuilder tokenRequestBuilder;
private long jwsIssuedAt;
private long accessTokenExpireTime;
@@ -65,6 +69,24 @@ public ConfidentialClient(final String configPath)
this(new Configuration(configPath));
}
+ /**
+ * Creates a new ConfidentialClient. When setting up the OAuth 2.0 client, this constructor reaches out to
+ * FactSet's well-known URI to retrieve metadata about its authorization server. This information along with
+ * information about the OAuth 2.0 client is stored and used whenever a new access token is fetched.
+ *
+ * @param configPath The path towards the file to pe parsed.
+ * @param requestOptions Object that can configure options like proxy and SSL settings
+ * @throws AuthServerMetadataContentException If Meta Issuer or Meta Token Endpoint is missing.
+ * @throws AuthServerMetadataException If reading from URL is unsuccessful.
+ * @throws ConfigurationException If JWK required keys are missing from the RSA or any keys with a value
+ * that is null or an empty string.
+ */
+ public ConfidentialClient(final String configPath, RequestOptions requestOptions)
+ throws AuthServerMetadataContentException, AuthServerMetadataException,
+ ConfigurationException {
+ this(new Configuration(configPath), requestOptions);
+ }
+
/**
* Creates a new ConfidentialClient. When setting up the OAuth 2.0 client, this constructor reaches out to
* FactSet's well-known URI to retrieve metadata about its authorization server. This information along with
@@ -77,25 +99,28 @@ public ConfidentialClient(final String configPath)
*/
public ConfidentialClient(final Configuration config)
throws AuthServerMetadataContentException, AuthServerMetadataException {
+ this(config, RequestOptions.builder().build());
+ }
+
+ /**
+ * Creates a new ConfidentialClient. When setting up the OAuth 2.0 client, this constructor reaches out to
+ * FactSet's well-known URI to retrieve metadata about its authorization server. This information along with
+ * information about the OAuth 2.0 client is stored and used whenever a new access token is fetched.
+ *
+ * @param config Configuration object.
+ * @param requestOptions Object that can configure options like proxy and SSL settings
+ * @throws AuthServerMetadataContentException If Meta Issuer or Meta Token Endpoint is missing.
+ * @throws AuthServerMetadataException If reading from URL is unsuccessful.
+ * @throws NullPointerException Unchecked exception, if config is null.
+ */
+ public ConfidentialClient(final Configuration config, RequestOptions requestOptions)
+ throws AuthServerMetadataContentException, AuthServerMetadataException {
Objects.requireNonNull(config, "Configuration object must not be null");
this.config = config;
LOGGER.debug("Finished initialising configuration");
+ this.requestOptions = requestOptions == null ? RequestOptions.builder().build() : requestOptions;
- LOGGER.debug("Attempting to get response from Well Known URI");
- try (InputStream stream = config.getWellKnownUrl().openStream()) {
- final String providerInfo = IOUtils.readInputStreamToString(stream);
- this.providerMetadata = OIDCProviderMetadata.parse(providerInfo);
- } catch (final ParseException e) {
- throw new AuthServerMetadataContentException("Content of WellKnownUri has errors: " +
- config.getWellKnownUrl().toString(), e);
- } catch (final IOException e) {
- throw new AuthServerMetadataException("Error retrieving contents from WellKnownUri: " +
- config.getWellKnownUrl().toString(), e);
- }
- LOGGER.debug("Response received from Well Known URI");
-
- this.tokenRequestBuilder =
- new TokenRequestBuilder().uri(this.providerMetadata.getTokenEndpointURI());
+ this.requestProviderMetadata();
}
/**
@@ -136,6 +161,25 @@ protected ConfidentialClient(final Configuration config, final TokenRequestBuild
this.tokenRequestBuilder = tokReqBuilder.uri(this.providerMetadata.getTokenEndpointURI());
}
+ /**
+ * Creates a new ConfidentialClient. When setting up the OAuth 2.0 client, this constructor reaches out to
+ * FactSet's well-known URI to retrieve metadata about its authorization server. This information along with
+ * information about the OAuth 2.0 client is stored and used whenever a new access token is fetched.
+ *
+ * @param config Configuration object.
+ * @param tokReqBuilder The TokenRequest builder, used to build custom TokenRequest instances.
+ * @param requestOptions Object that can configure options like proxy and SSL settings
+ * @throws AuthServerMetadataContentException If Meta Issuer or Meta Token Endpoint is missing.
+ * @throws AuthServerMetadataException If reading from URL is unsuccessful.
+ * @throws NullPointerException Unchecked exception, if config is null.
+ */
+ protected ConfidentialClient(final Configuration config, final TokenRequestBuilder tokReqBuilder, RequestOptions requestOptions)
+ throws AuthServerMetadataContentException,
+ AuthServerMetadataException {
+ this(config, requestOptions);
+ this.tokenRequestBuilder = tokReqBuilder.uri(this.providerMetadata.getTokenEndpointURI());
+ }
+
/**
* Returns an access token that can be used for authentication. If the cache contains a valid access token,
* it's returned. Otherwise, a new access token is retrieved from FactSet's authorization server. The access
@@ -156,6 +200,36 @@ public String getAccessToken() throws AccessTokenException, SigningJwsException
return this.fetchAccessToken();
}
+ private void requestProviderMetadata() throws AuthServerMetadataContentException, AuthServerMetadataException {
+ LOGGER.debug("Attempting to get response from Well Known URI");
+ URL wellKnownURL = this.config.getWellKnownUrl();
+ InputStream stream;
+
+ try {
+ HttpURLConnection conn = (HttpURLConnection) wellKnownURL.openConnection(this.requestOptions.getProxy());
+ if (conn instanceof HttpsURLConnection) {
+ HttpsURLConnection sslConn = (HttpsURLConnection) conn;
+ sslConn.setHostnameVerifier(this.requestOptions.getHostnameVerifier());
+ sslConn.setSSLSocketFactory(this.requestOptions.getSslSocketFactory());
+ }
+
+ stream = conn.getInputStream();
+
+ final String providerInfo = IOUtils.readInputStreamToString(stream);
+ this.providerMetadata = OIDCProviderMetadata.parse(providerInfo);
+ } catch (final ParseException e) {
+ throw new AuthServerMetadataContentException("Content of WellKnownUri has errors: " +
+ this.config.getWellKnownUrl().toString(), e);
+ } catch (final IOException e) {
+ throw new AuthServerMetadataException("Error retrieving contents from WellKnownUri: " +
+ this.config.getWellKnownUrl().toString(), e);
+ }
+ LOGGER.debug("Response received from Well Known URI");
+
+ this.tokenRequestBuilder =
+ new TokenRequestBuilder().uri(this.providerMetadata.getTokenEndpointURI());
+ }
+
private boolean isCachedTokenValid() {
if (this.accessToken == null) {
return false;
@@ -173,6 +247,10 @@ private String fetchAccessToken() throws AccessTokenException, SigningJwsExcepti
final TokenRequest tokenRequest = this.tokenRequestBuilder.signedJwt(signedJwt).build();
final HTTPRequest httpRequest = tokenRequest.toHTTPRequest();
+ httpRequest.setProxy(this.requestOptions.getProxy());
+ httpRequest.setHostnameVerifier(this.requestOptions.getHostnameVerifier());
+ httpRequest.setSSLSocketFactory(this.requestOptions.getSslSocketFactory());
+
logTokenRequest(httpRequest);
final HTTPResponse res = httpRequest.send();
diff --git a/src/main/java/com/factset/sdk/utils/authentication/RequestOptions.java b/src/main/java/com/factset/sdk/utils/authentication/RequestOptions.java
new file mode 100644
index 0000000..b40865c
--- /dev/null
+++ b/src/main/java/com/factset/sdk/utils/authentication/RequestOptions.java
@@ -0,0 +1,22 @@
+package com.factset.sdk.utils.authentication;
+
+import lombok.Builder;
+import lombok.Value;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSocketFactory;
+import java.net.Proxy;
+
+@Value
+@Builder
+public class RequestOptions {
+ @Builder.Default
+ Proxy proxy = Proxy.NO_PROXY;
+
+ @Builder.Default
+ HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+
+ @Builder.Default
+ SSLSocketFactory sslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
+}
diff --git a/src/test/java/com/factset/sdk/utils/authentication/ConfidentialClientTest.java b/src/test/java/com/factset/sdk/utils/authentication/ConfidentialClientTest.java
index 19d4efb..474862b 100644
--- a/src/test/java/com/factset/sdk/utils/authentication/ConfidentialClientTest.java
+++ b/src/test/java/com/factset/sdk/utils/authentication/ConfidentialClientTest.java
@@ -8,12 +8,11 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import javax.net.ssl.HttpsURLConnection;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
+import java.net.*;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
@@ -151,9 +150,11 @@ void confidentialClientValidPathValidConfigCannotGetInputStreamThrowsAuthServerM
}
@Test
- void confidentialClientValidPathValidConfigMissingIssuerAndTokenEndpointThrowsAuthServerMetadataContentException() {
+ void confidentialClientValidPathValidConfigMissingIssuerAndTokenEndpointThrowsAuthServerMetadataContentException() throws Exception {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("emptyJson.txt", mockedConn);
assertThrows(AuthServerMetadataContentException.class,
- () -> new ConfidentialClient(getConfigSpyMockedResponse("emptyJson.txt", "validConfig.txt")));
+ () -> new ConfidentialClient(getConfigSpyMockedResponse(mockedURL, "validConfig.txt")));
}
@Test
@@ -165,7 +166,8 @@ void confidentialClientValidPathValidConfigCustomWellKnownUriInitialisesWithNoEx
"https://test.test.com/.test-test/test-test");
// If this confidential client is instantiated without exceptions, that results in a passing test.
- URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt");
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationSpy = spy(configuration);
when(configurationSpy.getWellKnownUrl()).thenReturn(mockedURL);
new ConfidentialClient(configurationSpy);
@@ -176,10 +178,40 @@ void confidentialClientValidPathValidConfigCustomWellKnownUriInitialisesWithNoEx
void confidentialClientValidConfigInitialisesWithNoException() {
assertDoesNotThrow(() -> {
// If this confidential client is instantiated without exceptions, that results in a passing test.
- new ConfidentialClient(getConfigSpyMockedResponse("exampleResponseWellKnownUri.txt", "validConfig.txt"));
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
+ new ConfidentialClient(getConfigSpyMockedResponse(mockedURL, "validConfig.txt"));
});
}
+ @Test
+ void confidentialClientValidConfigInitialisesWithRequestOptions() throws Exception {
+ Proxy mockProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080));
+ RequestOptions reqOptions = RequestOptions.builder().proxy(mockProxy).build();
+
+ HttpsURLConnection mockedConn = mock(HttpsURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
+ Configuration config = getConfigSpyMockedResponse(mockedURL, "validConfig.txt");
+ new ConfidentialClient(config, reqOptions);
+
+ verify(mockedURL).openConnection(mockProxy);
+ verify(mockedConn).setHostnameVerifier(reqOptions.getHostnameVerifier());
+ verify(mockedConn).setSSLSocketFactory(reqOptions.getSslSocketFactory());
+ }
+
+ @Test
+ void confidentialClientValidConfigInitialisesWithRequestOptionsAsNull() throws Exception {
+ HttpsURLConnection mockedConn = mock(HttpsURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
+ Configuration config = getConfigSpyMockedResponse(mockedURL, "validConfig.txt");
+ RequestOptions reqOpts = null;
+ new ConfidentialClient(config, reqOpts);
+
+ verify(mockedURL).openConnection(Proxy.NO_PROXY);
+ verify(mockedConn).setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
+ verify(mockedConn).setSSLSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
+ }
+
@Test
void getAccessTokenCallingWithFailedSigningRaisesSigningJwsException() throws Exception {
try {
@@ -197,14 +229,18 @@ void getAccessTokenCallingWithFailedSigningRaisesSigningJwsException() throws Ex
@Test
void getAccessTokenCallingWithErroneousResponseRaisesAccessTokenException() throws Exception {
try {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
- "exampleResponseWellKnownUri.txt", "validConfig.txt"
+ mockedURL, "validConfig.txt"
);
+ HTTPRequest mockedRequest = mock(HTTPRequest.class);
TokenRequestBuilder tokenRequestBuilderSpy = ConfidentialClientTest.createTokenRequestBuilderSpy(
HTTPResponse.SC_UNAUTHORIZED,
"{\"error_description\":\"Unauthorized access.\",\"error\":\"invalid_request\"}",
- false
+ false,
+ mockedRequest
);
ConfidentialClient confidentialClientSpy = spy(new ConfidentialClient(configurationMock, tokenRequestBuilderSpy));
@@ -217,14 +253,18 @@ void getAccessTokenCallingWithErroneousResponseRaisesAccessTokenException() thro
@Test
void getAccessTokenCalledForTheFirstTimeReturnsANewAccessToken() throws Exception {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
- "exampleResponseWellKnownUri.txt", "validConfig.txt"
+ mockedURL, "validConfig.txt"
);
+ HTTPRequest mockedRequest = mock(HTTPRequest.class);
TokenRequestBuilder tokenRequestBuilderSpy = ConfidentialClientTest.createTokenRequestBuilderSpy(
HTTPResponse.SC_OK,
"{\"access_token\":\"test token\",\"token_type\":\"Bearer\",\"expires_in\":899}",
- true
+ true,
+ mockedRequest
);
ConfidentialClient confidentialClientSpy = spy(new ConfidentialClient(configurationMock, tokenRequestBuilderSpy));
@@ -233,10 +273,38 @@ void getAccessTokenCalledForTheFirstTimeReturnsANewAccessToken() throws Exceptio
assertEquals("test token", accessToken);
}
+ @Test
+ void getAccessTokenCalledWithRequestOptionsSetsProxyAndSSLSettings() throws Exception {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
+ Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
+ mockedURL, "validConfig.txt"
+ );
+
+ HTTPRequest mockedRequest = mock(HTTPRequest.class);
+ TokenRequestBuilder tokenRequestBuilderSpy = ConfidentialClientTest.createTokenRequestBuilderSpy(
+ HTTPResponse.SC_OK,
+ "{\"access_token\":\"test token\",\"token_type\":\"Bearer\",\"expires_in\":899}",
+ true,
+ mockedRequest
+ );
+
+ Proxy mockProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080));
+ RequestOptions reqOptions = RequestOptions.builder().proxy(mockProxy).build();
+ ConfidentialClient confidentialClientSpy = spy(new ConfidentialClient(configurationMock, tokenRequestBuilderSpy, reqOptions));
+ confidentialClientSpy.getAccessToken();
+
+ verify(mockedRequest).setProxy(mockProxy);
+ verify(mockedRequest).setHostnameVerifier(reqOptions.getHostnameVerifier());
+ verify(mockedRequest).setSSLSocketFactory(reqOptions.getSslSocketFactory());
+ }
+
@Test
void getAccessTokenCalledTwiceBeforeExpirationReturnsSameAccessToken() throws Exception {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
- "exampleResponseWellKnownUri.txt", "validConfig.txt"
+ mockedURL, "validConfig.txt"
);
HTTPResponse res = new HTTPResponse(HTTPResponse.SC_OK);
@@ -267,8 +335,10 @@ void getAccessTokenCalledTwiceBeforeExpirationReturnsSameAccessToken() throws Ex
@Test
void getAccessTokenCallingBeforeAndAfterExpirationReturnsDifferentAccessToken() throws Exception {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
- "exampleResponseWellKnownUri.txt", "validConfig.txt"
+ mockedURL, "validConfig.txt"
);
HTTPResponse res1 = new HTTPResponse(HTTPResponse.SC_OK);
@@ -304,14 +374,18 @@ void getAccessTokenCallingBeforeAndAfterExpirationReturnsDifferentAccessToken()
@Test
void getAccessTokenCallingWithSendErrorRaisesAccessTokenException() throws Exception {
try {
+ HttpURLConnection mockedConn = mock(HttpURLConnection.class);
+ URL mockedURL = getUrlMockResponse("exampleResponseWellKnownUri.txt", mockedConn);
Configuration configurationMock = ConfidentialClientTest.getConfigSpyMockedResponse(
- "exampleResponseWellKnownUri.txt", "validConfig.txt"
+ mockedURL, "validConfig.txt"
);
+ HTTPRequest mockedRequest = mock(HTTPRequest.class);
TokenRequestBuilder tokenRequestBuilderSpy = ConfidentialClientTest.createTokenRequestBuilderSpy(
HTTPResponse.SC_OK,
"{\"error_description\":\"Invalid request.\",\"error\":\"invalid_request\"}",
- false
+ false,
+ mockedRequest
);
ConfidentialClient confidentialClientSpy = spy(new ConfidentialClient(configurationMock, tokenRequestBuilderSpy));
@@ -323,17 +397,17 @@ void getAccessTokenCallingWithSendErrorRaisesAccessTokenException() throws Excep
}
}
- private static URL getUrlMockResponse(String stringFile) throws IOException {
+ private static URL getUrlMockResponse(String stringFile, HttpURLConnection mockedConn) throws IOException {
final File file = new File(String.valueOf(Paths.get(String.valueOf(pathToResources), stringFile)));
URL mockedUrl = mock(URL.class);
- when(mockedUrl.openStream()).thenReturn(new FileInputStream(file));
+ when(mockedUrl.openConnection(any(Proxy.class))).thenReturn(mockedConn);
+ when(mockedConn.getInputStream()).thenReturn(Files.newInputStream(file.toPath()));
return mockedUrl;
}
- private static Configuration getConfigSpyMockedResponse(String urlResponse, String configFile) throws IOException, ConfigurationException {
- URL mockedURL = getUrlMockResponse(urlResponse);
+ private static Configuration getConfigSpyMockedResponse(URL mockedURL, String configFile) throws ConfigurationException {
Configuration configuration = new Configuration(String.valueOf(Paths.get(pathToResources.toString(), configFile)));
Configuration configurationSpy = spy(configuration);
when(configurationSpy.getWellKnownUrl()).thenReturn(mockedURL);
@@ -343,7 +417,7 @@ private static Configuration getConfigSpyMockedResponse(String urlResponse, Stri
private static Configuration getConfigSpyThrowsIOException(String configFile) throws IOException, ConfigurationException {
URL mockedUrl = mock(URL.class);
- when(mockedUrl.openStream()).thenThrow(IOException.class);
+ when(mockedUrl.openConnection(any(Proxy.class))).thenThrow(IOException.class);
Configuration configuration = new Configuration(String.valueOf(Paths.get(pathToResources.toString(), configFile)));
Configuration configurationSpy = spy(configuration);
when(configurationSpy.getWellKnownUrl()).thenReturn(mockedUrl).thenCallRealMethod();
@@ -352,7 +426,7 @@ private static Configuration getConfigSpyThrowsIOException(String configFile) th
}
private static TokenRequestBuilder createTokenRequestBuilderSpy(int statusCode, String resContent,
- boolean requiresHeader) throws URISyntaxException,
+ boolean requiresHeader, HTTPRequest mockedRequest) throws URISyntaxException,
IOException {
HTTPResponse res = new HTTPResponse(statusCode);
res.setContent(resContent);
@@ -367,11 +441,9 @@ private static TokenRequestBuilder createTokenRequestBuilderSpy(int statusCode,
TokenRequestBuilder tokenRequestBuilderSpy = spy(new TokenRequestBuilder());
- HTTPRequest httpRequestMock = mock(HTTPRequest.class);
-
doReturn(tokenRequestMock).when(tokenRequestBuilderSpy).build();
- doReturn(httpRequestMock).when(tokenRequestMock).toHTTPRequest();
- doReturn(res).when(httpRequestMock).send();
+ doReturn(mockedRequest).when(tokenRequestMock).toHTTPRequest();
+ doReturn(res).when(mockedRequest).send();
return tokenRequestBuilderSpy;
}