RPC functionality refactoring for SNMP (#4492)

* Refactor RPC functionality for SNMP

* Refactor

* SNMP response PDU mapping refactoring
This commit is contained in:
Viacheslav Klimov 2021-04-28 16:40:45 +03:00 committed by GitHub
parent b34198f30c
commit 3b74a806bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 14 deletions

View File

@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.transport.snmp.SnmpMethod;
import org.thingsboard.server.common.data.transport.snmp.config.impl.ClientAttributesQueryingSnmpCommunicationConfig;
import org.thingsboard.server.common.data.transport.snmp.config.impl.SharedAttributesSettingSnmpCommunicationConfig;
import org.thingsboard.server.common.data.transport.snmp.config.impl.TelemetryQueryingSnmpCommunicationConfig;
import org.thingsboard.server.common.data.transport.snmp.config.impl.ToDeviceRpcRequestSnmpCommunicationConfig;
import java.util.List;
@ -34,7 +35,8 @@ import java.util.List;
@JsonSubTypes({
@Type(value = TelemetryQueryingSnmpCommunicationConfig.class, name = "TELEMETRY_QUERYING"),
@Type(value = ClientAttributesQueryingSnmpCommunicationConfig.class, name = "CLIENT_ATTRIBUTES_QUERYING"),
@Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING")
@Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING"),
@Type(value = ToDeviceRpcRequestSnmpCommunicationConfig.class, name = "TO_DEVICE_RPC_REQUEST")
})
public interface SnmpCommunicationConfig {

View File

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2021 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.common.data.transport.snmp.config.impl;
import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec;
import org.thingsboard.server.common.data.transport.snmp.config.MultipleMappingsSnmpCommunicationConfig;
public class ToDeviceRpcRequestSnmpCommunicationConfig extends MultipleMappingsSnmpCommunicationConfig {
@Override
public SnmpCommunicationSpec getSpec() {
return SnmpCommunicationSpec.TO_DEVICE_RPC_REQUEST;
}
}

View File

@ -151,7 +151,7 @@ public class PduService {
.collect(Collectors.toMap(VariableBinding::getOid, VariableBinding::toValueString));
}
private void processValue(String key, DataType dataType, String value, JsonObject result) {
public void processValue(String key, DataType dataType, String value, JsonObject result) {
switch (dataType) {
case LONG:
result.addProperty(key, Long.parseLong(value));

View File

@ -183,19 +183,28 @@ public class SnmpTransportService implements TbTransportService {
SnmpMethod snmpMethod = SnmpMethod.valueOf(toDeviceRpcRequestMsg.getMethodName());
JsonObject params = JsonConverter.parse(toDeviceRpcRequestMsg.getParams()).getAsJsonObject();
String oid = Optional.ofNullable(params.get("oid")).map(JsonElement::getAsString).orElse(null);
String key = Optional.ofNullable(params.get("key")).map(JsonElement::getAsString).orElse(null);
String value = Optional.ofNullable(params.get("value")).map(JsonElement::getAsString).orElse(null);
DataType dataType = Optional.ofNullable(params.get("dataType")).map(e -> DataType.valueOf(e.getAsString())).orElse(DataType.STRING);
if (oid == null || oid.isEmpty()) {
throw new IllegalArgumentException("OID in to-device RPC request is not specified");
}
if (value == null && snmpMethod == SnmpMethod.SET) {
throw new IllegalArgumentException("Value must be specified for SNMP method 'SET'");
}
SnmpCommunicationConfig communicationConfig = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream()
.filter(config -> config.getSpec() == SnmpCommunicationSpec.TO_DEVICE_RPC_REQUEST)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No communication config found with RPC spec"));
SnmpMapping snmpMapping = communicationConfig.getAllMappings().stream()
.filter(mapping -> mapping.getKey().equals(key))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No SNMP mapping found in the config for specified key"));
String oid = snmpMapping.getOid();
DataType dataType = snmpMapping.getDataType();
PDU request = pduService.createSingleVariablePdu(sessionContext, snmpMethod, oid, value, dataType);
sendRequest(sessionContext, request, new RequestInfo(toDeviceRpcRequestMsg.getRequestId(), SnmpCommunicationSpec.TO_DEVICE_RPC_REQUEST));
RequestInfo requestInfo = new RequestInfo(toDeviceRpcRequestMsg.getRequestId(), communicationConfig.getSpec(), communicationConfig.getAllMappings());
sendRequest(sessionContext, request, requestInfo);
}
@ -238,7 +247,12 @@ public class SnmpTransportService implements TbTransportService {
responseDataMappers.put(SnmpCommunicationSpec.TO_DEVICE_RPC_REQUEST, (pdu, requestInfo) -> {
JsonObject responseData = new JsonObject();
pduService.processPdu(pdu).forEach((oid, value) -> {
responseData.addProperty(oid.toDottedString(), value);
requestInfo.getResponseMappings().stream()
.filter(snmpMapping -> snmpMapping.getOid().equals(oid.toDottedString()))
.findFirst()
.ifPresent(snmpMapping -> {
pduService.processValue(snmpMapping.getKey(), snmpMapping.getDataType(), value, responseData);
});
});
return responseData;
});
@ -314,13 +328,10 @@ public class SnmpTransportService implements TbTransportService {
private SnmpCommunicationSpec communicationSpec;
private List<SnmpMapping> responseMappings;
public RequestInfo(Integer requestId, SnmpCommunicationSpec communicationSpec) {
public RequestInfo(Integer requestId, SnmpCommunicationSpec communicationSpec, List<SnmpMapping> responseMappings) {
this.requestId = requestId;
this.communicationSpec = communicationSpec;
}
public RequestInfo(SnmpCommunicationSpec communicationSpec) {
this.communicationSpec = communicationSpec;
this.responseMappings = responseMappings;
}
public RequestInfo(SnmpCommunicationSpec communicationSpec, List<SnmpMapping> responseMappings) {