Vxlan/Gre co-existence,Alarms,tunnelstate,TR fixes
[vpnservice.git] / itm / itm-impl / src / main / java / org / opendaylight / vpnservice / itm / monitoring / ItmTunnelEventListener.java
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/monitoring/ItmTunnelEventListener.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/monitoring/ItmTunnelEventListener.java
new file mode 100644 (file)
index 0000000..7ff0f0d
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.monitoring;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+/**
+ * Created by emnqrrw on 11/2/2015.
+ */
+public class ItmTunnelEventListener extends AbstractDataChangeListener<Interface> implements AutoCloseable {
+
+    private static final Logger logger = LoggerFactory.getLogger(ItmTunnelEventListener.class);
+    private final DataBroker broker;
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    public static final JMXAlarmAgent alarmAgent = new JMXAlarmAgent();
+
+    public ItmTunnelEventListener(final DataBroker db){
+        super(Interface.class);
+        broker = db;
+        registerListener(db);
+        alarmAgent.registerMbean();
+    }
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                            getWildCardPath(), ItmTunnelEventListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            logger.error("ITM Monitor Interfaces DataChange listener registration fail!", e);
+            throw new IllegalStateException("ITM Monitor registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<Interface> getWildCardPath() {
+        return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Interface> identifier, Interface del) {
+        String ifName = del.getName() ;
+        if( del.getType() != null && del.getType().equals(Tunnel.class)) {
+            InternalTunnel internalTunnel = ItmUtils.getInternalTunnel(ifName,broker);
+            if( internalTunnel != null) {
+                BigInteger srcDpId = internalTunnel.getSourceDPN();
+                BigInteger dstDpId = internalTunnel.getDestinationDPN();
+                String tunnelType = ItmUtils.convertTunnelTypetoString(internalTunnel.getTransportType());
+                logger.trace("ITM Tunnel removed b/w srcDpn: {} and dstDpn: {} for tunnelType: {}", srcDpId, dstDpId, tunnelType);
+                clearInternalDataPathAlarm(srcDpId.toString(),dstDpId.toString(),tunnelType);
+            }else {
+                ExternalTunnel externalTunnel = ItmUtils.getExternalTunnel(ifName,broker);
+                if( externalTunnel != null) {
+                    String srcNode = externalTunnel.getSourceDevice();
+                    String dstNode = externalTunnel.getDestinationDevice();
+                    String tunnelType = ItmUtils.convertTunnelTypetoString(externalTunnel.getTransportType());
+                    logger.trace("ITM Tunnel removed b/w srcNode: {} and dstNode: {} for tunnelType: {}", srcNode, dstNode, tunnelType);
+                    clearExternalDataPathAlarm(srcNode,dstNode,tunnelType);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
+        String ifName = update.getName() ;
+        if( update.getType() != null && update.getType().equals(Tunnel.class)) {
+            InternalTunnel internalTunnel = ItmUtils.getInternalTunnel(ifName,broker);
+            if( internalTunnel != null) {
+                BigInteger srcDpId = internalTunnel.getSourceDPN();
+                BigInteger dstDpId = internalTunnel.getDestinationDPN();
+                String tunnelType = ItmUtils.convertTunnelTypetoString(internalTunnel.getTransportType());
+                logger.trace("ITM Tunnel state event changed from :{} to :{} for Tunnel Interface - {}", isTunnelInterfaceUp(original), isTunnelInterfaceUp(update), ifName);
+                if(isTunnelInterfaceUp(update)) {
+                    logger.trace("ITM Tunnel State is UP b/w srcDpn: {} and dstDpn: {} for tunnelType {} ", srcDpId, dstDpId, tunnelType);
+                    clearInternalDataPathAlarm(srcDpId.toString(),dstDpId.toString(),tunnelType);
+                }else {
+                    logger.trace("ITM Tunnel State is DOWN b/w srcDpn: {} and dstDpn: {}", srcDpId, dstDpId);
+                    StringBuilder alarmText = new StringBuilder();
+                    alarmText.append("Data Path Connectivity is lost between ").append("openflow:").append(srcDpId).append(" and openflow:")
+                                    .append(dstDpId).append(" for tunnelType:").append(tunnelType);
+                    raiseInternalDataPathAlarm(srcDpId.toString(), dstDpId.toString(), tunnelType,alarmText.toString());
+                }
+            }else{
+                ExternalTunnel externalTunnel = ItmUtils.getExternalTunnel(ifName,broker);
+                if( externalTunnel != null) {
+                    String srcNode = externalTunnel.getSourceDevice();
+                    String dstNode = externalTunnel.getDestinationDevice();
+                    String tunnelType = ItmUtils.convertTunnelTypetoString(externalTunnel.getTransportType());
+                    logger.trace("ITM Tunnel state event changed from :{} to :{} for Tunnel Interface - {}", isTunnelInterfaceUp(original), isTunnelInterfaceUp(update), ifName);
+                    if(isTunnelInterfaceUp(update)) {
+                        logger.trace("ITM Tunnel State is UP b/w srcNode: {} and dstNode: {} for tunnelType: {}", srcNode, dstNode, tunnelType);
+                        clearExternalDataPathAlarm(srcNode.toString(),dstNode.toString(),tunnelType);
+                    }else {
+                        logger.trace("ITM Tunnel State is DOWN b/w srcNode: {} and dstNode: {}", srcNode, dstNode);
+                        StringBuilder alarmText = new StringBuilder();
+                        alarmText.append("Data Path Connectivity is lost between ").append(srcNode).append(dstNode).append(" for tunnelType:").append(tunnelType);
+                        raiseExternalDataPathAlarm(srcNode, dstNode, tunnelType,alarmText.toString());
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Interface> identifier, Interface add) {
+        String ifName = add.getName() ;
+        if( add.getType() != null && add.getType().equals(Tunnel.class)) {
+            InternalTunnel internalTunnel = ItmUtils.getInternalTunnel(ifName,broker);
+            if( internalTunnel != null) {
+                BigInteger srcDpId = internalTunnel.getSourceDPN();
+                BigInteger dstDpId = internalTunnel.getDestinationDPN();
+                String tunnelType = ItmUtils.convertTunnelTypetoString(internalTunnel.getTransportType());
+                if(!isTunnelInterfaceUp(add)) {
+                    logger.trace("ITM Tunnel State during tep add is DOWN b/w srcDpn: {} and dstDpn: {} for tunnelType: {}", srcDpId, dstDpId, tunnelType);
+                    StringBuilder alarmText = new StringBuilder();
+                    alarmText.append("Data Path Connection is down between ").append("openflow:").append(srcDpId).append(" and openflow:")
+                                    .append(dstDpId).append(" for tunnelType:").append(tunnelType).append(" during initial state");
+                    raiseInternalDataPathAlarm(srcDpId.toString(), dstDpId.toString(), tunnelType, alarmText.toString());
+                }
+            }else {
+                ExternalTunnel externalTunnel = ItmUtils.getExternalTunnel(ifName,broker);
+                if( externalTunnel != null) {
+                    String srcNode = externalTunnel.getSourceDevice();
+                    String dstNode = externalTunnel.getDestinationDevice();
+                    String tunnelType = ItmUtils.convertTunnelTypetoString(externalTunnel.getTransportType());
+                    if(!isTunnelInterfaceUp(add)) {
+                        logger.trace("ITM Tunnel State during tep add is DOWN b/w srcNode: {} and dstNode: {} for tunnelType: {}", srcNode, dstNode, tunnelType);
+                        StringBuilder alarmText = new StringBuilder();
+                        alarmText.append("Data Path Connection is down between ").append(srcNode).append(dstNode).append(" for tunnelType:").append(tunnelType).append(" during initial state");
+                        raiseExternalDataPathAlarm(srcNode, dstNode, tunnelType,alarmText.toString());
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                logger.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    public void raiseInternalDataPathAlarm(String srcDpnId,String dstDpnId,String tunnelType,String alarmText) {
+
+        StringBuilder source = new StringBuilder();
+        source.append("srcDpn=openflow:").append(srcDpnId).append("-dstDpn=openflow:").append(dstDpnId).append("-tunnelType").append(tunnelType);
+
+        logger.trace("Raising DataPathConnectionFailure alarm... alarmText {} source {} ", alarmText, source);
+        //Invokes JMX raiseAlarm method
+        alarmAgent.invokeFMraisemethod("DataPathConnectionFailure", alarmText, source.toString());
+    }
+
+    public void clearInternalDataPathAlarm(String srcDpnId,String dstDpnId,String tunnelType) {
+        StringBuilder source = new StringBuilder();
+
+        source.append("srcDpn=openflow:").append(srcDpnId).append("-dstDpn=openflow:").append(dstDpnId).append("-tunnelType").append(tunnelType);
+        logger.trace("Clearing DataPathConnectionFailure alarm of source {} ", source);
+        //Invokes JMX clearAlarm method
+        alarmAgent.invokeFMclearmethod("DataPathConnectionFailure", "Clearing ITM Tunnel down alarm", source.toString());
+    }
+
+    public void raiseExternalDataPathAlarm(String srcDevice,String dstDevice,String tunnelType, String alarmText) {
+
+        StringBuilder source = new StringBuilder();
+        source.append("srcDevice=").append(srcDevice).append("-dstDevice=").append(dstDevice).append("-tunnelType").append(tunnelType);
+
+        logger.trace("Raising DataPathConnectionFailure alarm... alarmText {} source {} ", alarmText, source);
+        //Invokes JMX raiseAlarm method
+        alarmAgent.invokeFMraisemethod("DataPathConnectionFailure", alarmText, source.toString());
+    }
+
+
+    public void clearExternalDataPathAlarm(String srcDevice,String dstDevice,String tunnelType) {
+
+        StringBuilder source = new StringBuilder();
+
+        source.append("srcDevice=").append(srcDevice).append("-dstDevice=").append(dstDevice).append("-tunnelType").append(tunnelType);
+
+        //logger.trace("Clearing DataPathConnectionFailure alarm of source {} ", source);
+        //Invokes JMX clearAlarm method
+        alarmAgent.invokeFMclearmethod("DataPathConnectionFailure", "Clearing ITM Tunnel down alarm", source.toString());
+
+    }
+
+    private boolean isTunnelInterfaceUp( Interface intf) {
+        boolean interfaceUp = (intf.getOperStatus().equals(Interface.OperStatus.Up)) ? true :false ;
+        return interfaceUp ;
+    }
+
+}