Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2016-present Open Networking Foundation |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 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.onosproject.snmp.ctl; |
| 17 | |
| 18 | import org.onosproject.net.DeviceId; |
| 19 | import org.onosproject.snmp.SnmpDevice; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 20 | import org.onosproject.snmp.SnmpDeviceConfig; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 21 | import org.slf4j.Logger; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 22 | import org.snmp4j.Snmp; |
| 23 | import org.snmp4j.TransportMapping; |
| 24 | import org.snmp4j.smi.GenericAddress; |
| 25 | import org.snmp4j.transport.DefaultTcpTransportMapping; |
| 26 | import org.snmp4j.transport.DefaultUdpTransportMapping; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 27 | |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 28 | import java.io.IOException; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 29 | import java.net.URI; |
| 30 | import java.net.URISyntaxException; |
| 31 | |
| 32 | import static com.google.common.base.Preconditions.checkNotNull; |
| 33 | import static org.slf4j.LoggerFactory.getLogger; |
| 34 | |
| 35 | /** |
| 36 | * This is a logical representation of actual SNMP device, carrying all the necessary information to connect and execute |
| 37 | * SNMP operations. |
| 38 | */ |
| 39 | public class DefaultSnmpDevice implements SnmpDevice { |
| 40 | |
| 41 | private final Logger log = getLogger(DefaultSnmpDevice.class); |
| 42 | |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 43 | private static final String SCHEME = "snmp"; |
| 44 | |
| 45 | private final String snmpHost; |
| 46 | private final DeviceId deviceId; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 47 | private final int snmpPort; |
| 48 | private final int notificationPort; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 49 | private final String username; |
| 50 | //Community is a conventional name for password in SNMP. |
| 51 | private final String community; |
| 52 | private boolean reachable = false; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 53 | private final String protocol; |
| 54 | private final String notificationProtocol; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 55 | |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 56 | private Snmp session; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 57 | |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 58 | public DefaultSnmpDevice(String snmpHost, int snmpPort, |
| 59 | String username, String community) { |
| 60 | this.protocol = GenericAddress.TYPE_UDP; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 61 | this.snmpHost = checkNotNull(snmpHost, "SNMP Device IP cannot be null"); |
Ray Milkey | 12ceb7a | 2018-06-05 12:45:04 -0700 | [diff] [blame] | 62 | this.snmpPort = snmpPort; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 63 | this.notificationProtocol = GenericAddress.TYPE_UDP; |
| 64 | this.notificationPort = 0; |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 65 | this.username = username; |
| 66 | this.community = community; |
| 67 | this.deviceId = createDeviceId(); |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 68 | initializeSession(); |
| 69 | } |
| 70 | |
| 71 | public DefaultSnmpDevice(SnmpDeviceConfig snmpDeviceConfig) { |
| 72 | checkNotNull(snmpDeviceConfig.ip(), "SNMP Device IP address cannot be null"); |
| 73 | this.protocol = snmpDeviceConfig.protocol(); |
| 74 | this.notificationProtocol = snmpDeviceConfig.notificationProtocol(); |
| 75 | this.snmpHost = checkNotNull(snmpDeviceConfig.ip().toString(), "SNMP Device IP cannot be null"); |
Ray Milkey | 12ceb7a | 2018-06-05 12:45:04 -0700 | [diff] [blame] | 76 | this.snmpPort = snmpDeviceConfig.port(); |
| 77 | this.notificationPort = snmpDeviceConfig.notificationPort(); |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 78 | this.username = snmpDeviceConfig.username(); |
| 79 | this.community = snmpDeviceConfig.password(); |
| 80 | this.deviceId = createDeviceId(); |
| 81 | initializeSession(); |
| 82 | } |
| 83 | |
| 84 | private void initializeSession() { |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 85 | reachable = true; |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 86 | try { |
| 87 | TransportMapping transport; |
Ray Milkey | 12ceb7a | 2018-06-05 12:45:04 -0700 | [diff] [blame] | 88 | if (protocol.equals(GenericAddress.TYPE_TCP)) { |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 89 | transport = new DefaultTcpTransportMapping(); |
| 90 | } else { |
| 91 | transport = new DefaultUdpTransportMapping(); |
| 92 | } |
| 93 | transport.listen(); |
| 94 | session = new Snmp(transport); |
| 95 | } catch (IOException e) { |
| 96 | log.error("Failed to connect to device: ", e); |
| 97 | } |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | @Override |
| 101 | public String deviceInfo() { |
| 102 | return new StringBuilder("host: ").append(snmpHost).append(". port: ") |
| 103 | .append(snmpPort).toString(); |
| 104 | } |
| 105 | |
| 106 | @Override |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 107 | public Snmp getSession() { |
| 108 | return session; |
| 109 | } |
| 110 | |
| 111 | @Override |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 112 | public void disconnect() { |
| 113 | log.info("disconnect"); |
| 114 | reachable = false; |
| 115 | } |
| 116 | |
| 117 | @Override |
| 118 | public boolean isReachable() { |
| 119 | return reachable; |
| 120 | } |
| 121 | |
| 122 | @Override |
| 123 | public String getSnmpHost() { |
| 124 | return snmpHost; |
| 125 | } |
| 126 | |
| 127 | |
| 128 | @Override |
| 129 | public int getSnmpPort() { |
| 130 | return snmpPort; |
| 131 | } |
| 132 | |
| 133 | @Override |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 134 | public int getNotificationPort() { |
| 135 | return notificationPort; |
| 136 | } |
| 137 | |
| 138 | @Override |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 139 | public String getUsername() { |
| 140 | return username; |
| 141 | } |
| 142 | |
| 143 | @Override |
| 144 | public String getCommunity() { |
| 145 | return community; |
| 146 | } |
| 147 | |
| 148 | @Override |
| 149 | public DeviceId deviceId() { |
| 150 | return deviceId; |
| 151 | } |
| 152 | |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 153 | @Override |
| 154 | public String getProtocol() { |
| 155 | return protocol; |
| 156 | } |
| 157 | |
| 158 | @Override |
| 159 | public String getNotificationProtocol() { |
| 160 | return notificationProtocol; |
| 161 | } |
| 162 | |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 163 | private DeviceId createDeviceId() { |
| 164 | String additionalSsp = new StringBuilder( |
| 165 | snmpHost).append(":") |
| 166 | .append(snmpPort).toString(); |
| 167 | try { |
| 168 | return DeviceId.deviceId(new URI(SCHEME, additionalSsp, |
| 169 | null)); |
| 170 | } catch (URISyntaxException e) { |
| 171 | log.error("Syntax Error while creating URI for the device: " |
| 172 | + additionalSsp |
| 173 | + " couldn't persist the device onto the store", e); |
| 174 | throw new IllegalArgumentException("Can't create device ID from " + additionalSsp, e); |
| 175 | } |
| 176 | } |
Laszlo Papp | 9655b18 | 2017-01-31 13:01:45 -0800 | [diff] [blame] | 177 | |
Andrea Campanella | c2d754b | 2016-03-29 17:51:07 -0700 | [diff] [blame] | 178 | } |