BUG 5746 - Ovsdb QoS and Queue model enhancements 72/36772/11
authorEric Multanen <eric.w.multanen@intel.com>
Fri, 25 Mar 2016 16:06:29 +0000 (09:06 -0700)
committerEric Multanen <eric.w.multanen@intel.com>
Wed, 15 Jun 2016 22:06:28 +0000 (15:06 -0700)
Update the QoS and Queue model to improve managability
of QoS and Queue tables via MD-SAL config model.

Adds code to update operational md-sal using updated
model.

Adds code to allow creation of queue and qos in same
transaction and assign queue to the qos row via
named-uuid.

QoS and Queue entries can be managed by ODL ID
values instead of needing to know the operational
UUID value.

Adds code to support assignment of QoS to port
by MD-SAL QoS ID.

Adds a QoS entry list to the termination point
model so updates and delete operations can be made
directly on the list instead of updating the
termination point.

Support for ingress policing rate and burst configuration
for interfaces is added.

Includes updated Postman examples.

v2 - clarify some logic based on comment feedback
     add additional qos types: linux-sfq, linux-codel
       linux-fq_codel, egress-policer
v3 - rebase, whitespace
v4 - address review comments
v5 - Changes to address review comments:
     Use a queue-ref (instance identifier instead
       of queue-id in the qos queue list.
     Use a qos-ref (instance identifier instead
       of qos-id in the port qos list.
     Use a key of '1' for the single item port qos list.
     Add instance identifer to the external-ids column
       of the qos and queue tables instead of just id
       value.  Use key of 'opendaylight-iid'.
     Updated the postman collection to account for changes
     Clarified the  comment and code of method
       bytesToHexString in TransactUtils.java.

Still to do:
- update unit tests
- update integration tests

Change-Id: I71ac462afe5a881c621fad9a3c5603e1aab8d021
Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
14 files changed:
resources/commons/Qos-and-Queue-Collection.json.postman_collection
schemas/openvswitch/src/main/java/org/opendaylight/ovsdb/schema/openvswitch/Interface.java
southbound/southbound-api/src/main/yang/ovsdb.yang
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundConstants.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/QosUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/QueueUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtils.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbQosUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbQueueUpdateCommand.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommandTest.java
southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java

index d1a1de72ce8dded435f4425a4cab70d7cd80c6fd..4f420c69a3ea50c058e47fb1e0beff13f4c6e676 100644 (file)
@@ -1,30 +1,35 @@
 {
-    "id": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+    "id": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
     "name": "Qos and Queue Collection",
     "description": "This collection demonstrates how to:\n\n- create Qos and Queue entries in the OVSDB\n- add or delete Queue entries from a Qos entry\n- add or delete a Qos entry from a termination point\n- delete Qos and Queue entries",
     "order": [
-        "8470a026-b32c-a292-49a2-a523fe831881",
-        "f1627096-7541-0c7e-e998-cd29e90f2547",
-        "78f912b9-eb93-6df1-e6bd-b175a8ee097a",
-        "17f45b0e-bdd2-6c7b-18a9-26df17d2ca20",
-        "194fbaf3-362e-54c9-2daf-c9b76f38ee57",
-        "64210287-3ec5-48f3-7ee5-447c09cc3c84",
-        "9d1dc5b0-99a2-9d31-29b6-35dcc0cf24fa",
-        "760bb52a-e621-bf9c-7053-e72a94899fa9",
-        "501cf348-4095-3826-1081-c1b3ba428f3c",
-        "61f5f3d5-1014-b211-b9bf-80a6b269d9b4",
-        "c3549a74-512b-7e93-a5e8-0219e1956c99",
-        "18641f3c-2f50-9761-c780-3f6ee358c616",
-        "fbecd07b-135b-6070-0178-71af93998104"
+        "400b68fe-7e92-8da8-29ed-ffc964e03eb3",
+        "479d3281-ac30-3b30-d727-80b0b8505140",
+        "d263138d-3ef5-733b-4337-87de3eccbecc",
+        "0105b240-9b36-79be-0251-9c2510563c71",
+        "a0b5092f-2bd2-3d6d-7891-a25df8d55d31",
+        "bdfa43fb-1d49-2433-da72-9a13f564680f",
+        "a0eb2758-39dd-2603-ba63-fd96abe51a9d",
+        "6034d635-e823-b733-e4b5-a9e2cefb27bd",
+        "9aa6926b-70db-1d22-dc30-db269e424bec",
+        "4298de9f-d2e0-a7c0-da4b-71ce9ecc7260",
+        "8ff38d91-00ee-e7c6-ef1a-e3d236f59641",
+        "ba67cc34-62d4-60e7-86be-7a187b4a9334",
+        "1468ceac-807b-d3c3-f07a-a6fd86c98ea0",
+        "a2f4d7cd-1de9-806e-e2e4-03ac2b618e66",
+        "14a55d30-ab5d-4007-3905-791a111457eb",
+        "494db14f-97e9-ce5b-5964-5504c9630a20",
+        "6293d31b-ea45-d504-ebac-8d765f46cb45",
+        "8dd9ab66-f999-6376-8584-ddc9729fb60c"
     ],
     "folders": [],
     "timestamp": 1454567977189,
-    "owner": "",
-    "remoteLink": "",
+    "owner": 0,
     "public": false,
+    "hasRequests": true,
     "requests": [
         {
-            "id": "17f45b0e-bdd2-6c7b-18a9-26df17d2ca20",
+            "id": "0105b240-9b36-79be-0251-9c2510563c71",
             "headers": "Content-Type: application/json\n",
             "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
             "preRequestScript": "",
             "time": 1454572576470,
             "name": "Add a QpS entry to a qos-entries list",
             "description": "This restconf request will create or update a Qos entry for the ovsdb node 'HOST1'.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
             "rawModeData": "{\n  \"ovsdb:qos-entries\": [\n    {\n      \"qos-id\": \"QOS-1\",\n      \"qos-type\": \"ovsdb:qos-type-linux-htb\",\n      \"qos-other-config\": [\n        {\n          \"other-config-key\": \"max-rate\",\n          \"other-config-value\": \"3300000\"\n        }\n      ]\n    }\n  ]\n}"
         },
         {
-            "id": "18641f3c-2f50-9761-c780-3f6ee358c616",
+            "id": "1468ceac-807b-d3c3-f07a-a6fd86c98ea0",
             "headers": "",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/QUEUE-1/",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
             "preRequestScript": "",
             "pathVariables": {},
             "method": "DELETE",
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572803238,
-            "name": "Delete a Queue entry from an ovsdb node",
-            "description": "This restconf command will delete a Qos entry.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1454572816260,
+            "name": "Delete a QoS entry from a node",
+            "description": "This restconf command will delete a Qos entry from an ovsdb node.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": []
         },
         {
-            "id": "194fbaf3-362e-54c9-2daf-c9b76f38ee57",
-            "headers": "Content-Type: application/json\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/QUEUE-1/",
+            "id": "14a55d30-ab5d-4007-3905-791a111457eb",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
             "preRequestScript": "",
             "pathVariables": {},
             "method": "PUT",
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572671919,
-            "name": "Add a Queue entry to the queues list of aovsdb node 'HOST1'",
-            "description": "This restconf request will create or update a Queue entry on ovsdb node 'HOST1'.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1466010716484,
+            "name": "Add existing QoS ID to a termination point",
+            "description": "This restconf request will specify the QoS ID of a Qos entry to associate with a port (termination point).\n\nThe QoS ID is the ODL identifier for identifying the QoS entry.  The actual UUID of the QoS entry will looked up and used to update the OVSDB port qos attributes.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
-            "rawModeData": "{\n  \"ovsdb:queues\": [\n    {\n      \"queue-id\": \"QUEUE-1\",\n      \"dscp\": 25,\n      \"queues-other-config\": [\n        {\n          \"queue-other-config-key\": \"max-rate\",\n          \"queue-other-config-value\": \"3600000\"\n        }\n      ]\n    }\n  ]\n}"
+            "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n \t  \t\t\"ovsdb:name\": \"testport\",\n \t\t\t\"tp-id\": \"testport\",\n \t\t\t\"ovsdb:qos-entry\": [\n                {\n                    \"qos-key\": 1,\n                    \"qos-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']/ovsdb:qos-entries[ovsdb:qos-id='QOS-1']\"\n                }\n            ]\n  \t\t}\n    ]\n}"
         },
         {
-            "id": "501cf348-4095-3826-1081-c1b3ba428f3c",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/queue-list/0/",
+            "id": "400b68fe-7e92-8da8-29ed-ffc964e03eb3",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/",
             "preRequestScript": "",
             "pathVariables": {},
-            "method": "DELETE",
+            "method": "POST",
             "data": [],
-            "dataMode": "params",
+            "dataMode": "raw",
             "version": 2,
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572752090,
-            "name": "Delete a Queue entry from a Qos entry",
-            "description": "This restconf command will delete a queue entry from a qos entry.\n\nThe queue entry is identified by it's key value (the queue number) in\nthe queue-list which is part of the qos entry.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
-            "responses": []
+            "time": 1454573115055,
+            "name": "POST to create OVSDB NODE HOST1",
+            "description": "Fire this Restconf request if you want to initiate the connection to ovsdb node from controller. It assumes that ovsdb node is listening for tcp connection in passive mode. To configure the ovsdb node for listening incoming connection, please fire following command at ovsdb node machine\n\n\"ovs-vsctl set-manager tcp:16640\"",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": [],
+            "rawModeData": "\r\n        {\r\n            \"node\": [\r\n                {\r\n                    \"node-id\": \"ovsdb:HOST1\",\r\n                    \"connection-info\": {\r\n                        \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\",\r\n                        \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\"\r\n                    }\r\n                }\r\n            ]\r\n        }\r\n"
         },
         {
-            "id": "61f5f3d5-1014-b211-b9bf-80a6b269d9b4",
+            "id": "4298de9f-d2e0-a7c0-da4b-71ce9ecc7260",
             "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
             "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
             "preRequestScript": "",
             "currentHelper": "normal",
             "helperAttributes": {},
             "time": 1454572769501,
-            "name": "Add existing QoS UUID to existing termination point",
-            "description": "This restconf request will specify the UUID of a Qos entry to associate with a port.\n\nThe Qos UUID is the actual operational value of a Qos entry.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "name": "Add existing QoS UUID to existing termination point (deprecated)",
+            "description": "This restconf request will specify the UUID of a Qos entry to associate with a port.\n\nThe Qos UUID is the actual operational value of a Qos entry.\n\nNote: The QoS model also has a QoS ID.  The preferred method for associating a QoS entry to a termination point is to use the QoS ID.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
             "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n \t  \t\t\"ovsdb:name\": \"testport\",\n \t\t\t\"tp-id\": \"testport\",\n \t\t\t\"qos\": \"4126e461-020d-497d-97b7-c8f409d1c9b9\"\n  \t\t}\n    ]\n}"
         },
         {
-            "id": "64210287-3ec5-48f3-7ee5-447c09cc3c84",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
+            "id": "479d3281-ac30-3b30-d727-80b0b8505140",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test",
             "preRequestScript": "",
             "pathVariables": {},
-            "method": "GET",
+            "method": "PUT",
             "data": [],
-            "dataMode": "params",
+            "dataMode": "raw",
             "version": 2,
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572690160,
-            "name": "Get Operational QoS Entry from Qos Entry list",
-            "description": "This restconf queries the operational md-sal for a specific Qos entry which was previously created by restconf (e.g. 'QOS-1').\n\nThis is useful for determining the actual UUID of the Qos entry in order to assign it to a port (i.e. termination point).",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
-            "responses": []
+            "time": 1461790310464,
+            "name": "Create bridge br-test on HOST1",
+            "description": "Create bridge \"br-test\" on OVSDB node \"ovsdb:HOST1\"",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": [],
+            "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb:HOST1/bridge/br-test\",\n             \"ovsdb:bridge-name\": \"br-test\",\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']\"\n        }\n    ]\n}"
+        },
+        {
+            "id": "494db14f-97e9-ce5b-5964-5504c9630a20",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/qos-entry/1",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1466012030265,
+            "name": "Delete QoS Entry from a termination point",
+            "description": "This restconf request specifies the QopS ID of a Qos entry to delete from the QoS entry list of the termination point.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": [],
+            "rawModeData": ""
         },
         {
-            "id": "760bb52a-e621-bf9c-7053-e72a94899fa9",
+            "id": "6034d635-e823-b733-e4b5-a9e2cefb27bd",
             "headers": "Content-Type: application/json\n",
             "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
             "preRequestScript": "",
             "currentHelper": "normal",
             "helperAttributes": {},
             "time": 1454572737919,
-            "name": "Add a Queue List to a QoS entry",
-            "description": "This restconf adds a Queue to a Qos entry by specifying a queue-list\nin the Qos entry which uses the operational queue UUID value.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "name": "Add a Queue List to a QoS entry (deprecated)",
+            "description": "This restconf adds a Queue to a Qos entry by specifying a queue-list\nin the Qos entry which uses the operational queue UUID value.\n\nNote - Queues can now be added to QoS entries using the ODL Queue ID value.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
             "rawModeData": "{\n  \"ovsdb:qos-entries\": [\n    {\n      \"qos-id\": \"QOS-1\",\n      \"queue-list\": [\n          {\n              \"queue-number\": \"0\",\n              \"queue-uuid\": \"8100a05f-d3fa-4e65-bbd1-6e886713f592\"\n          }\n        ]\n    }\n  ]\n}"
         },
         {
-            "id": "78f912b9-eb93-6df1-e6bd-b175a8ee097a",
+            "id": "6293d31b-ea45-d504-ebac-8d765f46cb45",
+            "headers": "Content-Type: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1465849834924,
+            "name": "Add existing Queue ID entry to a QoS entry",
+            "description": "Add a Queue to a QoS entry using the ODL Queue ID as the identifier for the Queue entry.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": [],
+            "rawModeData": "{\n    \"ovsdb:qos-entries\": [\n        {\n            \"qos-id\": \"QOS-1\",\n            \"queue-list\": [\n                {\n                    \"queue-number\": \"0\",\n                    \"queue-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']/ovsdb:queues[ovsdb:queue-id='QUEUE-1']\"\n                }\n            ]\n        }\n    ]\n}"
+        },
+        {
+            "id": "8dd9ab66-f999-6376-8584-ddc9729fb60c",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
+            "pathVariables": {},
+            "preRequestScript": "",
+            "method": "PUT",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "data": [],
+            "dataMode": "raw",
+            "name": "Set ingress policing attributes of a termination point",
+            "description": "Set the ingress policing attributes of an ovsdb interface by updating the termination point.\ningress-policing-rate\ningress-policing-burst\n\nNote - This is an update to a termination point's attributes.  If there is also a QoS entry configured for the termination point, then it must be supplied in the body as well.  Otherwise, not including the QoS entry in the body will result in the QoS entry being removed from the port.",
+            "descriptionFormat": "html",
+            "time": 1463685062091,
+            "version": 2,
+            "responses": [],
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "rawModeData": "{\n    \"network-topology:termination-point\": [\n    \t{\n\t  \t\t\"ovsdb:name\": \"testport\",\n  \t\t\t\"tp-id\": \"testport\",\n            \"ovsdb:ingress-policing-rate\": 1000,\n            \"ovsdb:ingress-policing-burst\": 2000\n\t\t}\n    ]\n}"
+        },
+        {
+            "id": "8ff38d91-00ee-e7c6-ef1a-e3d236f59641",
             "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
             "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
             "preRequestScript": "",
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454573176142,
-            "name": "Create Termination Point",
-            "description": "This restconf request creates port/interface (`testport`) and attach it to give bridge 'br-test'. \n",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1454572787173,
+            "name": "Delete a QoS UUID from a termination point (deprecated)",
+            "description": "This restconf request will delete a Qos entry from a port (termination point).\n\nNote - this is done by doing a PUT operation on the termination port with the Qos\nentry cleared.\n\nNote - The model now provides a QoS entry list (max number of one entry) as part of the termination point model.  This allows perfroaming a DELETE operation on the list entry instead of doing a PUT on the termination point.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
-            "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n\t  \t\t\"ovsdb:name\": \"testport\",\n  \t\t\t\"tp-id\": \"testport\"\n\t\t}\n    ]\n}"
+            "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n \t  \t\t\"ovsdb:name\": \"testport\",\n \t\t\t\"tp-id\": \"testport\"\n  \t\t}\n    ]\n}"
         },
         {
-            "id": "8470a026-b32c-a292-49a2-a523fe831881",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/",
+            "id": "9aa6926b-70db-1d22-dc30-db269e424bec",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/queue-list/0/",
             "preRequestScript": "",
             "pathVariables": {},
-            "method": "POST",
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1454572752090,
+            "name": "Delete a Queue entry from a Qos entry",
+            "description": "This restconf command will delete a queue entry from a qos entry.\n\nThe queue entry is identified by it's key value (the queue number) in\nthe queue-list which is part of the qos entry.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": []
+        },
+        {
+            "id": "a0b5092f-2bd2-3d6d-7891-a25df8d55d31",
+            "headers": "Content-Type: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/QUEUE-1/",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
             "data": [],
             "dataMode": "raw",
             "version": 2,
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454573115055,
-            "name": "POST to create OVSDB NODE HOST1",
-            "description": "Fire this Restconf request if you want to initiate the connection to ovsdb node from controller. It assumes that ovsdb node is listening for tcp connection in passive mode. To configure the ovsdb node for listening incoming connection, please fire following command at ovsdb node machine\n\n\"ovs-vsctl set-manager tcp:16640\"",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1454572671919,
+            "name": "Add a Queue entry to the queues list of aovsdb node 'HOST1'",
+            "description": "This restconf request will create or update a Queue entry on ovsdb node 'HOST1'.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
-            "rawModeData": "\r\n        {\r\n            \"node\": [\r\n                {\r\n                    \"node-id\": \"ovsdb:HOST1\",\r\n                    \"connection-info\": {\r\n                        \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\",\r\n                        \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\"\r\n                    }\r\n                }\r\n            ]\r\n        }\r\n"
+            "rawModeData": "{\n  \"ovsdb:queues\": [\n    {\n      \"queue-id\": \"QUEUE-1\",\n      \"dscp\": 25,\n      \"queues-other-config\": [\n        {\n          \"queue-other-config-key\": \"max-rate\",\n          \"queue-other-config-value\": \"3600000\"\n        }\n      ]\n    }\n  ]\n}"
         },
         {
-            "id": "9d1dc5b0-99a2-9d31-29b6-35dcc0cf24fa",
+            "id": "a0eb2758-39dd-2603-ba63-fd96abe51a9d",
             "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
             "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/QUEUE-1/",
             "preRequestScript": "",
             "helperAttributes": {},
             "time": 1454572710554,
             "name": "Get a specific operaiontal Queue entry",
-            "description": "This restconf command will query the operational md-sal for a specified Queue entry (e.g. 'QUEUE-1') which has previously been added to the config md-sal.\n\nThis is useful in order to get the actual UUID of the Queue entry in order to assign it to a Qos entry.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "description": "This restconf command will query the operational md-sal for a specified Queue entry (e.g. 'QUEUE-1') which has previously been added to the config md-sal.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": []
         },
         {
-            "id": "c3549a74-512b-7e93-a5e8-0219e1956c99",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
+            "id": "a2f4d7cd-1de9-806e-e2e4-03ac2b618e66",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1",
             "preRequestScript": "",
             "pathVariables": {},
             "method": "PUT",
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572787173,
-            "name": "Delete a QoS UUID from a termination point",
-            "description": "This restconf request will delete a Qos entry from a port (termination point).\n\nNote - this is done by doing a PUT operation on the termination port with the Qos\nentry cleared.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1466012434801,
+            "name": "Create a QoS and linked Queue entry to an OVSDB Node",
+            "description": "This restconf command will create new QoS and Queue entries.  The Queue entry is assigned to the QoS queueu list.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": [],
-            "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n \t  \t\t\"ovsdb:name\": \"testport\",\n \t\t\t\"tp-id\": \"testport\"\n  \t\t}\n    ]\n}"
+            "rawModeData": "{\r\n    \"network-topology:node\": [\r\n        {\r\n            \"node-id\": \"ovsdb:HOST1\",\r\n            \"ovsdb:qos-entries\": [\r\n                {\r\n                    \"qos-id\": \"QOS-1\",\r\n                    \"qos-other-config\": [\r\n                        {\r\n                            \"other-config-key\": \"max-rate\",\r\n                            \"other-config-value\": \"3300000\"\r\n                        }\r\n                    ],\r\n                    \"qos-type\": \"ovsdb:qos-type-linux-htb\",\r\n                    \"queue-list\": [\r\n                        {\r\n                            \"queue-number\": \"0\",\r\n                            \"queue-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']/ovsdb:queues[ovsdb:queue-id='QUEUE-1']\"\r\n                        }\r\n                    ]\r\n                }\r\n            ],\r\n            \"ovsdb:queues\": [\r\n                {\r\n                    \"queue-id\": \"QUEUE-1\",\r\n                    \"dscp\" : 51,\r\n                    \"queues-other-config\": [\r\n                        {\r\n                            \"queue-other-config-key\": \"max-rate\",\r\n                            \"queue-other-config-value\": \"1230000\"\r\n                        },\r\n                        {\r\n                            \"queue-other-config-key\": \"min-rate\",\r\n                            \"queue-other-config-value\": \"1000000\"\r\n                        }\r\n                    ],\r\n                    \"queues-external-ids\": [\r\n                        {\r\n                            \"queues-external-id-key\": \"Big\",\r\n                            \"queues-external-id-value\": \"Dog\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    ]\r\n}"
         },
         {
-            "id": "f1627096-7541-0c7e-e998-cd29e90f2547",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test",
+            "id": "ba67cc34-62d4-60e7-86be-7a187b4a9334",
+            "headers": "",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/QUEUE-1/",
             "preRequestScript": "",
             "pathVariables": {},
-            "method": "PUT",
+            "method": "DELETE",
             "data": [],
-            "dataMode": "raw",
+            "dataMode": "params",
             "version": 2,
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572634841,
-            "name": "Create bridge br-test on HOST1",
-            "description": "Create bridge \"br-test\" on OVSDB node \"ovsdb:HOST1\"",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
-            "responses": [],
-            "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb:HOST1/bridge/br-test\",\n             \"ovsdb:bridge-name\": \"br=test\",\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']\"\n        }\n    ]\n}"
+            "time": 1454572803238,
+            "name": "Delete a Queue entry from an ovsdb node",
+            "description": "This restconf command will delete a Qos entry.",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": []
         },
         {
-            "id": "fbecd07b-135b-6070-0178-71af93998104",
-            "headers": "",
-            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
+            "id": "bdfa43fb-1d49-2433-da72-9a13f564680f",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/QOS-1/",
             "preRequestScript": "",
             "pathVariables": {},
-            "method": "DELETE",
+            "method": "GET",
             "data": [],
             "dataMode": "params",
             "version": 2,
             "tests": "",
             "currentHelper": "normal",
             "helperAttributes": {},
-            "time": 1454572816260,
-            "name": "Delete a QoS entry from a node",
-            "description": "This restconf command will delete a Qos entry from an ovsdb node.",
-            "collectionId": "af60f3ad-e690-74ea-1a5a-2ed6f4013755",
+            "time": 1454572690160,
+            "name": "Get Operational QoS Entry from Qos Entry list",
+            "description": "This restconf queries the operational md-sal for a specific Qos entry which was previously created by restconf (e.g. 'QOS-1').",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
             "responses": []
+        },
+        {
+            "id": "d263138d-3ef5-733b-4337-87de3eccbecc",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+            "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fbr-test/termination-point/testport/",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1454573176142,
+            "name": "Create Termination Point",
+            "description": "This restconf request creates a port/interface (`testport`) and attaches it to bridge 'br-test'. \n",
+            "collectionId": "b96ed27e-7aee-47e1-daa6-e3dbe3f176af",
+            "responses": [],
+            "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n\t  \t\t\"ovsdb:name\": \"testport\",\n  \t\t\t\"tp-id\": \"testport\"\n\t\t}\n    ]\n}"
         }
     ]
 }
index e0bd8a20a7662ac64ea8e7feea668805cf93cbe9..2f2d0d32e7b507c7332d0c2a2b1c8218d27e8292 100644 (file)
@@ -42,14 +42,14 @@ public interface Interface extends TypedBaseTable<GenericTableSchema> {
     void setOptions(Map<String, String> options);
 
     @TypedColumn(name="ingress_policing_rate", method=MethodType.GETCOLUMN, fromVersion="1.0.0")
-    Column<GenericTableSchema, Set<Long>> getIngressPolicingRateColumn();
+    Column<GenericTableSchema, Long> getIngressPolicingRateColumn();
     @TypedColumn(name="ingress_policing_rate", method=MethodType.SETDATA, fromVersion="1.0.0")
-    void setIngressPolicingRate(Set<Long> ingressPolicingRate);
+    void setIngressPolicingRate(Long ingressPolicingRate);
 
     @TypedColumn(name="ingress_policing_burst", method=MethodType.GETCOLUMN, fromVersion="1.0.0")
-    Column<GenericTableSchema, Set<Long>> getIngressPolicingBurstColumn();
+    Column<GenericTableSchema, Long> getIngressPolicingBurstColumn();
     @TypedColumn(name="ingress_policing_burst", method=MethodType.SETDATA, fromVersion="1.0.0")
-    void setIngressPolicingBurst(Set<Long> ingressPolicingBurst);
+    void setIngressPolicingBurst(Long ingressPolicingBurst);
 
     @TypedColumn(name="mac_in_use", method=MethodType.GETCOLUMN, fromVersion="7.1.0")
     Column<GenericTableSchema,Set<String>> getMacInUseColumn();
index d303a2b30284a460011e59d73aec5be919fa433e..b5ca74a6c687255b71cd2ba5fc658091849684a6 100755 (executable)
@@ -34,6 +34,16 @@ module ovsdb {
         type instance-identifier;
     }
 
+    typedef ovsdb-qos-ref {
+        description "A reference to a ovsdb QoS entry";
+        type instance-identifier;
+    }
+
+    typedef ovsdb-queue-ref {
+        description "A reference to an ovsdb queue entry";
+        type instance-identifier;
+    }
+
     typedef ovsdb-bridge-name {
         type string;
     }
@@ -514,9 +524,15 @@ module ovsdb {
                     type uint32;
                 }
 
+                leaf queue-ref {
+                    description "Instance identifier to a Queue in the MD-SAL.";
+                    type ovsdb-queue-ref;
+                }
+
                 leaf queue-uuid {
                     description "The unique identifier of the queue record.";
                     type yang:uuid;
+                    status deprecated;
                 }
             }
             list qos-external-ids {
@@ -786,6 +802,26 @@ module ovsdb {
         base qos-type-base;
     }
 
+    identity qos-type-linux-sfq {
+        description "linux stochastic fairness queueing classifier";
+        base qos-type-base;
+    }
+
+    identity qos-type-linux-codel {
+        description "linux controlled delay classifier";
+        base qos-type-base;
+    }
+
+    identity qos-type-linux-fq-codel {
+        description "linux fair queueing controlled delay classifier";
+        base qos-type-base;
+    }
+
+    identity qos-type-egress-policer {
+        description "DPDK user space egress policer";
+        base qos-type-base;
+    }
+
     grouping ovsdb-port-interface-attributes {
         leaf port-uuid {
             description "The unique identifier of the OVSDB port";
@@ -1239,8 +1275,40 @@ module ovsdb {
 
         leaf qos {
             description "The unique identifier of the QoS entry for this port.";
+            status deprecated;
             type yang:uuid;
         }
+
+        list qos-entry {
+            key "qos-key";
+            max-elements 1;
+            leaf qos-key {
+                description "Fixed key to reference the QoS entry in MD-SAL.";
+                type uint32 {
+                    range "1..1";
+                }
+                mandatory true;
+            }
+            leaf qos-ref {
+                description "Instance identifier of a QoS entry in the MD-SAL.";
+                type ovsdb-qos-ref;
+                mandatory true;
+            }
+        }
+
+        leaf ingress-policing-rate {
+            description "Maximum rate for data received on this interface in kbps.
+                Data received faster than this rate is dropped.  Set to 0 (default)
+                to disable policing";
+            type uint32;
+        }
+
+        leaf ingress-policing-burst {
+            description "Maximum burst size for data received on this interface in kb.
+                The default burst size if set to 0 is 1000 kb.  This value has no
+                effect if ingress-policing-rate is 0.";
+            type uint32;
+        }
     }
 
     augment "/topo:network-topology/topo:topology/topo:node" {
index 0b3d0a08fb6960bc7080ff1f23cd9584d2e03cd7..4f28835230fff9f933b6f6e1f4c639f53af05b0e 100755 (executable)
@@ -40,8 +40,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeSystem;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeEgressPolicer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeLinuxHfsc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeLinuxHtb;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeLinuxCodel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeLinuxFqCodel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeLinuxSfq;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 
 import com.google.common.collect.ImmutableBiMap;
@@ -53,7 +57,10 @@ public class SouthboundConstants {
     public static final String BRIDGE_URI_PREFIX = "bridge";
     public static final String TP_URI_PREFIX = "terminationpoint";
     public static final String QOS_URI_PREFIX = "qos";
+    public static final String QOS_NAMED_UUID_PREFIX = "QOS";
+    public static final Integer PORT_QOS_LIST_KEY = 1;
     public static final String QUEUE_URI_PREFIX = "queue";
+    public static final String QUEUE_NAMED_UUID_PREFIX = "QUEUE";
     public static final String AUTOATTACH_URI_PREFIX = "autoattach";
     public static final String AUTOATTACH_SUPPORTED_OVS_SCHEMA_VERSION = "7.11.2";
     public static final Integer DEFAULT_OVSDB_PORT = 6640;
@@ -62,10 +69,20 @@ public class SouthboundConstants {
     public static final String UUID = "uuid";
     public static final String QOS_LINUX_HTB = "linux-htb";
     public static final String QOS_LINUX_HFSC = "linux-hfsc";
+    // The following four QoS types are present in OVS 2.5+
+    // Refer to http://openvswitch.org/support/dist-docs/ovs-vswitchd.conf.db.5.txt
+    public static final String QOS_LINUX_SFQ = "linux-sfq";
+    public static final String QOS_LINUX_CODEL = "linux-codel";
+    public static final String QOS_LINUX_FQ_CODEL = "linux-fq_codel";
+    public static final String QOS_EGRESS_POLICER = "egress-policer";
     public static final ImmutableBiMap<Class<? extends QosTypeBase>,String> QOS_TYPE_MAP
         = new ImmutableBiMap.Builder<Class<? extends QosTypeBase>,String>()
             .put(QosTypeLinuxHtb.class,QOS_LINUX_HTB)
             .put(QosTypeLinuxHfsc.class,QOS_LINUX_HFSC)
+            .put(QosTypeLinuxSfq.class,QOS_LINUX_SFQ)
+            .put(QosTypeLinuxCodel.class,QOS_LINUX_CODEL)
+            .put(QosTypeLinuxFqCodel.class,QOS_LINUX_FQ_CODEL)
+            .put(QosTypeEgressPolicer.class,QOS_EGRESS_POLICER)
             .build();
 
     public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
@@ -111,8 +128,6 @@ public class SouthboundConstants {
             .put(DatapathTypeNetdev.class,"netdev")
             .build();
     public static final String IID_EXTERNAL_ID_KEY = "opendaylight-iid";
-    public static final String QOS_ID_EXTERNAL_ID_KEY = "opendaylight-qos-id";
-    public static final String QUEUE_ID_EXTERNAL_ID_KEY = "opendaylight-queue-id";
     public static final String AUTOATTACH_ID_EXTERNAL_ID_KEY = "opendaylight-autoattach-id";
 
     public enum VLANMODES {
index 4f1cb86da4040d6135d6aa5e93da0a235dfa30c9..e3322fd6f5f58361d1852784a9dca9da84deaf10 100644 (file)
@@ -23,15 +23,21 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Qos;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
 import org.opendaylight.ovsdb.utils.yang.YangUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -71,6 +77,7 @@ public class QosUpdateCommand implements TransactCommand {
         }
         OvsdbNodeAugmentation operNode = state.getBridgeNode(iid).get().getAugmentation(OvsdbNodeAugmentation.class);
         List<QosEntries> operQosEntries = operNode.getQosEntries();
+        List<Queues> operQueues = operNode.getQueues();
 
         if (qosEntries != null) {
             for (QosEntries qosEntry : qosEntries) {
@@ -80,17 +87,15 @@ public class QosUpdateCommand implements TransactCommand {
                     qos.setType(SouthboundMapper.createQosType(qosEntry.getQosType()));
                 }
 
-                Uuid qosUuid = getQosEntryUuid(operQosEntries, qosEntry.getQosId());
-                UUID uuid = null;
-                if (qosUuid != null) {
-                    uuid = new UUID(qosUuid.getValue());
-                }
-
                 List<QueueList> queueList = qosEntry.getQueueList();
                 Map<Long, UUID>newQueueList = new HashMap<>();
                 if (queueList != null && !queueList.isEmpty()) {
                     for (QueueList queue : queueList) {
-                        newQueueList.put(queue.getQueueNumber(), new UUID(queue.getQueueUuid().getValue()));
+                        if (queue.getQueueRef() != null) {
+                            newQueueList.put(queue.getQueueNumber(), new UUID(getQueueUuid(queue.getQueueRef(), operNode)));
+                        } else if (queue.getQueueUuid() != null) {
+                            newQueueList.put(queue.getQueueNumber(), new UUID(queue.getQueueUuid().getValue()));
+                        }
                     }
                 }
                 qos.setQueues(newQueueList);
@@ -102,7 +107,11 @@ public class QosUpdateCommand implements TransactCommand {
                 } catch (NullPointerException e) {
                     LOG.warn("Incomplete Qos external IDs", e);
                 }
-                externalIdsMap.put(SouthboundConstants.QOS_ID_EXTERNAL_ID_KEY, qosEntry.getQosId().getValue());
+                externalIdsMap.put(SouthboundConstants.IID_EXTERNAL_ID_KEY,
+                        SouthboundUtil.serializeInstanceIdentifier(
+                        SouthboundMapper.createInstanceIdentifier(iid.firstKeyOf(Node.class, NodeKey.class).getNodeId())
+                        .augmentation(OvsdbNodeAugmentation.class)
+                        .child(QosEntries.class, new QosEntriesKey(qosEntry.getQosId()))));
                 qos.setExternalIds(externalIdsMap);
 
                 try {
@@ -111,9 +120,14 @@ public class QosUpdateCommand implements TransactCommand {
                 } catch (NullPointerException e) {
                     LOG.warn("Incomplete Qos other_config", e);
                 }
-                if (uuid == null) {
-                    transaction.add(op.insert(qos)).build();
+
+                Uuid operQosUuid = getQosEntryUuid(operQosEntries, qosEntry.getQosId());
+                if (operQosUuid == null) {
+                    UUID namedUuid = new UUID(SouthboundConstants.QOS_NAMED_UUID_PREFIX +
+                            TransactUtils.bytesToHexString(qosEntry.getQosId().getValue().getBytes()));
+                    transaction.add(op.insert(qos).withId(namedUuid.toString())).build();
                 } else {
+                    UUID uuid = new UUID(operQosUuid.getValue());
                     Qos extraQos = TyperUtils.getTypedRowWrapper(
                             transaction.getDatabaseSchema(), Qos.class, null);
                     extraQos.getUuidColumn().setData(uuid);
@@ -125,6 +139,19 @@ public class QosUpdateCommand implements TransactCommand {
         }
     }
 
+    private String getQueueUuid(OvsdbQueueRef queueRef, OvsdbNodeAugmentation operNode) {
+        QueuesKey queueKey = queueRef.getValue().firstKeyOf(Queues.class);
+        if (operNode.getQueues() != null && !operNode.getQueues().isEmpty()) {
+            for (Queues queue : operNode.getQueues()) {
+                if (queue.getQueueId().equals(queueKey.getQueueId())) {
+                    return queue.getQueueUuid().getValue();
+                }
+            }
+        }
+        return SouthboundConstants.QUEUE_NAMED_UUID_PREFIX +
+            TransactUtils.bytesToHexString(queueKey.getQueueId().getValue().getBytes());
+    }
+
     private Uuid getQosEntryUuid(List<QosEntries> operQosEntries, Uri qosId) {
         if (operQosEntries != null && !operQosEntries.isEmpty()) {
             for (QosEntries qosEntry : operQosEntries) {
index 6018b8572a898dcb82280756b469584d701dc47f..8d9ea99798e634b0b4baea111663aa873a22d20b 100644 (file)
@@ -24,14 +24,18 @@ import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Queue;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
 import org.opendaylight.ovsdb.utils.yang.YangUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -87,12 +91,6 @@ public class QueueUpdateCommand implements TransactCommand {
                     }
                 }
 
-                Uuid queueUuid = getQueueEntryUuid(operQueues, queueEntry.getQueueId());
-                UUID uuid = null;
-                if (queueUuid != null) {
-                    uuid = new UUID(queueUuid.getValue());
-                }
-
                 Map<String, String> externalIdsMap = new HashMap<>();
                 try {
                     YangUtils.copyYangKeyValueListToMap(externalIdsMap, queueEntry.getQueuesExternalIds(),
@@ -100,7 +98,11 @@ public class QueueUpdateCommand implements TransactCommand {
                 } catch (NullPointerException e) {
                     LOG.warn("Incomplete Queue external IDs", e);
                 }
-                externalIdsMap.put(SouthboundConstants.QUEUE_ID_EXTERNAL_ID_KEY, queueEntry.getQueueId().getValue());
+                externalIdsMap.put(SouthboundConstants.IID_EXTERNAL_ID_KEY,
+                        SouthboundUtil.serializeInstanceIdentifier(
+                        SouthboundMapper.createInstanceIdentifier(iid.firstKeyOf(Node.class, NodeKey.class).getNodeId())
+                        .augmentation(OvsdbNodeAugmentation.class)
+                        .child(Queues.class, new QueuesKey(queueEntry.getQueueId()))));
                 queue.setExternalIds(externalIdsMap);
 
                 try {
@@ -109,10 +111,15 @@ public class QueueUpdateCommand implements TransactCommand {
                 } catch (NullPointerException e) {
                     LOG.warn("Incomplete Queue other_config", e);
                 }
-                if (uuid == null) {
-                    transaction.add(op.insert(queue)).build();
+
+                Uuid operQueueUuid = getQueueEntryUuid(operQueues, queueEntry.getQueueId());
+                if (operQueueUuid == null) {
+                    UUID namedUuid = new UUID(SouthboundConstants.QUEUE_NAMED_UUID_PREFIX +
+                            TransactUtils.bytesToHexString(queueEntry.getQueueId().getValue().getBytes()));
+                    transaction.add(op.insert(queue).withId(namedUuid.toString())).build();
                 } else {
-                    transaction.add(op.update(queue)).build();
+                    UUID uuid = new UUID(operQueueUuid.getValue());
+                    //transaction.add(op.update(queue)).build();
                     Queue extraQueue = TyperUtils.getTypedRowWrapper(
                             transaction.getDatabaseSchema(), Queue.class, null);
                     extraQueue.getUuidColumn().setData(uuid);
index 3e91aab5e6f2a5a7e6dfd2399df0dfac1b495df1..0425d39e874eead6b1c9e2c07aee5cb51aeb0f6b 100644 (file)
@@ -16,20 +16,32 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
 import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundProvider;
 import org.opendaylight.ovsdb.utils.yang.YangUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQosRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
@@ -44,7 +56,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.CheckedFuture;
 
 public class TerminationPointUpdateCommand implements TransactCommand {
 
@@ -53,27 +67,27 @@ public class TerminationPointUpdateCommand implements TransactCommand {
     @Override
     public void execute(TransactionBuilder transaction, BridgeOperationalState state,
                         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> events) {
-        execute(transaction, TransactUtils.extractCreatedOrUpdated(events, OvsdbTerminationPointAugmentation.class));
+        execute(transaction, state, TransactUtils.extractCreatedOrUpdated(events, OvsdbTerminationPointAugmentation.class));
     }
 
     @Override
     public void execute(TransactionBuilder transaction, BridgeOperationalState state,
                         Collection<DataTreeModification<Node>> modifications) {
-        execute(transaction,
+        execute(transaction, state,
                 TransactUtils.extractCreatedOrUpdated(modifications, OvsdbTerminationPointAugmentation.class));
     }
 
-    private void execute(TransactionBuilder transaction,
+    private void execute(TransactionBuilder transaction, BridgeOperationalState state,
                          Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>,
                                  OvsdbTerminationPointAugmentation> createdOrUpdated) {
         LOG.trace("TerminationPointUpdateCommand called");
         for (Entry<InstanceIdentifier<OvsdbTerminationPointAugmentation>,
                 OvsdbTerminationPointAugmentation> terminationPointEntry : createdOrUpdated.entrySet()) {
-            updateTerminationPoint(transaction, terminationPointEntry.getKey(), terminationPointEntry.getValue());
+            updateTerminationPoint(transaction, state, terminationPointEntry.getKey(), terminationPointEntry.getValue());
         }
     }
 
-    public void updateTerminationPoint(TransactionBuilder transaction,
+    public void updateTerminationPoint(TransactionBuilder transaction, BridgeOperationalState state,
                                        InstanceIdentifier<OvsdbTerminationPointAugmentation> iid,
                                        OvsdbTerminationPointAugmentation terminationPoint) {
         if (terminationPoint != null) {
@@ -95,9 +109,10 @@ public class TerminationPointUpdateCommand implements TransactCommand {
                     iid.firstIdentifierOf(OvsdbTerminationPointAugmentation.class), terminationPoint.getName());
 
             // Update port
+            OvsdbBridgeAugmentation operBridge = state.getBridgeNode(iid).get().getAugmentation(OvsdbBridgeAugmentation.class);
             Port port = TyperUtils.getTypedRowWrapper(
                     transaction.getDatabaseSchema(), Port.class);
-            updatePort(terminationPoint, port);
+            updatePort(terminationPoint, port, operBridge);
             Port extraPort = TyperUtils.getTypedRowWrapper(
                     transaction.getDatabaseSchema(), Port.class);
             extraPort.setName("");
@@ -117,32 +132,74 @@ public class TerminationPointUpdateCommand implements TransactCommand {
         updateInterfaceExternalIds(terminationPoint, ovsInterface);
         updateInterfaceLldp(terminationPoint, ovsInterface);
         updateInterfaceBfd(terminationPoint, ovsInterface);
+        updateInterfacePolicing(terminationPoint, ovsInterface);
     }
 
     private void updatePort(
             final OvsdbTerminationPointAugmentation terminationPoint,
-            final Port port) {
+            final Port port,
+            final OvsdbBridgeAugmentation operBridge) {
 
         updatePortOtherConfig(terminationPoint, port);
         updatePortVlanTag(terminationPoint, port);
         updatePortVlanTrunk(terminationPoint, port);
         updatePortVlanMode(terminationPoint, port);
         updatePortExternalIds(terminationPoint, port);
-        updatePortQos(terminationPoint, port);
+        updatePortQos(terminationPoint, port, operBridge);
     }
 
     private void updatePortQos(
             final OvsdbTerminationPointAugmentation terminationPoint,
-            final Port port) {
+            final Port port,
+            final OvsdbBridgeAugmentation operBridge) {
 
         Set<UUID> uuidSet = Sets.newHashSet();
-        Uuid qosUuid = terminationPoint.getQos();
-        if (qosUuid != null) {
-            uuidSet.add(new UUID(qosUuid.getValue()));
+
+        // First check if QosEntry is present and use that
+        if (terminationPoint.getQosEntry() != null && !terminationPoint.getQosEntry().isEmpty()) {
+            OvsdbQosRef qosRef = terminationPoint.getQosEntry().iterator().next().getQosRef();
+            Uri qosId = qosRef.getValue().firstKeyOf(QosEntries.class).getQosId();
+            OvsdbNodeAugmentation operNode = getOperNode(operBridge);
+            if (operNode != null && operNode.getQosEntries() != null &&
+                    !operNode.getQosEntries().isEmpty()) {
+                for (QosEntries qosEntry : operNode.getQosEntries()) {
+                    if (qosEntry.getQosId().equals(qosId)) {
+                        uuidSet.add(new UUID(qosEntry.getQosUuid().getValue()));
+                    }
+                }
+            }
+            if (uuidSet.size() == 0) {
+                uuidSet.add(new UUID(SouthboundConstants.QOS_NAMED_UUID_PREFIX +
+                            TransactUtils.bytesToHexString(qosId.getValue().getBytes())));
+            }
+        } else {
+            // Second check if Qos is present and use that (deprecated)
+            // Do not bother to check if QosEntry and Qos are consistent if both are present
+            Uuid qosUuid = terminationPoint.getQos();
+            if (qosUuid != null) {
+                uuidSet.add(new UUID(qosUuid.getValue()));
+            }
         }
         port.setQos(uuidSet);
     }
 
+    private OvsdbNodeAugmentation getOperNode(final OvsdbBridgeAugmentation operBridge) {
+        @SuppressWarnings("unchecked")
+        InstanceIdentifier<Node> iidNode = (InstanceIdentifier<Node>)operBridge.getManagedBy().getValue();
+        OvsdbNodeAugmentation operNode = null;
+        ReadOnlyTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction();
+        CheckedFuture<Optional<Node>, ReadFailedException> future =
+                transaction.read(LogicalDatastoreType.OPERATIONAL, iidNode);
+        try {
+            Optional<Node> nodeOptional = future.get();
+            if (nodeOptional.isPresent()) {
+                operNode = nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class);
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.warn("Error reading from datastore", e);
+        }
+        return operNode;
+    }
 
     private void updateOfPort(
             final OvsdbTerminationPointAugmentation terminationPoint,
@@ -255,6 +312,20 @@ public class TerminationPointUpdateCommand implements TransactCommand {
         }
     }
 
+    private void updateInterfacePolicing(
+            final OvsdbTerminationPointAugmentation terminationPoint,
+            final Interface ovsInterface) {
+
+        Long ingressPolicingRate = terminationPoint.getIngressPolicingRate();
+        if (ingressPolicingRate != null) {
+            ovsInterface.setIngressPolicingRate(ingressPolicingRate);
+        }
+        Long ingressPolicingBurst = terminationPoint.getIngressPolicingBurst();
+        if (ingressPolicingBurst != null) {
+            ovsInterface.setIngressPolicingBurst(ingressPolicingBurst);
+        }
+    }
+
     private void updatePortExternalIds(
             final OvsdbTerminationPointAugmentation terminationPoint,
             final Port port) {
index 26b9581fa0675e1eed73f19a85e2612bd8964f08..3accf490c5fcf8b38ea97d749a19112fee78ef5e 100644 (file)
@@ -492,4 +492,41 @@ public class TransactUtils {
         mutate.setMutations(mutations);
         return mutate;
     }
+
+    /**
+     * This method builds a string by concatenating the 2 character
+     * hexadecimal representation of each byte from the input byte array.
+     *
+     * For example: an input byte array containing:
+     *   bytes[0] = 'a'
+     *   bytes[1] = 'b'
+     *   bytes[2] = 'c'
+     *   bytes[3] = '-'
+     *   bytes[4] = '1'
+     *   bytes[5] = '2'
+     *   bytes[6] = '3'
+     * returns the string "6162632d313233"
+     *
+     * @param bytes
+     *            The byte array to convert to string
+     * @return The hexadecimal representation of the byte array. If bytes is
+     *         null, the string "" is returned
+     */
+    public static String bytesToHexString(byte[] bytes) {
+
+        if (bytes == null) {
+            return "";
+        }
+
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < bytes.length; i++) {
+            short u8byte = (short) (bytes[i] & 0xff);
+            String tmp = Integer.toHexString(u8byte);
+            if (tmp.length() == 1) {
+                buf.append("0");
+            }
+            buf.append(tmp);
+        }
+        return buf.toString();
+    }
 }
index 81c39e861507418b3077621c3ac4fbaa9105f31a..da65b5b13e5bee7b344c564a5beb6b6645df5c55 100644 (file)
@@ -30,18 +30,22 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
 import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.ovsdb.schema.openvswitch.Qos;
 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQosRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdKey;
@@ -62,6 +66,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
@@ -87,6 +94,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
     private Map<UUID, Interface> interfaceUpdatedRows;
     private Map<UUID, Interface> interfaceOldRows;
     private Map<UUID, Bridge> bridgeUpdatedRows;
+    private Map<UUID, Qos> qosUpdatedRows;
     public OvsdbPortUpdateCommand(OvsdbConnectionInstance key, TableUpdates updates,
             DatabaseSchema dbSchema) {
         super(key, updates, dbSchema);
@@ -95,6 +103,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         interfaceUpdatedRows = TyperUtils.extractRowsUpdated(Interface.class, updates, dbSchema);
         interfaceOldRows = TyperUtils.extractRowsOld(Interface.class, updates, dbSchema);
         bridgeUpdatedRows = TyperUtils.extractRowsUpdated(Bridge.class, updates, dbSchema);
+        qosUpdatedRows = TyperUtils.extractRowsUpdated(Qos.class, updates, dbSchema);
     }
 
     @Override
@@ -127,7 +136,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
                         getInstanceIdentifier(bridgeIid.get(), portUpdate.getValue());
                 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
                         new OvsdbTerminationPointAugmentationBuilder();
-                buildTerminationPoint(tpAugmentationBuilder,portUpdate.getValue());
+                buildTerminationPoint(transaction, tpPath, tpAugmentationBuilder, node, portUpdate);
                 UUID interfaceUUID = (UUID)portUpdate.getValue().getInterfacesColumn().getData().toArray()[0];
                 if (interfaceUpdatedRows.containsKey(interfaceUUID)) {
                     buildTerminationPoint(tpAugmentationBuilder,
@@ -170,14 +179,16 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         }
 
     }
-    private void buildTerminationPoint(OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder,
-            Port portUpdate) {
+    private void buildTerminationPoint(ReadWriteTransaction transaction,
+            InstanceIdentifier<TerminationPoint> tpPath,
+            OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder,
+            Node node, Entry<UUID, Port> portUpdate) {
 
         tpAugmentationBuilder
-                .setName(portUpdate.getName());
+                .setName(portUpdate.getValue().getName());
         tpAugmentationBuilder.setPortUuid(new Uuid(
-                portUpdate.getUuid().toString()));
-        updatePort(portUpdate, tpAugmentationBuilder);
+                portUpdate.getValue().getUuid().toString()));
+        updatePort(transaction, node, tpPath, portUpdate, tpAugmentationBuilder);
     }
 
     private void buildTerminationPoint(OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder,
@@ -238,15 +249,16 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         updateInterface(interfaceUpdate, type,ovsdbTerminationPointBuilder);
     }
 
-    private void updatePort(final Port port,
+    private void updatePort(final ReadWriteTransaction transaction, final Node node,
+            final InstanceIdentifier<TerminationPoint> tpPath, final Entry<UUID, Port> port,
             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
 
-        updateVlan(port, ovsdbTerminationPointBuilder);
-        updateVlanTrunks(port, ovsdbTerminationPointBuilder);
-        updateVlanMode(port, ovsdbTerminationPointBuilder);
-        updateQos(port, ovsdbTerminationPointBuilder);
-        updatePortExternalIds(port, ovsdbTerminationPointBuilder);
-        updatePortOtherConfig(port, ovsdbTerminationPointBuilder);
+        updateVlan(port.getValue(), ovsdbTerminationPointBuilder);
+        updateVlanTrunks(port.getValue(), ovsdbTerminationPointBuilder);
+        updateVlanMode(port.getValue(), ovsdbTerminationPointBuilder);
+        updateQos(transaction, node, tpPath, port, ovsdbTerminationPointBuilder);
+        updatePortExternalIds(port.getValue(), ovsdbTerminationPointBuilder);
+        updatePortOtherConfig(port.getValue(), ovsdbTerminationPointBuilder);
     }
 
     private void updateInterface(final Interface interf,
@@ -265,6 +277,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         updateInterfaceLldp(interf, ovsdbTerminationPointBuilder);
         updateInterfaceBfd(interf, ovsdbTerminationPointBuilder);
         updateInterfaceBfdStatus(interf, ovsdbTerminationPointBuilder);
+        updateInterfacePolicing(interf, ovsdbTerminationPointBuilder);
     }
 
     private void updateVlan(final Port port,
@@ -320,17 +333,81 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         }
     }
 
-    private void updateQos(final Port port,
-            final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
-        if (port.getQosColumn() == null) {
+    private void updateQos(final ReadWriteTransaction transaction, final Node node, InstanceIdentifier<TerminationPoint> tpPath,
+            final Entry<UUID, Port> port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
+        if (port.getValue() == null) {
             return;
         }
-        Collection<UUID> qosUuidCol = port.getQosColumn().getData();
+        Collection<UUID> qosUuidCol = port.getValue().getQosColumn().getData();
         if (!qosUuidCol.isEmpty()) {
-            Iterator<UUID> itr = qosUuidCol.iterator();
-            UUID qosUuid = itr.next();
+            UUID qosUuid = qosUuidCol.iterator().next();
             ovsdbTerminationPointBuilder.setQos(new Uuid(qosUuid.toString()));
+
+            NodeId nodeId = node.getNodeId();
+            OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class);
+
+            // Delete an older QoS entry
+            if (portOldRows.containsKey(port.getKey()) &&
+                    portOldRows.get(port.getKey()).getQosColumn() != null) {
+                Collection<UUID> oldQos = portOldRows.get(port.getKey()).getQosColumn().getData();
+                if (!oldQos.isEmpty()) {
+                    UUID oldQosUuid = oldQos.iterator().next();
+                    if (!oldQosUuid.equals(qosUuid)) {
+                        InstanceIdentifier<QosEntries> oldQosIid = getQosIid(nodeId, ovsdbNode, oldQosUuid);
+                        if (oldQosIid != null) {
+                            InstanceIdentifier<QosEntry> oldPortQosIid = tpPath
+                                .augmentation(OvsdbTerminationPointAugmentation.class)
+                                .child(QosEntry.class,
+                                      new QosEntryKey(new Long(SouthboundConstants.PORT_QOS_LIST_KEY)));
+//                                    new QosEntryKey(new OvsdbQosRef(oldQosIid)));
+                            transaction.delete(LogicalDatastoreType.OPERATIONAL, oldPortQosIid);
+                        }
+                    }
+                }
+            }
+
+            InstanceIdentifier<QosEntries> qosIid = getQosIid(nodeId, ovsdbNode, qosUuid);
+            if (qosIid != null) {
+                List<QosEntry> qosList = new ArrayList<>();
+                OvsdbQosRef qosRef = new OvsdbQosRef(qosIid);
+                qosList.add(new QosEntryBuilder()
+                    .setKey(new QosEntryKey(new Long(SouthboundConstants.PORT_QOS_LIST_KEY)))
+                    .setQosRef(qosRef).build());
+                ovsdbTerminationPointBuilder.setQosEntry(qosList);
+            }
+        }
+    }
+
+    private InstanceIdentifier<QosEntries> getQosIid(NodeId nodeId, OvsdbNodeAugmentation ovsdbNode, UUID qosUuid) {
+        // Search for the QoS entry first in the operational datastore
+        for (QosEntries qosEntry : ovsdbNode.getQosEntries()) {
+            if (qosEntry.getQosUuid().equals(new Uuid(qosUuid.toString()))) {
+                return SouthboundMapper.createInstanceIdentifier(nodeId)
+                        .augmentation(OvsdbNodeAugmentation.class)
+                        .child(QosEntries.class, new QosEntriesKey(qosEntry.getQosId()));
+            }
+        }
+
+        // Search for the QoS entry in the current OVS updates
+        for (Entry<UUID, Qos> qosUpdate : qosUpdatedRows.entrySet()) {
+            Qos qos = qosUpdate.getValue();
+            if (qos.getUuid().equals(qosUuid)) {
+                if (qos.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
+                    return (InstanceIdentifier<QosEntries>) SouthboundUtil.deserializeInstanceIdentifier(
+                            qos.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY));
+                } else {
+                    return SouthboundMapper.createInstanceIdentifier(nodeId)
+                            .augmentation(OvsdbNodeAugmentation.class)
+                            .child(QosEntries.class, new QosEntriesKey(
+                                    new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString())));
+                }
+            }
         }
+        LOG.debug("QoS UUID {} assigned to port not found in operational node {} or QoS updates", qosUuid, ovsdbNode);
+        return SouthboundMapper.createInstanceIdentifier(nodeId)
+                .augmentation(OvsdbNodeAugmentation.class)
+                .child(QosEntries.class, new QosEntriesKey(
+                        new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString())));
     }
 
     private void updateOfPort(final Interface interf,
@@ -548,6 +625,38 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         }
     }
 
+    private void updateInterfacePolicing(final Interface interf,
+            final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
+
+        Long ingressPolicingRate = null;
+        if (interf.getIngressPolicingRateColumn() != null) {
+            ingressPolicingRate = interf.getIngressPolicingRateColumn().getData();
+        }
+        if (ingressPolicingRate != null) {
+            if (ingressPolicingRate >= 0) {
+                ovsdbTerminationPointBuilder
+                    .setIngressPolicingRate(ingressPolicingRate);
+            } else {
+                LOG.debug("Received negative value for ingressPolicingRate from ovsdb for {} {}",
+                        interf.getName(),ingressPolicingRate);
+            }
+        }
+
+        Long ingressPolicingBurst = null;
+        if (interf.getIngressPolicingBurstColumn() != null) {
+            ingressPolicingBurst = interf.getIngressPolicingBurstColumn().getData();
+        }
+        if (ingressPolicingBurst != null) {
+            if (ingressPolicingBurst >= 0) {
+                ovsdbTerminationPointBuilder
+                    .setIngressPolicingBurst(ingressPolicingBurst);
+            } else {
+                LOG.debug("Received negative value for ingressPolicingBurst from ovsdb for {} {}",
+                        interf.getName(),ingressPolicingBurst);
+            }
+        }
+    }
+
     private boolean portQosCleared(Entry<UUID, Port> portUpdate) {
         if (portUpdate.getValue().getQosColumn() == null) {
             return false;
index 231c722278559dc3db2d85e2c7f6b287d17b4df2..7fff0ba220c12fb75413c958422d7e5f4e13f508 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Qos;
+import org.opendaylight.ovsdb.schema.openvswitch.Queue;
 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
@@ -29,7 +30,11 @@ import org.opendaylight.ovsdb.southbound.SouthboundUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder;
@@ -53,12 +58,14 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
 
     private Map<UUID, Qos> updatedQosRows;
     private Map<UUID, Qos> oldQosRows;
+    private Map<UUID, Queue> updatedQueueRows;
 
     public OvsdbQosUpdateCommand(OvsdbConnectionInstance key,
             TableUpdates updates, DatabaseSchema dbSchema) {
         super(key, updates, dbSchema);
         updatedQosRows = TyperUtils.extractRowsUpdated(Qos.class,getUpdates(), getDbSchema());
         oldQosRows = TyperUtils.extractRowsOld(Qos.class, getUpdates(), getDbSchema());
+        updatedQueueRows = TyperUtils.extractRowsUpdated(Queue.class, getUpdates(), getDbSchema());
     }
 
     @Override
@@ -98,7 +105,7 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
                         SouthboundMapper.createQosType(qos.getTypeColumn().getData().toString()));
                 setOtherConfig(transaction, qosEntryBuilder, oldQos, qos, nodeIId);
                 setExternalIds(transaction, qosEntryBuilder, oldQos, qos, nodeIId);
-                setQueueList(transaction, qosEntryBuilder, oldQos, qos, nodeIId);
+                setQueueList(transaction, qosEntryBuilder, oldQos, qos, nodeIId, ovsdbNode.get());
 
                 QosEntries qosEntry = qosEntryBuilder.build();
                 LOG.debug("Update Ovsdb Node {} with qos entries {}",ovsdbNode.get(), qosEntry);
@@ -114,10 +121,52 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
     private String getQosId(Qos qos) {
         if (qos.getExternalIdsColumn() != null
                 && qos.getExternalIdsColumn().getData() != null
-                && qos.getExternalIdsColumn().getData().containsKey(SouthboundConstants.QOS_ID_EXTERNAL_ID_KEY)) {
-            return qos.getExternalIdsColumn().getData().get(SouthboundConstants.QOS_ID_EXTERNAL_ID_KEY);
+                && qos.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
+            InstanceIdentifier<QosEntries> qosIid = (InstanceIdentifier<QosEntries>) SouthboundUtil.deserializeInstanceIdentifier(
+                    qos.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY));
+            if (qosIid != null) {
+                QosEntriesKey qosEntriesKey = qosIid.firstKeyOf(QosEntries.class);
+                if (qosEntriesKey != null) {
+                    return qosEntriesKey.getQosId().getValue();
+                }
+            }
+        }
+        return SouthboundConstants.QOS_URI_PREFIX + "://" + qos.getUuid().toString();
+    }
+
+    private Queue getQueue(UUID queueUuid)
+    {
+        for (Entry<UUID, Queue> entry : updatedQueueRows.entrySet()) {
+            if (entry.getKey().equals(queueUuid)) {
+                return entry.getValue();
+            }
+        }
+        return null;
+    }
+
+    private InstanceIdentifier<Queues> getQueueIid(UUID queueUuid, Node ovsdbNode) {
+        Queue queue = getQueue(queueUuid);
+        if (queue != null && queue.getExternalIdsColumn() != null
+                && queue.getExternalIdsColumn().getData() != null
+                && queue.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
+            return (InstanceIdentifier<Queues>) SouthboundUtil.deserializeInstanceIdentifier(
+                    queue.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY));
         } else {
-            return SouthboundConstants.QOS_URI_PREFIX + "://" + qos.getUuid().toString();
+            OvsdbNodeAugmentation node = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+            if (node.getQueues() != null && !node.getQueues().isEmpty()) {
+                for (Queues q : node.getQueues()) {
+                    if (q.getQueueUuid().equals(new Uuid(queueUuid.toString()))) {
+                        return SouthboundMapper.createInstanceIdentifier(ovsdbNode.getNodeId())
+                                .augmentation(OvsdbNodeAugmentation.class)
+                                .child(Queues.class, new QueuesKey(q.getQueueId()));
+                    }
+                }
+            }
+            LOG.debug("A Queue with UUID {} was not found in Ovsdb Node {}", queueUuid, node);
+            return SouthboundMapper.createInstanceIdentifier(ovsdbNode.getNodeId())
+                    .augmentation(OvsdbNodeAugmentation.class)
+                    .child(Queues.class, new QueuesKey(
+                            new Uri(SouthboundConstants.QUEUE_URI_PREFIX + "://" + queueUuid.toString())));
         }
     }
 
@@ -223,7 +272,7 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
 
     private void setQueueList(ReadWriteTransaction transaction,
             QosEntriesBuilder qosEntryBuilder, Qos oldQos, Qos qos,
-            InstanceIdentifier<Node> nodeIId) {
+            InstanceIdentifier<Node> nodeIId, Node ovsdbNode) {
         Map<Long,UUID> oldQueueList = null;
         Map<Long,UUID> queueList = null;
 
@@ -237,7 +286,7 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
             removeOldQueues(transaction, qosEntryBuilder, oldQueueList, qos, nodeIId);
         }
         if (queueList != null && !queueList.isEmpty()) {
-            setNewQueues(qosEntryBuilder, queueList);
+            setNewQueues(qosEntryBuilder, queueList, ovsdbNode);
         }
     }
 
@@ -257,13 +306,18 @@ public class OvsdbQosUpdateCommand extends AbstractTransactionCommand {
     }
 
     private void setNewQueues(QosEntriesBuilder qosEntryBuilder,
-            Map<Long, UUID> queueList) {
+            Map<Long, UUID> queueList, Node ovsdbNode) {
         Set<Entry<Long, UUID>> queueEntries = queueList.entrySet();
         List<QueueList> newQueueList = new ArrayList<>();
         for (Entry<Long, UUID> queueEntry : queueEntries) {
+            InstanceIdentifier<Queues> queueIid = getQueueIid(queueEntry.getValue(), ovsdbNode);
+            if (queueIid != null) {
             newQueueList.add(
-                    new QueueListBuilder().setQueueNumber(queueEntry.getKey())
+                    new QueueListBuilder()
+                    .setQueueNumber(queueEntry.getKey())
+                    .setQueueRef(new OvsdbQueueRef(queueIid))
                     .setQueueUuid(new Uuid(queueEntry.getValue().toString())).build());
+            }
         }
         qosEntryBuilder.setQueueList(newQueueList);
     }
index 6ba2609281c806d8a70ad8b5ab653678b3f40ba0..2a30c49dc1e7b1c1c1318d02086047195fa66c47 100644 (file)
@@ -29,6 +29,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder;
@@ -110,11 +111,17 @@ public class OvsdbQueueUpdateCommand extends AbstractTransactionCommand {
     private String getQueueId(Queue queue) {
         if (queue.getExternalIdsColumn() != null
                 && queue.getExternalIdsColumn().getData() != null
-                && queue.getExternalIdsColumn().getData().containsKey(SouthboundConstants.QUEUE_ID_EXTERNAL_ID_KEY)) {
-            return queue.getExternalIdsColumn().getData().get(SouthboundConstants.QUEUE_ID_EXTERNAL_ID_KEY);
-        } else {
-            return SouthboundConstants.QUEUE_URI_PREFIX + "://" + queue.getUuid().toString();
+                && queue.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
+            InstanceIdentifier<Queues> queueIid = (InstanceIdentifier<Queues>) SouthboundUtil.deserializeInstanceIdentifier(
+                    queue.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY));
+            if (queueIid != null) {
+                QueuesKey queuesKey = queueIid.firstKeyOf(Queues.class);
+                if (queuesKey != null) {
+                    return queuesKey.getQueueId().getValue();
+                }
+            }
         }
+        return SouthboundConstants.QUEUE_URI_PREFIX + "://" + queue.getUuid().toString();
     }
 
     private void setOtherConfig(ReadWriteTransaction transaction,
index d6379dda926fd22ae2da4914877e3101f32d9219..176a1b5bd54d006879c94c46e9f9f1e82cb86a29 100644 (file)
@@ -40,7 +40,9 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
 import org.opendaylight.ovsdb.schema.openvswitch.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.api.support.membermodification.MemberMatcher;
@@ -48,6 +50,8 @@ import org.powermock.api.support.membermodification.MemberModifier;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
+import com.google.common.base.Optional;
+
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({TerminationPointUpdateCommand.class, TransactUtils.class, TyperUtils.class, VlanMode.class, TerminationPointCreateCommand.class, InstanceIdentifier.class})
 public class TerminationPointUpdateCommandTest {
@@ -68,9 +72,10 @@ public class TerminationPointUpdateCommandTest {
         PowerMockito.mockStatic(TransactUtils.class);
         PowerMockito.when(TransactUtils.extractCreated(any(AsyncDataChangeEvent.class), eq(OvsdbTerminationPointAugmentation.class))).thenReturn(created);
         MemberModifier.suppress(MemberMatcher.method(TerminationPointUpdateCommand.class, "updateTerminationPoint",
-                TransactionBuilder.class, InstanceIdentifier.class, OvsdbTerminationPointAugmentation.class));
+                TransactionBuilder.class, BridgeOperationalState.class,
+                InstanceIdentifier.class, OvsdbTerminationPointAugmentation.class));
         doNothing().when(terminationPointUpdateCommand)
-                .updateTerminationPoint(any(TransactionBuilder.class), any(InstanceIdentifier.class), any(OvsdbTerminationPointAugmentation.class));
+                .updateTerminationPoint(any(TransactionBuilder.class), any(BridgeOperationalState.class), any(InstanceIdentifier.class), any(OvsdbTerminationPointAugmentation.class));
 
         Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> updated = new HashMap<>();
         updated.put(mock(InstanceIdentifier.class), mock(OvsdbTerminationPointAugmentation.class));
@@ -85,9 +90,14 @@ public class TerminationPointUpdateCommandTest {
     @Test
     public void testUpdateTerminationPoint() throws Exception {
         TransactionBuilder transaction = mock(TransactionBuilder.class);
+        BridgeOperationalState state = mock(BridgeOperationalState.class);
         InstanceIdentifier<OvsdbTerminationPointAugmentation> iid = mock(InstanceIdentifier.class);
         OvsdbTerminationPointAugmentation terminationPoint = mock(OvsdbTerminationPointAugmentation.class);
         when(terminationPoint.getName()).thenReturn(TERMINATION_POINT_NAME);
+        Optional<Node> optNode = (Optional<Node>)mock(Optional.class);
+        when(state.getBridgeNode(any(InstanceIdentifier.class))).thenReturn(optNode);
+        when(state.getBridgeNode(any(InstanceIdentifier.class)).get()).thenReturn(mock(Node.class));
+        when(state.getBridgeNode(any(InstanceIdentifier.class)).get().getAugmentation(OvsdbBridgeAugmentation.class)).thenReturn(mock(OvsdbBridgeAugmentation.class));
 
         // Test updateInterface()
         Interface ovsInterface = mock(Interface.class);
@@ -124,7 +134,7 @@ public class TerminationPointUpdateCommandTest {
         when(op.update(any(Port.class))).thenReturn(update);
         when(extraPort.getNameColumn()).thenReturn(column);
 
-        terminationPointUpdateCommand.updateTerminationPoint(transaction, iid, terminationPoint);
+        terminationPointUpdateCommand.updateTerminationPoint(transaction, state, iid, terminationPoint);
         verify(transaction, times(2)).add(any(Operation.class));
     }
 
index ab067cdbb669be94690de778b9900167fbca846f..77a35c70bf33a2d97e806070a6fe502ecfa3688b 100644 (file)
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -197,7 +198,8 @@ import com.google.common.util.concurrent.CheckedFuture;
 
         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = mock(OvsdbTerminationPointAugmentationBuilder.class);
         PowerMockito.whenNew(OvsdbTerminationPointAugmentationBuilder.class).withNoArguments().thenReturn(tpAugmentationBuilder);
-        PowerMockito.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "buildTerminationPoint", OvsdbTerminationPointAugmentationBuilder.class, Port.class));
+        PowerMockito.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "buildTerminationPoint", ReadWriteTransaction.class,
+                InstanceIdentifier.class, OvsdbTerminationPointAugmentationBuilder.class, Node.class, Entry.class));
 
         Column<GenericTableSchema, Set<UUID>> interfacesColumn = mock(Column.class);
         when(port.getInterfacesColumn()).thenReturn(interfacesColumn);
@@ -240,21 +242,31 @@ import com.google.common.util.concurrent.CheckedFuture;
         verify(transaction, times(2)).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(TerminationPoint.class));
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void testBuildTerminationPoint() throws Exception {
         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = mock(OvsdbTerminationPointAugmentationBuilder.class);
         Port portUpdate = mock(Port.class);
+        ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
+        InstanceIdentifier<TerminationPoint> tpPath = mock(InstanceIdentifier.class);
+        Entry<UUID,Port> portEntry = mock(Entry.class);
+        Node node = mock(Node.class);
+        when(portEntry.getValue()).thenReturn(mock(Port.class));
+        when(portEntry.getValue().getName()).thenReturn(PORT_NAME);
+        when(portEntry.getValue().getUuid()).thenReturn(mock(UUID.class));
         when(portUpdate.getName()).thenReturn(PORT_NAME);
         when(portUpdate.getUuid()).thenReturn(mock(UUID.class));
         PowerMockito.whenNew(Uuid.class).withAnyArguments().thenReturn(mock(Uuid.class));
         when(tpAugmentationBuilder.setName(anyString())).thenReturn(tpAugmentationBuilder);
         when(tpAugmentationBuilder.setPortUuid(any(Uuid.class))).thenReturn(tpAugmentationBuilder);
-        MemberModifier.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "updatePort", Port.class, OvsdbTerminationPointAugmentationBuilder.class));
+        MemberModifier.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "updatePort", 
+                ReadWriteTransaction.class, Node.class, InstanceIdentifier.class, Entry.class, OvsdbTerminationPointAugmentationBuilder.class));
 
-        Whitebox.invokeMethod(ovsdbPortUpdateCommand, "buildTerminationPoint", tpAugmentationBuilder, portUpdate);
+        Whitebox.invokeMethod(ovsdbPortUpdateCommand, "buildTerminationPoint", transaction, tpPath, tpAugmentationBuilder, node, portEntry);
         verify(tpAugmentationBuilder).setName(anyString());
         verify(tpAugmentationBuilder).setPortUuid(any(Uuid.class));
-        PowerMockito.verifyPrivate(ovsdbPortUpdateCommand).invoke("updatePort", any(Port.class), any(OvsdbTerminationPointAugmentationBuilder.class));
+        PowerMockito.verifyPrivate(ovsdbPortUpdateCommand).invoke("updatePort", any(ReadWriteTransaction.class), any(Node.class),
+                any(InstanceIdentifier.class), any(Entry.class), any(OvsdbTerminationPointAugmentationBuilder.class));
     }
 
     @Test
@@ -402,9 +414,13 @@ import com.google.common.util.concurrent.CheckedFuture;
         PowerMockito.verifyPrivate(ovsdbPortUpdateCommand).invoke("updateInterfaceOtherConfig", any(Interface.class), any(OvsdbTerminationPointAugmentationBuilder.class));
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void testUpdatePort() throws Exception {
-        Port port = mock(Port.class);
+        ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
+        Node node = mock(Node.class);
+        InstanceIdentifier<TerminationPoint> tpPath = (InstanceIdentifier<TerminationPoint>) mock(InstanceIdentifier.class);
+        Entry<UUID, Port> port = mock(Entry.class);
         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder = mock(OvsdbTerminationPointAugmentationBuilder.class);
 
         MemberModifier.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "updateVlan", Port.class, OvsdbTerminationPointAugmentationBuilder.class));
@@ -413,7 +429,7 @@ import com.google.common.util.concurrent.CheckedFuture;
         MemberModifier.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "updatePortExternalIds", Port.class, OvsdbTerminationPointAugmentationBuilder.class));
         MemberModifier.suppress(MemberMatcher.method(OvsdbPortUpdateCommand.class, "updatePortOtherConfig", Port.class, OvsdbTerminationPointAugmentationBuilder.class));
 
-        Whitebox.invokeMethod(ovsdbPortUpdateCommand, "updatePort", port, ovsdbTerminationPointBuilder);
+        Whitebox.invokeMethod(ovsdbPortUpdateCommand, "updatePort", transaction, node, tpPath, port, ovsdbTerminationPointBuilder);
 
         PowerMockito.verifyPrivate(ovsdbPortUpdateCommand).invoke("updateVlan", any(Port.class), any(OvsdbTerminationPointAugmentationBuilder.class));
         PowerMockito.verifyPrivate(ovsdbPortUpdateCommand).invoke("updateVlanTrunks", any(Port.class), any(OvsdbTerminationPointAugmentationBuilder.class));
index eb0824c57a03e6b95567c931d371832095c7662c..f2827211e52722221095df2476f94931c3fad8db 100644 (file)
@@ -2124,7 +2124,7 @@ public class SouthboundIT extends AbstractMdsalTestBase {
 
     private Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
         for (Queues queue : node.getQueues()) {
-            if (queue.getKey().getQueueId().equals(queueId))
+            if (queue.getKey().getQueueId().getValue().equals(queueId.getValue()))
                 return queue;
         }
         return null;