Northbound migration to use the new Schema independent Library based Plugin. 49/8649/1
authorMadhu Venugopal <mavenugo@gmail.com>
Tue, 1 Jul 2014 08:11:34 +0000 (01:11 -0700)
committerMadhu Venugopal <mavenugo@gmail.com>
Thu, 3 Jul 2014 23:53:07 +0000 (16:53 -0700)
Following the Plugin Migration, this commit brings in the Northbound migration.
Due to the nature of the Library rearchiteture, the northbound APIs should not assume any schema.
But unfortunately, that is not the case with the existing APIs and hence we have split the APIs as V2 (older version)
and the newer V3.

This commit just migrates the V2 APIs to the newer Infra. V3 will be added soon.

Also, the GET serailization is still pending and will be addressed in subsequent commit.
But, all the IT tests are passing in this version.

Change-Id: I7c0e59f41499dadb2215fef3d597f98b2efa3c13
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
16 files changed:
commons/integrationtest/pom.xml
integrationtest/pom.xml
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/OvsdbIntegrationTestBase.java
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/northbound/OvsdbNorthboundIT.java
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/plugin/OvsdbPluginIT.java
library/src/main/java/org/opendaylight/ovsdb/lib/notation/Column.java
northbound/pom.xml
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBRow.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java [moved from northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBNorthbound.java with 78% similarity]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java [new file with mode: 0644]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java [new file with mode: 0644]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java [moved from northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBRows.java with 66% similarity]
plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConfigurationService.java
plugin/src/main/java/org/opendaylight/ovsdb/plugin/NodeDB.java
plugin/src/main/java/org/opendaylight/ovsdb/plugin/OvsVswitchdSchemaConstants.java
pom.xml

index 019ebfcb8c10162a18e8b43be93cbc68c0df8e3f..b993701755e44e6151c7881b94d9ce1ff4bb503e 100644 (file)
       <artifactId>ovsdb_plugin</artifactId>
       <version>${ovsdb.plugin.version}</version>
     </dependency>
-<!--
-    TODO : Remove this comment once the Northbound migration is complete.
-
     <dependency>
       <groupId>org.opendaylight.ovsdb</groupId>
       <artifactId>ovsdb_northbound</artifactId>
       <version>${ovsdb.northbound.version}</version>
     </dependency>
--->
     <dependency>
       <groupId>org.opendaylight.ovsdb</groupId>
       <artifactId>ovsdb_schema.Open_vSwitch</artifactId>
index 724cfff111cb1fb22583ba58e7c86fb796339c15..bb7caad105d1785126d7ac1fb7197595c0c175b0 100644 (file)
               <includes>
                 <include>**/*LibraryIT*</include>
                 <include>**/*PluginIT*</include>
+                <include>**/*NorthboundIT*</include>
               </includes>
             </configuration>
           </execution>
index 76f7647916d65f538e3ca856b54971c80e16f9fd..9a921cf56b4125926a33f07e9eea3bb4d840c65d 100644 (file)
 package org.opendaylight.ovsdb.integrationtest;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -23,10 +28,13 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import org.opendaylight.controller.sal.connection.ConnectionConstants;
+import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.ovsdb.lib.OvsdbClient;
 import org.opendaylight.ovsdb.lib.OvsdbConnection;
 import org.opendaylight.ovsdb.lib.OvsdbConnectionListener;
+import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
 
 public abstract class OvsdbIntegrationTestBase {
     protected final static String IDENTIFIER = "TEST";
@@ -49,6 +57,35 @@ public abstract class OvsdbIntegrationTestBase {
         return props;
     }
 
+    public Node getPluginTestConnection() throws IOException, InterruptedException, ExecutionException, TimeoutException {
+        Properties props = loadProperties();
+        String addressStr = props.getProperty(SERVER_IPADDRESS);
+        String portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
+        String connectionType = props.getProperty(CONNECTION_TYPE, "active");
+
+        IConnectionServiceInternal connection = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        // If the connection type is active, controller connects to the ovsdb-server
+        if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
+            if (addressStr == null) {
+                fail(usage());
+            }
+
+            Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
+            params.put(ConnectionConstants.ADDRESS, addressStr);
+            params.put(ConnectionConstants.PORT, portStr);
+            return connection.connect(IDENTIFIER, params);
+        }  else if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_PASSIVE)) {
+            // Wait for 10 seconds for the Passive connection to be initiated by the ovsdb-server.
+            Thread.sleep(10000);
+            List<Node> nodes = connection.getNodes();
+            assertNotNull(nodes);
+            assertTrue(nodes.size() > 0);
+            return nodes.get(0);
+        }
+        fail("Connection parameter ("+CONNECTION_TYPE+") must be active or passive");
+        return null;
+    }
+
     public OvsdbClient getTestConnection() throws IOException, InterruptedException, ExecutionException, TimeoutException {
         Properties props = loadProperties();
         String addressStr = props.getProperty(SERVER_IPADDRESS);
index 0f9988eed3dbcd5c531db0e2866ef04c19f2c2e6..6be61b2366dc6534f6ad4424b116ca860d05235a 100644 (file)
@@ -15,7 +15,6 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeNotNull;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.options;
@@ -38,7 +37,6 @@ import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
 import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExamParameterized;
@@ -79,7 +77,6 @@ public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
     @Inject
     private BundleContext bc;
     private Node node = null;
-    private OvsdbClient client = null;
     private IUserManager userManager;
 
     @Parameterized.Parameters(name = "ApiTest{index}:{0}")
@@ -116,10 +113,7 @@ public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
     @Test
     public void testApi() {
         System.out.println("Running " + fTestCase + "...\n");
-        /*
-         * TODO : Remove this assumeNotNull once the new library migration is completed.
-         */
-        assumeNotNull(node);
+
         Client client = Client.create();
         client.addFilter(new HTTPBasicAuthFilter(USERNAME , PASSWORD));
         String uri = BASE_URI + fPath;
@@ -151,7 +145,6 @@ public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
                 fail("Unsupported operation");
         }
         assertEquals(fExpectedStatusCode, response.getStatus());
-
     }
 
     private String expand(String content){
@@ -267,7 +260,7 @@ public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
         assertTrue(this.userManager != null);
 
         try {
-            client = getTestConnection();
+            node = getPluginTestConnection();
         } catch (Exception e) {
             fail("Exception : "+e.getMessage());
         }
@@ -297,6 +290,7 @@ public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
                 ConfigurationBundles.controllerBundles(),
                 ConfigurationBundles.controllerNorthboundBundles(),
                 ConfigurationBundles.ovsdbLibraryBundles(),
+                ConfigurationBundles.ovsdbDefaultSchemaBundles(),
                 mavenBundle("org.opendaylight.ovsdb", "ovsdb_plugin").versionAsInProject(),
                 mavenBundle("org.opendaylight.ovsdb", "ovsdb_northbound").versionAsInProject(),
                 junitBundles()
index d64112c4681f9129104b87175a7b269c234529fc..44fc0b7e5e78a5640bf6e62e7bdfcc2c35f94712 100644 (file)
@@ -21,21 +21,14 @@ import static org.ops4j.pax.exam.CoreOptions.options;
 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 
-import java.io.IOException;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Properties;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 
 import javax.inject.Inject;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.opendaylight.controller.sal.connection.ConnectionConstants;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
@@ -109,35 +102,6 @@ public class OvsdbPluginIT extends OvsdbIntegrationTestBase {
         }
     }
 
-    public Node getPluginTestConnection() throws IOException, InterruptedException, ExecutionException, TimeoutException {
-        Properties props = loadProperties();
-        String addressStr = props.getProperty(SERVER_IPADDRESS);
-        String portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
-        String connectionType = props.getProperty(CONNECTION_TYPE, "active");
-
-        IConnectionServiceInternal connection = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
-        // If the connection type is active, controller connects to the ovsdb-server
-        if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
-            if (addressStr == null) {
-                fail(usage());
-            }
-
-            Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
-            params.put(ConnectionConstants.ADDRESS, addressStr);
-            params.put(ConnectionConstants.PORT, portStr);
-            return connection.connect(IDENTIFIER, params);
-        }  else if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_PASSIVE)) {
-            // Wait for 10 seconds for the Passive connection to be initiated by the ovsdb-server.
-            Thread.sleep(10000);
-            List<Node> nodes = connection.getNodes();
-            assertNotNull(nodes);
-            assertTrue(nodes.size() > 0);
-            return nodes.get(0);
-        }
-        fail("Connection parameter ("+CONNECTION_TYPE+") must be active or passive");
-        return null;
-    }
-
     @Before
     public void areWeReady() throws InterruptedException {
         assertNotNull(bc);
index ed2edd8c18273aad1945b28090febea49aef335f..48ecc99514b9dbcf53c2cc5299c07bdf3e4e1825 100644 (file)
@@ -16,9 +16,11 @@ package org.opendaylight.ovsdb.lib.notation;
 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
 import org.opendaylight.ovsdb.lib.schema.TableSchema;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 
-public class Column<E extends TableSchema<E>, D> {
 
+public class Column<E extends TableSchema<E>, D> {
+    @JsonIgnore
     private ColumnSchema<E, D> schema;
     private D data;
 
index 8f9891ba3f533b558670f90db3bd83eccdece519..1695d346285dcdf05897d144e194df6cf6120c5c 100644 (file)
       <artifactId>ovsdb_plugin</artifactId>
       <version>1.0.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>
+    </dependency>
 
   </dependencies>
   <build>
               com.sun.jersey.spi.container.servlet,
               org.opendaylight.controller.sal.core,
               org.opendaylight.controller.sal.authorization,
+              org.opendaylight.ovsdb.plugin,
+              org.opendaylight.ovsdb.lib,
               org.opendaylight.ovsdb.lib.table,
+              org.opendaylight.ovsdb.lib.jsonrpc,
               org.opendaylight.ovsdb.lib.notation,
-              org.opendaylight.ovsdb.plugin,
+              org.opendaylight.ovsdb.lib.database,
+              org.opendaylight.ovsdb.lib.operations,
+              org.opendaylight.ovsdb.lib.message,
+              org.opendaylight.ovsdb.lib.schema,
+              org.opendaylight.ovsdb.lib.schema.typed,
               javax.ws.rs,
               javax.ws.rs.core,
               javax.xml.bind,
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
-              com.fasterxml.jackson.databind.annotation,
-              com.fasterxml.jackson.annotation,
-              !org.codehaus.enunciate.jaxrs</Import-Package>
+              !org.codehaus.enunciate.jaxrs,*</Import-Package>
             <Export-Package></Export-Package>
-            <Web-ContextPath>/ovsdb/nb/v2</Web-ContextPath>
+            <Web-ContextPath>/ovsdb/nb</Web-ContextPath>
             <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
           </instructions>
           <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBRow.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBRow.java
deleted file mode 100644 (file)
index fc2624e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2013 Red Hat, Inc.
- *
- * 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
- *
- * Authors : Madhu Venugopal, Brent Salisbury
- */
-package org.opendaylight.ovsdb.northbound;
-
-import org.opendaylight.ovsdb.lib.table.Bridge;
-import org.opendaylight.ovsdb.lib.table.Capability;
-import org.opendaylight.ovsdb.lib.table.Controller;
-import org.opendaylight.ovsdb.lib.table.IPFIX;
-import org.opendaylight.ovsdb.lib.table.Interface;
-import org.opendaylight.ovsdb.lib.table.Manager;
-import org.opendaylight.ovsdb.lib.table.Mirror;
-import org.opendaylight.ovsdb.lib.table.NetFlow;
-import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
-import org.opendaylight.ovsdb.lib.table.Port;
-import org.opendaylight.ovsdb.lib.table.Qos;
-import org.opendaylight.ovsdb.lib.table.Queue;
-import org.opendaylight.ovsdb.lib.table.SFlow;
-import org.opendaylight.ovsdb.lib.table.SSL;
-import org.opendaylight.ovsdb.lib.table.Table;
-
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-
-@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
-public class OVSDBRow {
-    String parent_uuid;
-    /*
-     * MINIMAL_CLASS Directive expects a leading "." character on the class name and is lame.
-     * Hence going with NAME directive even though it calls for SubTypes.
-     * Since we are using fixed table types for the Hydrogen release, this is acceptable.
-     * When we move towards Schema driven table definition, this is anyways not required.
-
-    @JsonTypeInfo(
-            use = JsonTypeInfo.Id.MINIMAL_CLASS,
-            include = JsonTypeInfo.As.PROPERTY,
-            property = "@class")
-    */
-
-    @JsonTypeInfo(
-            use = JsonTypeInfo.Id.NAME,
-            include = JsonTypeInfo.As.WRAPPER_OBJECT)
-    @JsonSubTypes({
-        @JsonSubTypes.Type(value=Bridge.class, name="Bridge"),
-        @JsonSubTypes.Type(value=Capability.class, name="Capbility"),
-        @JsonSubTypes.Type(value=Controller.class, name="Controller"),
-        @JsonSubTypes.Type(value=Interface.class, name="Interface"),
-        @JsonSubTypes.Type(value=Manager.class, name="Manager"),
-        @JsonSubTypes.Type(value=Mirror.class, name="Mirror"),
-        @JsonSubTypes.Type(value=NetFlow.class, name="NetFlow"),
-        @JsonSubTypes.Type(value=Open_vSwitch.class, name="Open_vSwitch"),
-        @JsonSubTypes.Type(value=Port.class, name="Port"),
-        @JsonSubTypes.Type(value=Qos.class, name="QoS"),
-        @JsonSubTypes.Type(value=Queue.class, name="Queue"),
-        @JsonSubTypes.Type(value=SFlow.class, name="sFlow"),
-        @JsonSubTypes.Type(value=SSL.class, name="SSL"),
-        @JsonSubTypes.Type(value=IPFIX.class, name="IPFIX")
-        })
-    Table row;
-
-    public OVSDBRow() {
-    }
-
-    public OVSDBRow(String parent_uuid, Table row) {
-        this.parent_uuid = parent_uuid;
-        this.row = row;
-    }
-
-    public String getParent_uuid() {
-        return parent_uuid;
-    }
-    public void setParent_uuid(String parent_uuid) {
-        this.parent_uuid = parent_uuid;
-    }
-    public Table getRow() {
-        return row;
-    }
-    public void setRow(Table row) {
-        this.row = row;
-    }
-}
similarity index 78%
rename from northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBNorthbound.java
rename to northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java
index 1a808eac13f5e3cbcb46df404f7d4a6238492b50..97d6076e845f9a8cb18f825e00133423315dae6c 100644 (file)
@@ -9,8 +9,9 @@
  */
 package org.opendaylight.ovsdb.northbound;
 
-import java.util.List;
+import java.io.IOException;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -38,15 +39,20 @@ import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.notation.Row;
 import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.table.Table;
-import org.opendaylight.ovsdb.lib.table.Tables;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.plugin.Connection;
+import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
+import org.opendaylight.ovsdb.plugin.OvsVswitchdSchemaConstants;
 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.fasterxml.jackson.databind.JsonNode;
+
 /**
 * OVSDB Northbound REST API.<br>
 * This class provides REST APIs to Create, Read, Update and Delete OVSDB Row in any of the ovsdb table
@@ -63,9 +69,9 @@ import org.slf4j.LoggerFactory;
 * HTTPS Authentication is disabled by default.
 */
 
-@Path("/")
-public class OVSDBNorthbound {
-    protected static final Logger logger = LoggerFactory.getLogger(OVSDBNorthbound.class);
+@Path("/v2/")
+public class OvsdbNorthboundV2 {
+    protected static final Logger logger = LoggerFactory.getLogger(OvsdbNorthboundV2.class);
 
     @Context
     private UriInfo _uriInfo;
@@ -94,24 +100,13 @@ public class OVSDBNorthbound {
                 + " : Table Name in URL does not match the row name in request body");
     }
 
-    private String getOVSTableName(String tableName) {
-        List<Table> tables = Tables.getTables();
-        for (Table table : tables) {
-            if (table.getTableName().getName().equalsIgnoreCase(tableName)) {
-                return table.getTableName().getName();
-            }
-        }
-        // TODO Auto-generated method stub
-        return null;
-    }
-
     /**
-     * Create a Row
+     * Create a Row for Open_vSwitch schema
      *
      * @param nodeType type of node e.g OVS
      * @param nodeId ID of the node
      * @param tableName name of the OVSDB table
-     * @param row the {@link OVSDBRow} Row that is being inserted
+     * @param row the {@link OvsdbRow} Row that is being inserted
      *
      * @return Response as dictated by the HTTP Response Status code
      *
@@ -311,6 +306,9 @@ public class OVSDBNorthbound {
      *   }
      * }
      * </pre>
+     * @throws IOException
+     * @throws ExecutionException
+     * @throws InterruptedException
      */
 
     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows")
@@ -320,41 +318,40 @@ public class OVSDBNorthbound {
         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
     @Consumes({ MediaType.APPLICATION_JSON})
     public Response addRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                           @PathParam("tableName") String tableName, @TypeHint(OVSDBRow.class) OVSDBRow row) {
+                           @PathParam("tableName") String tableName, JsonNode rowJson) throws IOException, InterruptedException, ExecutionException {
 
         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
             throw new UnauthorizedException("User is not authorized to perform this operation");
         }
 
-        String ovsTableName = getOVSTableName(tableName);
-        if (ovsTableName == null) {
-            Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
-            return NorthboundUtils.getResponse(status);
-        }
-
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
                                                                                             this);
         if (ovsdbTable == null) {
             throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
         }
 
-        if (row != null && row.getRow() != null) {
-            handleNameMismatch(tableName, row.getRow().getTableName().getName());
-            Node node = Node.fromString(nodeType, nodeId);
-            StatusWithUuid statusWithUUID = ovsdbTable.insertRow(node, ovsTableName, row.getParent_uuid(), row.getRow());
-
-            if (statusWithUUID.isSuccess()) {
-                UUID uuid = statusWithUUID.getUuid();
-                return Response.status(Response.Status.CREATED)
-                        .header("Location", String.format("%s/%s", _uriInfo.getAbsolutePath().toString(),
-                                                                    uuid.toString()))
-                        .entity(uuid.toString())
-                        .build();
-            } else {
-                return NorthboundUtils.getResponse(statusWithUUID);
-            }
+        Node node = Node.fromString(nodeType, nodeId);
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        Connection connection = connectionService.getConnection(node);
+        OvsdbClient client = connection.getClient();
+        OvsdbRow localRow = OvsdbRow.fromJsonNode(client, OvsVswitchdSchemaConstants.DATABASE_NAME, rowJson);
+        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
+
+        if (localRow == null) {
+            return Response.status(Response.Status.BAD_REQUEST).build();
+        }
+
+        StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, bckCompatibleTableName, localRow.getParentUuid(), localRow.getRow());
+
+        if (statusWithUuid.isSuccess()) {
+            UUID uuid = statusWithUuid.getUuid();
+            return Response.status(Response.Status.CREATED)
+                    .header("Location", String.format("%s/%s", _uriInfo.getAbsolutePath().toString(),
+                                                                uuid.toString()))
+                    .entity(uuid.toString())
+                    .build();
         }
-        return Response.status(Response.Status.BAD_REQUEST).build();
+        return NorthboundUtils.getResponse(statusWithUuid);
     }
 
     /**
@@ -409,17 +406,14 @@ public class OVSDBNorthbound {
         @ResponseCode(code = 400, condition = "Invalid data passed"),
         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
     @Consumes({ MediaType.APPLICATION_JSON})
-    @TypeHint(OVSDBRow.class)
-    public OVSDBRow getRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
+    @TypeHint(Row.class)
+    public Row getRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
                            @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid) {
 
         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
             throw new UnauthorizedException("User is not authorized to perform this operation");
         }
 
-        String ovsTableName = getOVSTableName(tableName);
-        if (ovsTableName == null) return null;
-
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
                                                                                             this);
         if (ovsdbTable == null) {
@@ -427,13 +421,18 @@ public class OVSDBNorthbound {
         }
 
         Node node = Node.fromString(nodeType, nodeId);
-        Table<?> row = null;
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        Connection connection = connectionService.getConnection(node);
+        OvsdbClient client = connection.getClient();
+        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
+
+        Row row = null;
         try {
-            row = ovsdbTable.getRow(node, ovsTableName, rowUuid);
+            row = ovsdbTable.getRow(node, bckCompatibleTableName, rowUuid);
         } catch (Exception e) {
             throw new BadRequestException(e.getMessage());
         }
-        return new OVSDBRow(null, row);
+        return row;
     }
 
     /**
@@ -490,16 +489,13 @@ public class OVSDBNorthbound {
         @ResponseCode(code = 400, condition = "Invalid data passed"),
         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
     @Consumes({ MediaType.APPLICATION_JSON})
-    @TypeHint(OVSDBRows.class)
-    public OVSDBRows getAllRows(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
+    @TypeHint(OvsdbRows.class)
+    public OvsdbRows getAllRows(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
                                @PathParam("tableName") String tableName) {
         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
             throw new UnauthorizedException("User is not authorized to perform this operation");
         }
 
-        String ovsTableName = getOVSTableName(tableName);
-        if (ovsTableName == null) return null;
-
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
                                                                                             this);
         if (ovsdbTable == null) {
@@ -507,15 +503,20 @@ public class OVSDBNorthbound {
         }
 
         Node node = Node.fromString(nodeType, nodeId);
-        Map<String, Table<?>> rows = null;
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        Connection connection = connectionService.getConnection(node);
+        OvsdbClient client = connection.getClient();
+        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
+        Map<String, Row> rows = null;
         try {
-            rows = ovsdbTable.getRows(node, ovsTableName);
+            rows = ovsdbTable.getRows(node, bckCompatibleTableName);
         } catch (Exception e) {
             throw new BadRequestException(e.getMessage());
         }
-        return new OVSDBRows(rows);
+        return new OvsdbRows(rows);
     }
 
+    /*
     /**
      * Update a Row
      *
@@ -563,31 +564,31 @@ public class OVSDBNorthbound {
     @Consumes({ MediaType.APPLICATION_JSON})
     public Response updateRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
                            @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid,
-                           @TypeHint(OVSDBRow.class) OVSDBRow row) {
+                           JsonNode rowJson) {
 
         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
             throw new UnauthorizedException("User is not authorized to perform this operation");
         }
 
-        String ovsTableName = getOVSTableName(tableName);
-        if (ovsTableName == null) {
-            Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
-            return NorthboundUtils.getResponse(status);
-        }
-
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
                                                                                             this);
         if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
+            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
         }
 
-        if (row != null && row.getRow() != null) {
-            handleNameMismatch(tableName, row.getRow().getTableName().getName());
-            Node node = Node.fromString(nodeType, nodeId);
-            Status status = ovsdbTable.updateRow(node, ovsTableName, row.getParent_uuid(), rowUuid, row.getRow());
-            return NorthboundUtils.getResponse(status);
+        Node node = Node.fromString(nodeType, nodeId);
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        Connection connection = connectionService.getConnection(node);
+        OvsdbClient client = connection.getClient();
+        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
+        OvsdbRow localRow = OvsdbRow.fromJsonNode(client, OvsVswitchdSchemaConstants.DATABASE_NAME, rowJson);
+
+        if (localRow == null) {
+            return Response.status(Response.Status.BAD_REQUEST).build();
         }
-        return Response.status(Response.Status.BAD_REQUEST).build();
+
+        Status status = ovsdbTable.updateRow(node, bckCompatibleTableName, localRow.getParentUuid(), rowUuid, localRow.getRow());
+        return NorthboundUtils.getResponse(status);
     }
 
     /**
@@ -635,6 +636,7 @@ public class OVSDBNorthbound {
      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/6f4c602c-026f-4390-beea-d50d6d448100
      * </pre>
      */
+
     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{uuid}")
     @DELETE
     @StatusCodes({ @ResponseCode(code = 204, condition = "User Deleted Successfully"),
@@ -648,21 +650,31 @@ public class OVSDBNorthbound {
             throw new UnauthorizedException("User is not authorized to perform this operation");
         }
 
-        String ovsTableName = getOVSTableName(tableName);
-        if (ovsTableName == null) {
-            Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
-            return NorthboundUtils.getResponse(status);
-        }
-
-        OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
+                this);
         if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
+            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
         }
+
         Node node = Node.fromString(nodeType, nodeId);
-        Status status = ovsdbTable.deleteRow(node, ovsTableName, uuid);
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        Connection connection = connectionService.getConnection(node);
+        OvsdbClient client = connection.getClient();
+        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
+
+        Status status = ovsdbTable.deleteRow(node, bckCompatibleTableName, uuid);
         if (status.isSuccess()) {
             return Response.noContent().build();
         }
         return NorthboundUtils.getResponse(status);
     }
+
+    private String getBackwardCompatibleTableName(OvsdbClient client, String databaseName, String tableName) {
+        DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
+        if (dbSchema == null || tableName == null) return tableName;
+        for (String dbTableName : dbSchema.getTables()) {
+            if (dbTableName.equalsIgnoreCase(tableName)) return dbTableName;
+        }
+        return tableName;
+    }
 }
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java
new file mode 100644 (file)
index 0000000..4a9e70f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc. and others
+ *
+ * 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
+ *
+ * Authors : Madhu Venugopal
+ */
+package org.opendaylight.ovsdb.northbound;
+
+import javax.ws.rs.Path;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+* OVSDB Northbound V3 REST API.<br>
+*/
+
+@Path("/v3/")
+public class OvsdbNorthboundV3 {
+    protected static final Logger logger = LoggerFactory.getLogger(OvsdbNorthboundV3.class);
+}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java
new file mode 100644 (file)
index 0000000..91562e7
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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
+ *
+ * Authors : Madhu Venugopal, Brent Salisbury
+ */
+package org.opendaylight.ovsdb.northbound;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.concurrent.ExecutionException;
+
+import javax.xml.bind.annotation.XmlElement;
+
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class OvsdbRow {
+    private static final String PARENTUUID = "parent_uuid";
+    private static final String ROW = "row";
+
+    @XmlElement(name=PARENTUUID)
+    String parentUuid;
+
+    String tableName;
+
+    @XmlElement(name=ROW)
+    Row<GenericTableSchema> row;
+
+    public OvsdbRow() {
+    }
+
+    public OvsdbRow(String parentUuid, String tableName, Row<GenericTableSchema> row) {
+        this.parentUuid = parentUuid;
+        this.tableName = tableName;
+        this.row = row;
+    }
+
+    public static OvsdbRow fromJsonNode(OvsdbClient client, String dbName, JsonNode json) {
+        JsonNode parentUuidNode = json.get(PARENTUUID);
+        String parentUuid = null;
+        if (parentUuidNode != null) parentUuid = parentUuidNode.asText();
+
+        JsonNode rowNode = json.get(ROW);
+        if (rowNode == null) return null;
+        for(Iterator<String> fieldNames = rowNode.fieldNames(); fieldNames.hasNext();) {
+            String tableName = fieldNames.next();
+            Row<GenericTableSchema> row = null;
+            try {
+                row = getRow(client, dbName, tableName, rowNode.get(tableName));
+            } catch (InterruptedException | ExecutionException | IOException e) {
+                e.printStackTrace();
+                return null;
+            }
+            return new OvsdbRow(parentUuid, tableName, row);
+        }
+        return null;
+    }
+
+    public static Row<GenericTableSchema> getRow(OvsdbClient client, String dbName, String tableName, JsonNode rowJson) throws InterruptedException, ExecutionException, JsonParseException, IOException {
+        DatabaseSchema dbSchema = client.getSchema(dbName).get();
+        GenericTableSchema schema = dbSchema.table(tableName, GenericTableSchema.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        objectMapper.setSerializationInclusion(Include.NON_NULL);
+        Row<GenericTableSchema> row = schema.createRow((ObjectNode)rowJson);
+        return row;
+    }
+
+    public String getParentUuid() {
+        return parentUuid;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public Row<GenericTableSchema> getRow() {
+        return row;
+    }
+
+    @Override
+    public String toString() {
+        return "OVSDBRow [parentUuid=" + parentUuid + ", tableName="
+                + tableName + ", row=" + row + "]";
+    }
+}
similarity index 66%
rename from northbound/src/main/java/org/opendaylight/ovsdb/northbound/OVSDBRows.java
rename to northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java
index 6d15b82c2469dbaf6225a4fe7fb0c44d60e69000..8862a7ca6ed7f879548f2f73bc942e02bec087ea 100644 (file)
@@ -11,21 +11,21 @@ package org.opendaylight.ovsdb.northbound;
 
 import java.util.Map;
 
-import org.opendaylight.ovsdb.lib.table.Table;
+import org.opendaylight.ovsdb.lib.notation.Row;
 
-public class OVSDBRows {
-    Map<String, Table<?>> rows;
+public class OvsdbRows {
+    Map<String, Row> rows;
 
-    public OVSDBRows(Map<String, Table<?>> rows) {
+    public OvsdbRows(Map<String, Row> rows) {
         super();
         this.rows = rows;
     }
 
-    public Map<String, Table<?>> getRows() {
+    public Map<String, Row> getRows() {
         return rows;
     }
 
-    public void setRows(Map<String, Table<?>> rows) {
+    public void setRows(Map<String, Row> rows) {
         this.rows = rows;
     }
 }
index 1b9e6bfd2ced4d25ec03b9a720c7bf17ae7a7e01..fc6d79337d38c034f4233c04365c1798c3617060 100644 (file)
@@ -215,7 +215,9 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService,
      * plugin layer.
      */
     public String getSpecialCaseParentUUID(Node node, String databaseName, String childTableName) {
-        if (databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME) && childTableName.equals("Bridge")) {
+        if (!databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME)) return null;
+        String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(childTableName);
+        if (parentColumn != null && parentColumn[0].equals(OvsVswitchdSchemaConstants.DATABASE_NAME)) {
             Connection connection = connectionService.getConnection(node);
             OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null);
             ConcurrentMap<String, Row> row = this.getRows(node, openVSwitch.getSchema().getName());
@@ -313,10 +315,10 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService,
                                     String parentTable, String parentColumn, String uuid, TransactionBuilder transactionBuilder) {
         DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
         TableSchema<GenericTableSchema> childTableSchema = dbSchema.table(childTable, GenericTableSchema.class);
-        TableSchema<GenericTableSchema> parentTableSchema = dbSchema.table(parentTable, GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, UUID> parentColumnSchema = parentTableSchema.column(parentColumn, UUID.class);
 
         if (parentColumn != null) {
+            TableSchema<GenericTableSchema> parentTableSchema = dbSchema.table(parentTable, GenericTableSchema.class);
+            ColumnSchema<GenericTableSchema, UUID> parentColumnSchema = parentTableSchema.column(parentColumn, UUID.class);
             transactionBuilder
                 .add(op.mutate(parentTableSchema)
                         .addMutation(parentColumnSchema, Mutator.DELETE, new UUID(uuid))
index d6118c0d46e5ee1240315262b54c2da84d0bf57d..5948a1a22edfd41bcb702d123ee975911029f473 100644 (file)
@@ -26,7 +26,7 @@ public class NodeDB {
         ConcurrentMap<String, ConcurrentMap<String,Row>> retMap = Maps.newConcurrentMap();
         for (String tableName : tdbMap.keySet()) {
             TableDB tdb = tdbMap.get(tableName);
-            retMap.put(tableName, tdb.getTableCache(tableName));
+            if (tdb != null && tdb.getTableCache(tableName) != null) retMap.put(tableName, tdb.getTableCache(tableName));
         }
         return retMap;
     }
index 03be637b75396ac8e1bd3976d17169555b7a55c2..0383bc822f97dedb4570cd9a1763197230ada911 100644 (file)
@@ -24,9 +24,10 @@ public class OvsVswitchdSchemaConstants {
         addParentColumnToMutate("Interface", "Port", "interfaces");
         addParentColumnToMutate("SSL", "Open_vSwitch", "ssl");
         addParentColumnToMutate("IPFIX", "Bridge", "ipfix");
-        addParentColumnToMutate("SFlow", "Bridge", "sflow");
-        addParentColumnToMutate("Qos", "Port", "qos");
-        addParentColumnToMutate("Netflow", "Bridge", "netflow");
+        addParentColumnToMutate("sFlow", "Bridge", "sflow");
+        addParentColumnToMutate("Flow_Table", "Bridge", "flow_tables");
+        addParentColumnToMutate("QoS", "Port", "qos");
+        addParentColumnToMutate("NetFlow", "Bridge", "netflow");
         addParentColumnToMutate("Mirror", "Bridge", "mirrors");
         addParentColumnToMutate("Manager", "Open_vSwitch", "manager_options");
         addParentColumnToMutate("Controller", "Bridge", "controller");
diff --git a/pom.xml b/pom.xml
index 11b671ebaa791e949e581c03f1a8c4f12a55db25..fe546dda79b7974b864fc2900283fc1d17fa5fe0 100755 (executable)
--- a/pom.xml
+++ b/pom.xml
@@ -22,9 +22,9 @@
     <module>plugin</module>
     <module>commons/parent</module>
     <module>commons/integrationtest</module>
+    <module>northbound</module>
     <!--
     TODO : remove this comment & let these modules build once the Library migraion is complete.
-    <module>northbound</module>
     <module>neutron</module>
     <module>distribution/opendaylight</module>
      -->