| /* |
| * Copyright 2016-present Open Networking Foundation |
| * |
| * 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.onosproject.drivers.fujitsu; |
| |
| import com.google.common.collect.ImmutableList; |
| import org.apache.commons.configuration.HierarchicalConfiguration; |
| import org.onosproject.drivers.utilities.XmlConfigParser; |
| import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; |
| import org.onosproject.incubator.net.faultmanagement.alarm.AlarmConsumer; |
| import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; |
| import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; |
| import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.driver.AbstractHandlerBehaviour; |
| import org.onosproject.net.driver.DriverHandler; |
| import org.onosproject.netconf.NetconfController; |
| import org.onosproject.netconf.NetconfException; |
| import org.onosproject.mastership.MastershipService; |
| |
| import org.slf4j.Logger; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.text.SimpleDateFormat; |
| import java.text.ParseException; |
| import java.util.Date; |
| import java.util.TimeZone; |
| |
| import java.nio.charset.StandardCharsets; |
| import java.io.ByteArrayInputStream; |
| |
| import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static org.onosproject.drivers.fujitsu.FujitsuVoltXmlUtility.*; |
| import static org.slf4j.LoggerFactory.getLogger; |
| |
| /** |
| * Fujitsu vOLT specific implementation to provide a list of current alarms. |
| */ |
| public class FujitsuVoltAlarmConsumer extends AbstractHandlerBehaviour implements AlarmConsumer { |
| private final Logger log = getLogger(getClass()); |
| private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| |
| private static final TimeZone ZONE = TimeZone.getTimeZone("UTC"); |
| |
| private static final String VOLT_ALERTS = "volt-alerts"; |
| private static final String OLT_ACTIVE_ALERTS = "olt-active-alerts"; |
| private static final String ALERT_INFO = "alert-info"; |
| private static final String ALERT_SEQNUM = "alert-seqnum"; |
| private static final String ALERT_TYPE = "alert-type"; |
| private static final String ALERT_TIME = "alert-time"; |
| private static final String ALERT_CLEAR = "alert-clear"; |
| private static final String RESOURCE_ID = "resource-id"; |
| private static final String SEVERITY = "severity"; |
| private static final String IP_ADDRESS = "ip-address"; |
| private static final String DATE = "date"; |
| private static final String TIME = "time"; |
| private static final String OLT_ACTIVE_ALERTS_KEY = |
| "data." + VOLT_NE + ".volt-alerts.olt-active-alerts"; |
| private static final String SLASH = "/"; |
| private DeviceId ncDeviceId; |
| |
| private enum AlertResourceType { |
| UNKNOWN, |
| PONLINK, |
| ONU, |
| SYSTEM |
| } |
| |
| private enum AlertSeverity { |
| INFO("info", SeverityLevel.WARNING), |
| MINOR("minor", SeverityLevel.MINOR), |
| MAJOR("major", SeverityLevel.MAJOR), |
| CRITICAL("critical", SeverityLevel.CRITICAL); |
| |
| private String text; |
| private SeverityLevel level; |
| |
| AlertSeverity(String text, SeverityLevel level) { |
| this.text = text; |
| this.level = level; |
| } |
| |
| public static SeverityLevel convertToAlarmSeverityLevel(String text) { |
| for (AlertSeverity severity : AlertSeverity.values()) { |
| if (text.equalsIgnoreCase(severity.text)) { |
| return severity.level; |
| } |
| } |
| return SeverityLevel.INDETERMINATE; |
| } |
| } |
| |
| @Override |
| public List<Alarm> consumeAlarms() { |
| DriverHandler handler = handler(); |
| NetconfController controller = handler.get(NetconfController.class); |
| MastershipService mastershipService = handler.get(MastershipService.class); |
| ncDeviceId = handler.data().deviceId(); |
| checkNotNull(controller, "Netconf controller is null"); |
| |
| if (!mastershipService.isLocalMaster(ncDeviceId)) { |
| log.warn("Not master for {} Use {} to execute command", |
| ncDeviceId, |
| mastershipService.getMasterFor(ncDeviceId)); |
| return null; |
| } |
| |
| dateFormat.setTimeZone(ZONE); |
| List<Alarm> alarms = new ArrayList<>(); |
| try { |
| StringBuilder request = new StringBuilder(); |
| request.append(VOLT_NE_OPEN + VOLT_NE_NAMESPACE) |
| .append(ANGLE_RIGHT + NEW_LINE) |
| .append(buildStartTag(VOLT_ALERTS)) |
| .append(buildEmptyTag(OLT_ACTIVE_ALERTS)) |
| .append(buildEndTag(VOLT_ALERTS)) |
| .append(VOLT_NE_CLOSE); |
| |
| String reply = controller.getDevicesMap() |
| .get(ncDeviceId) |
| .getSession() |
| .get(request.toString(), null); |
| if (reply != null) { |
| alarms = parseVoltActiveAlerts(XmlConfigParser. |
| loadXml(new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8)))); |
| } |
| } catch (NetconfException e) { |
| log.error("Error reading alarms for device {} exception {}", ncDeviceId, e); |
| } |
| |
| return ImmutableList.copyOf(alarms); |
| } |
| |
| /** |
| * Parses XML string to get controller information. |
| * |
| * @param cfg a hierarchical configuration |
| * @return a list of alarms |
| */ |
| private List<Alarm> parseVoltActiveAlerts(HierarchicalConfiguration cfg) { |
| List<Alarm> alarms = new ArrayList<>(); |
| List<HierarchicalConfiguration> fields = |
| cfg.configurationsAt(OLT_ACTIVE_ALERTS_KEY); |
| |
| for (HierarchicalConfiguration sub : fields) { |
| List<HierarchicalConfiguration> childFields = |
| sub.configurationsAt(ALERT_INFO); |
| |
| for (HierarchicalConfiguration child : childFields) { |
| try { |
| int seqNum = Integer.parseInt(child.getString(ALERT_SEQNUM)); |
| boolean cleared = Boolean.parseBoolean(child.getString(ALERT_CLEAR)); |
| String alertType = child.getString(ALERT_TYPE); |
| String severity = child.getString(SEVERITY); |
| |
| List<HierarchicalConfiguration> idFields = |
| child.configurationsAt(RESOURCE_ID); |
| if (idFields.isEmpty()) { |
| log.error("{} does not exist: SQ={}, TYPE={}, SEV={}, CLEARED={}", |
| RESOURCE_ID, seqNum, alertType, severity, cleared); |
| continue; |
| } |
| String alarmSrc = formAlarmSource(idFields); |
| if (alarmSrc == null) { |
| log.error("Cannot build description: SQ={}, TYPE={}, SEV={}, CLEARED={}", |
| seqNum, alertType, severity, cleared); |
| continue; |
| } |
| long timeRaised = getTimeRaised(child); |
| log.debug("VOLT: ACTIVE ALERT: SQ={}, TYPE={}, SEV={}, CLEARED={}, TIME={}", |
| seqNum, alertType, severity, cleared, timeRaised); |
| |
| SeverityLevel alarmLevel = |
| AlertSeverity.convertToAlarmSeverityLevel(severity); |
| if (alarmLevel.equals(SeverityLevel.INDETERMINATE)) { |
| log.warn("Unknown severity: {}", severity); |
| } |
| DefaultAlarm.Builder alarmBuilder = new DefaultAlarm.Builder( |
| AlarmId.alarmId(ncDeviceId, Long.toString(timeRaised)), |
| ncDeviceId, alertType.toUpperCase(), alarmLevel, timeRaised) |
| .forSource(AlarmEntityId.alarmEntityId(alarmSrc)); |
| alarms.add(alarmBuilder.build()); |
| } catch (NumberFormatException e) { |
| log.error("Non-number exception {}", e); |
| } catch (Exception e) { |
| log.error("Exception {}", e); |
| } |
| } |
| } |
| return alarms; |
| } |
| |
| /** |
| * Builds alarm source with resource information. |
| * @param idFields a hierarchical configuration |
| * @return formed alarm description |
| */ |
| private String formAlarmSource(List<HierarchicalConfiguration> idFields) { |
| AlertResourceType resourceType = AlertResourceType.UNKNOWN; |
| StringBuilder alarmSrc = new StringBuilder(); |
| String ipAddr = null; |
| int pon = ZERO; |
| int onu = ZERO; |
| |
| for (HierarchicalConfiguration id : idFields) { |
| String value; |
| try { |
| value = id.getString(PONLINK_ID); |
| if (value == null) { |
| resourceType = AlertResourceType.SYSTEM; |
| ipAddr = id.getString(IP_ADDRESS); |
| } else { |
| pon = Integer.parseInt(value); |
| value = id.getString(ONU_ID); |
| if (value == null) { |
| resourceType = AlertResourceType.PONLINK; |
| } else { |
| resourceType = AlertResourceType.ONU; |
| onu = Integer.parseInt(value); |
| } |
| } |
| } catch (NumberFormatException e) { |
| log.error("Non-number resource-id exception {}", e); |
| return null; |
| } |
| } |
| |
| alarmSrc.append("other:"); |
| alarmSrc.append(resourceType.name()).append(SLASH); |
| switch (resourceType) { |
| case PONLINK: |
| alarmSrc.append(pon); |
| break; |
| case ONU: |
| alarmSrc.append(pon).append(HYPHEN).append(onu); |
| break; |
| case SYSTEM: |
| if (ipAddr != null) { |
| alarmSrc.append(ipAddr); |
| } |
| break; |
| default: |
| break; |
| } |
| return alarmSrc.toString(); |
| } |
| |
| /** |
| * Converts time and date information from device. |
| * @param cfg a hierarchical configuration |
| * @return converted time from device or system time |
| */ |
| private long getTimeRaised(HierarchicalConfiguration cfg) { |
| String strDate; |
| String strTime; |
| long timeRaised; |
| |
| List<HierarchicalConfiguration> timeFields = |
| cfg.configurationsAt(ALERT_TIME); |
| if (timeFields.isEmpty()) { |
| log.debug("{} does not exist", ALERT_TIME); |
| } else { |
| for (HierarchicalConfiguration child : timeFields) { |
| strDate = child.getString(DATE); |
| strTime = child.getString(TIME); |
| if ((strDate != null) && (strTime != null)) { |
| try { |
| Date date = dateFormat.parse(strDate + SPACE + strTime); |
| timeRaised = date.getTime(); |
| log.debug("{} {} converted to {}", strDate, strTime, timeRaised); |
| return timeRaised; |
| } catch (ParseException e) { |
| log.error("Cannot parse exception {} {} {}", strDate, strTime, e); |
| } |
| } else { |
| log.error("{} or {} does not exist", DATE, TIME); |
| } |
| } |
| } |
| // Use the system's time instead. |
| return System.currentTimeMillis(); |
| } |
| |
| } |