Merge "make ConfigurationServiceFactoryImpl independent of OSGi"
[openflowplugin.git] / samples / learning-switch / src / main / java / org / opendaylight / openflowplugin / learningswitch / LearningSwitchHandlerSimpleImpl.java
index 90fd99510e02ec91bc54164bce061694ef97e6e3..d1a0b9be0ad08c26cca16637906dc30cf75fd407 100644 (file)
@@ -14,9 +14,13 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
@@ -42,36 +46,40 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Simple Learning Switch implementation which does mac learning for one switch.
- *
- *
  */
 public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, PacketProcessingListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(LearningSwitchHandlerSimpleImpl.class);
-
     private static final byte[] ETH_TYPE_IPV4 = new byte[] { 0x08, 0x00 };
-
     private static final int DIRECT_FLOW_PRIORITY = 512;
 
-    private DataChangeListenerRegistrationHolder registrationPublisher;
-    private FlowCommitWrapper dataStoreAccessor;
-    private PacketProcessingService packetProcessingService;
+    private final DataTreeChangeListenerRegistrationHolder registrationPublisher;
+    private final FlowCommitWrapper dataStoreAccessor;
+    private final PacketProcessingService packetProcessingService;
 
-    private boolean iAmLearning = false;
+    private volatile boolean isLearning = false;
 
     private NodeId nodeId;
-    private AtomicLong flowIdInc = new AtomicLong();
-    private AtomicLong flowCookieInc = new AtomicLong(0x2a00000000000000L);
+    private final AtomicLong flowIdInc = new AtomicLong();
+    private final AtomicLong flowCookieInc = new AtomicLong(0x2a00000000000000L);
 
     private InstanceIdentifier<Node> nodePath;
-    private InstanceIdentifier<Table> tablePath;
+    private volatile InstanceIdentifier<Table> tablePath;
 
     private Map<MacAddress, NodeConnectorRef> mac2portMapping;
-    private Set<String> coveredMacPaths;
+    private final Set<String> coveredMacPaths = new HashSet<>();
+
+    public LearningSwitchHandlerSimpleImpl(@Nonnull FlowCommitWrapper dataStoreAccessor,
+            @Nonnull PacketProcessingService packetProcessingService,
+            @Nullable DataTreeChangeListenerRegistrationHolder registrationPublisher) {
+        this.dataStoreAccessor = Objects.requireNonNull(dataStoreAccessor);
+        this.packetProcessingService = Objects.requireNonNull(packetProcessingService);
+        this.registrationPublisher = registrationPublisher;
+    }
 
     @Override
     public synchronized void onSwitchAppeared(InstanceIdentifier<Table> appearedTablePath) {
-        if (iAmLearning) {
+        if (isLearning) {
             LOG.debug("already learning a node, skipping {}", nodeId.getValue());
             return;
         }
@@ -80,22 +88,16 @@ public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, P
 
         // disable listening - simple learning handles only one node (switch)
         if (registrationPublisher != null) {
-            try {
-                LOG.debug("closing dataChangeListenerRegistration");
-                registrationPublisher.getDataChangeListenerRegistration().close();
-            } catch (Exception e) {
-                LOG.warn("closing registration upon flowCapable node update listener failed: {}", e.getMessage());
-                LOG.debug("closing registration upon flowCapable node update listener failed.. ", e);
-            }
+            LOG.debug("closing dataTreeChangeListenerRegistration");
+            registrationPublisher.getDataTreeChangeListenerRegistration().close();
         }
 
-        iAmLearning = true;
+        isLearning = true;
 
         tablePath = appearedTablePath;
         nodePath = tablePath.firstIdentifierOf(Node.class);
         nodeId = nodePath.firstKeyOf(Node.class, NodeKey.class).getId();
         mac2portMapping = new HashMap<>();
-        coveredMacPaths = new HashSet<>();
 
         // start forwarding all packages to controller
         FlowId flowId = new FlowId(String.valueOf(flowIdInc.getAndIncrement()));
@@ -112,24 +114,9 @@ public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, P
         dataStoreAccessor.writeFlowToConfig(flowPath, allToCtrlFlow.build());
     }
 
-    @Override
-    public void setRegistrationPublisher(DataChangeListenerRegistrationHolder registrationPublisher) {
-        this.registrationPublisher = registrationPublisher;
-    }
-
-    @Override
-    public void setDataStoreAccessor(FlowCommitWrapper dataStoreAccessor) {
-        this.dataStoreAccessor = dataStoreAccessor;
-    }
-
-    @Override
-    public void setPacketProcessingService(PacketProcessingService packetProcessingService) {
-        this.packetProcessingService = packetProcessingService;
-    }
-
     @Override
     public void onPacketReceived(PacketReceived notification) {
-        if (!iAmLearning) {
+        if (!isLearning) {
             // ignoring packets - this should not happen
             return;
         }
@@ -189,11 +176,6 @@ public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, P
 
     }
 
-    /**
-     * @param srcMac
-     * @param dstMac
-     * @param destNodeConnector
-     */
     private void addBridgeFlow(MacAddress srcMac, MacAddress dstMac, NodeConnectorRef destNodeConnector) {
         synchronized (coveredMacPaths) {
             String macPath = srcMac.toString() + dstMac.toString();
@@ -221,7 +203,8 @@ public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, P
 
     private void flood(byte[] payload, NodeConnectorRef ingress) {
         NodeConnectorKey nodeConnectorKey = new NodeConnectorKey(nodeConnectorId("0xfffffffb"));
-        InstanceIdentifier<?> nodeConnectorPath = InstanceIdentifierUtils.createNodeConnectorPath(nodePath, nodeConnectorKey);
+        InstanceIdentifier<?> nodeConnectorPath = InstanceIdentifierUtils.createNodeConnectorPath(
+                nodePath, nodeConnectorKey);
         NodeConnectorRef egressConnectorRef = new NodeConnectorRef(nodeConnectorPath);
 
         sendPacketOut(payload, ingress, egressConnectorRef);
@@ -241,6 +224,6 @@ public class LearningSwitchHandlerSimpleImpl implements LearningSwitchHandler, P
                 .setEgress(egress)
                 .setIngress(ingress)
                 .build();
-        packetProcessingService.transmitPacket(input);
+        JdkFutures.addErrorLogging(packetProcessingService.transmitPacket(input), LOG, "transmitPacket");
     }
 }