Commit d14a1d69a56b7f31f738526aa1d74cd4675a7c09

Authored by VoBa
Committed by GitHub
2 parents 17cb573e 65c67e78

Merge pull request #1137 from thingsboard/feature/entity-view-type

Feature/entity view type
@@ -85,11 +85,11 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -85,11 +85,11 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
85 testDevice = doPost("/api/device", device, Device.class); 85 testDevice = doPost("/api/device", device, Device.class);
86 86
87 telemetry = new TelemetryEntityView( 87 telemetry = new TelemetryEntityView(
88 - Arrays.asList("109", "209", "309"), 88 + Arrays.asList("tsKey1", "tsKey2", "tsKey3"),
89 new AttributesEntityView( 89 new AttributesEntityView(
90 - Arrays.asList("caValue1", "caValue2", "caValue3", "caValue4"),  
91 - Arrays.asList("saValue1", "saValue2", "saValue3", "saValue4"),  
92 - Arrays.asList("shValue1", "shValue2", "shValue3", "shValue4"))); 90 + Arrays.asList("caKey1", "caKey2", "caKey3", "caKey4"),
  91 + Arrays.asList("saKey1", "saKey2", "saKey3", "saKey4"),
  92 + Arrays.asList("shKey1", "shKey2", "shKey3", "shKey4")));
93 } 93 }
94 94
95 @After 95 @After
@@ -324,10 +324,10 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -324,10 +324,10 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
324 @Test 324 @Test
325 public void testTheCopyOfAttrsIntoTSForTheView() throws Exception { 325 public void testTheCopyOfAttrsIntoTSForTheView() throws Exception {
326 Set<String> actualAttributesSet = 326 Set<String> actualAttributesSet =
327 - getAttributesByKeys("{\"caValue1\":\"value1\", \"caValue2\":true, \"caValue3\":42.0, \"caValue4\":73}"); 327 + getAttributesByKeys("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}");
328 328
329 Set<String> expectedActualAttributesSet = 329 Set<String> expectedActualAttributesSet =
330 - new HashSet<>(Arrays.asList("caValue1", "caValue2", "caValue3", "caValue4")); 330 + new HashSet<>(Arrays.asList("caKey1", "caKey2", "caKey3", "caKey4"));
331 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet)); 331 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet));
332 Thread.sleep(1000); 332 Thread.sleep(1000);
333 333
@@ -335,18 +335,18 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -335,18 +335,18 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
335 List<Map<String, Object>> values = doGetAsync("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() + 335 List<Map<String, Object>> values = doGetAsync("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() +
336 "/values/attributes?keys=" + String.join(",", actualAttributesSet), List.class); 336 "/values/attributes?keys=" + String.join(",", actualAttributesSet), List.class);
337 337
338 - assertEquals("value1", getValue(values, "caValue1"));  
339 - assertEquals(true, getValue(values, "caValue2"));  
340 - assertEquals(42.0, getValue(values, "caValue3"));  
341 - assertEquals(73, getValue(values, "caValue4")); 338 + assertEquals("value1", getValue(values, "caKey1"));
  339 + assertEquals(true, getValue(values, "caKey2"));
  340 + assertEquals(42.0, getValue(values, "caKey3"));
  341 + assertEquals(73, getValue(values, "caKey4"));
342 } 342 }
343 343
344 @Test 344 @Test
345 public void testTheCopyOfAttrsOutOfTSForTheView() throws Exception { 345 public void testTheCopyOfAttrsOutOfTSForTheView() throws Exception {
346 Set<String> actualAttributesSet = 346 Set<String> actualAttributesSet =
347 - getAttributesByKeys("{\"caValue1\":\"value1\", \"caValue2\":true, \"caValue3\":42.0, \"caValue4\":73}"); 347 + getAttributesByKeys("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}");
348 348
349 - Set<String> expectedActualAttributesSet = new HashSet<>(Arrays.asList("caValue1", "caValue2", "caValue3", "caValue4")); 349 + Set<String> expectedActualAttributesSet = new HashSet<>(Arrays.asList("caKey1", "caKey2", "caKey3", "caKey4"));
350 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet)); 350 assertTrue(actualAttributesSet.containsAll(expectedActualAttributesSet));
351 Thread.sleep(1000); 351 Thread.sleep(1000);
352 352
@@ -368,6 +368,69 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -368,6 +368,69 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
368 assertEquals(0, values.size()); 368 assertEquals(0, values.size());
369 } 369 }
370 370
  371 +
  372 + @Test
  373 + public void testGetTelemetryWhenEntityViewTimeRangeInsideTimestampRange() throws Exception {
  374 + uploadTelemetry("{\"tsKey1\":\"value1\", \"tsKey2\":true, \"tsKey3\":40.0}");
  375 + Thread.sleep(1000);
  376 + long startTimeMs = System.currentTimeMillis();
  377 + uploadTelemetry("{\"tsKey1\":\"value2\", \"tsKey2\":false, \"tsKey3\":80.0}");
  378 + Thread.sleep(1000);
  379 + uploadTelemetry("{\"tsKey1\":\"value3\", \"tsKey2\":false, \"tsKey3\":120.0}");
  380 + long endTimeMs = System.currentTimeMillis();
  381 + uploadTelemetry("{\"tsKey1\":\"value4\", \"tsKey2\":true, \"tsKey3\":160.0}");
  382 +
  383 + String deviceId = testDevice.getId().getId().toString();
  384 + Set<String> keys = getTelemetryKeys("DEVICE", deviceId);
  385 + Thread.sleep(1000);
  386 +
  387 + EntityView view = createEntityView("Test entity view", startTimeMs, endTimeMs);
  388 + EntityView savedView = doPost("/api/entityView", view, EntityView.class);
  389 + String entityViewId = savedView.getId().getId().toString();
  390 +
  391 + Map<String, List<Map<String, String>>> expectedValues = getTelemetryValues("DEVICE", deviceId, keys, 0L, (startTimeMs + endTimeMs) / 2);
  392 + Assert.assertEquals(2, expectedValues.get("tsKey1").size());
  393 + Assert.assertEquals(2, expectedValues.get("tsKey2").size());
  394 + Assert.assertEquals(2, expectedValues.get("tsKey3").size());
  395 +
  396 + Map<String, List<Map<String, String>>> actualValues = getTelemetryValues("ENTITY_VIEW", entityViewId, keys, 0L, (startTimeMs + endTimeMs) / 2);
  397 + Assert.assertEquals(1, actualValues.get("tsKey1").size());
  398 + Assert.assertEquals(1, actualValues.get("tsKey2").size());
  399 + Assert.assertEquals(1, actualValues.get("tsKey3").size());
  400 + }
  401 +
  402 + private void uploadTelemetry(String strKvs) throws Exception {
  403 + String viewDeviceId = testDevice.getId().getId().toString();
  404 + DeviceCredentials deviceCredentials =
  405 + doGet("/api/device/" + viewDeviceId + "/credentials", DeviceCredentials.class);
  406 + assertEquals(testDevice.getId(), deviceCredentials.getDeviceId());
  407 +
  408 + String accessToken = deviceCredentials.getCredentialsId();
  409 + assertNotNull(accessToken);
  410 +
  411 + String clientId = MqttAsyncClient.generateClientId();
  412 + MqttAsyncClient client = new MqttAsyncClient("tcp://localhost:1883", clientId);
  413 +
  414 + MqttConnectOptions options = new MqttConnectOptions();
  415 + options.setUserName(accessToken);
  416 + client.connect(options);
  417 + Thread.sleep(3000);
  418 +
  419 + MqttMessage message = new MqttMessage();
  420 + message.setPayload(strKvs.getBytes());
  421 + client.publish("v1/devices/me/telemetry", message);
  422 + Thread.sleep(1000);
  423 + }
  424 +
  425 + private Set<String> getTelemetryKeys(String type, String id) throws Exception {
  426 + return new HashSet<>(doGetAsync("/api/plugins/telemetry/" + type + "/" + id + "/keys/timeseries", List.class));
  427 + }
  428 +
  429 + private Map<String, List<Map<String, String>>> getTelemetryValues(String type, String id, Set<String> keys, Long startTs, Long endTs) throws Exception {
  430 + return doGetAsync("/api/plugins/telemetry/" + type + "/" + id +
  431 + "/values/timeseries?keys=" + String.join(",", keys) + "&startTs=" + startTs + "&endTs=" + endTs, Map.class);
  432 + }
  433 +
371 private Set<String> getAttributesByKeys(String stringKV) throws Exception { 434 private Set<String> getAttributesByKeys(String stringKV) throws Exception {
372 String viewDeviceId = testDevice.getId().getId().toString(); 435 String viewDeviceId = testDevice.getId().getId().toString();
373 DeviceCredentials deviceCredentials = 436 DeviceCredentials deviceCredentials =
@@ -390,7 +453,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -390,7 +453,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
390 client.publish("v1/devices/me/attributes", message); 453 client.publish("v1/devices/me/attributes", message);
391 Thread.sleep(1000); 454 Thread.sleep(1000);
392 455
393 - return new HashSet<>(doGetAsync("/api/plugins/telemetry/DEVICE/" + viewDeviceId + "/keys/attributes", List.class)); 456 + return new HashSet<>(doGetAsync("/api/plugins/telemetry/DEVICE/" + viewDeviceId + "/keys/attributes", List.class));
394 } 457 }
395 458
396 private Object getValue(List<Map<String, Object>> values, String stringValue) { 459 private Object getValue(List<Map<String, Object>> values, String stringValue) {
@@ -401,13 +464,20 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -401,13 +464,20 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
401 } 464 }
402 465
403 private EntityView getNewSavedEntityView(String name) throws Exception { 466 private EntityView getNewSavedEntityView(String name) throws Exception {
  467 + EntityView view = createEntityView(name, 0, 0);
  468 + return doPost("/api/entityView", view, EntityView.class);
  469 + }
  470 +
  471 + private EntityView createEntityView(String name, long startTimeMs, long endTimeMs) {
404 EntityView view = new EntityView(); 472 EntityView view = new EntityView();
405 view.setEntityId(testDevice.getId()); 473 view.setEntityId(testDevice.getId());
406 view.setTenantId(savedTenant.getId()); 474 view.setTenantId(savedTenant.getId());
407 view.setName(name); 475 view.setName(name);
408 view.setType("default"); 476 view.setType("default");
409 view.setKeys(telemetry); 477 view.setKeys(telemetry);
410 - return doPost("/api/entityView", view, EntityView.class); 478 + view.setStartTimeMs(startTimeMs);
  479 + view.setEndTimeMs(endTimeMs);
  480 + return view;
411 } 481 }
412 482
413 private Customer getNewCustomer(String title) { 483 private Customer getNewCustomer(String title) {
@@ -87,7 +87,11 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -87,7 +87,11 @@ public class BaseTimeseriesService implements TimeseriesService {
87 .map(key -> new BaseReadTsKvQuery(key, entityView.getStartTimeMs(), entityView.getEndTimeMs(), 1, "ASC")) 87 .map(key -> new BaseReadTsKvQuery(key, entityView.getStartTimeMs(), entityView.getEndTimeMs(), 1, "ASC"))
88 .collect(Collectors.toList()); 88 .collect(Collectors.toList());
89 89
90 - return timeseriesDao.findAllAsync(entityView.getEntityId(), updateQueriesForEntityView(entityView, queries)); 90 + if (queries.size() > 0) {
  91 + return timeseriesDao.findAllAsync(entityView.getEntityId(), queries);
  92 + } else {
  93 + return Futures.immediateFuture(new ArrayList<>());
  94 + }
91 } 95 }
92 keys.forEach(key -> futures.add(timeseriesDao.findLatest(entityId, key))); 96 keys.forEach(key -> futures.add(timeseriesDao.findLatest(entityId, key)));
93 return Futures.allAsList(futures); 97 return Futures.allAsList(futures);
@@ -133,11 +137,20 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -133,11 +137,20 @@ public class BaseTimeseriesService implements TimeseriesService {
133 137
134 private List<ReadTsKvQuery> updateQueriesForEntityView(EntityView entityView, List<ReadTsKvQuery> queries) { 138 private List<ReadTsKvQuery> updateQueriesForEntityView(EntityView entityView, List<ReadTsKvQuery> queries) {
135 return queries.stream().map(query -> { 139 return queries.stream().map(query -> {
136 - long startTs = entityView.getStartTimeMs() == 0 ? query.getStartTs() : entityView.getStartTimeMs();  
137 - long endTs = entityView.getEndTimeMs() == 0 ? query.getEndTs() : entityView.getEndTimeMs(); 140 + long startTs;
  141 + if (entityView.getStartTimeMs() != 0 && entityView.getStartTimeMs() > query.getStartTs()) {
  142 + startTs = entityView.getStartTimeMs();
  143 + } else {
  144 + startTs = query.getStartTs();
  145 + }
138 146
139 - return startTs <= query.getStartTs() && endTs >= query.getEndTs() ? query :  
140 - new BaseReadTsKvQuery(query.getKey(), startTs, endTs, query.getInterval(), query.getLimit(), query.getAggregation()); 147 + long endTs;
  148 + if (entityView.getEndTimeMs() != 0 && entityView.getEndTimeMs() < query.getEndTs()) {
  149 + endTs = entityView.getEndTimeMs();
  150 + } else {
  151 + endTs = query.getEndTs();
  152 + }
  153 + return new BaseReadTsKvQuery(query.getKey(), startTs, endTs, query.getInterval(), query.getLimit(), query.getAggregation());
141 }).collect(Collectors.toList()); 154 }).collect(Collectors.toList());
142 } 155 }
143 156