use of tests.integration.com.microsoft.azure.sdk.iot.helpers.EventCallback in project azure-iot-sdk-java by Azure.
the class MultiplexingClientTests method testSendingMessageFromDeviceClient.
private static Success testSendingMessageFromDeviceClient(DeviceClient multiplexedClient, Message message) {
Success messageSendSuccess = new Success();
EventCallback messageSentCallback = new EventCallback(IotHubStatusCode.OK_EMPTY);
multiplexedClient.sendEventAsync(message, messageSentCallback, messageSendSuccess);
return messageSendSuccess;
}
use of tests.integration.com.microsoft.azure.sdk.iot.helpers.EventCallback in project azure-iot-sdk-java by Azure.
the class MultiplexingClientTests method multiplexedSessionsRecoverSubscriptionsFromDeviceSessionDrops.
// If a multiplexed device is subscribed to twin and/or methods and/or cloud to device messages, then loses its
// session due to network issues, it should still be subscribed to twin and/or methods and/or cloud to device messages
// after it finishes reconnection
@StandardTierHubOnlyTest
@ContinuousIntegrationTest
@ErrInjTest
@IotHubTest
@Test
public void multiplexedSessionsRecoverSubscriptionsFromDeviceSessionDrops() throws Exception {
testInstance.setup(DEVICE_MULTIPLEX_COUNT, MultiplexingClientOptions.builder().build(), true);
ConnectionStatusChangeTracker multiplexedConnectionStatusChangeTracker = new ConnectionStatusChangeTracker();
testInstance.multiplexingClient.registerConnectionStatusChangeCallback(multiplexedConnectionStatusChangeTracker, null);
ConnectionStatusChangeTracker[] connectionStatusChangeTrackers = new ConnectionStatusChangeTracker[DEVICE_MULTIPLEX_COUNT];
DeviceTwin deviceTwinServiceClient = new DeviceTwin(iotHubConnectionString, DeviceTwinClientOptions.builder().httpReadTimeout(0).build());
DeviceMethod deviceMethodServiceClient = new DeviceMethod(iotHubConnectionString, DeviceMethodClientOptions.builder().httpReadTimeout(0).build());
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
connectionStatusChangeTrackers[i] = new ConnectionStatusChangeTracker();
testInstance.deviceClientArray.get(i).registerConnectionStatusChangeCallback(connectionStatusChangeTrackers[i], null);
}
testInstance.multiplexingClient.open();
// Subscribe to methods for all multiplexed clients
DeviceMethodCallback[] deviceMethodCallbacks = new DeviceMethodCallback[DEVICE_MULTIPLEX_COUNT];
String[] expectedMethodNames = new String[DEVICE_MULTIPLEX_COUNT];
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
expectedMethodNames[i] = UUID.randomUUID().toString();
deviceMethodCallbacks[i] = new DeviceMethodCallback(expectedMethodNames[i]);
subscribeToDeviceMethod(testInstance.deviceClientArray.get(i), deviceMethodCallbacks[i]);
}
// Start twin for all multiplexed clients
String[] expectedPropertyKeys = new String[DEVICE_MULTIPLEX_COUNT];
String[] expectedPropertyValues = new String[DEVICE_MULTIPLEX_COUNT];
TwinPropertyCallBackImpl[] twinPropertyCallBacks = new TwinPropertyCallBackImpl[DEVICE_MULTIPLEX_COUNT];
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// The twin for this test identity is about to be modified. Set this flag so that the test identity recycler re-uses this identity only for tests
// that don't care about the initial twin state of an identity
testInstance.testDevicesArrayIdentity.get(i).twinUpdated = true;
expectedPropertyKeys[i] = UUID.randomUUID().toString();
expectedPropertyValues[i] = UUID.randomUUID().toString();
twinPropertyCallBacks[i] = new TwinPropertyCallBackImpl(expectedPropertyKeys[i], expectedPropertyValues[i]);
startTwin(testInstance.deviceClientArray.get(i), new EventCallback(IotHubStatusCode.OK), twinPropertyCallBacks[i]);
}
// Subscribe to cloud to device messages for all multiplexed clients
String[] expectedMessageCorrelationIds = new String[DEVICE_MULTIPLEX_COUNT];
MessageCallback[] messageCallbacks = new MessageCallback[DEVICE_MULTIPLEX_COUNT];
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
expectedMessageCorrelationIds[i] = UUID.randomUUID().toString();
messageCallbacks[i] = new MessageCallback(expectedMessageCorrelationIds[i]);
testInstance.deviceClientArray.get(i).setMessageCallback(messageCallbacks[i], null);
}
// For each multiplexed device, use fault injection to drop the session and see if it can recover, one device at a time
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
log.info("Starting loop for device {}", testInstance.deviceClientArray.get(i).getConfig().getDeviceId());
Message errorInjectionMessage = ErrorInjectionHelper.amqpsSessionDropErrorInjectionMessage(1, 10);
Success messageSendSuccess = testSendingMessageFromDeviceClient(testInstance.deviceClientArray.get(i), errorInjectionMessage);
waitForMessageToBeAcknowledged(messageSendSuccess, "Timed out waiting for error injection message to be acknowledged");
// Now that error injection message has been sent, need to wait for the device session to drop
assertConnectionStateCallbackFiredDisconnectedRetrying(connectionStatusChangeTrackers[i]);
// Next, the faulted device should eventually recover
log.info("Waiting for device {} to reconnect", testInstance.deviceClientArray.get(i).getConfig().getDeviceId());
assertConnectionStateCallbackFiredConnected(connectionStatusChangeTrackers[i], FAULT_INJECTION_RECOVERY_TIMEOUT_MILLIS);
for (int j = i + 1; j < DEVICE_MULTIPLEX_COUNT; j++) {
// devices above index i have not been deliberately faulted yet, so make sure they haven't seen a DISCONNECTED_RETRYING event yet.
assertFalse("Multiplexed device that hasn't been deliberately faulted yet saw an unexpected DISCONNECTED_RETRYING connection status callback", connectionStatusChangeTrackers[j].wentDisconnectedRetrying);
}
}
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// test d2c telemetry
testSendingMessagesFromMultiplexedClients(testInstance.deviceClientArray);
// test receiving direct methods
testDeviceMethod(deviceMethodServiceClient, testInstance.deviceIdentityArray.get(i).getDeviceId(), expectedMethodNames[i], deviceMethodCallbacks[i]);
// Send desired property update to multiplexed device
testDesiredPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, twinPropertyCallBacks[i], expectedPropertyKeys[i], expectedPropertyValues[i]);
// Testing sending reported properties
testReportedPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, expectedPropertyKeys[i], expectedPropertyValues[i]);
testReceivingCloudToDeviceMessage(testInstance.deviceIdentityArray.get(i).getDeviceId(), messageCallbacks[i], expectedMessageCorrelationIds[i]);
}
assertFalse(multiplexedConnectionStatusChangeTracker.wentDisconnectedRetrying);
testInstance.multiplexingClient.close();
assertMultiplexedDevicesClosedGracefully(connectionStatusChangeTrackers);
}
use of tests.integration.com.microsoft.azure.sdk.iot.helpers.EventCallback in project azure-iot-sdk-java by Azure.
the class MultiplexingClientTests method twinSubscriptionNotPreservedByDeviceClientAfterUnregistration.
// Twin subscriptions and callbacks should not be preserved between registrations by default
@Test
@ContinuousIntegrationTest
@StandardTierHubOnlyTest
public void twinSubscriptionNotPreservedByDeviceClientAfterUnregistration() throws Exception {
testInstance.setup(DEVICE_MULTIPLEX_COUNT, MultiplexingClientOptions.builder().build(), true);
testInstance.multiplexingClient.open();
DeviceTwin deviceTwinServiceClient = DeviceTwin.createFromConnectionString(iotHubConnectionString, DeviceTwinClientOptions.builder().httpReadTimeout(0).build());
String expectedPropertyKey = UUID.randomUUID().toString();
String expectedPropertyValue = UUID.randomUUID().toString();
List<TwinPropertyCallBackImpl> twinPropertyCallBacks = new ArrayList<>();
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// The twin for this test identity is about to be modified. Set this flag so that the test identity recycler re-uses this identity only for tests
// that don't care about the initial twin state of an identity
testInstance.testDevicesArrayIdentity.get(i).twinUpdated = true;
TwinPropertyCallBackImpl twinPropertyCallBack = new TwinPropertyCallBackImpl(expectedPropertyKey, expectedPropertyValue);
twinPropertyCallBacks.add(twinPropertyCallBack);
startTwin(testInstance.deviceClientArray.get(i), new EventCallback(IotHubStatusCode.OK), twinPropertyCallBack);
}
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// Testing subscribing to desired properties
testDesiredPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, twinPropertyCallBacks.get(i), expectedPropertyKey, expectedPropertyValue);
// Testing sending reported properties
testReportedPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, expectedPropertyKey, expectedPropertyValue);
}
// unregister and then re-register the clients to see if their subscriptions were preserved or not
testInstance.multiplexingClient.unregisterDeviceClients(testInstance.deviceClientArray);
testInstance.multiplexingClient.registerDeviceClients(testInstance.deviceClientArray);
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
boolean expectedExceptionThrown = false;
try {
// Testing sending reported properties
testReportedPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, expectedPropertyKey, expectedPropertyValue);
} catch (IOException e) {
// IOException seems odd here, since we are testing what should be an IllegalStateException or UnsupportedOperationException,
// but it would be a breaking change to modify the device clien to throw that exception when a twin method is
// called without first starting twin.
expectedExceptionThrown = true;
}
assertTrue("Expected twin method to throw since twin has not been started since re-registering client", expectedExceptionThrown);
}
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// The twin for this test identity is about to be modified. Set this flag so that the test identity recycler re-uses this identity only for tests
// that don't care about the initial twin state of an identity
testInstance.testDevicesArrayIdentity.get(i).twinUpdated = true;
TwinPropertyCallBackImpl twinPropertyCallBack = new TwinPropertyCallBackImpl(expectedPropertyKey, expectedPropertyValue);
twinPropertyCallBacks.add(twinPropertyCallBack);
startTwin(testInstance.deviceClientArray.get(i), new EventCallback(IotHubStatusCode.OK), twinPropertyCallBack);
}
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// Testing subscribing to desired properties
testDesiredPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, twinPropertyCallBacks.get(i), expectedPropertyKey, expectedPropertyValue);
// Testing sending reported properties
testReportedPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, expectedPropertyKey, expectedPropertyValue);
}
}
use of tests.integration.com.microsoft.azure.sdk.iot.helpers.EventCallback in project azure-iot-sdk-java by Azure.
the class MultiplexingClientTests method unregisterClientAfterOpen.
// Unregister a single device from an active multiplexed connection, test that other devices on that connection
// can still be used to send telemetry.
@Test
@StandardTierHubOnlyTest
public void unregisterClientAfterOpen() throws Exception {
testInstance.setup(DEVICE_MULTIPLEX_COUNT);
// pick the 0th client to unregister after open. This will help make sure we don't have any dependencies on the 0th registered client
DeviceClient clientToUnregisterAfterOpen = testInstance.deviceClientArray.get(0);
ConnectionStatusChangeTracker connectionStatusChangeTracker = new ConnectionStatusChangeTracker();
clientToUnregisterAfterOpen.registerConnectionStatusChangeCallback(connectionStatusChangeTracker, null);
testInstance.multiplexingClient.open();
assertConnectionStateCallbackFiredConnected(connectionStatusChangeTracker, DEVICE_SESSION_OPEN_TIMEOUT);
testInstance.multiplexingClient.unregisterDeviceClient(clientToUnregisterAfterOpen);
assertDeviceSessionClosesGracefully(connectionStatusChangeTracker, DEVICE_SESSION_CLOSE_TIMEOUT);
// start index from 1 since the 0th client was deliberately unregistered
for (int i = 1; i < DEVICE_MULTIPLEX_COUNT; i++) {
testSendingMessageFromDeviceClient(testInstance.deviceClientArray.get(i));
}
// verify that unregistered clients don't attempt to send messages on the active multiplexed connection after unregistration
boolean exceptionThrown;
try {
testInstance.deviceClientArray.get(0).sendEventAsync(new Message("This message shouldn't be sent"), new EventCallback(IotHubStatusCode.OK_EMPTY), null);
exceptionThrown = false;
} catch (UnsupportedOperationException e) {
exceptionThrown = true;
}
assertTrue("Expected exception to be thrown when sending a message from an unregistered client", exceptionThrown);
}
use of tests.integration.com.microsoft.azure.sdk.iot.helpers.EventCallback in project azure-iot-sdk-java by Azure.
the class MultiplexingClientTests method testTwin.
@Test
@StandardTierHubOnlyTest
public void testTwin() throws Exception {
testInstance.setup(DEVICE_MULTIPLEX_COUNT, MultiplexingClientOptions.builder().build(), true);
testInstance.multiplexingClient.open();
DeviceTwin deviceTwinServiceClient = DeviceTwin.createFromConnectionString(iotHubConnectionString, DeviceTwinClientOptions.builder().httpReadTimeout(0).build());
for (int i = 0; i < DEVICE_MULTIPLEX_COUNT; i++) {
// The twin for this test identity is about to be modified. Set this flag so that the test identity recycler re-uses this identity only for tests
// that don't care about the initial twin state of an identity
testInstance.testDevicesArrayIdentity.get(i).twinUpdated = true;
String expectedPropertyKey = UUID.randomUUID().toString();
String expectedPropertyValue = UUID.randomUUID().toString();
TwinPropertyCallBackImpl twinPropertyCallBack = new TwinPropertyCallBackImpl(expectedPropertyKey, expectedPropertyValue);
startTwin(testInstance.deviceClientArray.get(i), new EventCallback(IotHubStatusCode.OK), twinPropertyCallBack);
// Testing subscribing to desired properties
Map<Property, Pair<TwinPropertyCallBack, Object>> onDesiredPropertyChange = new HashMap<>();
onDesiredPropertyChange.put(new Property(expectedPropertyKey, null), new Pair<>(twinPropertyCallBack, null));
testInstance.deviceClientArray.get(i).subscribeToTwinDesiredProperties(onDesiredPropertyChange);
Thread.sleep(MAXIMUM_TIME_TO_WAIT_FOR_DESIRED_PROPERTY_SUBSCRIPTION_ACKNOWLEDGEMENT);
// Send desired property update to multiplexed device
testDesiredPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, twinPropertyCallBack, expectedPropertyKey, expectedPropertyValue);
// Testing sending reported properties
testReportedPropertiesFlow(testInstance.deviceClientArray.get(i), deviceTwinServiceClient, expectedPropertyKey, expectedPropertyValue);
}
}
Aggregations