blob: 203bd597a978908e3983f13fdcd2606d11b01cd3 [file] [log] [blame]
kmcpeakeb172d5f2015-12-10 11:30:43 +00001/*
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07002 * Copyright 2015-present Open Networking Laboratory
kmcpeakeb172d5f2015-12-10 11:30:43 +00003 *
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 *
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07008 * http://www.apache.org/licenses/LICENSE-2.0
kmcpeakeb172d5f2015-12-10 11:30:43 +00009 *
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 */
Andrea Campanellae72ac552016-04-11 10:04:52 -070016
17package org.onosproject.drivers.bti;
kmcpeakeb172d5f2015-12-10 11:30:43 +000018
19import com.btisystems.mibbler.mibs.bti7000.bti7000_13_2_0.I_Device;
20import com.btisystems.mibbler.mibs.bti7000.bti7000_13_2_0._OidRegistry;
21import com.btisystems.mibbler.mibs.bti7000.bti7000_13_2_0.btisystems.btiproducts.bti7000.objects.conditions.ActAlarmTable;
22import com.btisystems.mibbler.mibs.bti7000.interfaces.btisystems.btiproducts.bti7000.objects.conditions.IActAlarmTable;
23import com.btisystems.pronx.ems.core.model.ClassRegistry;
24import com.btisystems.pronx.ems.core.model.IClassRegistry;
25import com.btisystems.pronx.ems.core.model.NetworkDevice;
26import com.btisystems.pronx.ems.core.snmp.ISnmpSession;
Andrea Campanellae72ac552016-04-11 10:04:52 -070027import com.google.common.collect.ImmutableList;
kmcpeakeb172d5f2015-12-10 11:30:43 +000028import org.apache.commons.lang.StringUtils;
29import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
Andrea Campanellae72ac552016-04-11 10:04:52 -070030import org.onosproject.incubator.net.faultmanagement.alarm.AlarmConsumer;
kmcpeakeb172d5f2015-12-10 11:30:43 +000031import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
32import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
33import org.onosproject.net.DeviceId;
Andrea Campanellae72ac552016-04-11 10:04:52 -070034import org.onosproject.net.driver.AbstractHandlerBehaviour;
35import org.onosproject.snmp.SnmpController;
kmcpeakeb172d5f2015-12-10 11:30:43 +000036import org.slf4j.Logger;
kmcpeakeb172d5f2015-12-10 11:30:43 +000037import org.snmp4j.smi.OctetString;
38
Andrea Campanellae72ac552016-04-11 10:04:52 -070039import java.io.IOException;
40import java.util.ArrayList;
41import java.util.Calendar;
42import java.util.Collections;
43import java.util.Date;
44import java.util.GregorianCalendar;
45import java.util.List;
46import java.util.TimeZone;
47
48import static com.google.common.base.Preconditions.checkNotNull;
49import static org.slf4j.LoggerFactory.getLogger;
50
kmcpeakeb172d5f2015-12-10 11:30:43 +000051/**
52 * BTI 7000 specific implementation to provide a list of current alarms.
53 */
Andrea Campanellae72ac552016-04-11 10:04:52 -070054public class Bti7000SnmpAlarmConsumer extends AbstractHandlerBehaviour implements AlarmConsumer {
kmcpeakeb172d5f2015-12-10 11:30:43 +000055 private final Logger log = getLogger(getClass());
56 protected static final IClassRegistry CLASS_REGISTRY = new ClassRegistry(_OidRegistry.oidRegistry, I_Device.class);
57
58 static final int ALARM_SEVERITY_MINOR = 2;
59 static final int ALARM_SEVERITY_MAJOR = 3;
60 static final int ALARM_SEVERITY_CRITICAL = 4;
61
kmcpeakeb172d5f2015-12-10 11:30:43 +000062
63 private Alarm.SeverityLevel mapAlarmSeverity(int intAlarmSeverity) {
64 Alarm.SeverityLevel mappedSeverity;
65 switch (intAlarmSeverity) {
66 case ALARM_SEVERITY_MINOR:
67 mappedSeverity = Alarm.SeverityLevel.MINOR;
68 break;
69 case ALARM_SEVERITY_MAJOR:
70 mappedSeverity = Alarm.SeverityLevel.MAJOR;
71 break;
72 case ALARM_SEVERITY_CRITICAL:
73 mappedSeverity = Alarm.SeverityLevel.CRITICAL;
74 break;
75 default:
76 mappedSeverity = Alarm.SeverityLevel.MINOR;
77 log.warn("Unexpected alarm severity: {}", intAlarmSeverity);
78 }
79 return mappedSeverity;
80 }
Andrea Campanellae72ac552016-04-11 10:04:52 -070081
kmcpeakeb172d5f2015-12-10 11:30:43 +000082 /**
83 * Converts an SNMP string representation into a {@link Date} object,
84 * and applies time zone conversion to provide the time on the local machine, ie PSM server.
85 *
86 * @param actAlarmDateAndTime MIB-II DateAndTime formatted. May optionally contain
Andrea Campanellae72ac552016-04-11 10:04:52 -070087 * a timezone offset in 3 extra bytes
88 * @param sysInfoTimeZone Must be supplied if actAlarmDateAndTime is just local time (with no timezone)
89 * @param swVersion Must be supplied if actAlarmDateAndTime is just local time (with no timezone)
kmcpeakeb172d5f2015-12-10 11:30:43 +000090 * @return adjusted {@link Date} or a simple conversion if other fields are null.
91 */
92 public static Date getLocalDateAndTime(String actAlarmDateAndTime, String sysInfoTimeZone,
Andrea Campanellae72ac552016-04-11 10:04:52 -070093 String swVersion) {
kmcpeakeb172d5f2015-12-10 11:30:43 +000094 if (StringUtils.isBlank(actAlarmDateAndTime)) {
95 return null;
96 }
97
98 GregorianCalendar decodedDateAndTimeCal = btiMakeCalendar(OctetString.fromHexString(actAlarmDateAndTime));
99 if ((sysInfoTimeZone == null) || (swVersion == null)) {
100 return decodedDateAndTimeCal.getTime();
101 }
102
103 TimeZone javaTimeZone = getTimeZone();
104 decodedDateAndTimeCal.setTimeZone(javaTimeZone);
105
106 GregorianCalendar localTime = new GregorianCalendar();
107 localTime.setTimeInMillis(decodedDateAndTimeCal.getTimeInMillis());
108
109 return localTime.getTime();
110 }
111
112 /**
113 * This method is similar to SNMP4J approach with some fixes for the 11-bytes version (ie the one with timezone
114 * offset).
Andrea Campanellae72ac552016-04-11 10:04:52 -0700115 * <p>
kmcpeakeb172d5f2015-12-10 11:30:43 +0000116 * For original makeCalendar refer @see http://www.snmp4j.org/agent/doc/org/snmp4j/agent/mo/snmp/DateAndTime.html
Andrea Campanellae72ac552016-04-11 10:04:52 -0700117 * <p>
kmcpeakeb172d5f2015-12-10 11:30:43 +0000118 * Creates a <code>GregorianCalendar</code> from a properly formatted SNMP4J DateAndTime <code>OctetString</code>.
119 *
120 * @param dateAndTimeValue an OctetString conforming to the DateAndTime TC.
121 * @return the corresponding <code>GregorianCalendar</code> instance.
kmcpeakeb172d5f2015-12-10 11:30:43 +0000122 */
123 public static GregorianCalendar btiMakeCalendar(OctetString dateAndTimeValue) {
124 int year = (dateAndTimeValue.get(0) & 0xFF) * 256
125 + (dateAndTimeValue.get(1) & 0xFF);
126 int month = (dateAndTimeValue.get(2) & 0xFF);
127 int date = (dateAndTimeValue.get(3) & 0xFF);
128 int hour = (dateAndTimeValue.get(4) & 0xFF);
129 int minute = (dateAndTimeValue.get(5) & 0xFF);
130 int second = (dateAndTimeValue.get(6) & 0xFF);
131 int deci = (dateAndTimeValue.get(7) & 0xFF);
132 GregorianCalendar gc =
133 new GregorianCalendar(year, month - 1, date, hour, minute, second);
134 gc.set(Calendar.MILLISECOND, deci * 100);
135
136 if (dateAndTimeValue.length() == 11) {
137 char directionOfOffset = (char) dateAndTimeValue.get(8);
138 int hoursOffset = directionOfOffset == '+'
139 ? dateAndTimeValue.get(9) : -dateAndTimeValue.get(9);
140 org.joda.time.DateTimeZone offset =
141 org.joda.time.DateTimeZone.forOffsetHoursMinutes(hoursOffset, dateAndTimeValue.get(10));
142 org.joda.time.DateTime dt =
143 new org.joda.time.DateTime(year, month, date, hour, minute, second, offset);
144 return dt.toGregorianCalendar();
145 }
146 return gc;
147 }
148
149 private static TimeZone getTimeZone() {
150 return Calendar.getInstance().getTimeZone();
151 }
Andrea Campanellae72ac552016-04-11 10:04:52 -0700152
153 @Override
154 public List<Alarm> consumeAlarms() {
155 SnmpController controller = checkNotNull(handler().get(SnmpController.class));
156 ISnmpSession session;
157 List<Alarm> alarms = new ArrayList<>();
158 DeviceId deviceId = handler().data().deviceId();
159 try {
160 session = controller.getSession(deviceId);
161 log.debug("Getting alarms for BTI 7000 device at {}", deviceId);
162 NetworkDevice networkDevice = new NetworkDevice(CLASS_REGISTRY,
163 session.getAddress().getHostAddress());
164 session.walkDevice(networkDevice, Collections.singletonList(
165 CLASS_REGISTRY.getClassToOidMap().get(ActAlarmTable.class)));
166
167 IActAlarmTable deviceAlarms = (IActAlarmTable) networkDevice.getRootObject()
168 .getEntity(CLASS_REGISTRY.getClassToOidMap().get(ActAlarmTable.class));
169 if ((deviceAlarms != null) && (deviceAlarms.getActAlarmEntry() != null)
170 && (!deviceAlarms.getActAlarmEntry().isEmpty())) {
171
Sho SHIMIZUa09e1bb2016-08-01 14:25:25 -0700172 deviceAlarms.getActAlarmEntry().values().forEach((alarm) -> {
Andrea Campanellae72ac552016-04-11 10:04:52 -0700173 DefaultAlarm.Builder alarmBuilder = new DefaultAlarm.Builder(
174 deviceId, alarm.getActAlarmDescription(),
175 mapAlarmSeverity(alarm.getActAlarmSeverity()),
176 getLocalDateAndTime(alarm.getActAlarmDateAndTime(), null, null).getTime())
177 .forSource(AlarmEntityId.alarmEntityId("other:" + alarm.getActAlarmInstanceIdx()));
178 alarms.add(alarmBuilder.build());
179 });
180
181 }
182 log.debug("Conditions retrieved: {}", deviceAlarms);
183
184 } catch (IOException ex) {
185 log.error("Error reading alarms for device {}.", deviceId, ex);
186 alarms.add(controller.buildWalkFailedAlarm(deviceId));
187
188 }
189
190 return ImmutableList.copyOf(alarms);
191 }
kmcpeakeb172d5f2015-12-10 11:30:43 +0000192}