Adds the "Quality of Service" to the OpenDayLight Neutron 65/37165/27
authorpramod <pramod.raghavendra.jayathirth@intel.com>
Tue, 5 Apr 2016 23:46:55 +0000 (16:46 -0700)
committerPramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com>
Thu, 21 Jul 2016 00:32:11 +0000 (00:32 +0000)
This patch enables the Quality of Service feature in the OpenDayLight
Neutron.
The implementation is done as follows
1. Defining the YANG model
2. Implementing of API
3. Testing the developed API

The QOS is achieved using either limiting the bandwidth or through
DSCP marking

Data model -
https://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html
This link has the data model changes as suggested by the OpenStack
Neutron for the QOS feature
API -
http://developer.openstack.org/api-ref-networking-v2-ext.html#qos-ext
This link has the API for the Openstack for the QOS feature

Change-Id: I7074dbb6d494b1267b66a925742e9812ef8a9304
Signed-off-by: pramod <pramod.raghavendra.jayathirth@intel.com>
12 files changed:
integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronQosPolicyTests.java [new file with mode: 0644]
model/src/main/yang/neutron-qos-ext.yang [new file with mode: 0644]
model/src/main/yang/neutron-qos.yang [new file with mode: 0644]
model/src/main/yang/neutron.yang
neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronQosPolicyCRUD.java [new file with mode: 0644]
neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronCRUDInterfaces.java
neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosBandwidthRule.java [new file with mode: 0644]
neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosDscpMarkingRule.java [new file with mode: 0644]
neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosPolicy.java [new file with mode: 0644]
neutron-spi/src/test/java/org/opendaylight/neutron/spi/NeutronQosJAXBTest.java [new file with mode: 0644]
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyNorthbound.java [new file with mode: 0644]
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyRequest.java [new file with mode: 0644]

diff --git a/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronQosPolicyTests.java b/integration/test/src/test/java/org/opendaylight/neutron/e2etest/NeutronQosPolicyTests.java
new file mode 100644 (file)
index 0000000..dcad359
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 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 NeutronQosPolicyTests {
+    String base;
+
+    public NeutronQosPolicyTests(String base) {
+        this.base = base;
+    }
+
+    public void qos_policy_collection_get_test() {
+        String url = base + "/qos/policies";
+        ITNeutronE2E.test_fetch(url, "Qos Policy collection GET failed");
+    }
+
+    public String singleton_qos_policy_create_test() {
+        String url = base + "/qos/policies";
+        String content = "{\"policy\": {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3546\"," +
+            "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a13\"," + "\"name\": \"jaxb-test\", " +
+            "\"shared\": false }}";
+        ITNeutronE2E.test_create(url, content, "Qos Policy Singleton POST Failed");
+        return content;
+    }
+
+    public void singleton_qos_policy_get_with_query_item_test(String createJsonString) {
+        String url = base + "/qos/policies";
+        ITNeutronE2E.test_fetch_with_one_query_item(url, createJsonString, "policies");
+    }
+
+    public void qos_policy_modify_test() {
+        String url = base + "/qos/policies/d6220bbb-35f3-48ab-8eae-69c60aef3546";
+        String content = "{\"policy\": {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3546\"," +
+            "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a13\"," + "\"name\": \"jaxb-test\", " +
+            "\"shared\": false," +
+            "\"bandwidth_limit_rules\": [ {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3547\"," +
+            "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a14\",\"max_kbps\": 25," +
+            "\"max_burst_kbps\": 100 } ] ," +
+            "\"dscp_marking_rules\": [ {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3547\"," +
+            "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a14\", " +
+            "\"dscp_mark\": 8 } ] }}";
+        ITNeutronE2E.test_modify(url, content, "Qos Policy Singleton Put failed");
+    }
+
+    public void qos_policy_element_get_test() {
+        String url = base + "/qos/policies/d6220bbb-35f3-48ab-8eae-69c60aef3546";
+        ITNeutronE2E.test_fetch(url, true, "Qos Policy Element Get failed");
+    }
+
+    public void qos_policy_element_get_with_query_test() {
+        String url = base + "/qos/policies/d6220bbb-35f3-48ab-8eae-69c60aef3546" +
+            "?fields=tenant_id&fields=id&fields=name&fields=description" +
+            "&fields=shared&fields=limits" +
+            "&fields=marker&fields=page_reverse";
+        ITNeutronE2E.test_fetch(url, true, "Qos Firewall Element Get with Query Failed");
+    }
+
+    public void qos_policy_delete_test() {
+        String url = base + "/qos/policies/d6220bbb-35f3-48ab-8eae-69c60aef3546";
+        ITNeutronE2E.test_delete(url, "Qos Policy Delete Failed");
+    }
+
+    public void qos_policy_element_negative_get_test() {
+        String url = base + "/qos/policies/d6220bbb-35f3-48ab-8eae-69c60aef3546";
+        ITNeutronE2E.test_fetch(url, false, "Qos Policy Element Negative Get Failed");
+    }
+
+    public static void runTests(String base) {
+        NeutronQosPolicyTests qos_policy_tester = new NeutronQosPolicyTests(base);
+        String createJsonString = qos_policy_tester.singleton_qos_policy_create_test();
+        qos_policy_tester.singleton_qos_policy_get_with_query_item_test(createJsonString);
+        qos_policy_tester.qos_policy_element_get_test();
+        qos_policy_tester.qos_policy_element_get_with_query_test();
+        qos_policy_tester.qos_policy_collection_get_test();
+        qos_policy_tester.qos_policy_modify_test();
+        qos_policy_tester.qos_policy_delete_test();
+        qos_policy_tester.qos_policy_element_negative_get_test();
+    }
+}
diff --git a/model/src/main/yang/neutron-qos-ext.yang b/model/src/main/yang/neutron-qos-ext.yang
new file mode 100644 (file)
index 0000000..016f1a8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Intel Corporation, 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
+ */
+module neutron-qos-ext {
+    // This model augments the network and port yang model for Qos.
+    // In order to do that it is required to import neutron.yang.
+    // Neutron model can't be imported in neutron-qos.yang as neutron-qos.yang
+    // itself is imported in neutron.yang. Due to do this reason a seperate file is
+    // created for augmentation.
+
+    yang-version 1;
+
+    namespace "urn:opendaylight:neutron-qos-ext";
+
+    prefix neutron-qos-ext;
+
+    import neutron { prefix "neutron"; }
+    import yang-ext { prefix "ext"; }
+    import ietf-yang-types { prefix "yang"; revision-date "2013-07-15"; }
+
+    organization "OpenDaylight Neutron Group";
+
+    contact "Pramod Raghavendra Jayathirth <pramod.rj07@gmail.com>";
+
+    description "This YANG module defines Openstack Neutron Qos provider extensions model";
+
+    revision "2016-06-13" {
+        description
+                "OpenDaylight Boron release";
+    }
+
+    augment "/neutron:neutron/neutron:networks/neutron:network" {
+        description "This module augments the networks container
+            in the neutron-networks module with qos information";
+        // ext:augment-identifier value needs to unique as name of the generated classes
+        // is derived from this string
+        ext:augment-identifier "qos-network-extension";
+        leaf qos-policy-id {
+            description "The Networks to which the Qos Policies can be applied";
+            type yang:uuid;
+        }
+    }
+
+    augment "/neutron:neutron/neutron:ports/neutron:port" {
+        description "This module augments the ports container
+            in the neutron-ports module with qos information";
+        // ext:augment-identifier value needs to unique as name of the generated classes
+        // is derived from this string
+        ext:augment-identifier "qos-port-extension";
+        leaf qos-policy-id {
+            description "The ports to which the Qos Policies can be applied";
+            type yang:uuid;
+        }
+    }
+}
diff --git a/model/src/main/yang/neutron-qos.yang b/model/src/main/yang/neutron-qos.yang
new file mode 100644 (file)
index 0000000..1f3e724
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.  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
+ */
+module neutron-qos {
+
+    yang-version 1;
+
+    namespace "urn:opendaylight:neutron-qos";
+
+    prefix neutron-qos;
+
+    import ietf-yang-types { prefix "yang"; revision-date "2013-07-15"; }
+    import neutron-attrs { prefix "attrs"; }
+
+    organization "OpenDaylight Neutron Group";
+
+    contact "Pramod Raghavendra Jayathirth <pramod.rj07@gmail.com>";
+
+    description "This YANG module defines qos attributes that are used
+        by OpenDaylight Neutron YANG module.";
+
+    revision "2016-06-13" {
+        description
+                "OpenDaylight Boron release";
+    }
+
+    grouping qos-policy-attributes {
+        leaf shared {
+            type boolean;
+            description "Whether the policy is shared or not";
+        }
+    }
+
+    grouping qos-rule-type {
+        leaf rule-type {
+            type string;
+            config false;
+            description "The type of the qos rule";
+        }
+    }
+
+    grouping bandwidthlimit-rule-attributes {
+        leaf uuid {
+            type yang:uuid;
+            description "The rule id of the associated rule";
+        }
+        leaf tenant-id {
+            type yang:uuid;
+            description "The tenant id of OpenStack Tenant";
+        }
+        leaf max-kbps {
+            type uint64;
+            description "The maximum KBPS value";
+        }
+        leaf max-burst-kbps {
+            type uint64;
+            description "The burst over the maximum KBPS value";
+        }
+    }
+
+    grouping dscpmarking-rule-attributes {
+        leaf uuid {
+            type yang:uuid;
+            description "The rule id of the associated rule";
+        }
+        leaf tenant-id {
+            type yang:uuid;
+            description "The tenant id of OpenStack Tenant";
+        }
+        leaf dscp-mark {
+            type uint8 {
+                range "0 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36
+                | 38 | 40 | 46 | 48 | 56";
+            }
+            description "the value of dscp mark";
+        }
+    }
+
+    grouping qos-attributes {
+        container qos-policies {
+            list qos-policy {
+                key "uuid";
+                uses attrs:base-attributes;
+                uses qos-policy-attributes;
+                list bandwidth-limit-rules {
+                    key "uuid";
+                    uses bandwidthlimit-rule-attributes;
+                }
+                list dscpmarking-rules {
+                    key "uuid";
+                    uses dscpmarking-rule-attributes;
+                }
+            }
+        }
+        container qos-rule-types {
+            list rule-types {
+                key "rule-type";
+                config false;
+                uses qos-rule-type;
+            }
+        }
+    }
+}
index a6294cd85d9a9adbd1a0ad25cc015b1cb1124032..17cdf23875e69fdab06001c7367b232c885a313a 100644 (file)
@@ -27,6 +27,7 @@ module neutron {
     import neutron-fwaas { prefix "fwaas"; }
     import neutron-bgpvpns { prefix "bgpvpns"; }
     import neutron-hostconfig { prefix "hostconfig"; }
+    import neutron-qos { prefix "qos"; }
     import neutron-sfc-flow-classifier { prefix "sfc-flow-classifier"; }
     import neutron-sfc { prefix "sfc"; }
 
@@ -64,6 +65,7 @@ module neutron {
         uses l2gateways:l2gateways-attributes;
         uses l2gateways:l2gateway-connections-attributes;
         uses hostconfig:hostconfig-attributes;
+        uses qos:qos-attributes;
         uses sfc-flow-classifier:sfc-flow-classifiers-attributes;
         uses sfc:sfc-attributes;
     }
diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronQosPolicyCRUD.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronQosPolicyCRUD.java
new file mode 100644 (file)
index 0000000..7c6fcef
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.  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.neutron.spi;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Qos Policy objects
+ */
+
+public interface INeutronQosPolicyCRUD extends INeutronCRUD<NeutronQosPolicy> {
+    // Nothing Here.
+    // This class is defined to use reflection.
+}
index 287e230b195324f014a33ca3a5f54181399ef8a4..fc1f8164b26f203775c8d053186a7b34e83645b7 100644 (file)
@@ -45,6 +45,7 @@ public class NeutronCRUDInterfaces {
     private INeutronSFCPortPairCRUD sfcPortPairInterface;
     private INeutronSFCPortPairGroupCRUD sfcPortPairGroupInterface;
     private INeutronSFCPortChainCRUD sfcPortChainInterface;
+    private INeutronQosPolicyCRUD qospInterface;
 
     public NeutronCRUDInterfaces() {
     }
@@ -161,6 +162,10 @@ public class NeutronCRUDInterfaces {
         return sfcPortChainInterface;
     }
 
+    public INeutronQosPolicyCRUD getQosPolicyInterface() {
+        return qospInterface;
+    }
+
     public NeutronCRUDInterfaces fetchINeutronNetworkCRUD(Object obj) {
         networkInterface = (INeutronNetworkCRUD) getInstances(INeutronNetworkCRUD.class, obj);
         return this;
@@ -300,6 +305,11 @@ public class NeutronCRUDInterfaces {
         return this;
     }
 
+    public NeutronCRUDInterfaces fetchINeutronQosPolicyCRUD(Object obj) {
+        qospInterface = (INeutronQosPolicyCRUD) getInstances(INeutronQosPolicyCRUD.class, obj);
+        return this;
+    }
+
     public Object getInstances(Class<?> clazz, Object bundle) {
         try {
             BundleContext bCtx = FrameworkUtil.getBundle(bundle.getClass()).getBundleContext();
diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosBandwidthRule.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosBandwidthRule.java
new file mode 100644 (file)
index 0000000..f872687
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.  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.neutron.spi;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronQosBandwidthRule extends NeutronObject implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "max_kbps")
+    BigInteger maxKbps;
+
+    @XmlElement(name = "max_burst_kbps")
+    BigInteger maxBurstKbps;
+
+    public BigInteger getMaxKbps() {
+        return maxKbps;
+    }
+
+    public void setMaxKbps(BigInteger maxKbps) {
+        this.maxKbps = maxKbps;
+    }
+
+    public BigInteger getMaxBurstKbps() {
+        return maxBurstKbps;
+    }
+
+    public void setMaxBurstKbps(BigInteger maxBurstKbps) {
+        this.maxBurstKbps = maxBurstKbps;
+    }
+
+    public NeutronQosBandwidthRule extractFields(List<String> fields) {
+        NeutronQosBandwidthRule ans = new NeutronQosBandwidthRule();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setID(this.getID());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+            if (s.equals("max_kbps")) {
+                ans.setMaxKbps(this.getMaxKbps());
+            }
+            if (s.equals("max_burst_kbps")) {
+                ans.setMaxBurstKbps(this.getMaxBurstKbps());
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "qosBandwidthRules{" +
+            "qosBandwidthRuleUUID='" + uuid + '\'' +
+            ", qosBandwidthRuleTenantID='" + tenantID + '\'' +
+            ", qosBandwidthMaxValue='" + maxKbps + '\'' +
+            ", qosBandwidthMaxBurst='" + maxBurstKbps + '\'' +
+            '}';
+    }
+}
diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosDscpMarkingRule.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosDscpMarkingRule.java
new file mode 100644 (file)
index 0000000..a0141cc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.  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.neutron.spi;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronQosDscpMarkingRule extends NeutronObject implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "dscp_mark")
+    Short dscpMark;
+
+    public Short getDscpMark() {
+        return dscpMark;
+    }
+
+    public void setDscpMark(Short dscpMark) {
+        this.dscpMark = dscpMark;
+    }
+
+    public NeutronQosDscpMarkingRule extractFields(List<String> fields) {
+        NeutronQosDscpMarkingRule ans = new NeutronQosDscpMarkingRule();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setID(this.getID());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+            if (s.equals("dscp_mark")) {
+                ans.setDscpMark(this.getDscpMark());
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "qosDscpRules{" +
+            "qosDscpRuleUUID='" + uuid + '\'' +
+            ", qosDscpRuleTenantID='" + tenantID + '\'' +
+            ", qosDscpRuleDscpMark='" + dscpMark + '\'' +
+            '}';
+    }
+}
diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosPolicy.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/NeutronQosPolicy.java
new file mode 100644 (file)
index 0000000..1741073
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.  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.neutron.spi;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronQosPolicy extends NeutronObject implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "name")
+    String name;
+
+    @XmlElement(defaultValue = "false", name = "shared")
+    Boolean shared;
+
+    @XmlElement(name = "bandwidth_limit_rules")
+    List<NeutronQosBandwidthRule> bwLimitRules;
+
+    @XmlElement(name = "dscp_marking_rules")
+    List<NeutronQosDscpMarkingRule> dscpRules;
+
+    public String getQosPolicyName() {
+        return name;
+    }
+
+    public void setQosPolicyName(String qosPolicyName) {
+        this.name = qosPolicyName;
+    }
+
+    public Boolean getPolicyIsShared() {
+        return shared;
+    }
+
+    public void setPolicyIsShared(Boolean qosPolicyIsShared) {
+        this.shared = qosPolicyIsShared;
+    }
+
+    public List<NeutronQosBandwidthRule> getBwLimitRules() {
+        return bwLimitRules;
+    }
+
+    public void setQosBwLimitRules(List<NeutronQosBandwidthRule> qosBwLimitRules) {
+        this.bwLimitRules = qosBwLimitRules;
+    }
+
+    public List<NeutronQosDscpMarkingRule> getDscpRules() {
+        return dscpRules;
+    }
+
+    public void setDscpRules(List<NeutronQosDscpMarkingRule> qosDscpRules) {
+        this.dscpRules = qosDscpRules;
+    }
+
+    public NeutronQosPolicy extractFields(List<String> fields) {
+        NeutronQosPolicy ans = new NeutronQosPolicy();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setID(this.getID());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+            if (s.equals("name")) {
+                ans.setQosPolicyName(this.getQosPolicyName());
+            }
+            if (s.equals("shared")) {
+                ans.setPolicyIsShared(this.getPolicyIsShared());
+            }
+            if (s.equals("bandwidth_limit_rules")) {
+                List<NeutronQosBandwidthRule> qosBwRuleList = new ArrayList<>();
+                qosBwRuleList.addAll(this.getBwLimitRules());
+                ans.setQosBwLimitRules(qosBwRuleList);
+            }
+            if (s.equals("dscp_marking_rules")) {
+                List<NeutronQosDscpMarkingRule> qosDscpRuleList = new ArrayList<>();
+                qosDscpRuleList.addAll(this.getDscpRules());
+                ans.setDscpRules(qosDscpRuleList);
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronQosPolicy{" +
+            "qosPolicyUUID='" + uuid + '\'' +
+            ", qosPolicyTenantID='" + tenantID + '\'' +
+            ", qosPolicyName='" + name + '\'' +
+            ", qosPolicyIsShared='" + shared + '\'' +
+            ", qosBwLimitRules='" + bwLimitRules + '\'' +
+            ", qosDscpRules='" + dscpRules + '\'' +
+            '}';
+    }
+}
diff --git a/neutron-spi/src/test/java/org/opendaylight/neutron/spi/NeutronQosJAXBTest.java b/neutron-spi/src/test/java/org/opendaylight/neutron/spi/NeutronQosJAXBTest.java
new file mode 100644 (file)
index 0000000..17c7704
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 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.spi;
+
+import java.math.BigInteger;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import javax.xml.bind.JAXBException;
+
+public class NeutronQosJAXBTest {
+
+    private static final String NeutronQosPolicy_sourceJson =
+        "{" + "\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3546\"," +
+        "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a13\"," + "\"name\": \"jaxb-test\", " +
+        " \"shared\": false," + "\"rule_type\": \"rule\", " +
+        "\"bandwidth_limit_rules\": [ {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3547\", " +
+        "\"tenant_id\": \"aa902936679e4ea29bfe1158e3450a14\"," + "\"max_kbps\": 25, " +
+        "\"max_burst_kbps\": 100 } ]," +
+        "\"dscp_marking_rules\": [ {\"id\": \"d6220bbb-35f3-48ab-8eae-69c60aef3547\"," +
+        " \"tenant_id\": \"aa902936679e4ea29bfe1158e3450a14\", " +
+        "\"dscp_mark\": 8 } ] " +
+        "}";
+
+    @Test
+    public void test_NeutronQosPolicy_JAXB() throws JAXBException {
+        NeutronQosPolicy testObject = new NeutronQosPolicy();
+        NeutronQosPolicy neutronObject = (NeutronQosPolicy) JaxbTestHelper
+            .jaxbUnmarshall(testObject, NeutronQosPolicy_sourceJson);
+        Assert.assertEquals("NeutronQosPolicy JAXB Test 1: Testing id failed",
+            "d6220bbb-35f3-48ab-8eae-69c60aef3546", neutronObject.getID());
+
+        Assert.assertEquals("NeutronQosPolicy JAXB Test 2: Testing tenant_id failed",
+            "aa902936679e4ea29bfe1158e3450a13", neutronObject.getTenantID());
+
+        Assert.assertEquals("NeutronQosPolicy JAXB Test 3 : Testing Name failed", "jaxb-test",
+            neutronObject.getQosPolicyName());
+
+        Assert.assertFalse("NeutronQosPolicy JaxB Test 4 : Testing Shared failed",
+            neutronObject.getPolicyIsShared());
+
+        List<NeutronQosBandwidthRule> bwPolicyRules = neutronObject.getBwLimitRules();
+
+        Assert.assertEquals(
+            "NeutronQosPolicy JAXB Test 5.0: Testing Bandwidth Policy length failed", 1,
+            bwPolicyRules.size());
+
+        Assert.assertEquals("NeutronQosPolicy JaxB Test 5.1 : Testing ID failed",
+            "d6220bbb-35f3-48ab-8eae-69c60aef3547", bwPolicyRules.get(0).uuid);
+
+        Assert.assertEquals("NeutronQosPolicy JaxB Test 5.2 : Testing Tenant ID failed",
+            "aa902936679e4ea29bfe1158e3450a14", bwPolicyRules.get(0).tenantID);
+
+        Assert.assertEquals(
+            "NeutronQosPolicy JaxB Test 5.3 : Testing Max ingress/Egress value failed",
+            new BigInteger("25"), bwPolicyRules.get(0).maxKbps);
+
+        Assert.assertEquals("NeutronQosPolicy JaxB Test 5.4 : Testing Maximum Burst value failed",
+            new BigInteger("100"), bwPolicyRules.get(0).maxBurstKbps);
+
+        List<NeutronQosDscpMarkingRule> dscpPolicyRules = neutronObject.getDscpRules();
+
+        Assert.assertEquals(
+            "NeutronQosPolicy JAXB Test 6.0: Testing Bandwidth Policy length failed", 1,
+            dscpPolicyRules.size());
+
+        Assert.assertEquals("NeutronQosPolicy JaxB Test 6.1 : Testing ID failed",
+            "d6220bbb-35f3-48ab-8eae-69c60aef3547", dscpPolicyRules.get(0).uuid);
+
+        Assert.assertEquals("NeutronQosPolicy JaxB Test 6.2 : Testing Tenant ID failed",
+            "aa902936679e4ea29bfe1158e3450a14", dscpPolicyRules.get(0).tenantID);
+
+        Assert.assertEquals(
+            "NeutronQosPolicy JaxB Test 6.3 : Testing Max ingress/Egress value failed",
+            new Short("8"), dscpPolicyRules.get(0).dscpMark);
+    }
+}
diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyNorthbound.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyNorthbound.java
new file mode 100644 (file)
index 0000000..2852aae
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2016 Intel, Corp. 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.neutron.northbound.api;
+
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.neutron.spi.NeutronQosPolicy;
+import org.opendaylight.neutron.spi.INeutronQosPolicyCRUD;
+import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
+
+@Path("/qos/policies")
+public class NeutronQosPolicyNorthbound extends
+    AbstractNeutronNorthbound<NeutronQosPolicy, NeutronQosPolicyRequest, INeutronQosPolicyCRUD> {
+
+    private static final String RESOURCE_NAME = "Qos Policy";
+
+    @Override
+    protected String getResourceName() {
+        return RESOURCE_NAME;
+    }
+
+    @Override
+    protected NeutronQosPolicy extractFields(NeutronQosPolicy o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    @Override
+    protected NeutronQosPolicyRequest newNeutronRequest(NeutronQosPolicy o) {
+        return new NeutronQosPolicyRequest(o);
+    }
+
+    @Override
+    protected INeutronQosPolicyCRUD getNeutronCRUD() {
+        NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronQosPolicyCRUD(this);
+        if (answer.getQosPolicyInterface() == null) {
+            throw new ServiceUnavailableException(serviceUnavailable());
+        }
+        return answer.getQosPolicyInterface();
+    }
+
+    /**
+     * Returns a list of all Qos Policies
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+        @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
+        @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
+    public Response listGroups(
+        // return fields
+        @QueryParam("fields") List<String> fields,
+        // OpenStack qos Policy attributes
+        @QueryParam("id") String queryQosPolicyUUID,
+        @QueryParam("tenant_id") String queryQosPolicyTenantID,
+        @QueryParam("name") String queryQosPolicyName,
+        @QueryParam("shared") Boolean queryQosPolicyIsShared,
+        // pagination
+        @QueryParam("limit") String limit,
+        @QueryParam("marker") String marker,
+        @QueryParam("page_reverse") String pageReverse) {
+        INeutronQosPolicyCRUD qosPolicyInterface = getNeutronCRUD();
+        List<NeutronQosPolicy> ans = new ArrayList<>();
+        for (NeutronQosPolicy nsg : qosPolicyInterface.getAll()) {
+            if ((queryQosPolicyUUID == null || queryQosPolicyUUID.equals(nsg.getID())) &&
+                (queryQosPolicyTenantID == null || queryQosPolicyTenantID.equals(nsg.getTenantID())) &&
+                (queryQosPolicyName == null || queryQosPolicyName.equals(nsg.getQosPolicyName())) &&
+                (queryQosPolicyIsShared == null || queryQosPolicyIsShared.equals(nsg.getPolicyIsShared()))) {
+                if (fields.size() > 0) {
+                    ans.add(extractFields(nsg, fields));
+                } else {
+                    ans.add(nsg);
+                }
+            }
+        }
+        return Response.status(HttpURLConnection.HTTP_OK).entity(
+            new NeutronQosPolicyRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Qos Policy
+     */
+    @Path("{qosPolicyUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+        @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
+        @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
+        @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
+    public Response showQosPolicy(
+        @PathParam("qosPolicyUUID") String qosPolicyUUID,
+        @QueryParam("fields") List<String> fields) {
+        return show(qosPolicyUUID, fields);
+    }
+
+    /**
+     * Creates new Qos Policy
+     */
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+        @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
+    public Response createQosPolicies(final NeutronQosPolicyRequest input) {
+        return create(input);
+    }
+
+    /**
+     * Updates a Qos Policy
+     */
+    @Path("{qosPolicyUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+        @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
+        @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
+    public Response updateQosPolicy(
+        @PathParam("qosPolicyUUID") String qosPolicyUUID,
+        final NeutronQosPolicyRequest input) {
+        return update(qosPolicyUUID, input);
+    }
+
+    /**
+     * Deletes a Qos Policy
+     */
+    @Path("{qosPolicyUUID}")
+    @DELETE
+    @StatusCodes({
+        @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
+        @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
+        @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
+    public Response deleteQosPolicy(
+        @PathParam("qosPolicyUUID") String qosPolicyUUID) {
+        return delete(qosPolicyUUID);
+    }
+}
diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyRequest.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronQosPolicyRequest.java
new file mode 100644 (file)
index 0000000..dc5bad8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Intel, Corp. 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.neutron.northbound.api;
+
+import org.opendaylight.neutron.spi.NeutronQosPolicy;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronQosPolicyRequest implements INeutronRequest<NeutronQosPolicy> {
+
+    @XmlElement(name = "policy")
+    NeutronQosPolicy singletonQosPolicy;
+
+    @XmlElement(name = "policies")
+    List<NeutronQosPolicy> bulkRequest;
+
+    NeutronQosPolicyRequest() {
+    }
+
+    NeutronQosPolicyRequest(List<NeutronQosPolicy> bulk) {
+        bulkRequest = bulk;
+        singletonQosPolicy = null;
+    }
+
+    NeutronQosPolicyRequest(NeutronQosPolicy qos) {
+        singletonQosPolicy = qos;
+    }
+
+    @Override
+    public List<NeutronQosPolicy> getBulk() {
+        return bulkRequest;
+    }
+
+    @Override
+    public NeutronQosPolicy getSingleton() {
+        return singletonQosPolicy;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return (singletonQosPolicy != null);
+    }
+}