Skip to content
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

feat(iot-service): Add proxy support for registry manager #768

Merged
merged 3 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import com.microsoft.azure.sdk.iot.service.transport.http.HttpMethod;
import com.microsoft.azure.sdk.iot.service.transport.http.HttpRequest;
import com.microsoft.azure.sdk.iot.service.transport.http.HttpResponse;
import lombok.Getter;
import lombok.Setter;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import java.io.IOException;
import java.io.StringReader;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand All @@ -41,6 +44,10 @@ public class RegistryManager
private ExecutorService executor;
private IotHubConnectionString iotHubConnectionString;

@Getter
@Setter
private Proxy proxy;

/**
* Static constructor to create instance from connection string
*
Expand All @@ -65,6 +72,8 @@ public static RegistryManager createFromConnectionString(String connectionString
// Codes_SRS_SERVICE_SDK_JAVA_REGISTRYMANAGER_34_090: [The function shall start this object's executor service]
iotHubRegistryManager.executor = Executors.newFixedThreadPool(EXECUTOR_THREAD_POOL_SIZE);

iotHubRegistryManager.proxy = null;

return iotHubRegistryManager;
}

Expand Down Expand Up @@ -1595,7 +1604,7 @@ private JobProperties ProcessJobResponse(HttpResponse response) throws IotHubExc

private HttpRequest CreateRequest(URL url, HttpMethod method, byte[] payload, String sasToken) throws IOException
{
HttpRequest request = new HttpRequest(url, method, payload);
HttpRequest request = new HttpRequest(url, method, payload, proxy);
request.setReadTimeoutMillis(DEFAULT_HTTP_TIMEOUT_MS);
request.setHeaderField("authorization", sasToken);
request.setHeaderField("Request-Id", "1001");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -47,6 +48,20 @@ public class HttpConnection
* @throws IOException This exception is thrown if the connection was unable to be opened.
*/
public HttpConnection(URL url, HttpMethod method) throws IOException
{
this(url, method, null);
}

/**
* Constructor. Opens a connection to the given URL.
*
* @param url The URL for the HTTPS connection.
* @param method The HTTPS method (i.e. GET).
* @param proxy The proxy to send the connection through
*
* @throws IOException This exception is thrown if the connection was unable to be opened.
*/
public HttpConnection(URL url, HttpMethod method, Proxy proxy) throws IOException
{
// Codes_SRS_SERVICE_SDK_JAVA_HTTPCONNECTION_12_004: [If the URI given does not use the HTTPS protocol, the constructor shall throw an IllegalArgumentException.]
String protocol = url.getProtocol();
Expand All @@ -59,9 +74,15 @@ public HttpConnection(URL url, HttpMethod method) throws IOException
throw new IllegalArgumentException(errMsg);
}

// Codes_SRS_SERVICE_SDK_JAVA_HTTPCONNECTION_12_001: [The constructor shall open a connection to the given URL.]
// Coses_SRS_SERVICE_SDK_JAVA_HTTPCONNECTION_12_002: [The constructor shall throw an IOException if the connection was unable to be opened.]
this.connection = (HttpsURLConnection) url.openConnection();

if (proxy != null)
{
this.connection = (HttpsURLConnection) url.openConnection(proxy);
}
else
{
this.connection = (HttpsURLConnection) url.openConnection();
}
// Codes_SRS_SERVICE_SDK_JAVA_HTTPCONNECTION_12_003: [The constructor shall set the HTTPS method to the given method.]

if (method == HttpMethod.PATCH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.microsoft.azure.sdk.iot.service.transport.TransportUtils;

import java.io.IOException;
import java.net.Proxy;
import java.net.URL;
import java.util.List;
import java.util.Map;
Expand All @@ -31,11 +32,30 @@ public class HttpRequest
* given does not use the HTTPS protocol.
*/
public HttpRequest(URL url, HttpMethod method, byte[] body) throws IOException
{
this(url, method, body, null);
}

/**
* Constructor. Takes a URL as an argument and returns an HTTPS request that
* is ready to be sent through an optional proxy.
*
* @param url The URL for the request.
* @param method The HTTPS request method (i.e. GET).
* @param body The request body. Must be an array of size 0 if the request method is GET or DELETE.
* @param proxy The proxy to send the request through. May be null if no proxy should be used
*
* @throws IOException This exception thrown if an IOException occurs
* in setting up the HTTPS connection.
* @throws IllegalArgumentException This exception thrown if the endpoint
* given does not use the HTTPS protocol.
*/
public HttpRequest(URL url, HttpMethod method, byte[] body, Proxy proxy) throws IOException
{
// Codes_SRS_SERVICE_SDK_JAVA_HTTPREQUEST_12_001: [The function shall open a connection with the given URL as the endpoint.]
// Codes_SRS_SERVICE_SDK_JAVA_HTTPREQUEST_12_003: [The function shall use the given HTTPS method (i.e. GET) as the request method.]
// Codes_SRS_SERVICE_SDK_JAVA_HTTPREQUEST_12_004: [If an IOException occurs in setting up the HTTPS connection, the function shall throw an IOException.]
this.connection = new HttpConnection(url, method);
this.connection = new HttpConnection(url, method, proxy);
this.connection.setRequestHeader("User-Agent", TransportUtils.javaServiceClientIdentifier + TransportUtils.serviceVersion);
// Codes_SRS_SERVICE_SDK_JAVA_HTTPREQUEST_12_002: [The function shall write the body to the connection.]
this.connection.writeOutput(body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.junit.runner.RunWith;

import java.io.IOException;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -1083,22 +1084,22 @@ public Device removeDevice(String deviceId) throws IOException, IotHubException
// Tests_SRS_SERVICE_SDK_JAVA_REGISTRYMANAGER_12_058: [The function shall verify the response status and throw proper Exception]
// Tests_SRS_SERVICE_SDK_JAVA_REGISTRYMANAGER_12_059: [The function shall create a new RegistryStatistics object from the response and return with it]
@Test
public void getStatistics_good_case() throws Exception
public void getStatistics_good_case(@Mocked Proxy mockProxy) throws Exception
{
String connectionString = "HostName=aaa.bbb.ccc;SharedAccessKeyName=XXX;SharedAccessKey=YYY";
String deviceId = "somedevice";

commonExpectations(connectionString, deviceId);

RegistryManager registryManager = RegistryManager.createFromConnectionString(connectionString);

registryManager.setProxy(mockProxy);
RegistryStatistics statistics = registryManager.getStatistics();

new VerificationsInOrder()
{
{
iotHubConnectionString.getUrlDeviceStatistics();
new HttpRequest(mockUrl, HttpMethod.GET, new byte[0]);
new HttpRequest(mockUrl, HttpMethod.GET, new byte[0], mockProxy);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1130,7 +1131,7 @@ public void getStatisticsAsync_future_return_ok() throws Exception
{
{
iotHubConnectionString.getUrlDeviceStatistics();
new HttpRequest(mockUrl, HttpMethod.GET, new byte[0]);
new HttpRequest(mockUrl, HttpMethod.GET, new byte[0], (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1192,7 +1193,7 @@ public void exportDevices_jobProperties_good_case() throws Exception
{
{
iotHubConnectionString.getUrlCreateExportImportJob();
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1283,7 +1284,7 @@ public void exportDevices_good_case() throws Exception
{
{
iotHubConnectionString.getUrlCreateExportImportJob();
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1372,7 +1373,7 @@ public void importDevices_good_case() throws Exception
{
{
iotHubConnectionString.getUrlCreateExportImportJob();
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1437,7 +1438,7 @@ public void importDevices_jobProperties_good_case() throws Exception
{
{
iotHubConnectionString.getUrlCreateExportImportJob();
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.POST, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -1517,7 +1518,7 @@ public void getJob_good_case() throws Exception
{
{
iotHubConnectionString.getUrlImportExportJob(jobId);
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -2420,7 +2421,7 @@ public void applyConfigurationContentOnDeviceSuccess() throws Exception
iotHubConnectionString.getUrlApplyConfigurationContent(expectedDeviceId);
times = 1;

new HttpRequest(mockUrl, HttpMethod.POST, expectedJson.getBytes());
new HttpRequest(mockUrl, HttpMethod.POST, expectedJson.getBytes(), (Proxy) any);
times = 1;

new IotHubServiceSasToken(iotHubConnectionString);
Expand Down Expand Up @@ -2462,7 +2463,7 @@ private void commonVerifications(HttpMethod httpMethod, String requestDeviceId,
{
{
iotHubConnectionString.getUrlDevice(requestDeviceId);
new HttpRequest(mockUrl, httpMethod, (byte[]) any);
new HttpRequest(mockUrl, httpMethod, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -2501,7 +2502,7 @@ private void getDevicesVerifications(int numberOfDevices, ArrayList<Device> devi
{
iotHubConnectionString.getUrlDeviceList(numberOfDevices);
times = 1;
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any, (Proxy) any);
times = 1;
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
Expand Down Expand Up @@ -2541,7 +2542,7 @@ private void commonModuleVerifications(HttpMethod httpMethod, String requestDevi
{
{
iotHubConnectionString.getUrlModule(requestDeviceId, requestModuleId);
new HttpRequest(mockUrl, httpMethod, (byte[]) any);
new HttpRequest(mockUrl, httpMethod, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -2580,7 +2581,7 @@ private void getModulesVerifications(String deviceId, List<Module> modules) thro
{
iotHubConnectionString.getUrlModulesOnDevice(deviceId);
times = 1;
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any, (Proxy) any);
times = 1;
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
Expand Down Expand Up @@ -2620,7 +2621,7 @@ private void commonConfigVerifications(HttpMethod httpMethod, String requestConf
{
{
iotHubConnectionString.getUrlConfiguration(requestConfigId);
new HttpRequest(mockUrl, httpMethod, (byte[]) any);
new HttpRequest(mockUrl, httpMethod, (byte[]) any, (Proxy) any);
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
mockHttpRequest.setHeaderField("Request-Id", "1001");
Expand Down Expand Up @@ -2659,7 +2660,7 @@ private void getConfigsVerifications(int numOfConfigs, List<Configuration> confi
{
iotHubConnectionString.getUrlConfigurationsList(numOfConfigs);
times = 1;
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any);
new HttpRequest(mockUrl, HttpMethod.GET, (byte[]) any, (Proxy) any);
times = 1;
mockHttpRequest.setReadTimeoutMillis(anyInt);
mockHttpRequest.setHeaderField("authorization", anyString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.microsoft.azure.sdk.iot.service.transport.http.HttpConnection;
import com.microsoft.azure.sdk.iot.service.transport.http.HttpMethod;
import mockit.Expectations;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Verifications;
Expand All @@ -18,6 +19,7 @@
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.InputStream;
import java.net.Proxy;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
Expand Down Expand Up @@ -114,6 +116,25 @@ public void constructorSetsRequestMethod() throws IOException
};
}

// Tests_SRS_SERVICE_SDK_JAVA_HTTPSCONNECTION_12_003: [The constructor shall set the HTTPS method to the given method.]
@Test
public void constructorSetsProxy(@Mocked Proxy mockProxy) throws IOException
{
// Arrange
final HttpMethod httpsMethod = HttpMethod.PUT;
new Expectations()
{
{
mockUrl.getProtocol();
result = "https";
mockUrl.openConnection(mockProxy);
result = mockUrlConn;
}
};
// Act
new HttpConnection(mockUrl, httpsMethod, mockProxy);
}

// Tests_SRS_SERVICE_SDK_JAVA_HTTPSCONNECTION_12_004: [If the URI given does not use the HTTPS protocol, the constructor shall throw an IllegalArgumentException.]
// Assert
@Test(expected = IllegalArgumentException.class)
Expand Down
Loading