Added test-provider project. 18/3118/2
authorEd Warnicke <eaw@cisco.com>
Wed, 20 Nov 2013 01:23:28 +0000 (19:23 -0600)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 27 Nov 2013 21:19:24 +0000 (21:19 +0000)
This creates a bundle which:
1)  Provides a dummy listner for SalFlowService
2)  Provides an osgi command loadFlowData
that will write data to the MD-SAL for flows.

Patch 2:  Added commands for removing and modifying the
test flow.

To use, from the OSGI console type:

addFlow
modifyFlow
removeFlow

and you will see log messages indicating the dummy
rpc handler has received the rpc calls.

This basically tests the round tripping through the MD-SAL,
{add,modify,remove}Flow write data modifications for flows
to the tree, and then you see the RPC calls routed in the logs.

Very useful for testing.

Change-Id: I654e1f5a20fe9b964f1b69cebcb23d6744113112
Signed-off-by: Ed Warnicke <eaw@cisco.com>
Some work to try to add dumping routes

Change-Id: I798c8d4e050a39f224d1ac46609fc36667bedf47
Signed-off-by: Ed Warnicke <eaw@cisco.com>
.gitignore
distribution/base/pom.xml
openflowplugin-parent/pom.xml
test-provider/pom.xml [new file with mode: 0644]
test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestActivator.xtend [new file with mode: 0644]
test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestCommandProvider.java [new file with mode: 0644]
test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestServiceProvider.xtend [new file with mode: 0644]

index 48d2af9a5f11d1e46986bb38dd9b8474b46eb2a2..70a448c65e52e9731239ee6a78e87ce98feb341f 100755 (executable)
@@ -15,5 +15,6 @@ target
 .project\r
 .settings\r
 MANIFEST.MF\r
+xtend-gen\r
 \r
 \r
index ba25d0fb6b1c2835d634d89b4349dd6eb24fcd3a..9df6b463807a9a5d74fe9afcc092741d5b451cc9 100644 (file)
@@ -38,6 +38,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
       <artifactId>openflowplugin</artifactId>
       <version>0.0.1-SNAPSHOT</version>
     </dependency>
+    
+    <!-- debug provider -->
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>test-provider</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+
 
     <!-- openflowjava -->
     <dependency>
index 8e693eaf32b20c8fe60157ff6042a8e8dc2afcf7..e398c9f224ae2933ce9e8c312e5b3876bd30d01c 100644 (file)
@@ -13,6 +13,7 @@
       <module>../openflowplugin</module>
       <module>../distribution/base</module>
       <module>../openflowplugin-it</module>
+      <module>../test-provider</module>
     </modules>
 </project>
 
diff --git a/test-provider/pom.xml b/test-provider/pom.xml
new file mode 100644 (file)
index 0000000..055282d
--- /dev/null
@@ -0,0 +1,118 @@
+<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.openflowplugin</groupId>
+        <artifactId>openflowplugin-commons</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../commons</relativePath>
+    </parent>
+    <artifactId>test-provider</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/openflowplugin.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>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+        </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>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+            <version>${xtend.version}</version>
+        </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>
+             
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>${bundle.plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.openflowplugin.test.OpenflowpluginTestActivator</Bundle-Activator>
+                        <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>
+                <version>${xtend.version}</version>
+                <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>
+                <version>${maven.clean.plugin.version}</version>
+                <configuration>
+                    <filesets>
+                        <fileset>
+                            <directory>${basedir}/src/main/xtend-gen</directory>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestActivator.xtend b/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestActivator.xtend
new file mode 100644 (file)
index 0000000..7cd12d2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.openflowplugin.test
+
+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 OpenflowpluginTestActivator extends AbstractBindingAwareProvider {
+
+    static var OpenflowpluginTestServiceProvider provider = new OpenflowpluginTestServiceProvider();
+    var OpenflowpluginTestCommandProvider cmdProvider;
+    public static final String NODE_ID =  "foo:node:1";
+
+    override onSessionInitiated(ProviderContext session) {
+        provider.dataService = session.getSALService(DataProviderService)
+        provider.notificationService = session.getSALService(NotificationProviderService)
+        provider.start();
+        provider.register(session);
+        cmdProvider.onSessionInitiated(session);
+        
+    }
+    
+    override startImpl(BundleContext ctx) {
+        super.startImpl(ctx);
+        cmdProvider = new OpenflowpluginTestCommandProvider(ctx);
+        
+    }
+
+    override protected stopImpl(BundleContext context) {
+        provider.close();
+    }
+
+}
diff --git a/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestCommandProvider.java b/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestCommandProvider.java
new file mode 100644 (file)
index 0000000..d543acd
--- /dev/null
@@ -0,0 +1,196 @@
+
+/*
+ * Copyright (c) 2013 Ericsson , 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.openflowplugin.test;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+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.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.osgi.framework.BundleContext;
+
+
+
+public class OpenflowpluginTestCommandProvider implements CommandProvider {
+
+       private DataBrokerService dataBrokerService;
+       private ProviderContext pc;
+       private BundleContext ctx;
+       private Flow testFlow;
+    private Node testNode;
+    private String originalFlowName = "Foo";
+    private String updatedFlowName = "Bar";
+
+       public OpenflowpluginTestCommandProvider(BundleContext ctx) {
+           this.ctx = ctx;
+       }
+
+       public void onSessionInitiated(ProviderContext session) {
+           pc = session;
+               dataBrokerService = session.getSALService(DataBrokerService.class);
+               ctx.registerService(CommandProvider.class.getName(), this, null);
+               createTestNode();
+               createTestFlow();
+    }
+
+       private void createTestNode() {
+           NodeRef nodeOne = createNodeRef(OpenflowpluginTestActivator.NODE_ID);
+        NodeBuilder builder = new NodeBuilder();
+        builder.setId(new NodeId(OpenflowpluginTestActivator.NODE_ID));
+        builder.setKey(new NodeKey(builder.getId()));
+        testNode = builder.build();
+       }
+
+       private InstanceIdentifier<Node> nodeToInstanceId(Node node) {
+           return InstanceIdentifier.builder(Nodes.class).child(Node.class, node.getKey()).toInstance();
+       }
+
+       private void createTestFlow() {
+        // Sample data , committing to DataStore
+        DataModification modification = (DataModification) dataBrokerService.beginTransaction();
+        long id = 123;
+        FlowKey key = new FlowKey(id, new NodeRef(new NodeRef(nodeToInstanceId(testNode))));
+        FlowBuilder flow = new FlowBuilder();
+        flow.setKey(key);
+        MatchBuilder match = new MatchBuilder();
+        Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
+        // ipv4Match.setIpv4Destination(new Ipv4Prefix(cliInput.get(4)));
+        Ipv4Prefix prefix = new Ipv4Prefix("10.0.0.1/24");
+        ipv4Match.setIpv4Destination(prefix);
+        Ipv4Match i4m = ipv4Match.build();
+        match.setLayer3Match(i4m);
+        flow.setMatch(match.build());
+        DropAction dropAction = new DropActionBuilder().build();
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        ActionBuilder ab = new ActionBuilder();
+        ab.setAction(dropAction);
+        List<Action> actionList = new ArrayList<Action>();
+        actionList.add(ab.build());
+        aab.setAction(actionList);
+        InstructionBuilder ib = new InstructionBuilder();
+        ib.setInstruction(aab.build());
+        InstructionsBuilder isb = new InstructionsBuilder();
+        List<Instruction> instructions = new ArrayList<Instruction>();
+        isb.setInstruction(instructions);
+        flow.setInstructions(isb.build());
+     //   ActionBuilder action = new ActionBuilder();
+
+      //  List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Action> actions = Collections
+             //   .singletonList(action.build());
+     //   flow.setAction(actions);
+        flow.setPriority(2);
+        flow.setFlowName(originalFlowName);
+        testFlow = flow.build();
+       }
+
+       public void _removeFlow(CommandInterpreter ci) {
+           DataModification modification = (DataModification) dataBrokerService.beginTransaction();
+        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Flows.class).child(Flow.class, testFlow.getKey()).toInstance();
+        DataObject cls = (DataObject) modification.readConfigurationData(path1);
+        modification.removeOperationalData(nodeToInstanceId(testNode));
+        modification.removeOperationalData(path1);
+        modification.removeConfigurationData(nodeToInstanceId(testNode));
+        modification.removeConfigurationData(path1);
+        Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
+        try {
+            RpcResult<TransactionStatus> result = commitFuture.get();
+            TransactionStatus status = result.getResult();
+            ci.println("Status of Flow Data Loaded Transaction: " + status);
+
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+       }
+
+       public void _addFlow(CommandInterpreter ci) {
+        writeFlow(ci, testFlow);
+    }
+
+       private void writeFlow(CommandInterpreter ci,Flow flow) {
+           DataModification modification = (DataModification) dataBrokerService.beginTransaction();
+        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Flows.class).child(Flow.class, flow.getKey()).toInstance();
+        DataObject cls = (DataObject) modification.readConfigurationData(path1);
+        modification.putOperationalData(nodeToInstanceId(testNode), testNode);
+        modification.putOperationalData(path1, flow);
+        modification.putConfigurationData(nodeToInstanceId(testNode), testNode);
+        modification.putConfigurationData(path1, flow);
+        Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
+        try {
+            RpcResult<TransactionStatus> result = commitFuture.get();
+            TransactionStatus status = result.getResult();
+            ci.println("Status of Flow Data Loaded Transaction: " + status);
+
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+       }
+
+       public void _modifyFlow(CommandInterpreter ci) {
+           FlowBuilder flow = new FlowBuilder(testFlow);
+           flow.setFlowName(updatedFlowName);
+           writeFlow(ci, flow.build());
+           flow.setFlowName(originalFlowName);
+           writeFlow(ci, flow.build());
+       }
+
+       private static NodeRef createNodeRef(String string) {
+        NodeKey key = new NodeKey(new NodeId(string));
+        InstanceIdentifier<Node> path =
+               InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key).toInstance();
+
+        return new NodeRef(path);
+    }
+
+    @Override
+    public String getHelp() {
+        return "No help";
+    }
+}
+
diff --git a/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestServiceProvider.xtend b/test-provider/src/main/java/org/opendaylight/openflowplugin/test/OpenflowpluginTestServiceProvider.xtend
new file mode 100644 (file)
index 0000000..2e848aa
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.openflowplugin.test
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+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.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+
+class OpenflowpluginTestServiceProvider implements AutoCloseable, SalFlowService {
+
+
+    static val LOG = LoggerFactory.getLogger(OpenflowpluginTestServiceProvider);
+
+    @Property
+    DataProviderService dataService;
+    
+    @Property
+    RoutedRpcRegistration<SalFlowService> flowRegistration;
+        
+
+    @Property
+    NotificationProviderService notificationService;
+
+
+    def void start() {
+        LOG.info("SalFlowServiceProvider Started.");
+        
+    }
+
+
+    override close() {
+       LOG.info("SalFlowServiceProvide stopped.");
+        flowRegistration.close;
+    }
+    
+    override addFlow(AddFlowInput input) {
+        LOG.info("addFlow - " + input);
+        return null;
+        
+    }
+    
+    override removeFlow(RemoveFlowInput input) {
+        LOG.info("removeFlow - " + input);
+        return null;
+    }
+    
+    override updateFlow(UpdateFlowInput input) {
+        LOG.info("updateFlow - " + input);
+        return null;
+    }
+    
+    
+    def CompositeObjectRegistration<OpenflowpluginTestServiceProvider> register(ProviderContext ctx) {
+        val builder = CompositeObjectRegistration
+                .<OpenflowpluginTestServiceProvider> builderFor(this);
+
+        flowRegistration = ctx.addRoutedRpcImplementation(SalFlowService, this);
+        val nodeIndentifier = InstanceIdentifier.builder(Nodes).child(Node, new NodeKey(new NodeId(OpenflowpluginTestActivator.NODE_ID)));
+        flowRegistration.registerPath(NodeContext, nodeIndentifier.toInstance());
+        builder.add(flowRegistration);
+
+        return builder.toInstance();
+    }
+    
+}
+
+