MD-SAL RuntimeDataProvider for Forwarding Rules 82/1882/7
authorTony Tkacik <ttkacik@cisco.com>
Mon, 14 Oct 2013 16:56:43 +0000 (18:56 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 15 Oct 2013 15:43:49 +0000 (15:43 +0000)
Change-Id: I0eac10ec50c9f4a4e95a0d9542842078ef8c7422
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
opendaylight/md-sal/flow-management-compatibility/pom.xml [new file with mode: 0644]
opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-config.yang
opendaylight/md-sal/pom.xml

diff --git a/opendaylight/md-sal/flow-management-compatibility/pom.xml b/opendaylight/md-sal/flow-management-compatibility/pom.xml
new file mode 100644 (file)
index 0000000..5c24baa
--- /dev/null
@@ -0,0 +1,89 @@
+<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>
+  </parent>
+  <artifactId>flow-management-compatibility</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>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>Forwarding Rules Manager Adapter for MD-SAL</Bundle-Name>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.xtend</groupId>
+        <artifactId>xtend-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <artifactId>maven-clean-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-api</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.xtend</groupId>
+      <artifactId>org.eclipse.xtend.lib</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-flow-management</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>forwardingrulesmanager</artifactId>
+      <version>0.4.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-compability</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+
+  </dependencies>
+</project>
diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend
new file mode 100644 (file)
index 0000000..5824859
--- /dev/null
@@ -0,0 +1,165 @@
+package org.opendaylight.controller.md.frm.compatibility
+
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.FlowsBuilder
+import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager
+import static com.google.common.base.Preconditions.*;
+import static extension org.opendaylight.controller.md.frm.compatibility.FlowConfigMapping.*;
+import static extension org.opendaylight.controller.sal.compability.NodeMapping.*;
+import org.opendaylight.controller.sal.common.util.Arguments
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig
+import java.util.HashSet
+import org.opendaylight.controller.sal.common.util.Rpcs
+import java.util.Collections
+import org.opendaylight.yangtools.yang.common.RpcError
+
+class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    static val FLOWS_PATH = InstanceIdentifier.builder().node(Flows).toInstance;
+
+    @Property
+    var DataProviderService dataService;
+
+    @Property
+    var DataChangeListener changeListener;
+    
+    @Property
+    var IForwardingRulesManager manager;
+
+    FlowManagementReader configuration = new ConfigurationReader();
+
+    def init() {
+        //dataService.registerDataChangeListener(FLOWS_PATH, changeListener);
+        dataService.registerCommitHandler(FLOWS_PATH, this);
+    }
+
+    override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        return readFrom(configuration, path);
+    }
+
+    override DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        return readFrom(configuration, path);
+    }
+
+    def DataObject readFrom(FlowManagementReader store, InstanceIdentifier<? extends DataObject> path) {
+        if (FLOWS_PATH == path) {
+            return store.readAllFlows();
+        }
+        if (FLOWS_PATH.contains(path)) {
+            return store.readFlow(path.toFlowKey());
+        }
+        return null;
+    }
+
+    override FlowCommitTransaction requestCommit(
+        DataModification modification) {
+        return new FlowCommitTransaction(this,modification);
+    }
+
+    def toFlowKey(InstanceIdentifier<? extends DataObject> identifier) {
+        checkNotNull(identifier)
+        val item = Arguments.checkInstanceOf(identifier.path.get(1),IdentifiableItem);
+        val key = Arguments.checkInstanceOf(item.key,FlowKey)
+        return key;
+    }
+    
+    def RpcResult<Void> finish(FlowCommitTransaction transaction) {
+        for(flw: transaction.toRemove) {
+            manager.removeStaticFlow(flw.name,flw.node)
+        }
+        
+        for(flw: transaction.toUpdate) {
+            manager.removeStaticFlow(flw.name,flw.node);
+            manager.addStaticFlow(flw);
+        }
+        
+        return Rpcs.<Void>getRpcResult(true,null,Collections.<RpcError>emptySet())
+    }
+    
+    def RpcResult<Void> rollback(FlowCommitTransaction transaction) {
+        // NOOP: We did not changed any state.
+    }
+
+}
+
+class ConfigurationReader implements FlowManagementReader {
+
+    @Property
+    var IForwardingRulesManager manager;
+
+    override Flows readAllFlows() {
+        val it = new FlowsBuilder();
+        flow = manager.staticFlows.map[
+            toConfigurationFlow();
+        ]
+        return it.build();
+    }
+
+    override readFlow(FlowKey key) {
+        val flowCfg = manager.getStaticFlow(key.id,key.node.toADNode());
+        return flowCfg.toConfigurationFlow;
+    }
+}
+
+public static class FlowCommitTransaction implements DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    @Property
+    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+    @Property
+    val FRMRuntimeDataProvider flowManager;
+    
+    @Property
+    val toAdd = new HashSet<FlowConfig>();
+    
+    @Property
+    var Iterable<FlowConfig> toUpdate
+    
+    @Property
+    var Iterable<FlowConfig> toRemove
+    
+
+    new(FRMRuntimeDataProvider flowManager,DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        super();
+        _flowManager = flowManager;
+        _modification = modification;
+        processModification();
+    }
+
+    override finish() throws IllegalStateException {
+        return flowManager.finish(this);
+    }
+
+    override rollback() throws IllegalStateException
+{
+        return flowManager.rollback(this);
+    }
+
+    def processModification() {
+        val updated = modification.updatedConfigurationData.entrySet;
+        
+        val _toUpdate = updated.filter[key.isFlowPath].map[
+             return (value as Flow).toFlowConfig
+        ]
+        toUpdate = _toUpdate as Iterable<FlowConfig>
+        
+        
+        val _toRemove = modification.removedConfigurationData.filter[isFlowPath].map[
+             toFlowConfig
+        ]
+        toRemove = _toRemove as Iterable<FlowConfig>
+        
+    }
+}
diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend
new file mode 100644 (file)
index 0000000..602b626
--- /dev/null
@@ -0,0 +1,61 @@
+package org.opendaylight.controller.md.frm.compatibility
+
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder
+
+import static extension org.opendaylight.controller.sal.compability.NodeMapping.*
+import static org.opendaylight.controller.sal.compability.MDFlowMapping.*
+import static org.opendaylight.controller.sal.compability.ToSalConversionsUtils.*
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.binding.Identifiable
+
+class FlowConfigMapping {
+
+    static def toConfigurationFlow(FlowConfig sourceCfg) {
+        val it = new FlowBuilder();
+        val source = flowAdded(sourceCfg.flow);
+
+        action = source.action;
+        cookie = source.cookie;
+        hardTimeout = source.hardTimeout
+        idleTimeout = source.idleTimeout
+        match = source.match
+        node = source.node
+        key = new FlowKey(sourceCfg.name, node)
+        return it.build();
+    }
+
+    static def toFlowConfig(Flow sourceCfg) {
+        val flow = toFlow(sourceCfg);
+        val it = new FlowConfig;
+        name = sourceCfg.key.id
+        node = sourceCfg.node.toADNode();
+
+        return it
+    }
+
+    static def toFlowConfig(InstanceIdentifier<?> identifier) {
+        val it = new FlowConfig()
+        val FlowKey key = ((identifier.path.get(2) as IdentifiableItem<Flow,FlowKey>).key)
+        name = key.id;
+        node = key.node.toADNode();
+
+        return it;
+    }
+
+    static def boolean isFlowPath(InstanceIdentifier<?> path) {
+        if(path.path.size < 2) return false;
+        if (path.path.get(2) instanceof IdentifiableItem<?,?>) {
+            val IdentifiableItem<?,? extends Identifiable<?>> item = path.path.get(2) as IdentifiableItem<?,? extends Identifiable<?>>;
+            val Identifiable<?> key = item.key;
+            if (key instanceof FlowKey) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java
new file mode 100644 (file)
index 0000000..61566d7
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.controller.md.frm.compatibility;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+
+public interface FlowManagementReader {
+
+    Flows readAllFlows();
+
+    Flow readFlow(FlowKey key);
+
+}
index da8e914..5e6b59a 100644 (file)
@@ -20,7 +20,7 @@ module flow-management {
 
     container flows {
         list flow {
-            key "id";
+            key "id node";
             
             leaf id {
                 type string;
index 54fd037..60e5a3d 100644 (file)
@@ -39,6 +39,7 @@
         <!-- Connectors -->
         <module>sal-connector-api</module>
         <module>sal-rest-connector</module>
+        <module>flow-management-compatibility</module>
     </modules>
 
     <properties>