Showing
16 changed files
with
454 additions
and
234 deletions
@@ -17,16 +17,11 @@ package org.thingsboard.server.common.data.device.profile; | @@ -17,16 +17,11 @@ package org.thingsboard.server.common.data.device.profile; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.annotation.JsonIgnore; | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | -import org.apache.commons.lang3.ArrayUtils; | ||
21 | import org.thingsboard.server.common.data.DeviceTransportType; | 20 | import org.thingsboard.server.common.data.DeviceTransportType; |
22 | import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | 21 | import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; |
23 | -import org.thingsboard.server.common.data.transport.snmp.configs.SnmpCommunicationConfig; | 22 | +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; |
24 | 23 | ||
25 | -import java.util.Collections; | ||
26 | import java.util.List; | 24 | import java.util.List; |
27 | -import java.util.function.Function; | ||
28 | -import java.util.stream.Collectors; | ||
29 | -import java.util.stream.Stream; | ||
30 | 25 | ||
31 | @Data | 26 | @Data |
32 | public class SnmpDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration { | 27 | public class SnmpDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration { |
@@ -51,7 +46,7 @@ public class SnmpDeviceProfileTransportConfiguration implements DeviceProfileTra | @@ -51,7 +46,7 @@ public class SnmpDeviceProfileTransportConfiguration implements DeviceProfileTra | ||
51 | return timeoutMs != null && timeoutMs >= 0 && retries != null && retries >= 0 | 46 | return timeoutMs != null && timeoutMs >= 0 && retries != null && retries >= 0 |
52 | && communicationConfigs != null && !communicationConfigs.isEmpty() | 47 | && communicationConfigs != null && !communicationConfigs.isEmpty() |
53 | && communicationConfigs.stream().allMatch(config -> config != null && config.isValid()) | 48 | && communicationConfigs.stream().allMatch(config -> config != null && config.isValid()) |
54 | - && communicationConfigs.stream().flatMap(config -> config.getMappings().stream()).map(SnmpMapping::getOid) | ||
55 | - .distinct().count() == communicationConfigs.stream().mapToInt(config -> config.getMappings().size()).sum(); | 49 | + && communicationConfigs.stream().flatMap(config -> config.getAllMappings().stream()).map(SnmpMapping::getOid) |
50 | + .distinct().count() == communicationConfigs.stream().mapToInt(config -> config.getAllMappings().size()).sum(); | ||
56 | } | 51 | } |
57 | } | 52 | } |
@@ -16,22 +16,11 @@ | @@ -16,22 +16,11 @@ | ||
16 | package org.thingsboard.server.common.data.transport.snmp; | 16 | package org.thingsboard.server.common.data.transport.snmp; |
17 | 17 | ||
18 | public enum SnmpCommunicationSpec { | 18 | public enum SnmpCommunicationSpec { |
19 | - TELEMETRY_QUERYING(true), | ||
20 | - CLIENT_ATTRIBUTES_QUERYING(true), | 19 | + TELEMETRY_QUERYING, |
21 | 20 | ||
22 | - SHARED_ATTRIBUTES_SETTING; | 21 | + CLIENT_ATTRIBUTES_QUERYING, |
22 | + SHARED_ATTRIBUTES_SETTING, | ||
23 | 23 | ||
24 | - private final boolean isRepeatingQuerying; | ||
25 | - | ||
26 | - SnmpCommunicationSpec() { | ||
27 | - this.isRepeatingQuerying = false; | ||
28 | - } | ||
29 | - | ||
30 | - SnmpCommunicationSpec(boolean isRepeatingQuerying) { | ||
31 | - this.isRepeatingQuerying = isRepeatingQuerying; | ||
32 | - } | ||
33 | - | ||
34 | - public boolean isRepeatingQuerying() { | ||
35 | - return isRepeatingQuerying; | ||
36 | - } | 24 | + TO_DEVICE_RPC_COMMAND_SETTING, |
25 | + TO_DEVICE_RPC_RESPONSE_QUERYING | ||
37 | } | 26 | } |
@@ -16,13 +16,17 @@ | @@ -16,13 +16,17 @@ | ||
16 | package org.thingsboard.server.common.data.transport.snmp; | 16 | package org.thingsboard.server.common.data.transport.snmp; |
17 | 17 | ||
18 | import com.fasterxml.jackson.annotation.JsonIgnore; | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | +import lombok.AllArgsConstructor; | ||
19 | import lombok.Data; | 20 | import lombok.Data; |
21 | +import lombok.NoArgsConstructor; | ||
20 | import org.apache.commons.lang3.StringUtils; | 22 | import org.apache.commons.lang3.StringUtils; |
21 | import org.thingsboard.server.common.data.kv.DataType; | 23 | import org.thingsboard.server.common.data.kv.DataType; |
22 | 24 | ||
23 | import java.util.regex.Pattern; | 25 | import java.util.regex.Pattern; |
24 | 26 | ||
25 | @Data | 27 | @Data |
28 | +@AllArgsConstructor | ||
29 | +@NoArgsConstructor | ||
26 | public class SnmpMapping { | 30 | public class SnmpMapping { |
27 | private String oid; | 31 | private String oid; |
28 | private String key; | 32 | private String key; |
@@ -32,7 +36,6 @@ public class SnmpMapping { | @@ -32,7 +36,6 @@ public class SnmpMapping { | ||
32 | 36 | ||
33 | @JsonIgnore | 37 | @JsonIgnore |
34 | public boolean isValid() { | 38 | public boolean isValid() { |
35 | - return StringUtils.isNotEmpty(oid) && OID_PATTERN.matcher(oid).matches() && | ||
36 | - StringUtils.isNotBlank(key) && dataType != null; | 39 | + return StringUtils.isNotEmpty(oid) && OID_PATTERN.matcher(oid).matches() && StringUtils.isNotBlank(key); |
37 | } | 40 | } |
38 | } | 41 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.transport.snmp.config; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | ||
20 | + | ||
21 | +import java.util.List; | ||
22 | + | ||
23 | +@Data | ||
24 | +public abstract class MultipleMappingsSnmpCommunicationConfig implements SnmpCommunicationConfig { | ||
25 | + protected List<SnmpMapping> mappings; | ||
26 | + | ||
27 | + @Override | ||
28 | + public boolean isValid() { | ||
29 | + return mappings != null && !mappings.isEmpty() && mappings.stream().allMatch(mapping -> mapping != null && mapping.isValid()); | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public List<SnmpMapping> getAllMappings() { | ||
34 | + return mappings; | ||
35 | + } | ||
36 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/config/RepeatingQueryingSnmpCommunicationConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/configs/RepeatingQueryingSnmpCommunicationConfig.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.data.transport.snmp.configs; | 16 | +package org.thingsboard.server.common.data.transport.snmp.config; |
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.EqualsAndHashCode; | 19 | import lombok.EqualsAndHashCode; |
@@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | @@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | ||
21 | 21 | ||
22 | @EqualsAndHashCode(callSuper = true) | 22 | @EqualsAndHashCode(callSuper = true) |
23 | @Data | 23 | @Data |
24 | -public abstract class RepeatingQueryingSnmpCommunicationConfig extends SnmpCommunicationConfig { | 24 | +public abstract class RepeatingQueryingSnmpCommunicationConfig extends MultipleMappingsSnmpCommunicationConfig { |
25 | private Long queryingFrequencyMs; | 25 | private Long queryingFrequencyMs; |
26 | 26 | ||
27 | @Override | 27 | @Override |
@@ -31,6 +31,6 @@ public abstract class RepeatingQueryingSnmpCommunicationConfig extends SnmpCommu | @@ -31,6 +31,6 @@ public abstract class RepeatingQueryingSnmpCommunicationConfig extends SnmpCommu | ||
31 | 31 | ||
32 | @Override | 32 | @Override |
33 | public boolean isValid() { | 33 | public boolean isValid() { |
34 | - return super.isValid() && queryingFrequencyMs != null && queryingFrequencyMs > 0; | 34 | + return queryingFrequencyMs != null && queryingFrequencyMs > 0 && super.isValid(); |
35 | } | 35 | } |
36 | } | 36 | } |
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/config/SnmpCommunicationConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/configs/SnmpCommunicationConfig.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.data.transport.snmp.configs; | 16 | +package org.thingsboard.server.common.data.transport.snmp.config; |
17 | 17 | ||
18 | import com.fasterxml.jackson.annotation.JsonIgnore; | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 19 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
@@ -23,6 +23,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; | @@ -23,6 +23,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
23 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 23 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
24 | import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | 24 | import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; |
25 | import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | 25 | import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; |
26 | +import org.thingsboard.server.common.data.transport.snmp.config.impl.ClientAttributesQueryingSnmpCommunicationConfig; | ||
27 | +import org.thingsboard.server.common.data.transport.snmp.config.impl.SharedAttributesSettingSnmpCommunicationConfig; | ||
28 | +import org.thingsboard.server.common.data.transport.snmp.config.impl.TelemetryQueryingSnmpCommunicationConfig; | ||
26 | 29 | ||
27 | import java.util.List; | 30 | import java.util.List; |
28 | 31 | ||
@@ -33,22 +36,19 @@ import java.util.List; | @@ -33,22 +36,19 @@ import java.util.List; | ||
33 | @Type(value = ClientAttributesQueryingSnmpCommunicationConfig.class, name = "CLIENT_ATTRIBUTES_QUERYING"), | 36 | @Type(value = ClientAttributesQueryingSnmpCommunicationConfig.class, name = "CLIENT_ATTRIBUTES_QUERYING"), |
34 | @Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING") | 37 | @Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING") |
35 | }) | 38 | }) |
36 | -public abstract class SnmpCommunicationConfig { | ||
37 | - protected List<SnmpMapping> mappings; | 39 | +public interface SnmpCommunicationConfig { |
38 | 40 | ||
39 | - public List<SnmpMapping> getMappings() { | ||
40 | - return mappings; | ||
41 | - } | ||
42 | - | ||
43 | - public abstract SnmpCommunicationSpec getSpec(); | 41 | + SnmpCommunicationSpec getSpec(); |
44 | 42 | ||
45 | @JsonIgnore | 43 | @JsonIgnore |
46 | - public SnmpMethod getMethod() { | 44 | + default SnmpMethod getMethod() { |
47 | return null; | 45 | return null; |
48 | } | 46 | } |
49 | 47 | ||
50 | @JsonIgnore | 48 | @JsonIgnore |
51 | - public boolean isValid() { | ||
52 | - return mappings != null && !mappings.isEmpty() && mappings.stream().allMatch(mapping -> mapping != null && mapping.isValid()); | ||
53 | - } | 49 | + List<SnmpMapping> getAllMappings(); |
50 | + | ||
51 | + @JsonIgnore | ||
52 | + boolean isValid(); | ||
53 | + | ||
54 | } | 54 | } |
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/config/impl/ClientAttributesQueryingSnmpCommunicationConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/configs/ClientAttributesQueryingSnmpCommunicationConfig.java
@@ -13,13 +13,16 @@ | @@ -13,13 +13,16 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.data.transport.snmp.configs; | 16 | +package org.thingsboard.server.common.data.transport.snmp.config.impl; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 18 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
19 | +import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryingSnmpCommunicationConfig; | ||
19 | 20 | ||
20 | public class ClientAttributesQueryingSnmpCommunicationConfig extends RepeatingQueryingSnmpCommunicationConfig { | 21 | public class ClientAttributesQueryingSnmpCommunicationConfig extends RepeatingQueryingSnmpCommunicationConfig { |
22 | + | ||
21 | @Override | 23 | @Override |
22 | public SnmpCommunicationSpec getSpec() { | 24 | public SnmpCommunicationSpec getSpec() { |
23 | return SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING; | 25 | return SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING; |
24 | } | 26 | } |
27 | + | ||
25 | } | 28 | } |
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/config/impl/SharedAttributesSettingSnmpCommunicationConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/configs/SharedAttributesSettingSnmpCommunicationConfig.java
@@ -13,12 +13,14 @@ | @@ -13,12 +13,14 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.data.transport.snmp.configs; | 16 | +package org.thingsboard.server.common.data.transport.snmp.config.impl; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 18 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
19 | import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | 19 | import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; |
20 | +import org.thingsboard.server.common.data.transport.snmp.config.MultipleMappingsSnmpCommunicationConfig; | ||
21 | + | ||
22 | +public class SharedAttributesSettingSnmpCommunicationConfig extends MultipleMappingsSnmpCommunicationConfig { | ||
20 | 23 | ||
21 | -public class SharedAttributesSettingSnmpCommunicationConfig extends SnmpCommunicationConfig { | ||
22 | @Override | 24 | @Override |
23 | public SnmpCommunicationSpec getSpec() { | 25 | public SnmpCommunicationSpec getSpec() { |
24 | return SnmpCommunicationSpec.SHARED_ATTRIBUTES_SETTING; | 26 | return SnmpCommunicationSpec.SHARED_ATTRIBUTES_SETTING; |
@@ -28,4 +30,5 @@ public class SharedAttributesSettingSnmpCommunicationConfig extends SnmpCommunic | @@ -28,4 +30,5 @@ public class SharedAttributesSettingSnmpCommunicationConfig extends SnmpCommunic | ||
28 | public SnmpMethod getMethod() { | 30 | public SnmpMethod getMethod() { |
29 | return SnmpMethod.SET; | 31 | return SnmpMethod.SET; |
30 | } | 32 | } |
33 | + | ||
31 | } | 34 | } |
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/config/impl/TelemetryQueryingSnmpCommunicationConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/configs/TelemetryQueryingSnmpCommunicationConfig.java
@@ -13,17 +13,20 @@ | @@ -13,17 +13,20 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.common.data.transport.snmp.configs; | 16 | +package org.thingsboard.server.common.data.transport.snmp.config.impl; |
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.EqualsAndHashCode; | 19 | import lombok.EqualsAndHashCode; |
20 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 20 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
21 | +import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryingSnmpCommunicationConfig; | ||
21 | 22 | ||
22 | @EqualsAndHashCode(callSuper = true) | 23 | @EqualsAndHashCode(callSuper = true) |
23 | @Data | 24 | @Data |
24 | public class TelemetryQueryingSnmpCommunicationConfig extends RepeatingQueryingSnmpCommunicationConfig { | 25 | public class TelemetryQueryingSnmpCommunicationConfig extends RepeatingQueryingSnmpCommunicationConfig { |
26 | + | ||
25 | @Override | 27 | @Override |
26 | public SnmpCommunicationSpec getSpec() { | 28 | public SnmpCommunicationSpec getSpec() { |
27 | return SnmpCommunicationSpec.TELEMETRY_QUERYING; | 29 | return SnmpCommunicationSpec.TELEMETRY_QUERYING; |
28 | } | 30 | } |
31 | + | ||
29 | } | 32 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.transport.snmp.config.impl; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.kv.DataType; | ||
20 | +import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | ||
21 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | ||
22 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | ||
23 | +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; | ||
24 | + | ||
25 | +import java.util.Arrays; | ||
26 | +import java.util.Collections; | ||
27 | +import java.util.List; | ||
28 | + | ||
29 | +@Data | ||
30 | +public class ToDeviceRpcCommandSettingSnmpCommunicationConfig implements SnmpCommunicationConfig { | ||
31 | + private SnmpMapping mapping; | ||
32 | + | ||
33 | + @Override | ||
34 | + public SnmpCommunicationSpec getSpec() { | ||
35 | + return SnmpCommunicationSpec.TO_DEVICE_RPC_COMMAND_SETTING; | ||
36 | + } | ||
37 | + | ||
38 | + @Override | ||
39 | + public SnmpMethod getMethod() { | ||
40 | + return SnmpMethod.SET; | ||
41 | + } | ||
42 | + | ||
43 | + public void setMapping(SnmpMapping mapping) { | ||
44 | + this.mapping = mapping != null ? new SnmpMapping(mapping.getOid(), RPC_COMMAND_KEY_NAME, DataType.STRING) : null; | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public List<SnmpMapping> getAllMappings() { | ||
49 | + return Collections.singletonList(mapping); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public boolean isValid() { | ||
54 | + return mapping != null && mapping.isValid(); | ||
55 | + } | ||
56 | + | ||
57 | + public static final String RPC_COMMAND_KEY_NAME = "rpcCommand"; | ||
58 | + | ||
59 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.transport.snmp.config.impl; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import lombok.EqualsAndHashCode; | ||
20 | +import org.thingsboard.server.common.data.kv.DataType; | ||
21 | +import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | ||
22 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | ||
23 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; | ||
24 | +import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryingSnmpCommunicationConfig; | ||
25 | + | ||
26 | +import java.util.Collections; | ||
27 | +import java.util.List; | ||
28 | + | ||
29 | +@EqualsAndHashCode(callSuper = true) | ||
30 | +@Data | ||
31 | +public class ToDeviceRpcResponseQueryingSnmpCommunicationConfig extends RepeatingQueryingSnmpCommunicationConfig { | ||
32 | + private SnmpMapping mapping; | ||
33 | + | ||
34 | + @Override | ||
35 | + public SnmpCommunicationSpec getSpec() { | ||
36 | + return SnmpCommunicationSpec.TO_DEVICE_RPC_RESPONSE_QUERYING; | ||
37 | + } | ||
38 | + | ||
39 | + @Override | ||
40 | + public SnmpMethod getMethod() { | ||
41 | + return SnmpMethod.GET; | ||
42 | + } | ||
43 | + | ||
44 | + public void setMapping(SnmpMapping mapping) { | ||
45 | + this.mapping = mapping != null ? new SnmpMapping(mapping.getOid(), RPC_RESPONSE_KEY_NAME, DataType.STRING) : null; | ||
46 | + } | ||
47 | + | ||
48 | + @Override | ||
49 | + public List<SnmpMapping> getAllMappings() { | ||
50 | + return Collections.singletonList(mapping); | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + public boolean isValid() { | ||
55 | + return true; | ||
56 | + } | ||
57 | + | ||
58 | + public static final String RPC_RESPONSE_KEY_NAME = "rpcResponse"; | ||
59 | + | ||
60 | +} |
@@ -42,6 +42,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | @@ -42,6 +42,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | ||
42 | import org.thingsboard.server.queue.util.AfterStartUp; | 42 | import org.thingsboard.server.queue.util.AfterStartUp; |
43 | import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | 43 | import org.thingsboard.server.queue.util.TbSnmpTransportComponent; |
44 | import org.thingsboard.server.transport.snmp.service.ProtoTransportEntityService; | 44 | import org.thingsboard.server.transport.snmp.service.ProtoTransportEntityService; |
45 | +import org.thingsboard.server.transport.snmp.service.SnmpAuthService; | ||
45 | import org.thingsboard.server.transport.snmp.service.SnmpTransportBalancingService; | 46 | import org.thingsboard.server.transport.snmp.service.SnmpTransportBalancingService; |
46 | import org.thingsboard.server.transport.snmp.service.SnmpTransportService; | 47 | import org.thingsboard.server.transport.snmp.service.SnmpTransportService; |
47 | import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; | 48 | import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; |
@@ -116,7 +117,7 @@ public class SnmpTransportContext extends TransportContext { | @@ -116,7 +117,7 @@ public class SnmpTransportContext extends TransportContext { | ||
116 | ); | 117 | ); |
117 | registerSessionMsgListener(deviceSessionContext); | 118 | registerSessionMsgListener(deviceSessionContext); |
118 | } catch (Exception e) { | 119 | } catch (Exception e) { |
119 | - log.error("Failed to establish session for SNMP device {}: {}", device.getId(), e.getMessage()); | 120 | + log.error("Failed to establish session for SNMP device {}: {}", device.getId(), e.toString()); |
120 | return; | 121 | return; |
121 | } | 122 | } |
122 | sessions.put(device.getId(), deviceSessionContext); | 123 | sessions.put(device.getId(), deviceSessionContext); |
@@ -177,7 +178,9 @@ public class SnmpTransportContext extends TransportContext { | @@ -177,7 +178,9 @@ public class SnmpTransportContext extends TransportContext { | ||
177 | ); | 178 | ); |
178 | 179 | ||
179 | transportService.registerAsyncSession(sessionInfo, deviceSessionContext); | 180 | transportService.registerAsyncSession(sessionInfo, deviceSessionContext); |
180 | - transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); | 181 | + transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), TransportServiceCallback.EMPTY); |
182 | + transportService.process(sessionInfo, TransportProtos.SubscribeToRPCMsg.newBuilder().build(), TransportServiceCallback.EMPTY); | ||
183 | + | ||
181 | deviceSessionContext.setSessionInfo(sessionInfo); | 184 | deviceSessionContext.setSessionInfo(sessionInfo); |
182 | deviceSessionContext.setDeviceInfo(msg.getDeviceInfo()); | 185 | deviceSessionContext.setDeviceInfo(msg.getDeviceInfo()); |
183 | } else { | 186 | } else { |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/PduMapper.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.transport.snmp.service; | ||
17 | + | ||
18 | +import com.google.gson.JsonObject; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.snmp4j.PDU; | ||
21 | +import org.snmp4j.ScopedPDU; | ||
22 | +import org.snmp4j.smi.Integer32; | ||
23 | +import org.snmp4j.smi.Null; | ||
24 | +import org.snmp4j.smi.OID; | ||
25 | +import org.snmp4j.smi.OctetString; | ||
26 | +import org.snmp4j.smi.Variable; | ||
27 | +import org.snmp4j.smi.VariableBinding; | ||
28 | +import org.springframework.stereotype.Service; | ||
29 | +import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; | ||
30 | +import org.thingsboard.server.common.data.kv.DataType; | ||
31 | +import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | ||
32 | +import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion; | ||
33 | +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; | ||
34 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
35 | +import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; | ||
36 | + | ||
37 | +import java.util.HashMap; | ||
38 | +import java.util.List; | ||
39 | +import java.util.Map; | ||
40 | +import java.util.Objects; | ||
41 | +import java.util.Optional; | ||
42 | +import java.util.stream.Collectors; | ||
43 | +import java.util.stream.IntStream; | ||
44 | + | ||
45 | +@TbSnmpTransportComponent | ||
46 | +@Service | ||
47 | +@Slf4j | ||
48 | +public class PduMapper { | ||
49 | + public PDU createPdu(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) { | ||
50 | + PDU pdu; | ||
51 | + SnmpDeviceTransportConfiguration deviceTransportConfiguration = sessionContext.getDeviceTransportConfiguration(); | ||
52 | + SnmpProtocolVersion snmpVersion = deviceTransportConfiguration.getProtocolVersion(); | ||
53 | + switch (snmpVersion) { | ||
54 | + case V1: | ||
55 | + case V2C: | ||
56 | + pdu = new PDU(); | ||
57 | + break; | ||
58 | + case V3: | ||
59 | + ScopedPDU scopedPdu = new ScopedPDU(); | ||
60 | + scopedPdu.setContextName(new OctetString(deviceTransportConfiguration.getContextName())); | ||
61 | + scopedPdu.setContextEngineID(new OctetString(deviceTransportConfiguration.getEngineId())); | ||
62 | + pdu = scopedPdu; | ||
63 | + break; | ||
64 | + default: | ||
65 | + throw new UnsupportedOperationException("SNMP version " + snmpVersion + " is not supported"); | ||
66 | + } | ||
67 | + | ||
68 | + pdu.setType(communicationConfig.getMethod().getCode()); | ||
69 | + pdu.addAll(communicationConfig.getAllMappings().stream() | ||
70 | + .filter(mapping -> values.isEmpty() || values.containsKey(mapping.getKey())) | ||
71 | + .map(mapping -> Optional.ofNullable(values.get(mapping.getKey())) | ||
72 | + .map(value -> { | ||
73 | + Variable variable = toSnmpVariable(mapping, value); | ||
74 | + return new VariableBinding(new OID(mapping.getOid()), variable); | ||
75 | + }) | ||
76 | + .orElseGet(() -> new VariableBinding(new OID(mapping.getOid())))) | ||
77 | + .collect(Collectors.toList())); | ||
78 | + | ||
79 | + return pdu; | ||
80 | + } | ||
81 | + | ||
82 | + private Variable toSnmpVariable(SnmpMapping mapping, String value) { | ||
83 | + Variable variable; | ||
84 | + switch (mapping.getDataType()) { | ||
85 | + case LONG: | ||
86 | + try { | ||
87 | + variable = new Integer32(Integer.parseInt(value)); | ||
88 | + break; | ||
89 | + } catch (NumberFormatException ignored) { | ||
90 | + } | ||
91 | + case DOUBLE: | ||
92 | + case BOOLEAN: | ||
93 | + case STRING: | ||
94 | + case JSON: | ||
95 | + default: | ||
96 | + variable = new OctetString(value); | ||
97 | + } | ||
98 | + return variable; | ||
99 | + } | ||
100 | + | ||
101 | + | ||
102 | + public JsonObject processPdu(PDU pdu, DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) { | ||
103 | + List<VariableBinding> variablesBindings = IntStream.range(0, pdu.size()) | ||
104 | + .mapToObj(pdu::get) | ||
105 | + .filter(Objects::nonNull) | ||
106 | + .filter(variableBinding -> !(variableBinding.getVariable() instanceof Null)) | ||
107 | + .collect(Collectors.toList()); | ||
108 | + JsonObject data = new JsonObject(); | ||
109 | + | ||
110 | + Map<OID, SnmpMapping> mappings = new HashMap<>(); | ||
111 | + for (SnmpMapping mapping : communicationConfig.getAllMappings()) { | ||
112 | + OID oid = new OID(mapping.getOid()); | ||
113 | + mappings.put(oid, mapping); | ||
114 | + } | ||
115 | + | ||
116 | + variablesBindings.forEach(variableBinding -> { | ||
117 | + log.trace("Processing variable binding: {}", variableBinding); | ||
118 | + | ||
119 | + OID oid = variableBinding.getOid(); | ||
120 | + SnmpMapping mapping = mappings.get(oid); | ||
121 | + if (mapping == null) { | ||
122 | + log.debug("No SNMP mapping for oid {}", oid); | ||
123 | + return; | ||
124 | + } | ||
125 | + | ||
126 | + processValue(mapping.getKey(), mapping.getDataType(), variableBinding.toValueString(), data); | ||
127 | + }); | ||
128 | + | ||
129 | + return data; | ||
130 | + } | ||
131 | + | ||
132 | + | ||
133 | + private void processValue(String key, DataType dataType, String value, JsonObject result) { | ||
134 | + switch (dataType) { | ||
135 | + case LONG: | ||
136 | + result.addProperty(key, Long.parseLong(value)); | ||
137 | + break; | ||
138 | + case BOOLEAN: | ||
139 | + result.addProperty(key, Boolean.parseBoolean(value)); | ||
140 | + break; | ||
141 | + case DOUBLE: | ||
142 | + result.addProperty(key, Double.parseDouble(value)); | ||
143 | + break; | ||
144 | + case STRING: | ||
145 | + case JSON: | ||
146 | + default: | ||
147 | + result.addProperty(key, value); | ||
148 | + } | ||
149 | + } | ||
150 | +} |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpAuthService.java
renamed from
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpAuthService.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.transport.snmp; | 16 | +package org.thingsboard.server.transport.snmp.service; |
17 | 17 | ||
18 | import lombok.RequiredArgsConstructor; | 18 | import lombok.RequiredArgsConstructor; |
19 | import org.snmp4j.AbstractTarget; | 19 | import org.snmp4j.AbstractTarget; |
@@ -24,6 +24,7 @@ import org.snmp4j.security.SecurityLevel; | @@ -24,6 +24,7 @@ import org.snmp4j.security.SecurityLevel; | ||
24 | import org.snmp4j.security.SecurityModel; | 24 | import org.snmp4j.security.SecurityModel; |
25 | import org.snmp4j.security.SecurityProtocols; | 25 | import org.snmp4j.security.SecurityProtocols; |
26 | import org.snmp4j.security.USM; | 26 | import org.snmp4j.security.USM; |
27 | +import org.snmp4j.smi.Address; | ||
27 | import org.snmp4j.smi.GenericAddress; | 28 | import org.snmp4j.smi.GenericAddress; |
28 | import org.snmp4j.smi.OID; | 29 | import org.snmp4j.smi.OID; |
29 | import org.snmp4j.smi.OctetString; | 30 | import org.snmp4j.smi.OctetString; |
@@ -36,6 +37,8 @@ import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | @@ -36,6 +37,8 @@ import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
36 | import org.thingsboard.server.transport.snmp.service.SnmpTransportService; | 37 | import org.thingsboard.server.transport.snmp.service.SnmpTransportService; |
37 | import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; | 38 | import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; |
38 | 39 | ||
40 | +import java.util.Optional; | ||
41 | + | ||
39 | @Service | 42 | @Service |
40 | @TbSnmpTransportComponent | 43 | @TbSnmpTransportComponent |
41 | @RequiredArgsConstructor | 44 | @RequiredArgsConstructor |
@@ -97,7 +100,8 @@ public class SnmpAuthService { | @@ -97,7 +100,8 @@ public class SnmpAuthService { | ||
97 | throw new UnsupportedOperationException("SNMP protocol version " + protocolVersion + " is not supported"); | 100 | throw new UnsupportedOperationException("SNMP protocol version " + protocolVersion + " is not supported"); |
98 | } | 101 | } |
99 | 102 | ||
100 | - target.setAddress(GenericAddress.parse(snmpUnderlyingProtocol + ":" + deviceTransportConfig.getHost() + "/" + deviceTransportConfig.getPort())); | 103 | + Address address = GenericAddress.parse(snmpUnderlyingProtocol + ":" + deviceTransportConfig.getHost() + "/" + deviceTransportConfig.getPort()); |
104 | + target.setAddress(Optional.ofNullable(address).orElseThrow(() -> new IllegalArgumentException("Address of the SNMP device is invalid"))); | ||
101 | target.setTimeout(profileTransportConfig.getTimeoutMs()); | 105 | target.setTimeout(profileTransportConfig.getTimeoutMs()); |
102 | target.setRetries(profileTransportConfig.getRetries()); | 106 | target.setRetries(profileTransportConfig.getRetries()); |
103 | target.setVersion(protocolVersion.getCode()); | 107 | target.setVersion(protocolVersion.getCode()); |
@@ -16,11 +16,11 @@ | @@ -16,11 +16,11 @@ | ||
16 | package org.thingsboard.server.transport.snmp.service; | 16 | package org.thingsboard.server.transport.snmp.service; |
17 | 17 | ||
18 | import com.google.gson.JsonObject; | 18 | import com.google.gson.JsonObject; |
19 | +import lombok.Data; | ||
19 | import lombok.Getter; | 20 | import lombok.Getter; |
21 | +import lombok.RequiredArgsConstructor; | ||
20 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
21 | -import org.apache.commons.lang3.StringUtils; | ||
22 | import org.snmp4j.PDU; | 23 | import org.snmp4j.PDU; |
23 | -import org.snmp4j.ScopedPDU; | ||
24 | import org.snmp4j.Snmp; | 24 | import org.snmp4j.Snmp; |
25 | import org.snmp4j.TransportMapping; | 25 | import org.snmp4j.TransportMapping; |
26 | import org.snmp4j.event.ResponseEvent; | 26 | import org.snmp4j.event.ResponseEvent; |
@@ -28,26 +28,18 @@ import org.snmp4j.mp.MPv3; | @@ -28,26 +28,18 @@ import org.snmp4j.mp.MPv3; | ||
28 | import org.snmp4j.security.SecurityModels; | 28 | import org.snmp4j.security.SecurityModels; |
29 | import org.snmp4j.security.SecurityProtocols; | 29 | import org.snmp4j.security.SecurityProtocols; |
30 | import org.snmp4j.security.USM; | 30 | import org.snmp4j.security.USM; |
31 | -import org.snmp4j.smi.Integer32; | ||
32 | -import org.snmp4j.smi.Null; | ||
33 | -import org.snmp4j.smi.OID; | ||
34 | import org.snmp4j.smi.OctetString; | 31 | import org.snmp4j.smi.OctetString; |
35 | -import org.snmp4j.smi.Variable; | ||
36 | -import org.snmp4j.smi.VariableBinding; | ||
37 | import org.snmp4j.transport.DefaultTcpTransportMapping; | 32 | import org.snmp4j.transport.DefaultTcpTransportMapping; |
38 | import org.snmp4j.transport.DefaultUdpTransportMapping; | 33 | import org.snmp4j.transport.DefaultUdpTransportMapping; |
39 | import org.springframework.beans.factory.annotation.Value; | 34 | import org.springframework.beans.factory.annotation.Value; |
40 | import org.springframework.stereotype.Service; | 35 | import org.springframework.stereotype.Service; |
41 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 36 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
42 | import org.thingsboard.server.common.data.TbTransportService; | 37 | import org.thingsboard.server.common.data.TbTransportService; |
43 | -import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; | ||
44 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 38 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
45 | -import org.thingsboard.server.common.data.kv.DataType; | ||
46 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 39 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
47 | -import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; | ||
48 | -import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion; | ||
49 | -import org.thingsboard.server.common.data.transport.snmp.configs.RepeatingQueryingSnmpCommunicationConfig; | ||
50 | -import org.thingsboard.server.common.data.transport.snmp.configs.SnmpCommunicationConfig; | 40 | +import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryingSnmpCommunicationConfig; |
41 | +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; | ||
42 | +import org.thingsboard.server.common.data.transport.snmp.config.impl.ToDeviceRpcResponseQueryingSnmpCommunicationConfig; | ||
51 | import org.thingsboard.server.common.transport.TransportService; | 43 | import org.thingsboard.server.common.transport.TransportService; |
52 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 44 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
53 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 45 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
@@ -60,44 +52,37 @@ import javax.annotation.PreDestroy; | @@ -60,44 +52,37 @@ import javax.annotation.PreDestroy; | ||
60 | import java.io.IOException; | 52 | import java.io.IOException; |
61 | import java.util.Collections; | 53 | import java.util.Collections; |
62 | import java.util.EnumMap; | 54 | import java.util.EnumMap; |
63 | -import java.util.HashMap; | ||
64 | import java.util.List; | 55 | import java.util.List; |
65 | import java.util.Map; | 56 | import java.util.Map; |
66 | -import java.util.Optional; | ||
67 | import java.util.concurrent.ExecutorService; | 57 | import java.util.concurrent.ExecutorService; |
68 | import java.util.concurrent.Executors; | 58 | import java.util.concurrent.Executors; |
69 | import java.util.concurrent.ScheduledExecutorService; | 59 | import java.util.concurrent.ScheduledExecutorService; |
70 | import java.util.concurrent.ScheduledFuture; | 60 | import java.util.concurrent.ScheduledFuture; |
71 | import java.util.concurrent.TimeUnit; | 61 | import java.util.concurrent.TimeUnit; |
72 | -import java.util.function.BiConsumer; | ||
73 | import java.util.stream.Collectors; | 62 | import java.util.stream.Collectors; |
74 | 63 | ||
75 | @TbSnmpTransportComponent | 64 | @TbSnmpTransportComponent |
76 | @Service | 65 | @Service |
77 | @Slf4j | 66 | @Slf4j |
67 | +@RequiredArgsConstructor | ||
78 | public class SnmpTransportService implements TbTransportService { | 68 | public class SnmpTransportService implements TbTransportService { |
79 | private final TransportService transportService; | 69 | private final TransportService transportService; |
70 | + private final PduMapper pduMapper; | ||
80 | 71 | ||
81 | @Getter | 72 | @Getter |
82 | private Snmp snmp; | 73 | private Snmp snmp; |
83 | private ScheduledExecutorService queryingExecutor; | 74 | private ScheduledExecutorService queryingExecutor; |
84 | private ExecutorService responseProcessingExecutor; | 75 | private ExecutorService responseProcessingExecutor; |
85 | 76 | ||
86 | - private final Map<SnmpCommunicationSpec, BiConsumer<JsonObject, DeviceSessionContext>> responseProcessors = new EnumMap<>(SnmpCommunicationSpec.class); | 77 | + private final Map<SnmpCommunicationSpec, ResponseProcessor> responseProcessors = new EnumMap<>(SnmpCommunicationSpec.class); |
87 | 78 | ||
88 | @Value("${transport.snmp.response_processing.parallelism_level}") | 79 | @Value("${transport.snmp.response_processing.parallelism_level}") |
89 | private Integer responseProcessingParallelismLevel; | 80 | private Integer responseProcessingParallelismLevel; |
90 | @Value("${transport.snmp.underlying_protocol}") | 81 | @Value("${transport.snmp.underlying_protocol}") |
91 | private String snmpUnderlyingProtocol; | 82 | private String snmpUnderlyingProtocol; |
92 | 83 | ||
93 | - public SnmpTransportService(TransportService transportService) { | ||
94 | - this.transportService = transportService; | ||
95 | - } | ||
96 | - | ||
97 | @PostConstruct | 84 | @PostConstruct |
98 | private void init() throws IOException { | 85 | private void init() throws IOException { |
99 | - log.info("Initializing SNMP transport service"); | ||
100 | - | ||
101 | queryingExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("snmp-querying")); | 86 | queryingExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("snmp-querying")); |
102 | responseProcessingExecutor = Executors.newWorkStealingPool(responseProcessingParallelismLevel); | 87 | responseProcessingExecutor = Executors.newWorkStealingPool(responseProcessingParallelismLevel); |
103 | 88 | ||
@@ -128,26 +113,23 @@ public class SnmpTransportService implements TbTransportService { | @@ -128,26 +113,23 @@ public class SnmpTransportService implements TbTransportService { | ||
128 | 113 | ||
129 | public void createQueryingTasks(DeviceSessionContext sessionContext) { | 114 | public void createQueryingTasks(DeviceSessionContext sessionContext) { |
130 | List<ScheduledFuture<?>> queryingTasks = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() | 115 | List<ScheduledFuture<?>> queryingTasks = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() |
131 | - .filter(config -> config.getSpec().isRepeatingQuerying()) | 116 | + .filter(communicationConfig -> communicationConfig instanceof RepeatingQueryingSnmpCommunicationConfig) |
132 | .map(config -> { | 117 | .map(config -> { |
133 | RepeatingQueryingSnmpCommunicationConfig repeatingCommunicationConfig = (RepeatingQueryingSnmpCommunicationConfig) config; | 118 | RepeatingQueryingSnmpCommunicationConfig repeatingCommunicationConfig = (RepeatingQueryingSnmpCommunicationConfig) config; |
134 | - return createQueryingTaskForConfig(sessionContext, repeatingCommunicationConfig); | 119 | + Long queryingFrequency = repeatingCommunicationConfig.getQueryingFrequencyMs(); |
120 | + | ||
121 | + return queryingExecutor.scheduleWithFixedDelay(() -> { | ||
122 | + try { | ||
123 | + if (sessionContext.isActive()) { | ||
124 | + sendRequest(sessionContext, repeatingCommunicationConfig); | ||
125 | + } | ||
126 | + } catch (Exception e) { | ||
127 | + log.error("Failed to send SNMP request for device {}: {}", sessionContext.getDeviceId(), e.toString()); | ||
128 | + } | ||
129 | + }, queryingFrequency, queryingFrequency, TimeUnit.MILLISECONDS); | ||
135 | }) | 130 | }) |
136 | .collect(Collectors.toList()); | 131 | .collect(Collectors.toList()); |
137 | - sessionContext.setQueryingTasks(queryingTasks); | ||
138 | - } | ||
139 | - | ||
140 | - private ScheduledFuture<?> createQueryingTaskForConfig(DeviceSessionContext sessionContext, RepeatingQueryingSnmpCommunicationConfig communicationConfig) { | ||
141 | - Long queryingFrequency = communicationConfig.getQueryingFrequencyMs(); | ||
142 | - return queryingExecutor.scheduleWithFixedDelay(() -> { | ||
143 | - try { | ||
144 | - if (sessionContext.isActive()) { | ||
145 | - sendRequest(sessionContext, communicationConfig); | ||
146 | - } | ||
147 | - } catch (Exception e) { | ||
148 | - log.error("Failed to send SNMP request for device {}: {}", sessionContext.getDeviceId(), e.toString()); | ||
149 | - } | ||
150 | - }, queryingFrequency, queryingFrequency, TimeUnit.MILLISECONDS); | 132 | + sessionContext.getQueryingTasks().addAll(queryingTasks); |
151 | } | 133 | } |
152 | 134 | ||
153 | public void cancelQueryingTasks(DeviceSessionContext sessionContext) { | 135 | public void cancelQueryingTasks(DeviceSessionContext sessionContext) { |
@@ -155,67 +137,23 @@ public class SnmpTransportService implements TbTransportService { | @@ -155,67 +137,23 @@ public class SnmpTransportService implements TbTransportService { | ||
155 | sessionContext.getQueryingTasks().clear(); | 137 | sessionContext.getQueryingTasks().clear(); |
156 | } | 138 | } |
157 | 139 | ||
158 | - public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) throws IOException { | 140 | + |
141 | + public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) { | ||
159 | sendRequest(sessionContext, communicationConfig, Collections.emptyMap()); | 142 | sendRequest(sessionContext, communicationConfig, Collections.emptyMap()); |
160 | } | 143 | } |
161 | 144 | ||
162 | - public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) throws IOException { | ||
163 | - PDU request = createPdu(sessionContext, communicationConfig, values); | ||
164 | - executeRequest(sessionContext, request); | ||
165 | - } | 145 | + public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) { |
146 | + PDU request = pduMapper.createPdu(sessionContext, communicationConfig, values); | ||
166 | 147 | ||
167 | - private void executeRequest(DeviceSessionContext sessionContext, PDU request) throws IOException { | ||
168 | if (request.size() > 0) { | 148 | if (request.size() > 0) { |
169 | log.trace("Executing SNMP request for device {}. Variables bindings: {}", sessionContext.getDeviceId(), request.getVariableBindings()); | 149 | log.trace("Executing SNMP request for device {}. Variables bindings: {}", sessionContext.getDeviceId(), request.getVariableBindings()); |
170 | - snmp.send(request, sessionContext.getTarget(), sessionContext.getDeviceProfile().getId(), sessionContext); | ||
171 | - } | ||
172 | - } | ||
173 | - | ||
174 | - private PDU createPdu(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) { | ||
175 | - PDU pdu; | ||
176 | - SnmpDeviceTransportConfiguration deviceTransportConfiguration = sessionContext.getDeviceTransportConfiguration(); | ||
177 | - SnmpProtocolVersion snmpVersion = deviceTransportConfiguration.getProtocolVersion(); | ||
178 | - switch (snmpVersion) { | ||
179 | - case V1: | ||
180 | - case V2C: | ||
181 | - pdu = new PDU(); | ||
182 | - break; | ||
183 | - case V3: | ||
184 | - ScopedPDU scopedPdu = new ScopedPDU(); | ||
185 | - scopedPdu.setContextName(new OctetString(deviceTransportConfiguration.getContextName())); | ||
186 | - scopedPdu.setContextEngineID(new OctetString(deviceTransportConfiguration.getEngineId())); | ||
187 | - pdu = scopedPdu; | ||
188 | - break; | ||
189 | - default: | ||
190 | - throw new UnsupportedOperationException("SNMP version " + snmpVersion + " is not supported"); | 150 | + RequestInfo requestInfo = new RequestInfo(sessionContext.getDeviceProfile().getId(), communicationConfig); |
151 | + try { | ||
152 | + snmp.send(request, sessionContext.getTarget(), requestInfo, sessionContext); | ||
153 | + } catch (IOException e) { | ||
154 | + log.error("Failed to send SNMP request to device {}: {}", sessionContext.getDeviceId(), e.toString()); | ||
155 | + } | ||
191 | } | 156 | } |
192 | - | ||
193 | - pdu.setType(communicationConfig.getMethod().getCode()); | ||
194 | - pdu.addAll(communicationConfig.getMappings().stream() | ||
195 | - .filter(mapping -> values.isEmpty() || values.containsKey(mapping.getKey())) | ||
196 | - .map(mapping -> Optional.ofNullable(values.get(mapping.getKey())) | ||
197 | - .map(value -> { | ||
198 | - Variable variable; | ||
199 | - switch (mapping.getDataType()) { | ||
200 | - case LONG: | ||
201 | - try { | ||
202 | - variable = new Integer32(Integer.parseInt(value)); | ||
203 | - break; | ||
204 | - } catch (NumberFormatException ignored) { | ||
205 | - } | ||
206 | - case DOUBLE: | ||
207 | - case BOOLEAN: | ||
208 | - case STRING: | ||
209 | - case JSON: | ||
210 | - default: | ||
211 | - variable = new OctetString(value); | ||
212 | - } | ||
213 | - return new VariableBinding(new OID(mapping.getOid()), variable); | ||
214 | - }) | ||
215 | - .orElseGet(() -> new VariableBinding(new OID(mapping.getOid())))) | ||
216 | - .collect(Collectors.toList())); | ||
217 | - | ||
218 | - return pdu; | ||
219 | } | 157 | } |
220 | 158 | ||
221 | 159 | ||
@@ -223,7 +161,7 @@ public class SnmpTransportService implements TbTransportService { | @@ -223,7 +161,7 @@ public class SnmpTransportService implements TbTransportService { | ||
223 | ((Snmp) event.getSource()).cancel(event.getRequest(), sessionContext); | 161 | ((Snmp) event.getSource()).cancel(event.getRequest(), sessionContext); |
224 | 162 | ||
225 | if (event.getError() != null) { | 163 | if (event.getError() != null) { |
226 | - log.warn("Response error: {}", event.getError().getMessage(), event.getError()); | 164 | + log.warn("SNMP response error: {}", event.getError().toString()); |
227 | return; | 165 | return; |
228 | } | 166 | } |
229 | 167 | ||
@@ -232,108 +170,65 @@ public class SnmpTransportService implements TbTransportService { | @@ -232,108 +170,65 @@ public class SnmpTransportService implements TbTransportService { | ||
232 | log.debug("No response from SNMP device {}, requestId: {}", sessionContext.getDeviceId(), event.getRequest().getRequestID()); | 170 | log.debug("No response from SNMP device {}, requestId: {}", sessionContext.getDeviceId(), event.getRequest().getRequestID()); |
233 | return; | 171 | return; |
234 | } | 172 | } |
235 | - DeviceProfileId deviceProfileId = (DeviceProfileId) event.getUserObject(); | ||
236 | - log.debug("[{}] Processing SNMP response for device {} with device profile {}: {}", | ||
237 | - response.getRequestID(), sessionContext.getDeviceId(), deviceProfileId, response); | ||
238 | 173 | ||
239 | - responseProcessingExecutor.execute(() -> processResponse(sessionContext, response)); | 174 | + RequestInfo requestInfo = (RequestInfo) event.getUserObject(); |
175 | + responseProcessingExecutor.execute(() -> { | ||
176 | + processResponse(sessionContext, response, requestInfo); | ||
177 | + }); | ||
240 | } | 178 | } |
241 | 179 | ||
242 | - private void processResponse(DeviceSessionContext sessionContext, PDU responsePdu) { | ||
243 | - Map<OID, SnmpMapping> mappings = new HashMap<>(); | ||
244 | - Map<OID, SnmpCommunicationConfig> configs = new HashMap<>(); | ||
245 | - Map<SnmpCommunicationSpec, JsonObject> responses = new EnumMap<>(SnmpCommunicationSpec.class); | ||
246 | - | ||
247 | - for (SnmpCommunicationConfig config : sessionContext.getProfileTransportConfiguration().getCommunicationConfigs()) { | ||
248 | - for (SnmpMapping mapping : config.getMappings()) { | ||
249 | - OID oid = new OID(mapping.getOid()); | ||
250 | - mappings.put(oid, mapping); | ||
251 | - configs.put(oid, config); | ||
252 | - } | ||
253 | - responses.put(config.getSpec(), new JsonObject()); | ||
254 | - } | ||
255 | - | ||
256 | - for (int i = 0; i < responsePdu.size(); i++) { | ||
257 | - VariableBinding variableBinding = responsePdu.get(i); | ||
258 | - log.trace("Processing variable binding {}: {}", i, variableBinding); | ||
259 | - | ||
260 | - if (variableBinding.getVariable() instanceof Null) { | ||
261 | - log.debug("Response variable is empty"); | ||
262 | - continue; | ||
263 | - } | ||
264 | - | ||
265 | - OID oid = variableBinding.getOid(); | ||
266 | - if (!mappings.containsKey(oid)) { | ||
267 | - log.debug("No SNMP mapping for oid {}", oid); | ||
268 | - continue; | ||
269 | - } | ||
270 | - | ||
271 | - SnmpCommunicationSpec spec = configs.get(oid).getSpec(); | ||
272 | - if (!responseProcessors.containsKey(spec)) { | ||
273 | - log.debug("No response processor found for spec {}", spec); | ||
274 | - continue; | ||
275 | - } | ||
276 | - | ||
277 | - SnmpMapping mapping = mappings.get(oid); | ||
278 | - processValue(mapping.getKey(), mapping.getDataType(), variableBinding.toValueString(), responses.get(spec)); | 180 | + private void processResponse(DeviceSessionContext sessionContext, PDU response, RequestInfo requestInfo) { |
181 | + ResponseProcessor responseProcessor = responseProcessors.get(requestInfo.getCommunicationConfig().getSpec()); | ||
182 | + if (responseProcessor == null) { | ||
183 | + return; | ||
279 | } | 184 | } |
280 | 185 | ||
281 | - if (responses.values().stream().allMatch(response -> response.entrySet().isEmpty())) { | ||
282 | - log.debug("No values is the SNMP response for device {}. Request id: {}", sessionContext.getDeviceId(), responsePdu.getRequestID()); | 186 | + JsonObject responseData = pduMapper.processPdu(response, sessionContext, requestInfo.getCommunicationConfig()); |
187 | + if (responseData.entrySet().isEmpty()) { | ||
188 | + log.debug("No values is the SNMP response for device {}. Request id: {}", sessionContext.getDeviceId(), response.getRequestID()); | ||
283 | return; | 189 | return; |
284 | } | 190 | } |
285 | 191 | ||
286 | - responses.forEach((spec, response) -> { | ||
287 | - Optional.ofNullable(responseProcessors.get(spec)) | ||
288 | - .ifPresent(responseProcessor -> { | ||
289 | - if (!response.entrySet().isEmpty()) { | ||
290 | - responseProcessor.accept(response, sessionContext); | ||
291 | - } | ||
292 | - }); | ||
293 | - }); | ||
294 | - | 192 | + responseProcessor.process(responseData, sessionContext); |
295 | reportActivity(sessionContext.getSessionInfo()); | 193 | reportActivity(sessionContext.getSessionInfo()); |
296 | } | 194 | } |
297 | 195 | ||
298 | private void configureResponseProcessors() { | 196 | private void configureResponseProcessors() { |
299 | responseProcessors.put(SnmpCommunicationSpec.TELEMETRY_QUERYING, (response, sessionContext) -> { | 197 | responseProcessors.put(SnmpCommunicationSpec.TELEMETRY_QUERYING, (response, sessionContext) -> { |
300 | TransportProtos.PostTelemetryMsg postTelemetryMsg = JsonConverter.convertToTelemetryProto(response); | 198 | TransportProtos.PostTelemetryMsg postTelemetryMsg = JsonConverter.convertToTelemetryProto(response); |
301 | - transportService.process(sessionContext.getSessionInfo(), postTelemetryMsg, TransportServiceCallback.EMPTY); | ||
302 | - log.debug("Posted telemetry for device {}: {}", sessionContext.getDeviceId(), response); | 199 | + transportService.process(sessionContext.getSessionInfo(), postTelemetryMsg, null); |
200 | + log.debug("Posted telemetry for SNMP device {}: {}", sessionContext.getDeviceId(), response); | ||
303 | }); | 201 | }); |
304 | 202 | ||
305 | responseProcessors.put(SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING, (response, sessionContext) -> { | 203 | responseProcessors.put(SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING, (response, sessionContext) -> { |
306 | TransportProtos.PostAttributeMsg postAttributesMsg = JsonConverter.convertToAttributesProto(response); | 204 | TransportProtos.PostAttributeMsg postAttributesMsg = JsonConverter.convertToAttributesProto(response); |
307 | - transportService.process(sessionContext.getSessionInfo(), postAttributesMsg, TransportServiceCallback.EMPTY); | ||
308 | - log.debug("Posted attributes for device {}: {}", sessionContext.getDeviceId(), response); | 205 | + transportService.process(sessionContext.getSessionInfo(), postAttributesMsg, null); |
206 | + log.debug("Posted attributes for SNMP device {}: {}", sessionContext.getDeviceId(), response); | ||
207 | + }); | ||
208 | + | ||
209 | + responseProcessors.put(SnmpCommunicationSpec.TO_DEVICE_RPC_RESPONSE_QUERYING, (response, sessionContext) -> { | ||
210 | + String rpcResponse = response.get(ToDeviceRpcResponseQueryingSnmpCommunicationConfig.RPC_RESPONSE_KEY_NAME).getAsString(); | ||
211 | + TransportProtos.ToDeviceRpcResponseMsg rpcResponseMsg = TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
212 | + .setPayload(rpcResponse) | ||
213 | + .build(); | ||
214 | + transportService.process(sessionContext.getSessionInfo(), rpcResponseMsg, null); | ||
215 | + log.debug("Processed RPC response from device {}: {}", sessionContext.getDeviceId(), rpcResponse); | ||
309 | }); | 216 | }); |
217 | + | ||
218 | +// responseProcessors.put(, (response, sessionContext) -> { | ||
219 | +// TransportProtos.ClaimDeviceMsg claimDeviceMsg = JsonConverter.convertToClaimDeviceProto(sessionContext.getDeviceId(), response); | ||
220 | +// transportService.process(sessionContext.getSessionInfo(), claimDeviceMsg, null); | ||
221 | +// }); | ||
310 | } | 222 | } |
311 | 223 | ||
312 | private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { | 224 | private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { |
313 | transportService.process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() | 225 | transportService.process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() |
314 | - .setAttributeSubscription(false) | ||
315 | - .setRpcSubscription(false) | 226 | + .setAttributeSubscription(true) |
227 | + .setRpcSubscription(true) | ||
316 | .setLastActivityTime(System.currentTimeMillis()) | 228 | .setLastActivityTime(System.currentTimeMillis()) |
317 | .build(), TransportServiceCallback.EMPTY); | 229 | .build(), TransportServiceCallback.EMPTY); |
318 | } | 230 | } |
319 | 231 | ||
320 | - private void processValue(String key, DataType dataType, String value, JsonObject result) { | ||
321 | - if (StringUtils.isEmpty(value)) return; | ||
322 | - | ||
323 | - switch (dataType) { | ||
324 | - case LONG: | ||
325 | - result.addProperty(key, Long.parseLong(value)); | ||
326 | - break; | ||
327 | - case BOOLEAN: | ||
328 | - result.addProperty(key, Boolean.parseBoolean(value)); | ||
329 | - break; | ||
330 | - case DOUBLE: | ||
331 | - result.addProperty(key, Double.parseDouble(value)); | ||
332 | - break; | ||
333 | - default: | ||
334 | - result.addProperty(key, value); | ||
335 | - } | ||
336 | - } | ||
337 | 232 | ||
338 | @Override | 233 | @Override |
339 | public String getName() { | 234 | public String getName() { |
@@ -358,4 +253,15 @@ public class SnmpTransportService implements TbTransportService { | @@ -358,4 +253,15 @@ public class SnmpTransportService implements TbTransportService { | ||
358 | } | 253 | } |
359 | log.info("SNMP transport stopped!"); | 254 | log.info("SNMP transport stopped!"); |
360 | } | 255 | } |
256 | + | ||
257 | + @Data | ||
258 | + private static class RequestInfo { | ||
259 | + private final DeviceProfileId deviceProfileId; | ||
260 | + private final SnmpCommunicationConfig communicationConfig; | ||
261 | + } | ||
262 | + | ||
263 | + private interface ResponseProcessor { | ||
264 | + void process(JsonObject responseData, DeviceSessionContext sessionContext); | ||
265 | + } | ||
266 | + | ||
361 | } | 267 | } |
@@ -27,6 +27,8 @@ import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfigu | @@ -27,6 +27,8 @@ import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfigu | ||
27 | import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; | 27 | import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; |
28 | import org.thingsboard.server.common.data.id.DeviceId; | 28 | import org.thingsboard.server.common.data.id.DeviceId; |
29 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; | 29 | import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec; |
30 | +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; | ||
31 | +import org.thingsboard.server.common.data.transport.snmp.config.impl.ToDeviceRpcCommandSettingSnmpCommunicationConfig; | ||
30 | import org.thingsboard.server.common.transport.SessionMsgListener; | 32 | import org.thingsboard.server.common.transport.SessionMsgListener; |
31 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 33 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
32 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; | 34 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; |
@@ -36,13 +38,13 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponse | @@ -36,13 +38,13 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponse | ||
36 | import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto; | 38 | import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto; |
37 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; | 39 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; |
38 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; | 40 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; |
39 | -import org.thingsboard.server.transport.snmp.SnmpAuthService; | ||
40 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; | 41 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; |
41 | -import org.thingsboard.server.transport.snmp.service.SnmpTransportService; | ||
42 | 42 | ||
43 | +import java.io.IOException; | ||
43 | import java.util.LinkedList; | 44 | import java.util.LinkedList; |
44 | import java.util.List; | 45 | import java.util.List; |
45 | import java.util.Map; | 46 | import java.util.Map; |
47 | +import java.util.Optional; | ||
46 | import java.util.UUID; | 48 | import java.util.UUID; |
47 | import java.util.concurrent.ScheduledFuture; | 49 | import java.util.concurrent.ScheduledFuture; |
48 | import java.util.concurrent.atomic.AtomicInteger; | 50 | import java.util.concurrent.atomic.AtomicInteger; |
@@ -64,16 +66,12 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | @@ -64,16 +66,12 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | ||
64 | 66 | ||
65 | private final SnmpTransportContext snmpTransportContext; | 67 | private final SnmpTransportContext snmpTransportContext; |
66 | 68 | ||
67 | - @Getter | ||
68 | - @Setter | ||
69 | - private long previousRequestExecutedAt = 0; | ||
70 | private final AtomicInteger msgIdSeq = new AtomicInteger(0); | 69 | private final AtomicInteger msgIdSeq = new AtomicInteger(0); |
71 | @Getter | 70 | @Getter |
72 | private boolean isActive = true; | 71 | private boolean isActive = true; |
73 | 72 | ||
74 | @Getter | 73 | @Getter |
75 | - @Setter | ||
76 | - private List<ScheduledFuture<?>> queryingTasks = new LinkedList<>(); | 74 | + private final List<ScheduledFuture<?>> queryingTasks = new LinkedList<>(); |
77 | 75 | ||
78 | public DeviceSessionContext(Device device, DeviceProfile deviceProfile, String token, | 76 | public DeviceSessionContext(Device device, DeviceProfile deviceProfile, String token, |
79 | SnmpDeviceProfileTransportConfiguration profileTransportConfiguration, | 77 | SnmpDeviceProfileTransportConfiguration profileTransportConfiguration, |
@@ -116,7 +114,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | @@ -116,7 +114,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | ||
116 | public void initializeTarget(SnmpDeviceProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) throws Exception { | 114 | public void initializeTarget(SnmpDeviceProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) throws Exception { |
117 | log.trace("Initializing target for SNMP session of device {}", device); | 115 | log.trace("Initializing target for SNMP session of device {}", device); |
118 | this.target = snmpTransportContext.getSnmpAuthService().setUpSnmpTarget(profileTransportConfig, deviceTransportConfig); | 116 | this.target = snmpTransportContext.getSnmpAuthService().setUpSnmpTarget(profileTransportConfig, deviceTransportConfig); |
119 | - log.info("SNMP target initialized: {}", target); | 117 | + log.debug("SNMP target initialized: {}", target); |
120 | } | 118 | } |
121 | 119 | ||
122 | public void close() { | 120 | public void close() { |
@@ -138,20 +136,14 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | @@ -138,20 +136,14 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | ||
138 | 136 | ||
139 | @Override | 137 | @Override |
140 | public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) { | 138 | public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) { |
141 | - profileTransportConfiguration.getCommunicationConfigs().stream() | ||
142 | - .filter(config -> config.getSpec() == SnmpCommunicationSpec.SHARED_ATTRIBUTES_SETTING) | ||
143 | - .findFirst() | 139 | + getCommunicationConfigForSpec(SnmpCommunicationSpec.SHARED_ATTRIBUTES_SETTING) |
144 | .ifPresent(communicationConfig -> { | 140 | .ifPresent(communicationConfig -> { |
145 | Map<String, String> sharedAttributes = JsonConverter.toJson(attributeUpdateNotification).entrySet().stream() | 141 | Map<String, String> sharedAttributes = JsonConverter.toJson(attributeUpdateNotification).entrySet().stream() |
146 | .collect(Collectors.toMap( | 142 | .collect(Collectors.toMap( |
147 | Map.Entry::getKey, | 143 | Map.Entry::getKey, |
148 | entry -> entry.getValue().isJsonPrimitive() ? entry.getValue().getAsString() : entry.getValue().toString() | 144 | entry -> entry.getValue().isJsonPrimitive() ? entry.getValue().getAsString() : entry.getValue().toString() |
149 | )); | 145 | )); |
150 | - try { | ||
151 | - snmpTransportContext.getSnmpTransportService().sendRequest(this, communicationConfig, sharedAttributes); | ||
152 | - } catch (Exception e) { | ||
153 | - log.error("Failed to send request with shared attributes to SNMP device {}: {}", getDeviceId(), e.getMessage()); | ||
154 | - } | 146 | + snmpTransportContext.getSnmpTransportService().sendRequest(this, communicationConfig, sharedAttributes); |
155 | }); | 147 | }); |
156 | } | 148 | } |
157 | 149 | ||
@@ -161,9 +153,23 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | @@ -161,9 +153,23 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S | ||
161 | 153 | ||
162 | @Override | 154 | @Override |
163 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { | 155 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
156 | + getCommunicationConfigForSpec(SnmpCommunicationSpec.TO_DEVICE_RPC_COMMAND_SETTING) | ||
157 | + .ifPresent(communicationConfig -> { | ||
158 | + String value = JsonConverter.toJson(toDeviceRequest, true).toString(); | ||
159 | + snmpTransportContext.getSnmpTransportService().sendRequest( | ||
160 | + this, communicationConfig, | ||
161 | + Map.of(ToDeviceRpcCommandSettingSnmpCommunicationConfig.RPC_COMMAND_KEY_NAME, value) | ||
162 | + ); | ||
163 | + }); | ||
164 | } | 164 | } |
165 | 165 | ||
166 | @Override | 166 | @Override |
167 | public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { | 167 | public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { |
168 | } | 168 | } |
169 | + | ||
170 | + private Optional<SnmpCommunicationConfig> getCommunicationConfigForSpec(SnmpCommunicationSpec spec) { | ||
171 | + return profileTransportConfiguration.getCommunicationConfigs().stream() | ||
172 | + .filter(config -> config.getSpec() == spec) | ||
173 | + .findFirst(); | ||
174 | + } | ||
169 | } | 175 | } |