diff --git a/iot-e2e-tests/common/src/main/java/com/microsoft/azure/sdk/iot/common/tests/iothub/serviceclient/RegistryManagerTests.java b/iot-e2e-tests/common/src/main/java/com/microsoft/azure/sdk/iot/common/tests/iothub/serviceclient/RegistryManagerTests.java index 1fe3a28211..0bbe2728bc 100644 --- a/iot-e2e-tests/common/src/main/java/com/microsoft/azure/sdk/iot/common/tests/iothub/serviceclient/RegistryManagerTests.java +++ b/iot-e2e-tests/common/src/main/java/com/microsoft/azure/sdk/iot/common/tests/iothub/serviceclient/RegistryManagerTests.java @@ -5,9 +5,7 @@ package com.microsoft.azure.sdk.iot.common.tests.iothub.serviceclient; -import com.microsoft.azure.sdk.iot.common.helpers.ConditionalIgnoreRule; -import com.microsoft.azure.sdk.iot.common.helpers.IotHubIntegrationTest; -import com.microsoft.azure.sdk.iot.common.helpers.StandardTierOnlyRule; +import com.microsoft.azure.sdk.iot.common.helpers.*; import com.microsoft.azure.sdk.iot.common.helpers.Tools; import com.microsoft.azure.sdk.iot.deps.twin.DeviceCapabilities; import com.microsoft.azure.sdk.iot.service.*; @@ -16,9 +14,14 @@ import com.microsoft.azure.sdk.iot.service.exceptions.IotHubBadFormatException; import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException; import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; +import org.littleshoot.proxy.HttpProxyServer; +import org.littleshoot.proxy.impl.DefaultHttpProxyServer; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.net.URISyntaxException; import java.util.HashMap; import java.util.UUID; @@ -37,17 +40,19 @@ public class RegistryManagerTests extends IotHubIntegrationTest private static String moduleIdPrefix = "java-crud-module-e2e-test-"; private static String configIdPrefix = "java-crud-adm-e2e-test-"; private static String hostName; - private static RegistryManager registryManager; private static final String primaryThumbprint = "0000000000000000000000000000000000000000"; private static final String secondaryThumbprint = "1111111111111111111111111111111111111111"; private static final String primaryThumbprint2 = "2222222222222222222222222222222222222222"; private static final String secondaryThumbprint2 = "3333333333333333333333333333333333333333"; + protected static HttpProxyServer proxyServer; + protected static String testProxyHostname = "127.0.0.1"; + protected static int testProxyPort = 8879; + private static final long MAX_TEST_MILLISECONDS = 1 * 60 * 1000; public static void setUp() throws IOException { - registryManager = RegistryManager.createFromConnectionString(iotHubConnectionString); hostName = IotHubConnectionStringBuilder.createConnectionString(iotHubConnectionString).getHostName(); } @@ -58,6 +63,7 @@ public class RegistryManagerTestInstance public String deviceId; public String moduleId; public String configId; + private RegistryManager registryManager; public RegistryManagerTestInstance() throws InterruptedException, IOException, IotHubException, URISyntaxException { @@ -65,43 +71,78 @@ public RegistryManagerTestInstance() throws InterruptedException, IOException, I deviceId = deviceIdPrefix + uuid; moduleId = moduleIdPrefix + uuid; configId = configIdPrefix + uuid; + registryManager = RegistryManager.createFromConnectionString(iotHubConnectionString); } } - @AfterClass - public static void tearDown() + @BeforeClass + public static void startProxy() { - if (registryManager != null) - { - registryManager.close(); - registryManager = null; - } + proxyServer = DefaultHttpProxyServer.bootstrap() + .withPort(testProxyPort) + .start(); } + + @AfterClass + public static void stopProxy() + { + proxyServer.stop(); + } + @Test (timeout=MAX_TEST_MILLISECONDS) - public void crud_device_e2e() throws Exception + public void deviceLifecycle() throws Exception { //-Create-// RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); Device deviceAdded = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); - Tools.addDeviceWithRetry(registryManager, deviceAdded); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceAdded); + + //-Read-// + Device deviceRetrieved = testInstance.registryManager.getDevice(testInstance.deviceId); + + //-Update-// + Device deviceUpdated = testInstance.registryManager.getDevice(testInstance.deviceId); + deviceUpdated.setStatus(DeviceStatus.Disabled); + deviceUpdated = testInstance.registryManager.updateDevice(deviceUpdated); + + //-Delete-// + testInstance.registryManager.removeDevice(testInstance.deviceId); + + // Assert + assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceAdded.getDeviceId()); + assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceRetrieved.getDeviceId()); + assertEquals(buildExceptionMessage("", hostName), DeviceStatus.Disabled, deviceUpdated.getStatus()); + assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId)); + } + + @Test (timeout=MAX_TEST_MILLISECONDS) + public void deviceLifecycleWithProxy() throws Exception + { + RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); + Proxy testProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(testProxyHostname, testProxyPort)); + testInstance.registryManager.setProxy(testProxy); + + //-Create-// + Device deviceAdded = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceAdded); //-Read-// - Device deviceRetrieved = registryManager.getDevice(testInstance.deviceId); + Device deviceRetrieved = testInstance.registryManager.getDevice(testInstance.deviceId); //-Update-// - Device deviceUpdated = registryManager.getDevice(testInstance.deviceId); + Device deviceUpdated = testInstance.registryManager.getDevice(testInstance.deviceId); deviceUpdated.setStatus(DeviceStatus.Disabled); - deviceUpdated = registryManager.updateDevice(deviceUpdated); + deviceUpdated = testInstance.registryManager.updateDevice(deviceUpdated); //-Delete-// - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceAdded.getDeviceId()); assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceRetrieved.getDeviceId()); assertEquals(buildExceptionMessage("", hostName), DeviceStatus.Disabled, deviceUpdated.getStatus()); - assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(registryManager, testInstance.deviceId)); + assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId)); } @Test (timeout=MAX_TEST_MILLISECONDS) @@ -110,18 +151,18 @@ public void crud_device_e2e_X509_CA_signed() throws Exception //-Create-// RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); Device deviceAdded = Device.createDevice(testInstance.deviceId, AuthenticationType.CERTIFICATE_AUTHORITY); - Tools.addDeviceWithRetry(registryManager, deviceAdded); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceAdded); //-Read-// - Device deviceRetrieved = registryManager.getDevice(testInstance.deviceId); + Device deviceRetrieved = testInstance.registryManager.getDevice(testInstance.deviceId); //-Update-// - Device deviceUpdated = registryManager.getDevice(testInstance.deviceId); + Device deviceUpdated = testInstance.registryManager.getDevice(testInstance.deviceId); deviceUpdated.setStatus(DeviceStatus.Disabled); - deviceUpdated = registryManager.updateDevice(deviceUpdated); + deviceUpdated = testInstance.registryManager.updateDevice(deviceUpdated); //-Delete-// - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceAdded.getDeviceId()); @@ -132,7 +173,7 @@ public void crud_device_e2e_X509_CA_signed() throws Exception assertNull(buildExceptionMessage("", hostName), deviceAdded.getSecondaryKey()); assertNull(buildExceptionMessage("", hostName), deviceRetrieved.getPrimaryThumbprint()); assertNull(buildExceptionMessage("", hostName), deviceRetrieved.getSecondaryThumbprint()); - assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(registryManager, testInstance.deviceId)); + assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId)); } @Test (timeout=MAX_TEST_MILLISECONDS) @@ -142,18 +183,18 @@ public void crud_device_e2e_X509_self_signed() throws Exception RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); Device deviceAdded = Device.createDevice(testInstance.deviceId, AuthenticationType.SELF_SIGNED); deviceAdded.setThumbprintFinal(primaryThumbprint, secondaryThumbprint); - Tools.addDeviceWithRetry(registryManager, deviceAdded); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceAdded); //-Read-// - Device deviceRetrieved = registryManager.getDevice(testInstance.deviceId); + Device deviceRetrieved = testInstance.registryManager.getDevice(testInstance.deviceId); //-Update-// - Device deviceUpdated = registryManager.getDevice(testInstance.deviceId); + Device deviceUpdated = testInstance.registryManager.getDevice(testInstance.deviceId); deviceUpdated.setThumbprintFinal(primaryThumbprint2, secondaryThumbprint2); - deviceUpdated = registryManager.updateDevice(deviceUpdated); + deviceUpdated = testInstance.registryManager.updateDevice(deviceUpdated); //-Delete-// - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, deviceAdded.getDeviceId()); @@ -166,7 +207,7 @@ public void crud_device_e2e_X509_self_signed() throws Exception assertEquals(buildExceptionMessage("", hostName), secondaryThumbprint, deviceRetrieved.getSecondaryThumbprint()); assertEquals(buildExceptionMessage("", hostName), primaryThumbprint2, deviceUpdated.getPrimaryThumbprint()); assertEquals(buildExceptionMessage("", hostName), secondaryThumbprint2, deviceUpdated.getSecondaryThumbprint()); - assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(registryManager, testInstance.deviceId)); + assertTrue(buildExceptionMessage("", hostName), deviceWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId)); } //TODO what is this testing? @@ -187,24 +228,24 @@ public void crud_module_e2e() throws Exception SymmetricKey expectedSymmetricKey = new SymmetricKey(); Device deviceSetup = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); - Tools.addDeviceWithRetry(registryManager, deviceSetup); - deleteModuleIfItExistsAlready(registryManager, testInstance.deviceId, testInstance.moduleId); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceSetup); + deleteModuleIfItExistsAlready(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId); //-Create-// Module moduleAdded = Module.createFromId(testInstance.deviceId, testInstance.moduleId, null); - Tools.addModuleWithRetry(registryManager, moduleAdded); + Tools.addModuleWithRetry(testInstance.registryManager, moduleAdded); //-Read-// - Module moduleRetrieved = registryManager.getModule(testInstance.deviceId, testInstance.moduleId); + Module moduleRetrieved = testInstance.registryManager.getModule(testInstance.deviceId, testInstance.moduleId); //-Update-// - Module moduleUpdated = registryManager.getModule(testInstance.deviceId, testInstance.moduleId); + Module moduleUpdated = testInstance.registryManager.getModule(testInstance.deviceId, testInstance.moduleId); moduleUpdated.getSymmetricKey().setPrimaryKeyFinal(expectedSymmetricKey.getPrimaryKey()); - moduleUpdated = registryManager.updateModule(moduleUpdated); + moduleUpdated = testInstance.registryManager.updateModule(moduleUpdated); //-Delete-// - registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, moduleAdded.getDeviceId()); @@ -212,7 +253,7 @@ public void crud_module_e2e() throws Exception assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, moduleRetrieved.getDeviceId()); assertEquals(buildExceptionMessage("", hostName), testInstance.moduleId, moduleRetrieved.getId()); assertEquals(buildExceptionMessage("", hostName), expectedSymmetricKey.getPrimaryKey(), moduleUpdated.getPrimaryKey()); - assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(registryManager, testInstance.deviceId, testInstance.moduleId)); + assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId)); } @Test (timeout=MAX_TEST_MILLISECONDS) @@ -221,21 +262,21 @@ public void crud_module_e2e_X509_CA_signed() throws Exception { // Arrange RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); - deleteModuleIfItExistsAlready(registryManager, testInstance.deviceId, testInstance.moduleId); + deleteModuleIfItExistsAlready(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId); Device deviceSetup = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); - Tools.addDeviceWithRetry(registryManager, deviceSetup); - deleteModuleIfItExistsAlready(registryManager, testInstance.deviceId, testInstance.moduleId); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceSetup); + deleteModuleIfItExistsAlready(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId); //-Create-// Module moduleAdded = Module.createModule(testInstance.deviceId, testInstance.moduleId, AuthenticationType.CERTIFICATE_AUTHORITY); - Tools.addModuleWithRetry(registryManager, moduleAdded); + Tools.addModuleWithRetry(testInstance.registryManager, moduleAdded); //-Read-// - Module moduleRetrieved = registryManager.getModule(testInstance.deviceId, testInstance.moduleId); + Module moduleRetrieved = testInstance.registryManager.getModule(testInstance.deviceId, testInstance.moduleId); //-Delete-// - registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, moduleAdded.getDeviceId()); @@ -246,7 +287,7 @@ public void crud_module_e2e_X509_CA_signed() throws Exception assertNull(buildExceptionMessage("", hostName), moduleAdded.getSecondaryThumbprint()); assertNull(buildExceptionMessage("", hostName), moduleRetrieved.getPrimaryThumbprint()); assertNull(buildExceptionMessage("", hostName), moduleRetrieved.getSecondaryThumbprint()); - assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(registryManager, testInstance.deviceId, testInstance.moduleId)); + assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId)); } @Test (timeout=MAX_TEST_MILLISECONDS) @@ -256,24 +297,24 @@ public void crud_module_e2e_X509_self_signed() throws Exception // Arrange RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); Device deviceSetup = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); - Tools.addDeviceWithRetry(registryManager, deviceSetup); - deleteModuleIfItExistsAlready(registryManager, testInstance.deviceId, testInstance.moduleId); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceSetup); + deleteModuleIfItExistsAlready(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId); //-Create-// Module moduleAdded = Module.createModule(testInstance.deviceId, testInstance.moduleId, AuthenticationType.SELF_SIGNED); moduleAdded.setThumbprintFinal(primaryThumbprint, secondaryThumbprint); - Tools.addModuleWithRetry(registryManager, moduleAdded); + Tools.addModuleWithRetry(testInstance.registryManager, moduleAdded); //-Read-// - Module moduleRetrieved = registryManager.getModule(testInstance.deviceId, testInstance.moduleId); + Module moduleRetrieved = testInstance.registryManager.getModule(testInstance.deviceId, testInstance.moduleId); //-Update-// - Module moduleUpdated = registryManager.getModule(testInstance.deviceId, testInstance.moduleId); + Module moduleUpdated = testInstance.registryManager.getModule(testInstance.deviceId, testInstance.moduleId); moduleUpdated.setThumbprintFinal(primaryThumbprint2, secondaryThumbprint2); - moduleUpdated = registryManager.updateModule(moduleUpdated); + moduleUpdated = testInstance.registryManager.updateModule(moduleUpdated); //-Delete-// - registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); + testInstance.registryManager.removeModule(testInstance.deviceId, testInstance.moduleId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.deviceId, moduleAdded.getDeviceId()); @@ -288,7 +329,7 @@ public void crud_module_e2e_X509_self_signed() throws Exception assertEquals(buildExceptionMessage("", hostName), secondaryThumbprint, moduleRetrieved.getSecondaryThumbprint()); assertEquals(buildExceptionMessage("", hostName), primaryThumbprint2, moduleUpdated.getPrimaryThumbprint()); assertEquals(buildExceptionMessage("", hostName), secondaryThumbprint2, moduleUpdated.getSecondaryThumbprint()); - assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(registryManager, testInstance.deviceId, testInstance.moduleId)); + assertTrue(buildExceptionMessage("", hostName), moduleWasDeletedSuccessfully(testInstance.registryManager, testInstance.deviceId, testInstance.moduleId)); } @Test (timeout=MAX_TEST_MILLISECONDS) @@ -321,18 +362,18 @@ public void crud_adm_configuration_e2e() throws Exception "SELECT deviceId FROM devices WHERE properties.reported.chillerWaterSettings.status=\'pending\'");}}); configAdded.setTargetCondition("properties.reported.chillerProperties.model=\'4000x\'"); configAdded.setPriority(20); - registryManager.addConfiguration(configAdded); + testInstance.registryManager.addConfiguration(configAdded); //-Read-// - Configuration configRetrieved = registryManager.getConfiguration(testInstance.configId); + Configuration configRetrieved = testInstance.registryManager.getConfiguration(testInstance.configId); //-Update-// - Configuration configUpdated = registryManager.getConfiguration(testInstance.configId); + Configuration configUpdated = testInstance.registryManager.getConfiguration(testInstance.configId); configUpdated.setPriority(1); - configUpdated = registryManager.updateConfiguration(configUpdated); + configUpdated = testInstance.registryManager.updateConfiguration(configUpdated); //-Delete-// - registryManager.removeConfiguration(testInstance.configId); + testInstance.registryManager.removeConfiguration(testInstance.configId); // Assert assertEquals(buildExceptionMessage("", hostName), testInstance.configId, configAdded.getId()); @@ -355,7 +396,7 @@ public void crud_adm_configuration_e2e() throws Exception assertEquals(buildExceptionMessage("", hostName), new Integer(20), configRetrieved.getPriority()); assertEquals(buildExceptionMessage("", hostName), testInstance.configId, configUpdated.getId()); assertEquals(buildExceptionMessage("", hostName), new Integer(1), configUpdated.getPriority()); - assertTrue(buildExceptionMessage("", hostName), configWasDeletedSuccessfully(registryManager, testInstance.configId)); + assertTrue(buildExceptionMessage("", hostName), configWasDeletedSuccessfully(testInstance.registryManager, testInstance.configId)); } @Test (expected = IotHubBadFormatException.class) @@ -365,7 +406,7 @@ public void apply_configuration_e2e() throws Exception // Arrange RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); Device deviceSetup = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); - Tools.addDeviceWithRetry(registryManager, deviceSetup); + Tools.addDeviceWithRetry(testInstance.registryManager, deviceSetup); final HashMap testDeviceContent = new HashMap() { { @@ -383,7 +424,7 @@ public void apply_configuration_e2e() throws Exception content.setDeviceContent(testDeviceContent); // Act - registryManager.applyConfigurationContentOnDevice(testInstance.deviceId, content); + testInstance.registryManager.applyConfigurationContentOnDevice(testInstance.deviceId, content); } @ConditionalIgnoreRule.ConditionalIgnore(condition = StandardTierOnlyRule.class) @@ -392,26 +433,26 @@ public void deviceCreationWithSecurityScope() throws IOException, InterruptedExc { // Arrange RegistryManagerTestInstance testInstance = new RegistryManagerTestInstance(); - deleteDeviceIfItExistsAlready(registryManager, testInstance.deviceId); + deleteDeviceIfItExistsAlready(testInstance.registryManager, testInstance.deviceId); //-Create-// Device edgeDevice = Device.createFromId(testInstance.deviceId, DeviceStatus.Enabled, null); DeviceCapabilities capabilities = new DeviceCapabilities(); capabilities.setIotEdge(true); edgeDevice.setCapabilities(capabilities); - edgeDevice = Tools.addDeviceWithRetry(registryManager, edgeDevice); + edgeDevice = Tools.addDeviceWithRetry(testInstance.registryManager, edgeDevice); Device leafDevice = Device.createFromId(testInstance.deviceId + "-leaf", DeviceStatus.Enabled, null); assertNotNull(edgeDevice.getScope()); leafDevice.setScope(edgeDevice.getScope()); - Tools.addDeviceWithRetry(registryManager, leafDevice); + Tools.addDeviceWithRetry(testInstance.registryManager, leafDevice); //-Read-// - Device deviceRetrieved = registryManager.getDevice(testInstance.deviceId); + Device deviceRetrieved = testInstance.registryManager.getDevice(testInstance.deviceId); //-Delete-// - registryManager.removeDevice(testInstance.deviceId); + testInstance.registryManager.removeDevice(testInstance.deviceId); // Assert assertEquals(buildExceptionMessage("Registered device id is not correct", hostName), testInstance.deviceId, edgeDevice.getDeviceId()); @@ -419,7 +460,7 @@ public void deviceCreationWithSecurityScope() throws IOException, InterruptedExc assertEquals(buildExceptionMessage("Security scopes did not match", hostName), deviceRetrieved.getScope(), edgeDevice.getScope()); } - private void deleteDeviceIfItExistsAlready(RegistryManager registryManager, String deviceId) throws IOException, InterruptedException + private static void deleteDeviceIfItExistsAlready(RegistryManager registryManager, String deviceId) throws IOException, InterruptedException { try { @@ -440,7 +481,7 @@ private void deleteDeviceIfItExistsAlready(RegistryManager registryManager, Stri } } - private void deleteModuleIfItExistsAlready(RegistryManager registryManager, String deviceId, String moduleId) throws IOException, InterruptedException + private static void deleteModuleIfItExistsAlready(RegistryManager registryManager, String deviceId, String moduleId) throws IOException, InterruptedException { try { @@ -461,7 +502,7 @@ private void deleteModuleIfItExistsAlready(RegistryManager registryManager, Stri } } - private boolean deviceWasDeletedSuccessfully(RegistryManager registryManager, String deviceId) throws IOException + private static boolean deviceWasDeletedSuccessfully(RegistryManager registryManager, String deviceId) throws IOException { try { @@ -477,7 +518,7 @@ private boolean deviceWasDeletedSuccessfully(RegistryManager registryManager, St return false; } - private boolean moduleWasDeletedSuccessfully(RegistryManager registryManager, String deviceId, String moduleId) throws IOException + private static boolean moduleWasDeletedSuccessfully(RegistryManager registryManager, String deviceId, String moduleId) throws IOException { try { @@ -493,7 +534,7 @@ private boolean moduleWasDeletedSuccessfully(RegistryManager registryManager, St return false; } - private boolean configWasDeletedSuccessfully(RegistryManager registryManager, String configId) throws IOException + private static boolean configWasDeletedSuccessfully(RegistryManager registryManager, String configId) throws IOException { try { diff --git a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/RegistryManager.java b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/RegistryManager.java index d4e2c22793..1fd63b42cb 100644 --- a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/RegistryManager.java +++ b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/RegistryManager.java @@ -16,6 +16,8 @@ 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; @@ -23,6 +25,7 @@ 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; @@ -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 * @@ -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; } @@ -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"); diff --git a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnection.java b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnection.java index 54036aac4d..57a9ffac26 100644 --- a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnection.java +++ b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnection.java @@ -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; @@ -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(); @@ -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) diff --git a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpRequest.java b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpRequest.java index d61fc03306..4066b75795 100644 --- a/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpRequest.java +++ b/service/iot-service-client/src/main/java/com/microsoft/azure/sdk/iot/service/transport/http/HttpRequest.java @@ -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; @@ -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); diff --git a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/RegistryManagerTest.java b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/RegistryManagerTest.java index 6e3b61316a..eb0262ea5f 100644 --- a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/RegistryManagerTest.java +++ b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/RegistryManagerTest.java @@ -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; @@ -1083,7 +1084,7 @@ 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"; @@ -1091,14 +1092,14 @@ public void getStatistics_good_case() throws Exception 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"); @@ -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"); @@ -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"); @@ -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"); @@ -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"); @@ -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"); @@ -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"); @@ -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); @@ -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"); @@ -2501,7 +2502,7 @@ private void getDevicesVerifications(int numberOfDevices, ArrayList 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); @@ -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"); @@ -2580,7 +2581,7 @@ private void getModulesVerifications(String deviceId, List 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); @@ -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"); @@ -2659,7 +2660,7 @@ private void getConfigsVerifications(int numOfConfigs, List 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); diff --git a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnectionTest.java b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnectionTest.java index 977931c4c3..0c5ce1d574 100644 --- a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnectionTest.java +++ b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpConnectionTest.java @@ -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; @@ -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; @@ -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) diff --git a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpsRequestTest.java b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpsRequestTest.java index 95bb174ee5..1e7880461f 100644 --- a/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpsRequestTest.java +++ b/service/iot-service-client/src/test/java/tests/unit/com/microsoft/azure/sdk/iot/service/transport/http/HttpsRequestTest.java @@ -16,6 +16,7 @@ import org.junit.runner.RunWith; import java.io.IOException; +import java.net.Proxy; import java.net.URL; import java.util.HashMap; import java.util.LinkedList; @@ -49,7 +50,7 @@ public void constructorOpensConnection(@Mocked final HttpConnection mockConn, fi new Verifications() { { - new HttpConnection(mockUrl, (HttpMethod) any); + new HttpConnection(mockUrl, (HttpMethod) any, (Proxy) any); } }; } @@ -75,7 +76,7 @@ public void constructorWritesBodyToConnection(@Mocked final HttpConnection mockC new Verifications() { { - new HttpConnection(mockUrl, (HttpMethod) any) + new HttpConnection(mockUrl, (HttpMethod) any, (Proxy) any) .writeOutput(expectedBody); } }; @@ -101,7 +102,7 @@ public void constructorSetsHttpsMethodCorrectly(@Mocked final HttpConnection moc new Verifications() { { - new HttpConnection((URL) any, httpsMethod); + new HttpConnection((URL) any, httpsMethod, (Proxy) any); } }; } @@ -119,7 +120,7 @@ public void constructorThrowsIoExceptionIfCannotSetupConnection(@Mocked final Ht { mockUrl.getProtocol(); result = "http"; - new HttpConnection(mockUrl, httpsMethod); + new HttpConnection(mockUrl, httpsMethod, (Proxy) any); result = new IOException(); } }; @@ -139,7 +140,7 @@ public void sendHasCorrectHttpsMethod() throws IOException HttpMethod testMethod; @Mock - public void $init(URL url, HttpMethod method) + public void $init(URL url, HttpMethod method, Proxy proxy) { this.testMethod = method; } @@ -195,7 +196,7 @@ public Map> getResponseHeaders() } }; // Assert - HttpRequest request = new HttpRequest(new URL("http://www.microsoft.com"), expectedMethod, body); + HttpRequest request = new HttpRequest(new URL("https://www.microsoft.com"), expectedMethod, body); // Act request.send(); } @@ -277,7 +278,7 @@ public Map> getResponseHeaders() }; // Assert // Act - HttpRequest request = new HttpRequest(new URL("http://www.microsoft.com"), expectedMethod, body); + HttpRequest request = new HttpRequest(new URL("https://www.microsoft.com"), expectedMethod, body); request.setHeaderField(field0, value0); request.setHeaderField(field1, value1); request.send(); @@ -350,7 +351,7 @@ public Map> getResponseHeaders() } }; // Act - HttpRequest request = new HttpRequest(new URL("http://www.microsoft.com"), httpsMethod, expectedBody); + HttpRequest request = new HttpRequest(new URL("https://www.microsoft.com"), httpsMethod, expectedBody); request.send(); }