use of com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery in project azure-iot-sdk-java by Azure.
the class QueryTwinTests method testQueryTwin.
public void testQueryTwin() throws InterruptedException, ModuleClientException, IOException, GeneralSecurityException, IotHubException, URISyntaxException {
addMultipleDevices(MAX_DEVICES, false);
// Add same desired on multiple devices
final String queryProperty = PROPERTY_KEY_QUERY + UUID.randomUUID().toString();
final String queryPropertyValue = PROPERTY_VALUE_QUERY + UUID.randomUUID().toString();
setDesiredProperties(queryProperty, queryPropertyValue, MAX_DEVICES);
// Query multiple devices having same property
final String where = "is_defined(properties.desired." + queryProperty + ")";
SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, where, null);
Thread.sleep(MAXIMUM_TIME_FOR_IOTHUB_PROPAGATION_BETWEEN_DEVICE_SERVICE_CLIENTS);
Query twinQuery = testInstance.twinServiceClient.queryTwin(sqlQuery.getQuery(), PAGE_SIZE);
for (int i = 0; i < MAX_DEVICES; i++) {
if (testInstance.twinServiceClient.hasNextDeviceTwin(twinQuery)) {
DeviceTwinDevice d = testInstance.twinServiceClient.getNextDeviceTwin(twinQuery);
assertNotNull(d.getVersion());
assertEquals(TwinConnectionState.DISCONNECTED.toString(), d.getConnectionState());
for (Pair dp : d.getDesiredProperties()) {
Assert.assertEquals("Unexpected desired property key, expected " + queryProperty + " but was " + dp.getKey(), queryProperty, dp.getKey());
Assert.assertEquals("Unexpected desired property value, expected " + queryPropertyValue + " but was " + dp.getValue(), queryPropertyValue, dp.getValue());
}
}
}
assertFalse(testInstance.twinServiceClient.hasNextDeviceTwin(twinQuery));
}
use of com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery in project azure-iot-sdk-java by Azure.
the class QueryTwinTests method testRawQueryTwin.
public void testRawQueryTwin() throws IOException, InterruptedException, IotHubException, GeneralSecurityException, URISyntaxException, ModuleClientException {
addMultipleDevices(MAX_DEVICES, false);
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().serializeNulls().create();
// Add same desired on multiple devices
final String queryProperty = PROPERTY_KEY_QUERY + UUID.randomUUID().toString();
final String queryPropertyValue = PROPERTY_VALUE_QUERY + UUID.randomUUID().toString();
final int expectedNumberOfDevices = MAX_DEVICES;
setDesiredProperties(queryProperty, queryPropertyValue, MAX_DEVICES);
Thread.sleep(DESIRED_PROPERTIES_PROPAGATION_TIME_MILLISECONDS);
// Raw Query for multiple devices having same property
final String select = "properties.desired." + queryProperty + " AS " + queryProperty + "," + " COUNT() AS numberOfDevices";
final String groupBy = "properties.desired." + queryProperty;
final SqlQuery sqlQuery = SqlQuery.createSqlQuery(select, SqlQuery.FromType.DEVICES, null, groupBy);
boolean querySucceeded = false;
long startTime = System.currentTimeMillis();
while (!querySucceeded) {
Query rawTwinQuery = testInstance.rawTwinQueryClient.query(sqlQuery.getQuery(), PAGE_SIZE);
while (testInstance.rawTwinQueryClient.hasNext(rawTwinQuery)) {
String result = testInstance.rawTwinQueryClient.next(rawTwinQuery);
assertNotNull(result);
Map map = gson.fromJson(result, Map.class);
if (map.containsKey("numberOfDevices") && map.containsKey(queryProperty)) {
// Casting as a double first to get the value from the map, but then casting to an int because the
// number of devices should always be an integer
int actualNumberOfDevices = (int) (double) map.get("numberOfDevices");
if (actualNumberOfDevices == expectedNumberOfDevices) {
// Due to propagation delays, there will be times when the query is executed and only a
// subset of the expected devices are queryable. This test will loop until all of them are queryable
// to avoid this issue.
querySucceeded = true;
} else {
log.info("Expected device count not correct, re-running query");
Thread.sleep(200);
}
}
}
if (System.currentTimeMillis() - startTime > QUERY_TIMEOUT_MILLISECONDS) {
fail("Timed out waiting for query results to match expectations");
}
}
}
use of com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery in project azure-iot-sdk-java by Azure.
the class QueryTwinTests method testQueryTwinWithContinuationToken.
@Test
@StandardTierHubOnlyTest
@ContinuousIntegrationTest
public void testQueryTwinWithContinuationToken() throws IOException, InterruptedException, IotHubException, GeneralSecurityException, URISyntaxException, ModuleClientException {
addMultipleDevices(PAGE_SIZE + 1, false);
// Add same desired on multiple devices so that they can be queried
final String queryProperty = PROPERTY_KEY_QUERY + UUID.randomUUID().toString();
final String queryPropertyValue = PROPERTY_VALUE_QUERY + UUID.randomUUID().toString();
setDesiredProperties(queryProperty, queryPropertyValue, PAGE_SIZE + 1);
// Query multiple devices having same property
final String where = "is_defined(properties.desired." + queryProperty + ")";
SqlQuery sqlQuery;
if (this.testInstance.clientType == ClientType.MODULE_CLIENT) {
sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.MODULES, where, null);
} else {
sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, where, null);
}
// There is some propagation delay between when all the devices are created and have their twins set, and when
// they become queryable. This test assumes that eventually, the query result will have multiple pages. To
// avoid querying too soon, this test repeatedly queries until the continuation token is present in the return value
// as expected or until a timeout is hit.
String continuationToken = null;
Collection<DeviceTwinDevice> queriedDeviceTwinDeviceCollection = null;
long startTime = System.currentTimeMillis();
while (continuationToken == null) {
QueryCollection twinQueryCollection = testInstance.twinServiceClient.queryTwinCollection(sqlQuery.getQuery(), PAGE_SIZE);
// Run a query and save the continuation token for the second page of results
QueryCollectionResponse<DeviceTwinDevice> queryCollectionResponse = testInstance.twinServiceClient.next(twinQueryCollection);
queriedDeviceTwinDeviceCollection = queryCollectionResponse.getCollection();
continuationToken = queryCollectionResponse.getContinuationToken();
if (continuationToken == null) {
log.info("No continuation token detected yet, re-running the query");
Thread.sleep(200);
}
if (System.currentTimeMillis() - startTime > QUERY_TIMEOUT_MILLISECONDS) {
fail("Timed out waiting for query to return a continuation token");
}
}
// Re-run the same query using the saved continuation token. The results can be predicted since this test caused them
QueryOptions options = new QueryOptions();
options.setContinuationToken(continuationToken);
options.setPageSize(PAGE_SIZE);
QueryCollection twinQueryToReRun = testInstance.twinServiceClient.queryTwinCollection(sqlQuery.getQuery());
Collection<DeviceTwinDevice> continuedDeviceTwinDeviceQuery = testInstance.twinServiceClient.next(twinQueryToReRun, options).getCollection();
// Assert
assertEquals((long) PAGE_SIZE, queriedDeviceTwinDeviceCollection.size());
assertEquals(1, continuedDeviceTwinDeviceQuery.size());
// since order is not guaranteed, we cannot check that the third updated deviceTwinDevice is the third queried.
// Instead, all we can check is that each updated device twin identity is in either the initial query or the continued query.
ArrayList<String> expectedDeviceIds = new ArrayList<>();
for (int deviceTwinDeviceIndex = 0; deviceTwinDeviceIndex < PAGE_SIZE + 1; deviceTwinDeviceIndex++) {
expectedDeviceIds.add(testInstance.devicesUnderTest[deviceTwinDeviceIndex].sCDeviceForTwin.getDeviceId());
}
Collection<DeviceTwinDevice> allQueriedDeviceTwinDevices = new ArrayList<>(continuedDeviceTwinDeviceQuery);
continuedDeviceTwinDeviceQuery.addAll(queriedDeviceTwinDeviceCollection);
for (DeviceTwinDevice deviceTwinDevice : allQueriedDeviceTwinDevices) {
if (!expectedDeviceIds.contains(deviceTwinDevice.getDeviceId())) {
fail("Missing deviceTwinDevice: continuation token did not continue query where expected");
}
}
}
Aggregations