5 changed files with 158 additions and 100 deletions
@ -0,0 +1,103 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.lwm2m.rpc.sql; |
|||
|
|||
import com.fasterxml.jackson.databind.JsonNode; |
|||
import com.fasterxml.jackson.databind.node.ArrayNode; |
|||
import com.fasterxml.jackson.databind.node.ObjectNode; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest; |
|||
import java.util.concurrent.atomic.AtomicReference; |
|||
import static java.util.concurrent.TimeUnit.SECONDS; |
|||
import static org.awaitility.Awaitility.await; |
|||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_12; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3303_12_5700_TS_0; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3303_12_5700_TS_1; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3303_12_5700_VALUE_0; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3303_12_5700_VALUE_1; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_3303_12_5700; |
|||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_VALUE_3303_12_5700_DELTA_TS; |
|||
|
|||
@Slf4j |
|||
public class RpcLwm2mIntegrationReadCollectedValueTest extends AbstractRpcLwM2MIntegrationTest { |
|||
|
|||
@Before |
|||
public void startInitRPC() throws Exception { |
|||
initRpc(true); |
|||
} |
|||
|
|||
/** |
|||
* Read {"id":"/3303/12/5700"} |
|||
* Trigger a Send operation from the client with multiple values for the same resource as a payload |
|||
* acked "[{"bn":"/3303/12/5700","bt":1724".. 116 bytes] |
|||
* 2 values for the resource /3303/12/5700 should be stored with: |
|||
* - timestamps1 = Instance.now() + RESOURCE_ID_VALUE_3303_12_5700_1 |
|||
* - timestamps2 = (timestamps1 + 3 sec) + RESOURCE_ID_VALUE_3303_12_5700_2 |
|||
* @throws Exception |
|||
*/ |
|||
@Test |
|||
public void testReadSingleResource_sendFromClient_CollectedValue() throws Exception { |
|||
// init test
|
|||
int cntValues = 2; |
|||
int resourceId = 5700; |
|||
String expectedIdVer = objectIdVer_3303 + "/" + OBJECT_INSTANCE_ID_12 + "/" + resourceId; |
|||
sendRPCById(expectedIdVer); |
|||
|
|||
// verify time start/end send CollectedValue;
|
|||
await().atMost(40, SECONDS).until(() -> RESOURCE_ID_3303_12_5700_TS_0 > 0 |
|||
&& RESOURCE_ID_3303_12_5700_TS_1 > 0); |
|||
|
|||
// verify result read: verify count value: 1-2: send CollectedValue;
|
|||
AtomicReference<ObjectNode> actualValues = new AtomicReference<>(); |
|||
await().atMost(40, SECONDS).until(() -> { |
|||
actualValues.set(doGetAsync( |
|||
"/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" |
|||
+ RESOURCE_ID_NAME_3303_12_5700 |
|||
+ "&startTs=" + (RESOURCE_ID_3303_12_5700_TS_0 - RESOURCE_ID_VALUE_3303_12_5700_DELTA_TS) |
|||
+ "&endTs=" + (RESOURCE_ID_3303_12_5700_TS_1 + RESOURCE_ID_VALUE_3303_12_5700_DELTA_TS) |
|||
+ "&interval=0&limit=100&useStrictDataTypes=false", |
|||
ObjectNode.class)); |
|||
return actualValues.get() != null && actualValues.get().size() > 0 |
|||
&& actualValues.get().get(RESOURCE_ID_NAME_3303_12_5700).size() >= cntValues && verifyTs(actualValues); |
|||
}); |
|||
} |
|||
|
|||
private boolean verifyTs(AtomicReference<ObjectNode> actualValues) { |
|||
String expectedVal_0 = String.valueOf(RESOURCE_ID_3303_12_5700_VALUE_0); |
|||
String expectedVal_1 = String.valueOf(RESOURCE_ID_3303_12_5700_VALUE_1); |
|||
ArrayNode actual = (ArrayNode) actualValues.get().get(RESOURCE_ID_NAME_3303_12_5700); |
|||
long actualTS0 = 0; |
|||
long actualTS1 = 0; |
|||
for (JsonNode tsNode : actual) { |
|||
if (tsNode.get("value").asText().equals(expectedVal_0)) { |
|||
actualTS0 = tsNode.get("ts").asLong(); |
|||
} else if (tsNode.get("value").asText().equals(expectedVal_1)) { |
|||
actualTS1 = tsNode.get("ts").asLong(); |
|||
} |
|||
} |
|||
return actualTS0 >= RESOURCE_ID_3303_12_5700_TS_0 |
|||
&& actualTS1 <= RESOURCE_ID_3303_12_5700_TS_1 |
|||
&& (actualTS1 - actualTS0) >= RESOURCE_ID_VALUE_3303_12_5700_DELTA_TS; |
|||
} |
|||
|
|||
private String sendRPCById(String path) throws Exception { |
|||
String setRpcRequest = "{\"method\": \"Read\", \"params\": {\"id\": \"" + path + "\"}}"; |
|||
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue