Merge "transcriber: qos policy rule"
authorIsaku Yamahata <isaku.yamahata@gmail.com>
Fri, 17 Mar 2017 04:58:40 +0000 (04:58 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 17 Mar 2017 04:58:40 +0000 (04:58 +0000)
integration/test/src/test/java/org/opendaylight/neutron/e2etest/ITNeutronE2E.java
integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronProjectIdTests.java [new file with mode: 0644]
integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronRevisionNumberTests.java [new file with mode: 0644]
model/src/main/yang/neutron-attrs.yang
neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronObject.java
neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronObject.java
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java
transcriber/src/main/java/org/opendaylight/neutron/transcriber/AbstractNeutronInterface.java

index 35870ac79c5f1120a7f0722ee959f47c3cde6fda..910ea8218ba8fcd7f351f6ba81bcc9e463cf32da 100644 (file)
@@ -116,7 +116,8 @@ public class ITNeutronE2E {
         NeutronSFCPortChainTests.runTests(base);
         NeutronSFCFlowClassifierTests.runTests(base);
         NeutronTrunkTests.runTests(base);
-
+        NeutronRevisionNumberTests.runTests(base);
+        NeutronProjectIdTests.runTests(base);
         // tests related to bugs
         NeutronBug3812Tests.runTests(base);
         TempestPortsIpV6TestJSON.runTests(base);
diff --git a/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronProjectIdTests.java b/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronProjectIdTests.java
new file mode 100644 (file)
index 0000000..1aac649
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Intel Corp.
+ *
+ * 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.neutron.e2etest;
+
+public class NeutronProjectIdTests {
+    String base;
+
+    public NeutronProjectIdTests(String base) {
+        this.base = base;
+    }
+
+    public void collection_get_test() {
+        String url = base + "/fw/firewalls";
+        ITNeutronE2E.test_fetch(url, "RevisionID Collection GET failed");
+    }
+
+    public String singleton_create_test() {
+        String url = base + "/fw/firewalls";
+        String content = " { \"firewall\": { \"admin_state_up\": true," + "\"description\": \"\","
+                + "\"firewall_policy_id\": \"c69933c1-b472-44f9-8226-30dc4ffd454c\","
+                + "\"id\": \"4b0ef8f4-82c7-44d4-a4fb-6177f9a21977\","
+                + "\"name\": \"\","
+                + "\"project_id\": \"45977fa2dbd7482098dd68d0d8970117\" } }";
+        ITNeutronE2E.test_create(url, content, "RevisionID Singleton Post Failed");
+        return content;
+    }
+
+    public void singleton_get_with_one_query_item_test(String createJsonString) {
+        String url = base + "/fw/firewalls";
+        ITNeutronE2E.test_fetch_with_one_query_item(url, createJsonString, "firewalls");
+    }
+
+    public void modify_test() {
+        String url = base + "/fw/firewalls/4b0ef8f4-82c7-44d4-a4fb-6177f9a21977";
+        String content = " { \"firewall\": { \"admin_state_up\": false," + "\"description\": \"\","
+                + "\"firewall_policy_id\": \"c69933c1-b472-44f9-8226-30dc4ffd454c\","
+                + "\"id\": \"4b0ef8f4-82c7-44d4-a4fb-6177f9a21977\","
+                + "\"name\": \"\","
+                + "\"project_id\": \"45977fa2dbd7482098dd68d0d8970117\" } }";
+        ITNeutronE2E.test_modify(url, content, "RevisionID Singleton Post Failed");
+    }
+
+    public void element_get_test() {
+        String url = base + "/fw/firewalls/4b0ef8f4-82c7-44d4-a4fb-6177f9a21977";
+        ITNeutronE2E.test_fetch(url, true, "RevisionID Element Get Failed");
+    }
+
+    public void delete_test() {
+        String url = base + "/fw/firewalls/4b0ef8f4-82c7-44d4-a4fb-6177f9a21977";
+        ITNeutronE2E.test_delete(url, "RevisionID Delete Failed");
+    }
+
+    public String singleton_create_test_with_tenant_id() {
+        String url = base + "/fw/firewalls";
+        String content = " { \"firewall\": { \"admin_state_up\": true," + "\"description\": \"\","
+                + "\"firewall_policy_id\": \"c69933c1-b472-44f9-8226-30dc4ffd454c\","
+                + "\"id\": \"5b0ef8f4-82c7-44d4-a4fb-6177f9a21977\","
+                + "\"name\": \"\","
+                + "\"tenant_id\": \"55988fb3dbd7482098dd68d0d8970228\","
+                + "\"project_id\": \"45977fa2dbd7482098dd68d0d8970117\" } }";
+        ITNeutronE2E.test_create(url, content, "RevisionID Singleton Post Failed");
+        return content;
+    }
+
+    public void delete_test_with_tenant_id() {
+        String url = base + "/fw/firewalls/5b0ef8f4-82c7-44d4-a4fb-6177f9a21977";
+        ITNeutronE2E.test_delete(url, "RevisionID Delete Failed");
+    }
+
+    public static void runTests(String base) {
+        NeutronProjectIdTests tester = new NeutronProjectIdTests(base);
+        String createJsonString = tester.singleton_create_test();
+        tester.singleton_get_with_one_query_item_test(createJsonString);
+        tester.element_get_test();
+        tester.collection_get_test();
+        tester.modify_test();
+        tester.delete_test();
+        tester.singleton_create_test_with_tenant_id();
+        tester.delete_test_with_tenant_id();
+    }
+}
diff --git a/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronRevisionNumberTests.java b/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronRevisionNumberTests.java
new file mode 100644 (file)
index 0000000..e4b40fc
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 Intel, Corp.
+ *
+ * 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.neutron.e2etest;
+
+public class NeutronRevisionNumberTests {
+
+    String base;
+
+    public NeutronRevisionNumberTests(String base) {
+        this.base = base;
+    }
+
+    public void subnet_create_test() {
+        String url = base + "/subnets";
+        String content = " { \"subnets\": [ " + " { \"allocation_pools\": [ "
+                + " { \"end\": \"192.168.199.254\", \"start\": \"192.168.199.2\" } ], "
+                + " \"cidr\": \"192.168.199.0/24\", " + " \"dns_nameservers\": [\"8.8.8.8\"], "
+                + " \"enable_dhcp\": true, " + " \"gateway_ip\": \"192.168.199.1\", "
+                + " \"host_routes\":[ { \"destination\":\"0.0.0.0/0\", " + " \"nexthop\":\"192.168.199.3\" }, "
+                + " { \"destination\":\"192.168.0.0/24\", " + " \"nexthop\":\"192.168.199.4\" } ], "
+                + " \"id\": \"1468a7a7-290d-4127-aedd-6c9449775a24\", " + " \"ip_version\": 4, " + " \"name\": \"\", "
+                + " \"network_id\": \"af374017-c9ae-4a1d-b799-ab73111476e2\", "
+                + " \"tenant_id\": \"4fd44f30292945e481c7b8a0c8908869\" }, { "
+                + " \"allocation_pools\": [ { \"end\": \"10.56.7.254\", \"start\": \"10.56.4.2\" } ], "
+                + " \"cidr\": \"10.56.4.0/22\", " + " \"dns_nameservers\": [\"8.8.8.8\", \"8.8.8.4\"], "
+                + " \"enable_dhcp\": true, " + " \"gateway_ip\": \"10.56.4.1\", "
+                + " \"host_routes\":[ { \"destination\":\"0.0.0.0/0\", " + " \"nexthop\":\"10.56.4.3\" }, "
+                + " { \"destination\":\"192.168.0.0/24\", " + " \"nexthop\":\"10.56.4.4\" } ], "
+                + " \"id\": \"c0e7435c-1512-45fb-aa9e-9a7c5932fb30\", " + " \"ip_version\": 4, " + " \"name\": \"\", "
+                + " \"network_id\": \"af374017-c9ae-4a1d-b799-ab73111476e2\", "
+                + " \"tenant_id\": \"4fd44f30292945e481c7b8a0c8908869\" } ] }";
+        ITNeutronE2E.test_create(url, content, "Revision Number Post Failed");
+    }
+
+    public void subnet_update_test() {
+        String url = base + "/subnets/c0e7435c-1512-45fb-aa9e-9a7c5932fb30";
+        String content = " { \"subnet\": { " + " \"name\": \"my_subnet\", " + " \"enable_dhcp\": true, "
+                + " \"network_id\": \"af374017-c9ae-4a1d-b799-ab73111476e2\", "
+                + " \"tenant_id\": \"4fd44f30292945e481c7b8a0c8908869\", "
+                + " \"dns_nameservers\": [\"8.8.8.8\", \"8.8.8.4\"], "
+                + " \"allocation_pools\": [ { \"start\": \"10.0.0.2\", \"end\": \"10.0.0.254\" } ], "
+                + " \"host_routes\": [{ \"destination\":\"192.168.0.0/24\", " + " \"nexthop\":\"10.0.0.11\" } ], "
+                + " \"ip_version\": 4, " + " \"gateway_ip\": \"10.0.0.1\", " + " \"cidr\": \"10.0.0.0/24\", "
+                + "\"revision_number\": 3, "
+                + " \"id\": \"c0e7435c-1512-45fb-aa9e-9a7c5932fb30\" } }";
+        ITNeutronE2E.test_modify(url, content, "Revision Number Put Failed");
+    }
+
+    public void subnet_update_test_with_old_value() {
+        String url = base + "/subnets/c0e7435c-1512-45fb-aa9e-9a7c5932fb30";
+        String content = " { \"subnet\": { " + " \"name\": \"my_subnet\", " + " \"enable_dhcp\": true, "
+                + " \"network_id\": \"af374017-c9ae-4a1d-b799-ab73111476e2\", "
+                + " \"tenant_id\": \"4fd44f30292945e481c7b8a0c8908869\", "
+                + " \"dns_nameservers\": [\"8.8.8.8\", \"8.8.8.4\"], "
+                + " \"allocation_pools\": [ { \"start\": \"10.0.0.2\", \"end\": \"10.0.0.254\" } ], "
+                + " \"host_routes\": [{ \"destination\":\"192.168.0.0/24\", " + " \"nexthop\":\"10.0.0.11\" } ], "
+                + " \"ip_version\": 4, " + " \"gateway_ip\": \"10.0.0.1\", " + " \"cidr\": \"10.0.0.0/24\", "
+                + "\"revision_number\": 2, "
+                + " \"id\": \"c0e7435c-1512-45fb-aa9e-9a7c5932fb30\" } }";
+        ITNeutronE2E.test_modify(url, content, "Revision Number Put Failed");
+    }
+
+    public void subnet_update_test_with_no_value() {
+        String url = base + "/subnets/c0e7435c-1512-45fb-aa9e-9a7c5932fb30";
+        String content = " { \"subnet\": { " + " \"name\": \"my_subnet\", " + " \"enable_dhcp\": true, "
+                + " \"network_id\": \"af374017-c9ae-4a1d-b799-ab73111476e2\", "
+                + " \"tenant_id\": \"4fd44f30292945e481c7b8a0c8908869\", "
+                + " \"dns_nameservers\": [\"8.8.8.8\", \"8.8.8.4\"], "
+                + " \"allocation_pools\": [ { \"start\": \"10.0.0.2\", \"end\": \"10.0.0.254\" } ], "
+                + " \"host_routes\": [{ \"destination\":\"192.168.0.0/24\", " + " \"nexthop\":\"10.0.0.11\" } ], "
+                + " \"ip_version\": 4, " + " \"gateway_ip\": \"10.0.0.1\", " + " \"cidr\": \"10.0.0.0/24\", "
+                + " \"id\": \"c0e7435c-1512-45fb-aa9e-9a7c5932fb30\" } }";
+        ITNeutronE2E.test_modify(url, content, "Revision Number Put Failed");
+    }
+
+    public void subnet_element_get_test() {
+        String url = base + "/subnets/c0e7435c-1512-45fb-aa9e-9a7c5932fb30";
+        ITNeutronE2E.test_fetch(url, true, "Revision Number Element Get Failed");
+    }
+
+    public void subnet_delete_test() {
+        String url = base + "/subnets/c0e7435c-1512-45fb-aa9e-9a7c5932fb30";
+        ITNeutronE2E.test_delete(url, "Revision Number Element Delete Failed");
+    }
+
+    public static void runTests(String base) {
+        NeutronRevisionNumberTests tester = new NeutronRevisionNumberTests(base);
+        tester.subnet_create_test();
+        tester.subnet_element_get_test();
+        tester.subnet_update_test();
+        tester.subnet_update_test_with_old_value();
+        tester.subnet_update_test_with_no_value();
+        tester.subnet_delete_test();
+    }
+}
index 1d1f41c8318b0c26b44af6a7a3b1d0b8cd1daa35..a2d2bf669a631dab26309b38cd93dd3a2b706f7d 100644 (file)
@@ -40,9 +40,24 @@ module neutron-attrs {
         }
 
         leaf tenant-id {
+            status deprecated;
             type yang:uuid;
             description "The UUID of the tenant that will own the object.";
         }
+
+        leaf project-id {
+            type string {
+                length "0..255";
+            }
+            description "The id of the project.";
+        }
+
+        leaf revision-number {
+            type int64;
+            description "The revision number of the resource. Used as monotonic
+                         counter that is updated whenever an object is updated
+                         on neutron server";
+        }
     }
 
     grouping admin-attributes {
index ad2913c73b38657a0232d6972f02ecc31a4aa6e3..9d9bbcf5786d73ed286fce2086d7bf02b935a085 100644 (file)
@@ -27,6 +27,14 @@ public interface INeutronObject<T extends INeutronObject> {
 
     void setTenantID(Uuid tenantID);
 
+    String getProjectID();
+
+    void setProjectID(String projectID);
+
+    Long getRevisionNumber();
+
+    void setRevisionNumber(Long revisionNumber);
+
     void initDefaults();
 
     T extractFields(List<String> fields);
index f6858669e71649645daaa1a4de1622bb4d1cf892..61e9b030b1a19683606afb41c84032b98ff01663 100644 (file)
@@ -27,6 +27,12 @@ public abstract class NeutronObject<T extends NeutronObject> extends NeutronID
     @XmlElement(name = "tenant_id")
     String tenantID;
 
+    @XmlElement(name = "project_id")
+    String projectID;
+
+    @XmlElement(name = "revision_number")
+    Long revisionNumber;
+
     public NeutronObject() {
         super();
     }
@@ -57,8 +63,34 @@ public abstract class NeutronObject<T extends NeutronObject> extends NeutronID
         return "NeutronObject [id=" + uuid + ", tenantID=" + tenantID + "]";
     }
 
+    @Override
+    public void setProjectID(String projectID) {
+        this.projectID = projectID;
+    }
+
+    @Override
+    public String getProjectID() {
+        return this.projectID;
+    }
+
+    @Override
+    public Long getRevisionNumber() {
+        return revisionNumber;
+    }
+
+    @Override
+    public void setRevisionNumber(Long revisionNumber) {
+        this.revisionNumber = revisionNumber;
+    }
+
     @Override
     public void initDefaults() {
+        if (projectID != null && tenantID == null) {
+            tenantID = projectID;
+        }
+        if (projectID == null && tenantID != null) {
+            projectID = tenantID;
+        }
     }
 
     @Override
@@ -71,5 +103,11 @@ public abstract class NeutronObject<T extends NeutronObject> extends NeutronID
         if (field.equals("tenant_id")) {
             ans.setTenantID(this.getTenantID());
         }
+        if (field.equals("project_id")) {
+            ans.setProjectID(this.getProjectID());
+        }
+        if (field.equals("revision_number")) {
+            ans.setRevisionNumber(this.getRevisionNumber());
+        }
     }
 }
index cad9f32bff528145225684678e54d441346c59f3..76c7967014ef83376c7ea74894bed3ab10167405 100644 (file)
@@ -121,6 +121,21 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     protected void updateDelta(String uuid, T delta, T original) {
     }
 
+    private boolean checkRevisionNumber(T original, T delta) {
+        // If new update is null ignore the original revision number
+        if (delta.getRevisionNumber() == null) {
+            return false;
+        }
+        // If what is stored is null no need for comparison
+        if (original.getRevisionNumber() == null) {
+            return false;
+        }
+        if (original.getRevisionNumber() > delta.getRevisionNumber()) {
+            return true;
+        }
+        return false;
+    }
+
     protected Response update(String uuid, final R input) {
         I neutronCRUD = getNeutronCRUD();
         if (!input.isSingleton()) {
@@ -131,8 +146,10 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
         if (original == null) {
             throw new ResourceNotFoundException(uuidNoExist());
         }
+        if (checkRevisionNumber(original, delta)) {
+            return Response.status(HttpURLConnection.HTTP_OK).build();
+        }
         updateDelta(uuid, delta, original);
-
         /*
          * update the object and return it
          */
index 0244a16e5a79e8be462ba0e1af3bb0decf6cd35f..58e7456d9025441c8b14662b7bbb5f652626d964 100644 (file)
@@ -78,9 +78,11 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
     private final Class<? extends Builder<T>> builderClass;
     private final Method setUuid;
     private final Method setTenantId;
+    private final Method setProjectId;
     private final Method setName;
     private final Method setAdminStateUp;
     private final Method setStatus;
+    private final Method setRevisionNumber;
 
     AbstractNeutronInterface(Class<? extends Builder<T>> builderClass, DataBroker db) {
         this.db = Preconditions.checkNotNull(db);
@@ -101,9 +103,14 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
             setTenantId = builderClass.getDeclaredMethod("setTenantId", Uuid.class);
             if (INeutronBaseAttributes.class.isAssignableFrom(neutronObjectClass)) {
                 setName = builderClass.getDeclaredMethod("setName", String.class);
+                setProjectId = builderClass.getDeclaredMethod("setProjectId", String.class);
+                setRevisionNumber = builderClass.getDeclaredMethod("setRevisionNumber", Long.class);
             } else {
                 setName = null;
+                setProjectId = null;
+                setRevisionNumber = null;
             }
+
             if (INeutronAdminAttributes.class.isAssignableFrom(neutronObjectClass)) {
                 setAdminStateUp = builderClass.getDeclaredMethod("setAdminStateUp", Boolean.class);
                 setStatus = builderClass.getDeclaredMethod("setStatus", String.class);
@@ -140,6 +147,9 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
             if (neutronObject.getTenantID() != null && !neutronObject.getTenantID().isEmpty()) {
                 setTenantId.invoke(builder, toUuid(neutronObject.getTenantID()));
             }
+            if (neutronObject.getProjectID() != null) {
+                setProjectId.invoke(builder, neutronObject.getTenantID());
+            }
         } catch (IllegalAccessException | InvocationTargetException e) {
             throw new IllegalArgumentException(e);
         }
@@ -153,6 +163,9 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
         if (baseAttributes.getTenantId() != null) {
             answer.setTenantID(baseAttributes.getTenantId());
         }
+        if (baseAttributes.getProjectId() != null) {
+            answer.setProjectID(baseAttributes.getProjectId());
+        }
     }
 
     protected <S1 extends INeutronBaseAttributes<S1>, M extends BaseAttributes, B extends Builder<M>>
@@ -162,6 +175,9 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
             if (neutronObject.getName() != null) {
                 setName.invoke(builder, neutronObject.getName());
             }
+            if (neutronObject.getRevisionNumber() != null) {
+                setRevisionNumber.invoke(builder, neutronObject.getRevisionNumber());
+            }
         } catch (IllegalAccessException | InvocationTargetException e) {
             throw new IllegalArgumentException(e);
         }
@@ -173,6 +189,9 @@ public abstract class AbstractNeutronInterface<T extends DataObject & Identifiab
         if (baseAttributes.getName() != null) {
             answer.setName(baseAttributes.getName());
         }
+        if (baseAttributes.getRevisionNumber() != null) {
+            answer.setRevisionNumber(baseAttributes.getRevisionNumber());
+        }
     }
 
     protected <S1 extends INeutronAdminAttributes<S1>, M extends BaseAttributes & AdminAttributes, B extends Builder<M>>