|
|
|
@ -20,9 +20,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; |
|
|
|
import com.fasterxml.jackson.databind.node.NullNode; |
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
|
|
|
import org.junit.Test; |
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
|
import org.thingsboard.server.common.data.AttributeScope; |
|
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
|
import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.EntityInfo; |
|
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
|
@ -76,7 +74,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
public void testSimpleCalculatedFieldWhenAllTelemetryPresent() throws Exception { |
|
|
|
Device testDevice = createDevice("Test device", "1234567890"); |
|
|
|
postTelemetry(testDevice.getId(), "{\"temperature\":25}"); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"deviceTemperature\":40}")); |
|
|
|
postAttributes(testDevice.getId(), AttributeScope.SERVER_SCOPE, "{\"deviceTemperature\":40}"); |
|
|
|
|
|
|
|
CalculatedField calculatedField = new CalculatedField(); |
|
|
|
calculatedField.setEntityId(testDevice.getId()); |
|
|
|
@ -259,15 +257,15 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
@Test |
|
|
|
public void testSimpleCalculatedFieldWhenEntityIdIsProfile() throws Exception { |
|
|
|
Device testDevice = createDevice("Test device", "1234567890"); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"x\":40}")); |
|
|
|
postAttributes(testDevice.getId(), AttributeScope.SERVER_SCOPE, "{\"x\":40}"); |
|
|
|
|
|
|
|
AssetProfile assetProfile = doPost("/api/assetProfile", createAssetProfile("Test Asset Profile"), AssetProfile.class); |
|
|
|
|
|
|
|
Asset asset1 = createAsset("Test asset 1", assetProfile.getId()); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + asset1.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"y\":11}")); |
|
|
|
postAttributes(asset1.getId(), AttributeScope.SERVER_SCOPE, "{\"y\":11}"); |
|
|
|
|
|
|
|
Asset asset2 = createAsset("Test asset 2", assetProfile.getId()); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + asset2.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"y\":12}")); |
|
|
|
postAttributes(asset2.getId(), AttributeScope.SERVER_SCOPE, "{\"y\":12}"); |
|
|
|
|
|
|
|
CalculatedField calculatedField = new CalculatedField(); |
|
|
|
calculatedField.setEntityId(assetProfile.getId()); |
|
|
|
@ -316,7 +314,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(z2.get(0).get("value").asText()).isEqualTo("52.0"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"x\":25}")); |
|
|
|
postAttributes(testDevice.getId(), AttributeScope.SERVER_SCOPE, "{\"x\":25}"); |
|
|
|
|
|
|
|
await().alias("update device telemetry -> recalculate state for all assets").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -332,7 +330,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(z2.get(0).get("value").asText()).isEqualTo("37.0"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + asset1.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"y\":15}")); |
|
|
|
postAttributes(asset1.getId(), AttributeScope.SERVER_SCOPE, "{\"y\":15}"); |
|
|
|
|
|
|
|
await().alias("update asset 1 telemetry -> recalculate state only for asset 1").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -348,7 +346,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(z2.get(0).get("value").asText()).isEqualTo("37.0"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + asset2.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"y\":5}")); |
|
|
|
postAttributes(asset2.getId(), AttributeScope.SERVER_SCOPE, "{\"y\":5}"); |
|
|
|
|
|
|
|
await().alias("update asset 2 telemetry -> recalculate state only for asset 2").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -365,7 +363,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
}); |
|
|
|
|
|
|
|
Asset asset3 = createAsset("Test asset 3", assetProfile.getId()); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + asset3.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"y\":13}")); |
|
|
|
postAttributes(asset3.getId(), AttributeScope.SERVER_SCOPE, "{\"y\":13}"); |
|
|
|
|
|
|
|
Asset finalAsset3 = asset3; |
|
|
|
await().alias("add new entity to profile -> calculate state for new entity").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
@ -377,7 +375,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(z3.get(0).get("value").asText()).isEqualTo("38.0"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"x\":20}")); |
|
|
|
postAttributes(testDevice.getId(), AttributeScope.SERVER_SCOPE, "{\"x\":20}"); |
|
|
|
|
|
|
|
await().alias("update device telemetry -> recalculate state for all assets").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -403,7 +401,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
asset3.setAssetProfileId(newAssetProfile.getId()); |
|
|
|
asset3 = doPost("/api/asset", asset3, Asset.class); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"x\":15}")); |
|
|
|
postAttributes(testDevice.getId(), AttributeScope.SERVER_SCOPE, "{\"x\":15}"); |
|
|
|
|
|
|
|
Asset updatedAsset3 = asset3; |
|
|
|
await().alias("update device telemetry -> recalculate state for asset 1 and asset 2").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
@ -662,7 +660,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(d.get("d").get(0).get("value").asText()).isEqualTo("600"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"a\":10}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"a\":10}"); |
|
|
|
|
|
|
|
await().alias("update telemetry -> save result with ts of 'a' argument").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -674,8 +672,8 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(keys.get("d").get(0).get("value").asText()).isEqualTo("510"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"b\":20}")); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"c\":30}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"b\":20}"); |
|
|
|
postTelemetry(testDevice.getId(), "{\"c\":30}"); |
|
|
|
|
|
|
|
await().alias("update telemetry -> save result with latest ts of updated arguments").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -726,7 +724,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
|
|
|
|
calculatedField = doPost("/api/calculatedField", calculatedField, CalculatedField.class); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"m\":1}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"m\":1}"); |
|
|
|
|
|
|
|
await().alias("create CF -> ctx is initialized -> perform calculation").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -740,7 +738,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
calculatedField.setConfiguration(config); |
|
|
|
calculatedField = doPost("/api/calculatedField", calculatedField, CalculatedField.class); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"m\":2}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"m\":2}"); |
|
|
|
|
|
|
|
await().alias("update CF -> ctx is not initialized -> no calculation performed").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -761,15 +759,11 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
// Restricted zone polygon (square)
|
|
|
|
String restrictedPolygon = "[[50.475000, 30.510000], [50.475000, 30.512000], [50.477000, 30.512000], [50.477000, 30.510000]]"; |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"allowedZone\":" + allowedPolygon + "}")).andExpect(status().isOk()); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"restrictedZone\":" + restrictedPolygon + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(device.getId(), AttributeScope.SERVER_SCOPE, "{\"allowedZone\":" + allowedPolygon + "}"); |
|
|
|
postAttributes(device.getId(), AttributeScope.SERVER_SCOPE, "{\"restrictedZone\":" + restrictedPolygon + "}"); |
|
|
|
|
|
|
|
// Initial device coordinates (inside Allowed, outside Restricted)
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4730,\"longitude\":30.5050}")); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4730,\"longitude\":30.5050}"); |
|
|
|
|
|
|
|
// --- Build CF: GEOFENCING ---
|
|
|
|
CalculatedField cf = new CalculatedField(); |
|
|
|
@ -817,8 +811,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
doDelete("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/SERVER_SCOPE?keys=allowedZonesStatus,restrictedZonesStatus", String.class); |
|
|
|
|
|
|
|
// --- Update restrictedZone by 'restrictedZone' attribute update
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"restrictedZone\":" + restrictedPolygon + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(device.getId(), AttributeScope.SERVER_SCOPE, "{\"restrictedZone\":" + restrictedPolygon + "}"); |
|
|
|
|
|
|
|
// --- Assert no transition ---
|
|
|
|
// --- Assert attributes updated with the same values for restrictedZones ---
|
|
|
|
@ -848,30 +841,17 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
String restrictedPolygon = "[[50.475000, 30.510000], [50.475000, 30.512000], [50.477000, 30.512000], [50.477000, 30.510000]]"; |
|
|
|
|
|
|
|
Asset allowedZoneAsset = createAsset("Allowed Zone", null); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + allowedZoneAsset.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"zone\":" + allowedPolygon + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(allowedZoneAsset.getId(), AttributeScope.SERVER_SCOPE, "{\"zone\":" + allowedPolygon + "}"); |
|
|
|
|
|
|
|
Asset restrictedZoneAsset = createAsset("Restricted Zone", null); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + restrictedZoneAsset.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"zone\":" + restrictedPolygon + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(restrictedZoneAsset.getId(), AttributeScope.SERVER_SCOPE, "{\"zone\":" + restrictedPolygon + "}"); |
|
|
|
|
|
|
|
// Relations from device to zones
|
|
|
|
EntityRelation deviceToAllowedZoneRelation = new EntityRelation(); |
|
|
|
deviceToAllowedZoneRelation.setFrom(device.getId()); |
|
|
|
deviceToAllowedZoneRelation.setTo(allowedZoneAsset.getId()); |
|
|
|
deviceToAllowedZoneRelation.setType("AllowedZone"); |
|
|
|
|
|
|
|
EntityRelation deviceToRestrictedZoneRelation = new EntityRelation(); |
|
|
|
deviceToRestrictedZoneRelation.setFrom(device.getId()); |
|
|
|
deviceToRestrictedZoneRelation.setTo(restrictedZoneAsset.getId()); |
|
|
|
deviceToRestrictedZoneRelation.setType("RestrictedZone"); |
|
|
|
|
|
|
|
doPost("/api/relation", deviceToAllowedZoneRelation).andExpect(status().isOk()); |
|
|
|
doPost("/api/relation", deviceToRestrictedZoneRelation).andExpect(status().isOk()); |
|
|
|
createEntityRelation(device.getId(), allowedZoneAsset.getId(), "AllowedZone"); |
|
|
|
createEntityRelation(device.getId(), restrictedZoneAsset.getId(), "RestrictedZone"); |
|
|
|
|
|
|
|
// Initial device coordinates (inside Allowed, outside Restricted)
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4730,\"longitude\":30.5050}")); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4730,\"longitude\":30.5050}"); |
|
|
|
|
|
|
|
// --- Build CF: GEOFENCING ---
|
|
|
|
CalculatedField cf = new CalculatedField(); |
|
|
|
@ -922,8 +902,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
}); |
|
|
|
|
|
|
|
// --- Move the device into Restricted zone (and outside Allowed) ---
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4760,\"longitude\":30.5110}")); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4760,\"longitude\":30.5110}"); |
|
|
|
|
|
|
|
// --- Assert transition (LEFT / ENTERED) ---
|
|
|
|
await().alias("transition evaluation after movement") |
|
|
|
@ -965,19 +944,13 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
String allowedPolygonA = "[[50.472000, 30.504000], [50.472000, 30.506000], [50.474000, 30.506000], [50.474000, 30.504000]]"; |
|
|
|
|
|
|
|
Asset allowedZoneA = createAsset("Allowed Zone A", null); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + allowedZoneA.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"zone\":" + allowedPolygonA + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(allowedZoneA.getId(), AttributeScope.SERVER_SCOPE, "{\"zone\":" + allowedPolygonA + "}"); |
|
|
|
|
|
|
|
// Relation from device to Allowed Zone A
|
|
|
|
EntityRelation relAllowedA = new EntityRelation(); |
|
|
|
relAllowedA.setFrom(device.getId()); |
|
|
|
relAllowedA.setTo(allowedZoneA.getId()); |
|
|
|
relAllowedA.setType("AllowedZone"); |
|
|
|
doPost("/api/relation", relAllowedA).andExpect(status().isOk()); |
|
|
|
createEntityRelation(device.getId(), allowedZoneA.getId(), "AllowedZone"); |
|
|
|
|
|
|
|
// Initial device coordinates: INSIDE Zone A
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4730,\"longitude\":30.5050}")).andExpect(status().isOk()); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4730,\"longitude\":30.5050}"); |
|
|
|
|
|
|
|
// --- Build CF: GEOFENCING with dynamic 'allowedZones' and short scheduled refresh ---
|
|
|
|
CalculatedField cf = new CalculatedField(); |
|
|
|
@ -1024,8 +997,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
}); |
|
|
|
|
|
|
|
// --- Move device OUTSIDE Zone A (expect LEFT) ---
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4760,\"longitude\":30.5110}")).andExpect(status().isOk()); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4760,\"longitude\":30.5110}"); |
|
|
|
|
|
|
|
await().alias("outside zone A (LEFT)") |
|
|
|
.atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
@ -1042,21 +1014,15 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
String allowedPolygonB = "[[50.475500, 30.510500], [50.475500, 30.511500], [50.476500, 30.511500], [50.476500, 30.510500]]"; |
|
|
|
|
|
|
|
Asset allowedZoneB = createAsset("Allowed Zone B", null); |
|
|
|
doPost("/api/plugins/telemetry/ASSET/" + allowedZoneB.getUuidId() + "/attributes/" + DataConstants.SERVER_SCOPE, |
|
|
|
JacksonUtil.toJsonNode("{\"zone\":" + allowedPolygonB + "}")).andExpect(status().isOk()); |
|
|
|
postAttributes(allowedZoneB.getId(), AttributeScope.SERVER_SCOPE, "{\"zone\":" + allowedPolygonB + "}"); |
|
|
|
|
|
|
|
// Add a new relation
|
|
|
|
EntityRelation relAllowedB = new EntityRelation(); |
|
|
|
relAllowedB.setFrom(device.getId()); |
|
|
|
relAllowedB.setTo(allowedZoneB.getId()); |
|
|
|
relAllowedB.setType("AllowedZone"); |
|
|
|
doPost("/api/relation", relAllowedB).andExpect(status().isOk()); |
|
|
|
createEntityRelation(device.getId(), allowedZoneB.getId(), "AllowedZone"); |
|
|
|
|
|
|
|
awaitForCalculatedFieldEntityMessageProcessorToRegisterCfStateAsReadyToRefreshDynamicArguments(device.getId(), savedCalculatedField.getId(), minAllowedScheduledUpdateIntervalInSecForCF); |
|
|
|
|
|
|
|
// --- Same coordinates as before, but now we expect INSIDE group status since a new zone is registered ---
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"latitude\":50.4760,\"longitude\":30.5110}")).andExpect(status().isOk()); |
|
|
|
postTelemetry(device.getId(), "{\"latitude\":50.4760,\"longitude\":30.5110}"); |
|
|
|
|
|
|
|
// --- Assert dynamic refresh picks up a new relation and flips status back to INSIDE on the next telemetry update ---
|
|
|
|
await().alias("dynamic refresh rebinds allowedZones") |
|
|
|
@ -1079,14 +1045,11 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
Asset asset2 = createAsset("Propagated Asset 2", null); |
|
|
|
|
|
|
|
// Create relations FROM assets TO device
|
|
|
|
EntityRelation rel1 = new EntityRelation(asset1.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
EntityRelation rel2 = new EntityRelation(asset2.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
doPost("/api/relation", rel1).andExpect(status().isOk()); |
|
|
|
doPost("/api/relation", rel2).andExpect(status().isOk()); |
|
|
|
createEntityRelation(asset1.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
createEntityRelation(asset2.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
|
|
|
|
// Telemetry on device
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"temperature\":12.5, \"humidity\":85}")).andExpect(status().isOk()); |
|
|
|
postTelemetry(device.getId(), "{\"temperature\":12.5, \"humidity\":85}"); |
|
|
|
|
|
|
|
// --- Build CF: PROPAGATION with expression ---
|
|
|
|
CalculatedField cf = new CalculatedField(); |
|
|
|
@ -1136,8 +1099,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
doDelete(deleteUrl).andExpect(status().isOk()); |
|
|
|
doDelete("/api/plugins/telemetry/ASSET/" + asset1.getId() + "/SERVER_SCOPE?keys=testResult").andExpect(status().isOk()); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/unusedScope", |
|
|
|
JacksonUtil.toJsonNode("{\"temperature\":25}")).andExpect(status().isOk()); |
|
|
|
postTelemetry(device.getId(), "{\"temperature\":25}"); |
|
|
|
|
|
|
|
// --- Assert propagated calculation (expression applied with new temperature argument and one relation removed) ---
|
|
|
|
await().alias("propagation expr mode evaluation after temperature update") |
|
|
|
@ -1160,10 +1122,8 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
Asset asset2 = createAsset("Propagated Asset 2", null); |
|
|
|
|
|
|
|
// Create relations FROM assets TO device
|
|
|
|
EntityRelation rel1 = new EntityRelation(asset1.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
EntityRelation rel2 = new EntityRelation(asset2.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
doPost("/api/relation", rel1).andExpect(status().isOk()); |
|
|
|
doPost("/api/relation", rel2).andExpect(status().isOk()); |
|
|
|
createEntityRelation(asset1.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
createEntityRelation(asset2.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
|
|
|
|
// Telemetry on device
|
|
|
|
long ts = System.currentTimeMillis() - 300000L; |
|
|
|
@ -1245,8 +1205,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
}); |
|
|
|
|
|
|
|
Asset asset3 = createAsset("Propagated Asset 3", null); |
|
|
|
EntityRelation rel3 = new EntityRelation(asset3.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
doPost("/api/relation", rel3).andExpect(status().isOk()); |
|
|
|
createEntityRelation(asset3.getId(), device.getId(), EntityRelation.CONTAINS_TYPE); |
|
|
|
|
|
|
|
// --- Assert propagated calculation (arguments-only mode after update) ---
|
|
|
|
await().alias("propagation args-only to new entity after relation creation") |
|
|
|
@ -1266,7 +1225,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
@Test |
|
|
|
public void testCalculatedFieldWhenTheSameTelemetryKeysUsed() throws Exception { |
|
|
|
Device testDevice = createDevice("Test device", "1234567890"); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"a\":5}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"a\":5}"); |
|
|
|
|
|
|
|
CalculatedField calculatedField = new CalculatedField(); |
|
|
|
calculatedField.setEntityId(testDevice.getId()); |
|
|
|
@ -1301,7 +1260,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(c.get("c").get(0).get("value").asText()).isEqualTo("10"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"a\":10}")); |
|
|
|
postTelemetry(testDevice.getId(), "{\"a\":10}"); |
|
|
|
|
|
|
|
await().alias("update telemetry -> recalculate state").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
@ -1316,8 +1275,8 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
public void testCalculatedFieldWhenBatchOfTelemetrySent() throws Exception { |
|
|
|
Device testDevice = createDevice("Test device", "1234567890"); |
|
|
|
long now = System.currentTimeMillis(); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode(String.format("{\"ts\": %s, \"values\": {\"a\":5, \"b\":10}}", now - TimeUnit.MINUTES.toMillis(3)))); |
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode(String.format("{\"ts\": %s, \"values\": {\"b\":20}}", now - TimeUnit.MINUTES.toMillis(1)))); |
|
|
|
postTelemetry(testDevice.getId(), String.format("{\"ts\": %s, \"values\": {\"a\":5, \"b\":10}}", now - TimeUnit.MINUTES.toMillis(3))); |
|
|
|
postTelemetry(testDevice.getId(), String.format("{\"ts\": %s, \"values\": {\"b\":20}}", now - TimeUnit.MINUTES.toMillis(1))); |
|
|
|
|
|
|
|
CalculatedField calculatedField = new CalculatedField(); |
|
|
|
calculatedField.setEntityId(testDevice.getId()); |
|
|
|
@ -1358,7 +1317,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
assertThat(result.get("avgB").get(0).get("value").asText()).isEqualTo("15.0"); |
|
|
|
}); |
|
|
|
|
|
|
|
doPost("/api/plugins/telemetry/DEVICE/" + testDevice.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode(String.format(""" |
|
|
|
postTelemetry(testDevice.getId(), String.format(""" |
|
|
|
[{ |
|
|
|
"ts": %s, |
|
|
|
"values": { |
|
|
|
@ -1377,7 +1336,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes |
|
|
|
"a": 8, |
|
|
|
"b": 300 |
|
|
|
} |
|
|
|
}]""", now - TimeUnit.MINUTES.toMillis(2), now, now - TimeUnit.MINUTES.toMillis(5)))); |
|
|
|
}]""", now - TimeUnit.MINUTES.toMillis(2), now, now - TimeUnit.MINUTES.toMillis(5))); |
|
|
|
|
|
|
|
await().alias("update telemetry -> recalculate state").atMost(TIMEOUT, TimeUnit.SECONDS) |
|
|
|
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) |
|
|
|
|