Merge changes Idf3f69db,I4499d7c7,I512af911
authorAlessandro Boch <aboch@cisco.com>
Fri, 3 Jan 2014 17:52:35 +0000 (17:52 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 3 Jan 2014 17:52:35 +0000 (17:52 +0000)
* changes:
  Initial fix to topology-adapter.
  Fixed topology-manager now that we have topology-lldp-discovery
  Added topology-lldp-discovery module

15 files changed:
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java
opendaylight/md-sal/topology-lldp-discovery/pom.xml [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java [new file with mode: 0644]
opendaylight/md-sal/topology-manager/pom.xml
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend [new file with mode: 0644]

index b0f7ad89a4b81694c889c52e51f5cc00947c8c4f..64872e9f1179713c3a2b8e5818bbc67645157191 100644 (file)
           <artifactId>forwardingrules-manager</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>topology-lldp-discovery</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>topology-manager</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-topology</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+         <groupId>org.opendaylight.yangtools.model</groupId>
+         <artifactId>ietf-topology</artifactId>
+         <version>2013.07.12.2-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>statistics-manager</artifactId>
index 31ae745d73054ed0c046d94c05c8f38ba26f786f..2124185b6c297906d617cbef74d9481e6367ace9 100644 (file)
@@ -105,9 +105,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
 
     @Property
     IPluginOutTopologyService topologyPublisher;
-    
-    @Property
-    IDiscoveryService discoveryPublisher;
 
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
@@ -470,7 +467,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     
     override onLinkDiscovered(LinkDiscovered notification) {
         val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
-        discoveryPublisher.notifyEdge(notification.toADEdge,UpdateType.ADDED,Collections.emptySet());
         topologyPublisher.edgeUpdate(Collections.singletonList(update))
     }
     
index 33c03ba059722a1a2162c7f3b3559a24c6267b49..ceeef45f238046881e1cace964cb814cf7ddede7 100644 (file)
@@ -21,12 +21,14 @@ module opendaylight-topology-inventory {
 
     augment "/topo:network-topology/topo:topology/topo:node" {
         ext:augment-identifier "inventory-node";
-        uses inv:node-context-ref;
+        leaf inventory-node-ref {
+            type inv:node-ref;
+        }
     }
 
     augment "/topo:network-topology/topo:topology/topo:node/topo:termination-point" {
         ext:augment-identifier "inventory-node-connector";
-        leaf node-connector {
+        leaf inventory-node-connector-ref {
             ext:context-reference "inv:node-connector-context";
             type inv:node-connector-ref;
         }
index 0d6523bc0bbb38dd059e9c978be147cab7a4b7e8..efc84237b5ba202b0806bfa2e34db3a94e0d7a20 100644 (file)
@@ -50,7 +50,9 @@
 
         <module>inventory-manager</module>
         <module>statistics-manager</module>
+        <module>topology-manager</module>
         <module>forwardingrules-manager</module>
+        <module>topology-lldp-discovery</module>
 
         <!-- Compability Packages -->
         <module>compatibility</module>
index 738a14a9bd408ddeed36aa161824ceb2f39e91e4..fd81af353ceb0d137bf9fbd527a349b6430fd20c 100644 (file)
@@ -7,7 +7,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public final class TypeSafeDataReader {
 
     
-    private final DataReader<InstanceIdentifier<?>,DataObject> delegate;
+    private final DataReader<InstanceIdentifier<? extends DataObject>,DataObject> delegate;
     
     
     
@@ -16,7 +16,7 @@ public final class TypeSafeDataReader {
     }
 
 
-    public TypeSafeDataReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+    public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         this.delegate = delegate;
     }
 
@@ -32,7 +32,7 @@ public final class TypeSafeDataReader {
         return (D) delegate.readOperationalData(path);
     }
     
-    public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+    public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         return new TypeSafeDataReader(delegate);
     }
 }
diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml
new file mode 100644 (file)
index 0000000..ed94c8d
--- /dev/null
@@ -0,0 +1,129 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+    </parent>
+    <groupId>org.opendaylight.controller.md</groupId>
+    <artifactId>topology-lldp-discovery</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    </scm>
+    <properties>
+        <guava.version>14.0.1</guava.version>
+        <xtend.version>2.4.3</xtend.version>
+        <bundle.plugin.version>2.4.0</bundle.plugin.version>
+        <maven.clean.plugin.version>2.5</maven.clean.plugin.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>    
+           <dependency>
+             <groupId>org.opendaylight.controller.model</groupId>
+             <artifactId>model-flow-base</artifactId>
+             <version>1.0-SNAPSHOT</version>
+           </dependency>
+          <dependency>
+             <groupId>org.opendaylight.controller.model</groupId>
+             <artifactId>model-flow-management</artifactId>
+             <version>1.0-SNAPSHOT</version>
+           </dependency>    
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+         <dependency>
+               <groupId>equinoxSDK381</groupId>
+               <artifactId>org.eclipse.osgi</artifactId>
+               <version>3.8.1.v20120830-144521</version>
+             </dependency>
+             <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+          </dependency>
+          <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+          </dependency>
+          <dependency>
+                   <groupId>commons-codec</groupId>
+                   <artifactId>commons-codec</artifactId>
+                   <version>1.8</version>
+                 </dependency>
+    <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal</artifactId>
+            <version>0.7.0-SNAPSHOT</version>
+        </dependency>
+             
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.md.controller.topology.lldp.LLDPActivator</Bundle-Activator>
+                        <Export-Package>org.opendaylight.md.controller.topology.lldp.utils</Export-Package>
+                        <Embed-Dependency>commons-lang</Embed-Dependency>>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                    </instructions>
+                    <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+                <executions>
+                  <execution>
+                      <goals>
+                          <goal>compile</goal>
+                      </goals>
+                      <configuration>
+                          <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
+                      </configuration>
+                  </execution>
+              </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+                <configuration>
+                    <filesets>
+                        <fileset>
+                            <directory>${basedir}/src/main/xtend-gen</directory>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend
new file mode 100644 (file)
index 0000000..674e919
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.osgi.framework.BundleContext
+
+class LLDPActivator extends AbstractBindingAwareProvider {
+
+    static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
+
+    override onSessionInitiated(ProviderContext session) {
+        provider.dataService = session.getSALService(DataProviderService)
+        provider.notificationService = session.getSALService(NotificationProviderService)
+        provider.start();
+    }
+
+    override protected stopImpl(BundleContext context) {
+        provider.close();
+    }
+
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java
new file mode 100644 (file)
index 0000000..095d12e
--- /dev/null
@@ -0,0 +1,34 @@
+package org.opendaylight.md.controller.topology.lldp;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscoveredBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class LLDPDiscoveryListener implements PacketProcessingListener {
+    static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryListener.class);
+
+    private LLDPDiscoveryProvider manager;
+
+    LLDPDiscoveryListener(LLDPDiscoveryProvider manager) {
+        this.manager = manager;
+    }
+    
+    public void onPacketReceived(PacketReceived lldp) {
+        NodeConnectorRef src = LLDPDiscoveryUtils.lldpToNodeConnectorRef(lldp.getPayload());
+        if(src != null) {
+            LinkDiscoveredBuilder ldb = new LinkDiscoveredBuilder();
+            ldb.setDestination(lldp.getIngress());
+            ldb.setSource(new NodeConnectorRef(src));
+            LinkDiscovered ld = ldb.build();
+            
+            manager.getNotificationService().publish(ld);
+            LLDPLinkAger.getInstance().put(ld);
+        }
+    }
+    
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend
new file mode 100644 (file)
index 0000000..fc724ac
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+
+class LLDPDiscoveryProvider implements AutoCloseable {
+
+
+    static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider);
+
+    @Property
+    DataProviderService dataService;        
+
+    @Property
+    NotificationProviderService notificationService;
+
+    val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this);
+
+    Registration<NotificationListener> listenerRegistration
+
+    def void start() {
+        listenerRegistration = notificationService.registerNotificationListener(commiter);
+        LLDPLinkAger.instance.manager = this;
+        LOG.info("LLDPDiscoveryListener Started.");
+        
+    }   
+    
+    override close() {
+       LOG.info("LLDPDiscoveryListener stopped.");
+        listenerRegistration?.close();
+        LLDPLinkAger.instance.close();
+    }
+    
+}
+
+
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java
new file mode 100644 (file)
index 0000000..171783b
--- /dev/null
@@ -0,0 +1,65 @@
+package org.opendaylight.md.controller.topology.lldp;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Timer;
+import java.util.Map.Entry;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemovedBuilder;
+
+
+public class LLDPLinkAger {
+    private static final LLDPLinkAger instance = new LLDPLinkAger();
+    private Map<LinkDiscovered,Date> linkToDate = new ConcurrentHashMap<LinkDiscovered,Date>();
+    private LLDPDiscoveryProvider manager;
+    private Timer timer = new Timer();
+
+    public LLDPDiscoveryProvider getManager() {
+        return manager;
+    }
+    public void setManager(LLDPDiscoveryProvider manager) {
+        this.manager = manager;
+    }
+    private LLDPLinkAger() {
+        timer.schedule(new LLDPAgingTask(), 0,LLDPDiscoveryUtils.LLDP_INTERVAL);
+    }
+    public static LLDPLinkAger getInstance() {
+        return instance;
+    }
+    
+    public void put(LinkDiscovered link) {
+        Date expires = new Date();
+        expires.setTime(expires.getTime() + LLDPDiscoveryUtils.LLDP_EXPIRATION_TIME);
+        linkToDate.put(link, expires);
+    }
+    
+    public void close() {
+        timer.cancel();
+    }
+    
+    private class LLDPAgingTask extends TimerTask {
+
+        @Override
+        public void run() {
+            for (Entry<LinkDiscovered,Date> entry : linkToDate.entrySet()) {
+                LinkDiscovered link = entry.getKey();
+                Date expires = entry.getValue();
+                Date now = new Date();
+                if(now.after(expires)) {
+                    if(getInstance().getManager() != null) {
+                        LinkRemovedBuilder lrb = new LinkRemovedBuilder(link);
+                        getInstance().getManager().getNotificationService().publish(lrb.build());
+                        linkToDate.remove(link);
+                    }
+                }
+            }
+            
+        }
+        
+    }
+}
+
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java
new file mode 100644 (file)
index 0000000..d5dee32
--- /dev/null
@@ -0,0 +1,76 @@
+package org.opendaylight.md.controller.topology.lldp.utils;
+
+import java.nio.charset.Charset;
+import java.util.List;
+
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.LLDP;
+import org.opendaylight.controller.sal.packet.LLDPTLV;
+import org.opendaylight.controller.sal.utils.NetUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LLDPDiscoveryUtils {
+    static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryUtils.class);
+    
+    public static final Long LLDP_INTERVAL = (long) (1000*5); // Send LLDP every five seconds
+    public static final Long LLDP_EXPIRATION_TIME = LLDP_INTERVAL*3; // Let up to three intervals pass before we decide we are expired.
+    
+    public static String macToString(byte[] mac) {
+        StringBuilder b = new StringBuilder();
+        for (int i = 0; i < mac.length; i++) {
+            b.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
+        }
+
+        return b.toString();
+    }
+    
+    public static NodeConnectorRef lldpToNodeConnectorRef(byte[] payload)  {
+        Ethernet ethPkt = new Ethernet();
+        try {
+            ethPkt.deserialize(payload, 0,payload.length * NetUtils.NumBitsInAByte);
+        } catch (Exception e) {
+            LOG.warn("Failed to decode LLDP packet {}", e);
+        }
+
+        if (ethPkt.getPayload() instanceof LLDP) {
+            LLDP lldp = (LLDP) ethPkt.getPayload();
+    
+            try {
+                List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
+                if (optionalTLVList == null) {
+                    return null;
+                }
+                NodeId srcNodeId = null;
+                NodeConnectorId srcNodeConnectorId = null;
+                for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
+                    if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
+                        srcNodeConnectorId = new NodeConnectorId(LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength()));
+                    }
+                    if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
+                        String srcNodeIdString = new String(lldptlv.getValue(),Charset.defaultCharset());
+                        srcNodeId = new NodeId(srcNodeIdString);
+                    }
+                }
+                
+                InstanceIdentifier<NodeConnector> srcInstanceId = InstanceIdentifier.builder(Nodes.class)
+                        .child(Node.class,new NodeKey(srcNodeId))
+                        .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId))
+                        .toInstance();
+                return new NodeConnectorRef(srcInstanceId);
+            } catch (Exception e) {
+                LOG.warn("Caught exception ", e);
+            }
+        }
+        return null;
+    }
+}
index 6e50f9ce73aab798124ea7c9624cda5f881104d5..76300864fd3367092babd58b6d0d97595851e640 100644 (file)
@@ -42,7 +42,7 @@
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-topology-view</artifactId>
+            <artifactId>model-topology</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
@@ -58,8 +58,8 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-                        <Bundle-Activator>org.opendaylight.controller.md.inventory.manager.InventoryActivator</Bundle-Activator>
-                        <Private-Package>org.opendaylight.controller.md.inventory.manager</Private-Package>
+                        <Bundle-Activator>org.opendaylight.md.controller.topology.manager.FlowCapableTopologyProvider</Bundle-Activator>
+                        <Private-Package>org.opendaylight.md.controller.topology.manager</Private-Package>
                     </instructions>
                 </configuration>
             </plugin>
index 46f5d2b406916d5f46bc9e7ab5527278a8090914..05f7fe12729384590459ed9a41bb271ca2ffa157 100644 (file)
@@ -5,7 +5,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
@@ -14,6 +14,17 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
 
 class FlowCapableNodeMapping {
 
@@ -29,12 +40,6 @@ class FlowCapableNodeMapping {
         (ref?.value?.path?.get(2) as IdentifiableItem<NodeConnector,NodeConnectorKey>).key
     }
 
-    static def TerminationPoint toTerminationPoint(NodeConnectorUpdated updated) {
-        val it = new TerminationPointBuilder
-        key = new TerminationPointKey(new TpId(updated.id));
-        return it.build()
-    }
-
     static def NodeId toToplogyNodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) {
         return new NodeId(nodeId);
     }
@@ -42,4 +47,36 @@ class FlowCapableNodeMapping {
     static def toTerminationPointId(NodeConnectorId id) {
         return new TpId(id);
     }
+    
+    static def toTopologyNode(NodeId nodeId,NodeRef invNodeRef) {
+        val nb = new NodeBuilder();
+        nb.setNodeId(nodeId)
+        val inb = new InventoryNodeBuilder
+        inb.setInventoryNodeRef(invNodeRef)
+        nb.addAugmentation(InventoryNode,inb.build)
+        return nb.build();
+    }
+    
+    static def toTerminationPoint(TpId id, NodeConnectorRef invNodeConnectorRef) {
+        val tpb = new TerminationPointBuilder
+        tpb.setTpId(id);
+        val incb = new InventoryNodeConnectorBuilder
+        incb.setInventoryNodeConnectorRef(invNodeConnectorRef)
+        tpb.addAugmentation(InventoryNodeConnector,incb.build())
+        return tpb.build();
+    }
+    
+    static def toTopologyLink(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) {
+        val sb = new SourceBuilder();
+        sb.setSourceNode(link.source.nodeKey.id.toToplogyNodeId)
+        sb.setSourceTp(link.source.nodeConnectorKey.id.toTerminationPointId)
+        val db = new DestinationBuilder();
+        db.setDestNode(link.destination.nodeKey.id.toToplogyNodeId)
+        db.setDestTp(link.destination.nodeConnectorKey.id.toTerminationPointId)
+        val lb = new LinkBuilder();
+        lb.setSource(sb.build())
+        lb.setDestination(db.build());
+        lb.setLinkId(new LinkId(lb.source.sourceTp.value))
+        return lb.build();
+    } 
 }
index fb129e47106a363d99f6729a3fd53490448b488c..de61daeae3380f35fee50acf43aeebc766416c5c 100644 (file)
 package org.opendaylight.md.controller.topology.manager
 
+import com.google.common.collect.FluentIterable
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyBuilder
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
-
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
 import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.*
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import com.google.common.collect.FluentIterable
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
 
 class FlowCapableTopologyExporter implements //
 FlowTopologyDiscoveryListener, //
 OpendaylightInventoryListener //
 {
 
-    var TopologyKey topology;
+    var TopologyKey topology = new TopologyKey(new TopologyId("flow:1"));
 
     @Property
     var DataProviderService dataService;
+    
+    def start() {
+        val tb = new TopologyBuilder();
+        tb.setKey(topology);
+        val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance;
+        val top = tb.build();
+        val it = dataService.beginTransaction
+        putOperationalData(path,top);
+        commit()       
+    }
 
     override onNodeRemoved(NodeRemoved notification) {
-        val invNodeKey = notification.nodeRef.nodeKey
-        val tpNodeId = invNodeKey.id.toToplogyNodeId()
-        val tpNodeInstance = notification.nodeRef.toNodeIdentifier()
+        val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId()
+        val nodeInstance = notification.nodeRef.toNodeIdentifier()
 
         val it = dataService.beginTransaction
-        removeRuntimeData(tpNodeInstance);
-        removeAffectedLinks(tpNodeId)
+        removeOperationalData(nodeInstance);
+        removeAffectedLinks(it,nodeId)
         commit()
 
     }
 
     override onNodeUpdated(NodeUpdated notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val fcnu = notification.getAugmentation(FlowCapableNodeUpdated)
+        if(fcnu != null) {
+            val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef)
+            val path = notification.id.toToplogyNodeId.nodePath;
+            val it = dataService.beginTransaction
+            putOperationalData(path, node);
+            commit()
+        }
     }
 
     override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
-        val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier();
+        val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier;
+        val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId;
         val it = dataService.beginTransaction
-        removeRuntimeData(tpRef);
+        removeOperationalData(tpInstance);
+        removeAffectedLinks(it,tpId)
         commit()
 
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated notification) {
-        val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId();
-        val TerminationPoint point = notification.toTerminationPoint();
-        val path = tpPath(nodeId, point.key.tpId);
-
-        val it = dataService.beginTransaction
-        putRuntimeData(path, point);
-        commit()
+        val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated)
+        if(fcncu != null) {
+            val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId;
+            val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef);
+            val path = tpPath(nodeId, point.key.tpId);
+    
+            val it = dataService.beginTransaction
+            putOperationalData(path, point);
+            commit()     
+       }
     }
 
     override onLinkDiscovered(LinkDiscovered notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val link = notification.toTopologyLink;
+        val path = link.linkPath;
+        val it = dataService.beginTransaction
+        putOperationalData(path, link);
+        commit()
     }
 
     override onLinkOverutilized(LinkOverutilized notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        // NOOP
     }
 
     override onLinkRemoved(LinkRemoved notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-
+        val path = notification.toTopologyLink.linkPath
+        val it = dataService.beginTransaction
+        removeOperationalData(path);
+        commit()
     }
 
     override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        // NOOP
     }
 
     def InstanceIdentifier<Node> toNodeIdentifier(NodeRef ref) {
         val invNodeKey = ref.nodeKey
 
         val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId);
-        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+        return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
             toInstance;
     }
 
@@ -107,7 +138,7 @@ OpendaylightInventoryListener //
 
     private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) {
         val reader = TypeSafeDataReader.forReader(transaction)
-        val topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).toInstance;
+        val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
         val topologyData = reader.readOperationalData(topologyPath);
         if (topologyData === null) {
             return;
@@ -115,18 +146,52 @@ OpendaylightInventoryListener //
         val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
             source.sourceNode == id || destination.destNode == id].transform [
             //
-            InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+            InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
         //
         ]
         for(affectedLink : affectedLinkInstances) {
-            transaction.removeRuntimeData(affectedLink);
+            transaction.removeOperationalData(affectedLink);
         }
     }
     
+    private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) {
+        val reader = TypeSafeDataReader.forReader(transaction)
+        val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
+        val topologyData = reader.readOperationalData(topologyPath);
+        if (topologyData === null) {
+            return;
+        }
+        val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
+            source.sourceTp == id || destination.destTp == id].transform [
+            //
+            InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+        //
+        ]
+        for(affectedLink : affectedLinkInstances) {
+            transaction.removeOperationalData(affectedLink);
+        }
+    }
+    
+    private def InstanceIdentifier<Node> nodePath(NodeId nodeId) {
+        val nodeKey = new NodeKey(nodeId);
+        return InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology, topology)
+            .child(Node, nodeKey)
+            .toInstance;
+    }
+    
     private def InstanceIdentifier<TerminationPoint> tpPath(NodeId nodeId, TpId tpId) {
         val nodeKey = new NodeKey(nodeId);
         val tpKey = new TerminationPointKey(tpId)
-        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+        return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
             child(TerminationPoint, tpKey).toInstance;
     }
+    
+    private def InstanceIdentifier<Link> linkPath(Link link) {
+        val linkInstanceId = InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology, topology)
+            .child(Link, link.key)
+            .toInstance;
+        return linkInstanceId;
+    }    
 }
diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend
new file mode 100644 (file)
index 0000000..036fe73
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.md.controller.topology.manager
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+
+class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable {
+
+
+
+    static val LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider);
+
+    @Property
+    DataProviderService dataService;        
+
+    @Property
+    NotificationProviderService notificationService;
+
+    val FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter();
+
+    Registration<NotificationListener> listenerRegistration
+    
+    override close() {
+       LOG.info("FlowCapableTopologyProvider stopped.");
+        listenerRegistration?.close();
+    }
+    
+    override onSessionInitiated(ProviderContext session) {
+        dataService = session.getSALService(DataProviderService)
+        notificationService = session.getSALService(NotificationProviderService)
+        exporter.setDataService(dataService);
+        exporter.start();
+        listenerRegistration = notificationService.registerNotificationListener(exporter);
+    }
+    
+}
+
+