Handle nullable lists
[genius.git] / alivenessmonitor / alivenessmonitor-impl / src / main / java / org / opendaylight / genius / alivenessmonitor / internal / HwVtepTunnelsStateHandler.java
index 5c56f2ded04b60673fac4e54d3aae5f881932b2d..93c33218daf9b511cde46ea6d990927bb4a7b41c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2016, 2018 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,
@@ -7,27 +7,32 @@
  */
 package org.opendaylight.genius.alivenessmonitor.internal;
 
-import static org.opendaylight.genius.alivenessmonitor.internal.AlivenessMonitorUtil.getMonitorStateId;
+import static org.opendaylight.genius.alivenessmonitor.utils.AlivenessMonitorUtil.getMonitorStateId;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.Semaphore;
-import javax.annotation.PostConstruct;
+import javax.annotation.Nonnull;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.controller.liblldp.Packet;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.hwvtep.HwvtepAbstractDataTreeChangeListener;
+import org.opendaylight.genius.alivenessmonitor.protocols.AlivenessProtocolHandler;
+import org.opendaylight.genius.alivenessmonitor.protocols.AlivenessProtocolHandlerRegistry;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.EtherTypes;
+import org.opendaylight.openflowplugin.libraries.liblldp.Packet;
+import org.opendaylight.serviceutils.tools.mdsal.listener.AbstractSyncDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.LivenessState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProtocolType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.EndpointType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.configs.MonitoringInfo;
@@ -35,7 +40,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsBuilder;
@@ -62,45 +66,33 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListener<Tunnels, HwVtepTunnelsStateHandler>
-        implements AlivenessProtocolHandler, AutoCloseable {
+public class HwVtepTunnelsStateHandler extends AbstractSyncDataTreeChangeListener<Tunnels>
+        implements AlivenessProtocolHandler<Packet> {
 
     private static final Logger LOG = LoggerFactory.getLogger(HwVtepTunnelsStateHandler.class);
+
     private final DataBroker dataBroker;
     private final AlivenessMonitor alivenessMonitor;
 
     @Inject
-    public HwVtepTunnelsStateHandler(final DataBroker dataBroker, final AlivenessMonitor alivenessMonitor) {
-        super(Tunnels.class, HwVtepTunnelsStateHandler.class);
+    public HwVtepTunnelsStateHandler(final DataBroker dataBroker, final AlivenessMonitor alivenessMonitor,
+                                     final AlivenessProtocolHandlerRegistry alivenessProtocolHandlerRegistry) {
+        super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+              InstanceIdentifier.create(NetworkTopology.class).child(Topology.class).child(Node.class)
+                      .augmentation(PhysicalSwitchAugmentation.class).child(Tunnels.class));
         this.dataBroker = dataBroker;
         this.alivenessMonitor = alivenessMonitor;
-    }
-
-    @PostConstruct
-    public void start() {
-        LOG.info("{} start", getClass().getSimpleName());
-        alivenessMonitor.registerHandler(EtherTypes.Bfd, this);
-        registerListener(LogicalDatastoreType.CONFIGURATION, this.dataBroker);
-    }
-
-    @Override
-    protected InstanceIdentifier<Tunnels> getWildCardPath() {
-        return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class).child(Node.class)
-                .augmentation(PhysicalSwitchAugmentation.class).child(Tunnels.class);
+        alivenessProtocolHandlerRegistry.register(MonitorProtocolType.Bfd, this);
     }
 
     @Override
-    protected HwVtepTunnelsStateHandler getDataTreeChangeListener() {
-        return HwVtepTunnelsStateHandler.this;
+    public void remove(@Nonnull InstanceIdentifier<Tunnels> instanceIdentifier, @Nonnull Tunnels tunnelInfo) {
+        // Do nothing
     }
 
     @Override
-    protected void removed(InstanceIdentifier<Tunnels> identifier, Tunnels del) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    protected void updated(InstanceIdentifier<Tunnels> identifier, Tunnels oldTunnelInfo, Tunnels updatedTunnelInfo) {
+    public void update(@Nonnull InstanceIdentifier<Tunnels> instanceIdentifier, @Nonnull Tunnels oldTunnelInfo,
+                       @Nonnull Tunnels updatedTunnelInfo) {
         List<BfdStatus> oldBfdStatus = oldTunnelInfo.getBfdStatus();
         List<BfdStatus> newBfdStatus = updatedTunnelInfo.getBfdStatus();
         LivenessState oldTunnelOpState = getTunnelOpState(oldBfdStatus);
@@ -112,11 +104,11 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         updatedTunnelInfo.getTunnelUuid();
         String interfaceName = "<TODO>";
         // TODO: find out the corresponding interface using tunnelIdentifier or
-        // any attributes of tunneInfo object
+        // any attributes of tunnelInfo object
         final String monitorKey = getBfdMonitorKey(interfaceName);
         LOG.debug("Processing monitorKey: {} for received Tunnels update DCN", monitorKey);
 
-        final Semaphore lock = alivenessMonitor.lockMap.get(monitorKey);
+        final Semaphore lock = alivenessMonitor.getLock(monitorKey);
         LOG.debug("Acquiring lock for monitor key : {} to process monitor DCN", monitorKey);
         alivenessMonitor.acquireLock(lock);
 
@@ -127,7 +119,7 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         Futures.addCallback(stateResult, new FutureCallback<Optional<MonitoringState>>() {
 
             @Override
-            public void onSuccess(Optional<MonitoringState> optState) {
+            public void onSuccess(@Nonnull Optional<MonitoringState> optState) {
                 if (optState.isPresent()) {
                     final MonitoringState currentState = optState.get();
                     if (currentState.getState() == newTunnelOpState) {
@@ -157,14 +149,14 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
                         }
 
                         @Override
-                        public void onFailure(Throwable error) {
+                        public void onFailure(@Nonnull Throwable error) {
                             alivenessMonitor.releaseLock(lock);
                             LOG.warn("Error in writing monitoring state : {} to Datastore", monitorKey, error);
                             if (LOG.isTraceEnabled()) {
                                 LOG.trace("Error in writing monitoring state: {} to Datastore", state);
                             }
                         }
-                    });
+                    }, MoreExecutors.directExecutor());
                 } else {
                     LOG.warn("Monitoring State not available for key: {} to process the Packet received", monitorKey);
                     // Complete the transaction
@@ -174,14 +166,14 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
             }
 
             @Override
-            public void onFailure(Throwable error) {
+            public void onFailure(@Nonnull Throwable error) {
                 LOG.error("Error when reading Monitoring State for key: {} to process the Packet received", monitorKey,
                         error);
                 // FIXME: Not sure if the transaction status is valid to cancel
                 tx.cancel();
                 alivenessMonitor.releaseLock(lock);
             }
-        });
+        }, MoreExecutors.directExecutor());
     }
 
     private LivenessState getTunnelOpState(List<BfdStatus> tunnelBfdStatus) {
@@ -190,9 +182,9 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
             return livenessState;
         }
         for (BfdStatus bfdState : tunnelBfdStatus) {
-            if (bfdState.getBfdStatusKey().equalsIgnoreCase(AlivenessMonitorConstants.BFD_OP_STATE)) {
+            if (AlivenessMonitorConstants.BFD_OP_STATE.equalsIgnoreCase(bfdState.getBfdStatusKey())) {
                 String bfdOpState = bfdState.getBfdStatusValue();
-                if (bfdOpState.equalsIgnoreCase(AlivenessMonitorConstants.BFD_STATE_UP)) {
+                if (AlivenessMonitorConstants.BFD_STATE_UP.equalsIgnoreCase(bfdOpState)) {
                     livenessState = LivenessState.Up;
                 } else {
                     livenessState = LivenessState.Down;
@@ -204,14 +196,14 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
     }
 
     @Override
-    protected void added(InstanceIdentifier<Tunnels> identifier, Tunnels add) {
+    public void add(@Nonnull InstanceIdentifier<Tunnels> instanceIdentifier, @Nonnull Tunnels tunnelInfo) {
         // TODO: need to add the code to enable BFD if tunnels are created
         // dynamically by TOR switch
     }
 
     @Override
-    public Class<?> getPacketClass() {
-        return null;
+    public Class<Packet> getPacketClass() {
+        return Packet.class;
     }
 
     @Override
@@ -219,34 +211,42 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         return null;
     }
 
-    void resetMonitoringTask(MonitoringInfo monitorInfo, boolean isEnable) {
+    // tunnelKey, nodeId, topologyId are initialized to null and immediately passed to getTunnelIdentifier which
+    // FindBugs as a "Load of known null value" violation. Not sure sure what the intent...
+    @SuppressFBWarnings("NP_LOAD_OF_KNOWN_NULL_VALUE")
+    void resetMonitoringTask(boolean isEnable) {
         // TODO: get the corresponding hwvtep tunnel from the sourceInterface
-        // once InterfaceMgr
-        // implments renderer for hwvtep vxlan tunnels
+        // once InterfaceMgr implements renderer for HWVTEP VXLAN tunnels
+
+        // tunnelKey, nodeId, topologyId are initialized to null and immediately passed to getTunnelIdentifier which
+        // FindBugs flags as a "Load of known null value" violation. Not sure sure what the intent...
         TunnelsKey tunnelKey = null;
         String nodeId = null;
         String topologyId = null;
-        Optional<Tunnels> tunnelsOptional = alivenessMonitor.read(LogicalDatastoreType.CONFIGURATION,
-                getTunnelIdentifier(topologyId, nodeId, tunnelKey));
+        Optional<Tunnels> tunnelsOptional =
+                SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
+                        LogicalDatastoreType.CONFIGURATION, getTunnelIdentifier(topologyId, nodeId, tunnelKey));
         if (!tunnelsOptional.isPresent()) {
-            LOG.warn("Tunnel {} is not present on the Node {}. So not disabling the BFD monitoing", tunnelKey, nodeId);
+            LOG.warn("Tunnel {} is not present on the Node {}. So not disabling the BFD monitoring", tunnelKey, nodeId);
             return;
         }
         Tunnels tunnel = tunnelsOptional.get();
         List<BfdParams> tunnelBfdParams = tunnel.getBfdParams();
         if (tunnelBfdParams == null || tunnelBfdParams.isEmpty()) {
             LOG.debug("there is no bfd params available for the tunnel {}", tunnel);
+            return;
         }
-        Iterator<BfdParams> tunnelBfdParamsInterator = tunnelBfdParams.iterator();
-        while (tunnelBfdParamsInterator.hasNext()) {
-            BfdParams bfdParam = tunnelBfdParamsInterator.next();
-            if (bfdParam.getBfdParamKey().equals(AlivenessMonitorConstants.BFD_PARAM_ENABLE)) {
-                tunnelBfdParamsInterator.remove();
+
+        Iterator<BfdParams> tunnelBfdParamsIterator = tunnelBfdParams.iterator();
+        while (tunnelBfdParamsIterator.hasNext()) {
+            BfdParams bfdParam = tunnelBfdParamsIterator.next();
+            if (AlivenessMonitorConstants.BFD_PARAM_ENABLE.equals(bfdParam.getBfdParamKey())) {
+                tunnelBfdParamsIterator.remove();
                 break;
             }
         }
         setBfdParamForEnable(tunnelBfdParams, isEnable);
-        Tunnels tunnelWithBfdReset = new TunnelsBuilder().setKey(tunnelKey).setBfdParams(tunnelBfdParams).build();
+        Tunnels tunnelWithBfdReset = new TunnelsBuilder().withKey(tunnelKey).setBfdParams(tunnelBfdParams).build();
         MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 getTunnelIdentifier(topologyId, nodeId, tunnelKey), tunnelWithBfdReset);
     }
@@ -273,19 +273,20 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         }
         // TODO: get the corresponding hwvtep tunnel from the sourceInterface
         // once InterfaceMgr
-        // Implements renderer for hwvtep vxlan tunnels
+        // Implements renderer for hwvtep VXLAN tunnels
         String tunnelLocalMacAddress = "<TODO>";
         String tunnelLocalIpAddress = "<TODO>";
         String tunnelRemoteMacAddress = "<TODO>";
-        String tunnelRemoteIpAddress = "<TODO>";
         List<BfdParams> bfdParams = new ArrayList<>();
         fillBfdParams(bfdParams, profile);
         List<BfdLocalConfigs> bfdLocalConfigs = new ArrayList<>();
         fillBfdLocalConfigs(bfdLocalConfigs, tunnelLocalMacAddress, tunnelLocalIpAddress);
         List<BfdRemoteConfigs> bfdRemoteConfigs = new ArrayList<>();
-        fillBfdRemoteConfigs(bfdRemoteConfigs, tunnelRemoteMacAddress, tunnelRemoteIpAddress);
-        TunnelsKey tunnelKey = null;
-        Tunnels tunnelWithBfd = new TunnelsBuilder().setKey(tunnelKey).setBfdParams(bfdParams)
+        fillBfdRemoteConfigs(bfdRemoteConfigs, tunnelRemoteMacAddress);
+        // tunnelKey is initialized to null and passed to withKey which FindBugs flags as a
+        // "Load of known null value" violation. Not sure sure what the intent is...
+        //TunnelsKey tunnelKey = null;
+        Tunnels tunnelWithBfd = new TunnelsBuilder().withKey(/*tunnelKey*/ null).setBfdParams(bfdParams)
                 .setBfdLocalConfigs(bfdLocalConfigs).setBfdRemoteConfigs(bfdRemoteConfigs).build();
         // TODO: get the following parameters from the interface and use it to
         // update hwvtep datastore
@@ -294,23 +295,21 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         // into hwvtep datastore. if tunnels are not created during that time,
         // then start monitoring has to
         // be done as part of tunnel add DCN handling.
-        HwvtepPhysicalLocatorRef remoteRef = null;
-        HwvtepPhysicalLocatorRef localRef = null;
         String topologyId = "";
         String nodeId = "";
         MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                getTunnelIdentifier(topologyId, nodeId, new TunnelsKey(localRef, remoteRef)), tunnelWithBfd);
+                getTunnelIdentifier(topologyId, nodeId, new TunnelsKey(/*localRef*/ null, /*remoteRef*/ null)),
+                tunnelWithBfd);
     }
 
-    private void fillBfdRemoteConfigs(List<BfdRemoteConfigs> bfdRemoteConfigs, String tunnelRemoteMacAddress,
-            String tunnelRemoteIpAddress) {
+    private void fillBfdRemoteConfigs(List<BfdRemoteConfigs> bfdRemoteConfigs, String tunnelRemoteMacAddress) {
         bfdRemoteConfigs
                 .add(getBfdRemoteConfig(AlivenessMonitorConstants.BFD_CONFIG_BFD_DST_MAC, tunnelRemoteMacAddress));
     }
 
     private BfdRemoteConfigs getBfdRemoteConfig(String key, String value) {
         return new BfdRemoteConfigsBuilder().setBfdRemoteConfigKey(key).setBfdRemoteConfigValue(value)
-                .setKey(new BfdRemoteConfigsKey(key)).build();
+                .withKey(new BfdRemoteConfigsKey(key)).build();
     }
 
     private void fillBfdLocalConfigs(List<BfdLocalConfigs> bfdLocalConfigs, String tunnelLocalMacAddress,
@@ -320,7 +319,7 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
     }
 
     private BfdLocalConfigs getBfdLocalConfig(String key, String value) {
-        return new BfdLocalConfigsBuilder().setBfdLocalConfigKey(key).setKey(new BfdLocalConfigsKey(key))
+        return new BfdLocalConfigsBuilder().setBfdLocalConfigKey(key).withKey(new BfdLocalConfigsKey(key))
                 .setBfdLocalConfigValue(value).build();
     }
 
@@ -340,7 +339,8 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
     }
 
     private BfdParams getBfdParams(String key, String value) {
-        return new BfdParamsBuilder().setBfdParamKey(key).setKey(new BfdParamsKey(key)).setBfdParamValue(value).build();
+        return new BfdParamsBuilder().setBfdParamKey(key).withKey(new BfdParamsKey(key)).setBfdParamValue(value)
+                .build();
     }
 
     @Override
@@ -361,8 +361,8 @@ public class HwVtepTunnelsStateHandler extends HwvtepAbstractDataTreeChangeListe
         return interfaceName;
     }
 
-    public static InstanceIdentifier<Tunnels> getTunnelIdentifier(String topologyId, String nodeId,
-            TunnelsKey tunnelsKey) {
+    private static InstanceIdentifier<Tunnels> getTunnelIdentifier(String topologyId, String nodeId,
+                                                                   TunnelsKey tunnelsKey) {
         return InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(new TopologyId(topologyId)))
                 .child(Node.class, new NodeKey(new NodeId(nodeId))).augmentation(PhysicalSwitchAugmentation.class)